From c5859778bc18ef8114b57b616675de15a8e177cb Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 17 Jan 2020 21:08:38 +0200
Subject: SL-379 WIP Joint overrides tab

---
 indra/llcharacter/lljoint.cpp                      |   4 +-
 indra/llcharacter/lljoint.h                        |   4 +-
 indra/llui/llscrolllistctrl.cpp                    |   3 +-
 indra/llui/llscrolllistctrl.h                      |   1 +
 indra/newview/CMakeLists.txt                       |   1 +
 indra/newview/llfloatermodelpreview.cpp            | 141 ++++++++++++++++++++-
 indra/newview/llfloatermodelpreview.h              |   8 +-
 indra/newview/lljointoverridedata.h                |  52 ++++++++
 indra/newview/llvoavatar.cpp                       |  50 ++++++++
 indra/newview/llvoavatar.h                         |  26 ++--
 .../skins/default/xui/en/floater_model_preview.xml | 116 +++++++++++++++++
 11 files changed, 383 insertions(+), 23 deletions(-)
 create mode 100644 indra/newview/lljointoverridedata.h

(limited to 'indra')

diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index e2f512f86e..441ef1a352 100644
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -510,7 +510,7 @@ void LLJoint::clearAttachmentPosOverrides()
 // getAllAttachmentPosOverrides()
 //--------------------------------------------------------------------
 void LLJoint::getAllAttachmentPosOverrides(S32& num_pos_overrides,
-                                           std::set<LLVector3>& distinct_pos_overrides)
+                                           std::set<LLVector3>& distinct_pos_overrides) const
 {
     num_pos_overrides = m_attachmentPosOverrides.count();
     LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin();
@@ -524,7 +524,7 @@ void LLJoint::getAllAttachmentPosOverrides(S32& num_pos_overrides,
 // getAllAttachmentScaleOverrides()
 //--------------------------------------------------------------------
 void LLJoint::getAllAttachmentScaleOverrides(S32& num_scale_overrides,
-                                             std::set<LLVector3>& distinct_scale_overrides)
+                                             std::set<LLVector3>& distinct_scale_overrides) const
 {
     num_scale_overrides = m_attachmentScaleOverrides.count();
     LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin();
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index 8112d246f2..6f69786f53 100644
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -287,9 +287,9 @@ public:
     void showAttachmentScaleOverrides(const std::string& av_info) const;
 
     void getAllAttachmentPosOverrides(S32& num_pos_overrides,
-                                      std::set<LLVector3>& distinct_pos_overrides);
+                                      std::set<LLVector3>& distinct_pos_overrides) const;
     void getAllAttachmentScaleOverrides(S32& num_scale_overrides,
-                                        std::set<LLVector3>& distinct_scale_overrides);
+                                        std::set<LLVector3>& distinct_scale_overrides) const;
     
     // These are used in checks of whether a pos/scale override is considered significant.
     bool aboveJointPosThreshold(const LLVector3& pos) const;
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index f4028057e8..a564b5b2ce 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -132,6 +132,7 @@ LLScrollListCtrl::Params::Params()
 	sort_ascending("sort_ascending", true),
 	mouse_wheel_opaque("mouse_wheel_opaque", false),
 	commit_on_keyboard_movement("commit_on_keyboard_movement", true),
+	commit_on_selection_change("commit_on_selection_change", false),
 	heading_height("heading_height"),
 	page_lines("page_lines", 0),
 	background_visible("background_visible"),
@@ -161,7 +162,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mMaxSelectable(0),
 	mAllowKeyboardMovement(true),
 	mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
-	mCommitOnSelectionChange(false),
+	mCommitOnSelectionChange(p.commit_on_selection_change),
 	mSelectionChanged(false),
 	mNeedsScroll(false),
 	mCanSelect(true),
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index b35a8608e7..0d6ff67321 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -97,6 +97,7 @@ public:
 		// behavioral flags
 		Optional<bool>	multi_select,
 						commit_on_keyboard_movement,
