From 3c2f3edb5fefff69e370f4e427dd23236cf8edbf Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Tue, 31 Mar 2020 15:40:48 +0300
Subject: [PATCH] SL-379 Render selected joint yellow when Avatar tab is open

---
 indra/newview/llfloatermodelpreview.cpp       | 52 +++++++++++--------
 indra/newview/llfloatermodelpreview.h         |  7 ++-
 indra/newview/llvoavatar.cpp                  | 21 ++++++--
 indra/newview/llvoavatar.h                    |  2 +-
 .../default/xui/en/floater_model_preview.xml  |  2 +-
 5 files changed, 55 insertions(+), 29 deletions(-)

diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index b0dfe19451c..2a0e51f496d 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -266,7 +266,8 @@ LLFloaterModelUploadBase(key),
 mUploadBtn(NULL),
 mCalculateBtn(NULL),
 mUploadLogText(NULL),
-mTabContainer(NULL)
+mTabContainer(NULL),
+mAvatarTabIndex(0)
 {
 	sInstance = this;
 	mLastMouseX = 0;
@@ -408,15 +409,10 @@ 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);
+    LLPanel *panel = mTabContainer->getPanelByName("avatar_panel");
+    mAvatarTabIndex = mTabContainer->getIndexForPanel(panel);
     panel->getChild<LLScrollListCtrl>("joints_list")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onJointListSelection, this));
 
-	// Disable Logs tab untill it has something to show
-	panel = mTabContainer->getPanelByName("logs_panel");
-	index = mTabContainer->getIndexForPanel(panel);
-
 	if (LLConvexDecomposition::getInstance() != NULL)
 	{
 	mCalculateBtn->setClickedCallback(boost::bind(&LLFloaterModelPreview::onClickCalculateBtn, this));
@@ -635,7 +631,7 @@ void populate_list_with_map(LLScrollListCtrl *list, const std::map<std::string,
 void LLFloaterModelPreview::onJointListSelection()
 {
     S32 display_lod = mModelPreview->mPreviewLOD;
-    LLPanel *panel = mTabContainer->getPanelByName("overrides_panel");
+    LLPanel *panel = mTabContainer->getPanelByName("avatar_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");
@@ -652,12 +648,14 @@ void LLFloaterModelPreview::onJointListSelection()
         populate_list_with_map(joints_pos, data.mPosOverrides);
 
         joint_pos_descr->setTextArg("[JOINT]", label);
+        mSelectedJointName = label;
     }
     else
     {
         // temporary value (shouldn't happen)
         std::string label = "mPelvis";
         joint_pos_descr->setTextArg("[JOINT]", label);
+        mSelectedJointName.clear();
     }
 
     // Note: We can make a version of renderBones() to highlight selected joint
@@ -1440,14 +1438,13 @@ void LLFloaterModelPreview::addStringToLog(const std::ostringstream& strm, bool
     }
 }
 
-void LLFloaterModelPreview::clearOverridesTab()
+void LLFloaterModelPreview::clearAvatarTab()
 {
-    LLPanel *panel = mTabContainer->getPanelByName("overrides_panel");
+    LLPanel *panel = mTabContainer->getPanelByName("avatar_panel");
     LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
     joints_list->deleteAllItems();
     LLScrollListCtrl *joints_pos = panel->getChild<LLScrollListCtrl>("pos_overrides_list");
-    joints_pos->deleteAllItems();
-
+    joints_pos->deleteAllItems();    mSelectedJointName.clear();
 
     for (U32 i = 0; i < LLModel::NUM_LODS; ++i)
     {
@@ -1463,11 +1460,12 @@ void LLFloaterModelPreview::clearOverridesTab()
     joint_pos_descr->setTextArg("[JOINT]", std::string("mPelvis")); // Might be better to hide it
 }
 
-void LLFloaterModelPreview::updateOverridesTab()
+void LLFloaterModelPreview::updateAvatarTab()
 {
     S32 display_lod = mModelPreview->mPreviewLOD;
     if (mModelPreview->mModel[display_lod].empty())
     {
+        mSelectedJointName.clear();
         return;
     }
 
@@ -1507,7 +1505,7 @@ void LLFloaterModelPreview::updateOverridesTab()
         }
     }
 
-    LLPanel *panel = mTabContainer->getPanelByName("overrides_panel");
+    LLPanel *panel = mTabContainer->getPanelByName("avatar_panel");
     LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
 
     if (joints_list->isEmpty())
@@ -1548,6 +1546,11 @@ void LLFloaterModelPreview::updateOverridesTab()
             joint_iter++;
         }
         joints_list->selectFirstItem();
+        LLScrollListItem *selected = joints_list->getFirstSelected();
+        if (selected)
+        {
+            mSelectedJointName = selected->getValue().asString();
+        }
 
         LLTextBox *joint_conf_descr = panel->getChild<LLTextBox>("conflicts_description");
         joint_conf_descr->setTextArg("[CONFLICTS]", llformat("%d", conflicts));
@@ -2482,7 +2485,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
 			}
             else
             {
-                fmp->clearOverridesTab();
+                fmp->clearAvatarTab();
             }
 
 			if (lock_scale_if_joint_position)
@@ -4237,7 +4240,7 @@ BOOL LLModelPreview::render()
         mFMP->childEnable("lock_scale_if_joint_position");
         if (fmp)
         {
-            fmp->updateOverridesTab();
+            fmp->updateAvatarTab();
         }
     }
     else
@@ -4246,7 +4249,7 @@ BOOL LLModelPreview::render()
         mFMP->childSetValue("lock_scale_if_joint_position", false);
         if (fmp)
         {
-            fmp->clearOverridesTab();
+            fmp->clearAvatarTab();
         }
     }
     
@@ -4774,7 +4777,14 @@ BOOL LLModelPreview::render()
 					gDebugProgram.bind();
 				}
 				getPreviewAvatar()->renderCollisionVolumes();
-				getPreviewAvatar()->renderBones();
+                if (fmp->mTabContainer->getCurrentPanelIndex() == fmp->mAvatarTabIndex)
+                {
+                    getPreviewAvatar()->renderBones(fmp->mSelectedJointName);
+                }
+                else
+                {
+                    getPreviewAvatar()->renderBones();
+                }
 				if (shader)
 				{
 					shader->bind();
@@ -4865,7 +4875,7 @@ void LLModelPreview::setPreviewLOD(S32 lod)
         if (fmp)
         {
             // make preview repopulate tab
-            fmp->clearOverridesTab();
+            fmp->clearAvatarTab();
         }
 	}
 	refresh();
@@ -4888,7 +4898,7 @@ void LLFloaterModelPreview::onReset(void* user_data)
 	LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) user_data;
 	fmp->childDisable("reset_btn");
 	fmp->clearLogTab();
-	fmp->clearOverridesTab();
+	fmp->clearAvatarTab();
 	LLModelPreview* mp = fmp->mModelPreview;
 	std::string filename = mp->mLODFile[LLModel::LOD_HIGH]; 
 
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index d079a3d7825..1542e971603 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -108,8 +108,8 @@ class LLFloaterModelPreview : public LLFloaterModelUploadBase
 	static void addStringToLog(const std::string& message, const LLSD& args, bool flash, S32 lod = -1);
 	static void addStringToLog(const std::string& str, bool flash);
 	static void addStringToLog(const std::ostringstream& strm, bool flash);
-	void clearOverridesTab(); // clears table
-	void updateOverridesTab(); // populates table and data as nessesary
+	void clearAvatarTab(); // clears table
+	void updateAvatarTab(); // populates table and data as nessesary
 
 	void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
 	void setPreviewLOD(S32 lod);
@@ -249,6 +249,9 @@ class LLFloaterModelPreview : public LLFloaterModelUploadBase
 	LLViewerTextEditor* mUploadLogText;
 	LLTabContainer* mTabContainer;
 
+	S32			mAvatarTabIndex; // just to avoid any issues in case of xml changes
+	std::string	mSelectedJointName;
+
 	joint_override_data_map_t mJointOverrides[LLModel::NUM_LODS];
 };
 
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b524db478e7..32e6535465d 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1574,13 +1574,16 @@ void LLVOAvatar::renderCollisionVolumes()
 	}
 }
 
-void LLVOAvatar::renderBones()
+void LLVOAvatar::renderBones(const std::string &selected_joint)
 {
     LLGLEnable blend(GL_BLEND);
 
 	avatar_joint_list_t::iterator iter = mSkeleton.begin();
-	avatar_joint_list_t::iterator end  = mSkeleton.end();
+    avatar_joint_list_t::iterator end = mSkeleton.end();
 
+    // For selected joints
+    static LLVector3 SELECTED_COLOR_OCCLUDED(1.0f, 1.0f, 0.0f);
+    static LLVector3 SELECTED_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
     // For bones with position overrides defined
     static LLVector3 OVERRIDE_COLOR_OCCLUDED(1.0f, 0.0f, 0.0f);
     static LLVector3 OVERRIDE_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
@@ -1607,7 +1610,18 @@ void LLVOAvatar::renderBones()
 
         LLVector3 pos;
         LLUUID mesh_id;
-        if (jointp->hasAttachmentPosOverride(pos,mesh_id))
+        F32 sphere_scale = SPHERE_SCALEF;
+
+        // We are in render, so it is preferable to implement selection
+        // in a different way, but since this is for debug/preview, this
+        // is low priority
+        if (jointp->getName() == selected_joint)
+        {
+            sphere_scale *= 16;
+            occ_color = SELECTED_COLOR_OCCLUDED;
+            visible_color = SELECTED_COLOR_VISIBLE;
+        }
+        else if (jointp->hasAttachmentPosOverride(pos,mesh_id))
         {
             occ_color = OVERRIDE_COLOR_OCCLUDED;
             visible_color = OVERRIDE_COLOR_VISIBLE;
@@ -1628,7 +1642,6 @@ void LLVOAvatar::renderBones()
         LLVector3 begin_pos(0,0,0);
         LLVector3 end_pos(jointp->getEnd());
 
-        F32 sphere_scale = SPHERE_SCALEF;
         
 		gGL.pushMatrix();
 		gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] );
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 00dccc5d121..f19bdb3071f 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -443,7 +443,7 @@ class LLVOAvatar :
 	F32			getLastSkinTime() { return mLastSkinTime; }
 	U32 		renderTransparent(BOOL first_pass);
 	void 		renderCollisionVolumes();
-	void		renderBones();
+	void		renderBones(const std::string &selected_joint = std::string());
 	void		renderJoints();
 	static void	deleteCachedImages(bool clearAll=true);
 	static void	destroyGL();
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 aeed3b4623c..da4190c4fcd 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1169,7 +1169,7 @@
       <panel
        label="Overrides"
        layout="topleft"
-       name="overrides_panel"
+       name="avatar_panel"
        title="Avatar">
         <view_border
          bevel_style="none"
-- 
GitLab