+						commit_on_selection_change,
 						mouse_wheel_opaque;
 
 		// display flags
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 694e89ab99..7995e7ddf8 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1000,6 +1000,7 @@ set(viewer_HEADER_FILES
     llinventorymodelbackgroundfetch.h
     llinventoryobserver.h
     llinventorypanel.h
+    lljointoverridedata.h
     lljoystickbutton.h
     lllandmarkactions.h
     lllandmarklist.h
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 38b5fc271f..3e4d9020b7 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -404,9 +404,15 @@ BOOL LLFloaterModelPreview::postBuild()
 	mUploadLogText = getChild<LLViewerTextEditor>("log_text");
 	mTabContainer = getChild<LLTabContainer>("import_tab");
 
+    // Disable Overrides tab untill it has something to show and set callbacks
+    LLPanel *panel = mTabContainer->getPanelByName("overrides_panel");
+    S32 index = mTabContainer->getIndexForPanel(panel);
+    mTabContainer->enableTabButton(index, false);
+    panel->getChild<LLScrollListCtrl>("joints_list")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onJointListSelection, this));
+
 	// Disable Logs tab untill it has something to show
-	LLPanel* panel = mTabContainer->getPanelByName("logs_panel");
-	S32 index = mTabContainer->getIndexForPanel(panel);
+	panel = mTabContainer->getPanelByName("logs_panel");
+	index = mTabContainer->getIndexForPanel(panel);
 	mTabContainer->enableTabButton(index, false);
 
 	if (LLConvexDecomposition::getInstance() != NULL)
@@ -563,9 +569,12 @@ void LLFloaterModelPreview::onClickCalculateBtn()
 
     if (upload_joint_positions)
     {
-        // Diagnostic message showing list of joints for which joint offsets are defined.
-        // FIXME - given time, would be much better to put this in the UI, in updateStatusMessages().
-		mModelPreview->getPreviewAvatar()->showAttachmentOverrides();
+        // Todo: this probably should be enabled when checkbox enables, not on calculate
+        populateOverridesTab();
+    }
+    else
+    {
+        disableOverridesTab();
     }
 
 	mUploadModelUrl.clear();
@@ -580,6 +589,89 @@ void LLFloaterModelPreview::onClickCalculateBtn()
 	mUploadBtn->setEnabled(false);
 }
 
+void populate_list_with_vectors(LLScrollListCtrl *list, const std::set<LLVector3> &vector_set, const LLVector3 &active)
+{
+    if (vector_set.empty())
+    {
+        return;
+    }
+    S32 count = 0;
+    LLScrollListCell::Params cell_params;
+    cell_params.font = LLFontGL::getFontSansSerif();
+    // Start out right justifying numeric displays
+    cell_params.font_halign = LLFontGL::HCENTER;
+
+    std::set<LLVector3>::const_iterator iter = vector_set.begin();
+    std::set<LLVector3>::const_iterator end = vector_set.end();
+    while (iter != end)
+    {
+        LLScrollListItem::Params item_params;
+        item_params.value = LLSD::Integer(count);
+
+        cell_params.column = "override";
+        if (*iter != active)
+        {
+            cell_params.value = "";
+        }
+        else
+        {
+            cell_params.value = "active"; //todo: localize
+        }
+
+        item_params.columns.add(cell_params);
+
+        cell_params.column = "axis_x";
+        cell_params.value = iter->mV[VX];
+        item_params.columns.add(cell_params);
+
+        cell_params.column = "axis_y";
+        cell_params.value = iter->mV[VY];
+        item_params.columns.add(cell_params);
+
+        cell_params.column = "axis_z";
+        cell_params.value = iter->mV[VZ];
+
+        item_params.columns.add(cell_params);
+
+        list->addRow(item_params);
+        count++;
+        iter++;
+    }
+}
+
+void LLFloaterModelPreview::onJointListSelection()
+{
+    LLPanel *panel = mTabContainer->getPanelByName("overrides_panel");
+    LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
+    LLScrollListCtrl *joints_pos = panel->getChild<LLScrollListCtrl>("pos_overrides_list");
+    LLScrollListCtrl *joints_scale = panel->getChild<LLScrollListCtrl>("scale_overrides_list");
+    LLTextBox *joint_pos_descr = panel->getChild<LLTextBox>("pos_overrides_descr");
+    LLTextBox *joint_scale_descr = panel->getChild<LLTextBox>("scale_overrides_descr");
+
+    joints_pos->deleteAllItems();
+    joints_scale->deleteAllItems();
+
+    LLScrollListItem *selected = joints_list->getFirstSelected();
+    if (selected)
+    {
+        std::string label = selected->getValue().asString();
+        LLJointOverrideData *data = &mJointOverrides[label];
+        populate_list_with_vectors(joints_pos, data->mPosOverrides, data->mActivePosOverride);
+        populate_list_with_vectors(joints_scale, data->mScaleOverrides, data->mActiveScaleOverride);
+
+        joint_pos_descr->setTextArg("[JOINT]", label);
+        joint_scale_descr->setTextArg("[JOINT]", label);
+    }
+    else
+    {
+        // temporary value (shouldn't happen)
+        std::string label = "mPelvis";
+        joint_pos_descr->setTextArg("[JOINT]", label);
+        joint_scale_descr->setTextArg("[JOINT]", label);
+    }
+
+}
+
 void LLFloaterModelPreview::onDescriptionKeystroke(LLUICtrl* ctrl)
 {
 	// Workaround for SL-4186, server doesn't allow name changes after 'calculate' stage
@@ -3861,7 +3953,7 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget )
 	pTarget->setNumVolumeFaces( faceCnt+1 );	
 	pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() );
 	
-}	
+}
 
 //-----------------------------------------------------------------------------
 // render()
@@ -4813,6 +4905,43 @@ void LLFloaterModelPreview::clearLogTab()
     mTabContainer->setTabPanelFlashing(panel, false);
 }
 
+void LLFloaterModelPreview::populateOverridesTab()
+{
+    mJointOverrides.clear();
+    attach_override_data_map_t attach_not_in_use;
+    mModelPreview->getPreviewAvatar()->getAttachmentOverrides(mJointOverrides, attach_not_in_use);
+
+    if (mJointOverrides.empty())
+    {
+        disableOverridesTab();
+        return;
+    }
+
+    LLPanel *panel = mTabContainer->getPanelByName("overrides_panel");
+    S32 index = mTabContainer->getIndexForPanel(panel);
+    mTabContainer->enableTabButton(index, true);
+
+    LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
+    joints_list->deleteAllItems();
+    
+    joint_override_data_map_t::iterator joint_iter = mJointOverrides.begin();
+    joint_override_data_map_t::iterator joint_end = mJointOverrides.end();
+    while (joint_iter != joint_end)
+    {
+        const std::string& listName = joint_iter->first;
+        joints_list->addSimpleElement(listName);
+        joint_iter++;
+    }
+    joints_list->selectFirstItem();
+}
+
+void LLFloaterModelPreview::disableOverridesTab()
+{
+    LLPanel *panel = mTabContainer->getPanelByName("overrides_panel");
+    S32 index = mTabContainer->getIndexForPanel(panel);
+    mTabContainer->enableTabButton(index, false);
+}
+
 void LLFloaterModelPreview::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url)
 {
 	mModelPhysicsFee = result;
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 8f6ca49cb8..8988dd2565 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -30,6 +30,7 @@
 #include "llfloaternamedesc.h"
 
 #include "lldynamictexture.h"
+#include "lljointoverridedata.h"
 #include "llquaternion.h"
 #include "llmeshrepository.h"
 #include "llmodel.h"
@@ -213,7 +214,8 @@ protected:
 	LLSD mModelPhysicsFee;
 
 private:
-	void onClickCalculateBtn();
+    void onClickCalculateBtn();
+    void onJointListSelection();
 
 	void onLoDSourceCommit(S32 lod);
 
@@ -225,6 +227,8 @@ private:
 
 	void resetUploadOptions();
 	void clearLogTab();
+	void populateOverridesTab();
+	void disableOverridesTab();
 
 	void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
 
@@ -232,6 +236,8 @@ private:
 	LLButton* mCalculateBtn;
 	LLViewerTextEditor* mUploadLogText;
 	LLTabContainer* mTabContainer;
+
+	joint_override_data_map_t mJointOverrides;
 };
 
 class LLMeshFilePicker : public LLFilePickerThread
diff --git a/indra/newview/lljointoverridedata.h b/indra/newview/lljointoverridedata.h
new file mode 100644
index 0000000000..55e1878eec
--- /dev/null
+++ b/indra/newview/lljointoverridedata.h
@@ -0,0 +1,52 @@
+/**
+ * @file lljointoverridedata.h
+ * @brief Declaration of LLJointOverrideData and LLAttachmentOverrideData
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer2020, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_JOINTOVERRIDEDATA_H
+#define LL_JOINTOVERRIDEDATA_H
+
+//#include <map>
+//#include <string>
+//#include <vector>
+
+
+struct LLJointOverrideData
+{
+    std::set<LLVector3> mPosOverrides;
+    LLVector3 mActivePosOverride;
+    std::set<LLVector3> mScaleOverrides;
+    LLVector3 mActiveScaleOverride;
+};
+
+struct LLAttachmentOverrideData
+{
+    std::set<LLVector3> mPosOverrides;
+    LLVector3 mActivePosOverride;
+};
+
+typedef std::map<std::string, LLJointOverrideData> joint_override_data_map_t;
+typedef std::map<std::string, LLAttachmentOverrideData> attach_override_data_map_t;
+
+#endif // LL_JOINTOVERRIDEDATA_H
+
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index ca1216b89d..7700109fa4 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -6374,6 +6374,56 @@ void LLVOAvatar::showAttachmentOverrides(bool verbose) const
     }
 }
 
+//-----------------------------------------------------------------------------
+// getAttachmentOverrides
+//-----------------------------------------------------------------------------
+void LLVOAvatar::getAttachmentOverrides(joint_override_data_map_t &joint_overrides, attach_override_data_map_t &attach_overrides) const
+{
+    LLVector3 pos, scale;
+    LLUUID mesh_id;
+    S32 count = 0;
+
+    // Bones
+    for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin();
+        iter != mSkeleton.end(); ++iter)
+    {
+        const LLJoint* pJoint = (*iter);
+        LLJointOverrideData data;
+        bool joint_override = false;
+        if (pJoint && pJoint->hasAttachmentPosOverride(pos, mesh_id))
+        {
+            pJoint->getAllAttachmentPosOverrides(count, data.mPosOverrides);
+            data.mActivePosOverride = pos;
+            joint_override = true;
+        }
+        if (pJoint && pJoint->hasAttachmentScaleOverride(scale, mesh_id))
+        {
+            pJoint->getAllAttachmentScaleOverrides(count, data.mPosOverrides);
+            data.mActiveScaleOverride = scale;
+            joint_override = true;
+        }
+        if (joint_override)
+        {
+            joint_overrides[pJoint->getName()] = data;
+        }
+    }
+
+    // Attachment points
+    for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+        iter != mAttachmentPoints.end();
+        ++iter)
+    {
+        const LLViewerJointAttachment *attachment_pt = (*iter).second;
+        if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos, mesh_id))
+        {
+            LLAttachmentOverrideData data;
+            attachment_pt->getAllAttachmentPosOverrides(count, data.mPosOverrides);
+            data.mActivePosOverride = pos;
+            attach_overrides[attachment_pt->getName()] = data;
+        }
+    }
+}
+
 //-----------------------------------------------------------------------------
 // removeAttachmentOverridesForObject
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 00dccc5d12..53a1d48d72 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -36,23 +36,25 @@
 #include <boost/signals2/trackable.hpp>
 
 #include "llavatarappearance.h"
+#include "llavatarappearancedefines.h"
+#include "llavatarrendernotifier.h"
+#include "llcontrol.h"
+#include "llcharacter.h"
 #include "llchat.h"
 #include "lldrawpoolalpha.h"
-#include "llviewerobject.h"
-#include "llcharacter.h"
-#include "llcontrol.h"
-#include "llviewerjointmesh.h"
-#include "llviewerjointattachment.h"
-#include "llrendertarget.h"
-#include "llavatarappearancedefines.h"
-#include "lltexglobalcolor.h"
 #include "lldriverparam.h"
-#include "llviewertexlayer.h"
-#include "material_codes.h"		// LL_MCODE_END
+#include "lljointoverridedata.h"
+#include "llrendertarget.h"
 #include "llrigginginfo.h"
+#include "lltexglobalcolor.h"
+#include "llviewerjointmesh.h"
+#include "llviewerjointattachment.h"
+#include "llviewerobject.h"
 #include "llviewerstats.h"
+#include "llviewertexlayer.h"
 #include "llvovolume.h"
-#include "llavatarrendernotifier.h"
+
+#include "material_codes.h"		// LL_MCODE_END
 
 extern const LLUUID ANIM_AGENT_BODY_NOISE;
 extern const LLUUID ANIM_AGENT_BREATHE_ROT;
@@ -215,6 +217,8 @@ public:
 	void					rebuildAttachmentOverrides();
     void					updateAttachmentOverrides();
     void                    showAttachmentOverrides(bool verbose = false) const;
+    void                    getAttachmentOverrides(joint_override_data_map_t& joint_overrides,
+                                                   attach_override_data_map_t& attach_overrides) const;
     void                    getAttachmentOverrideNames(std::set<std::string>& pos_names, 
                                                        std::set<std::string>& scale_names) const;
 
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index f5be4bab10..b675a3e3be 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1246,6 +1246,122 @@
              value="0.0"
              width="80"/>
      </panel>
+      <panel
+       label="Overrides"
+       layout="topleft"
+       name="overrides_panel"
+       title="Overrides">
+        <view_border
+         bevel_style="none"
+         follows="top|left"
+         height="275"
+         layout="topleft"
+         left="3"
+         name="log_tab_border"
+         top_pad="0"
+         width="619" />
+        <text
+          layout="topleft"
+          follows="top|left"
+          height="15"
+          left="6"
+          name="joints_descr"
+          top="4"
+          width="300">
+          Joints:
+        </text>
+        <scroll_list
+         layout="topleft"
+         follows="top|left"
+         name="joints_list"
+         column_padding="0"
+         draw_heading="false"
+         draw_stripes="false"
+         commit_on_selection_change="true"
+         heading_height="23"
+         height="253"
+         left="6"
+         top_pad="0"
+         width="150"/>
+        <text
+          layout="topleft"
+          follows="top|left"
+          height="15"
+          left_pad="5"
+          name="pos_overrides_descr"
+          top="4"
+          width="300">
+          Position overrides for joint '[JOINT]':
+        </text>
+        <scroll_list
+         layout="topleft"
+         follows="top|left"
+         name="pos_overrides_list"
+         column_padding="0"
+         draw_heading="true"
+         draw_stripes="false"
+         heading_height="23"
+         height="100"
+         left_delta="0"
+         top_pad="0"
+         width="310">
+          <scroll_list.columns
+           label="*"
+           name="override"
+           relative_width="0.22"  />
+          <scroll_list.columns
+           label="X"
+           name="axis_x"
+           relative_width="0.26"  />
+          <scroll_list.columns
+           label="Y"
+           name="axis_y"
+           relative_width="0.26"  />
+          <scroll_list.columns
+           label="Z"
+           name="axis_z"
+           relative_width="0.26"  />
+        </scroll_list>
+        <text
+          layout="topleft"
+          follows="top|left"
+          height="15"
+          left_delta="0"
+          name="scale_overrides_descr"
+          top_pad="3"
+          width="300">
+          Scale overrides for joint '[JOINT]':
+        </text>
+        <scroll_list
+         layout="topleft"
+         follows="top|left"
+         name="scale_overrides_list"
+         column_padding="0"
+         draw_heading="true"
+         draw_stripes="false"
+         heading_height="23"
+         height="100"
+         left_delta="0"
+         top_pad="0"
+         width="310">
+          <scroll_list.columns
+           label="*"
+           name="override"
+           relative_width="0.22"  />
+          <scroll_list.columns
+           label="X"
+           name="axis_x"
+           relative_width="0.26"  />
+          <scroll_list.columns
+           label="Y"
+           name="axis_y"
+           relative_width="0.26"  />
+          <scroll_list.columns
+           label="Z"
+           name="axis_z"
+           relative_width="0.26"  />
+        </scroll_list>
+      </panel>
       <panel
        label="Log"
        layout="topleft"
-- 
cgit v1.2.3