From 3a53109152b961c9d0e7d6dd4f66b02d7531fb2a Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Tue, 7 Jun 2016 10:39:32 -0400
Subject: SL-395 - support scale overrides (currently no way to get these into
 a dae, so the actual scale values are fabricated at run-time based on the
 joint name)

---
 indra/llcharacter/lljoint.cpp | 228 ++++++++++++++++++++++++++++++++++++++----
 indra/llcharacter/lljoint.h   |  27 ++++-
 2 files changed, 228 insertions(+), 27 deletions(-)

(limited to 'indra/llcharacter')

diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index c4eda0b432..f764b53ba5 100644
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -44,7 +44,7 @@ bool attachment_map_iter_compare_key(const T& a, const T& b)
 	return a.first < b.first;
 }
 
-bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const
+bool LLVector3OverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const
 {
 	pos = LLVector3(0,0,0);
 	mesh_id = LLUUID();
@@ -62,7 +62,7 @@ bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const
 	return found;
 }
 
-void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const
+void LLVector3OverrideMap::showJointVector3Overrides( std::ostringstream& os ) const
 {
 	map_type::const_iterator max_it = std::max_element(m_map.begin(),
 													   m_map.end(),
@@ -75,23 +75,23 @@ void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const
 	}
 }
 
-U32 LLPosOverrideMap::count() const
+U32 LLVector3OverrideMap::count() const
 {
 	return m_map.size();
 }
 
-void LLPosOverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos)
+void LLVector3OverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos)
 {
 	m_map[mesh_id] = pos;
 }
 
-bool LLPosOverrideMap::remove(const LLUUID& mesh_id)
+bool LLVector3OverrideMap::remove(const LLUUID& mesh_id)
 {
 	U32 remove_count = m_map.erase(mesh_id);
 	return (remove_count > 0);
 }
 
-void LLPosOverrideMap::clear()
+void LLVector3OverrideMap::clear()
 {
 	m_map.clear();
 }
@@ -342,7 +342,7 @@ void LLJoint::setPosition( const LLVector3& requested_pos, bool apply_attachment
 
     LLVector3 active_override;
     LLUUID mesh_id;
-    if (apply_attachment_overrides && m_attachmentOverrides.findActiveOverride(mesh_id,active_override))
+    if (apply_attachment_overrides && m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override))
     {  
         if (pos != active_override && do_debug_joint(getName()))
         {
@@ -374,11 +374,30 @@ const LLVector3& LLJoint::getDefaultPosition() const
 {
     return mDefaultPosition;
 }
+
+void LLJoint::setDefaultScale( const LLVector3& scale )
+{
+    mDefaultScale = scale;
+}
+
+const LLVector3& LLJoint::getDefaultScale() const
+{
+    return mDefaultScale;
+}
+
 void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info )
 {
         std::ostringstream os;
         os << joint.m_posBeforeOverrides;
-        joint.m_attachmentOverrides.showJointPosOverrides(os);
+        joint.m_attachmentPosOverrides.showJointVector3Overrides(os);
+        LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL;
+}
+
+void showJointScaleOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info )
+{
+        std::ostringstream os;
+        os << joint.m_scaleBeforeOverrides;
+        joint.m_attachmentScaleOverrides.showJointVector3Overrides(os);
         LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL;
 }
 
@@ -389,6 +408,13 @@ bool above_joint_pos_threshold(const LLVector3& diff)
 	return diff.lengthSquared() > max_joint_pos_offset * max_joint_pos_offset;
 }
 
+bool above_joint_scale_threshold(const LLVector3& diff)
+{
+	//return !diff.isNull();
+	const F32 max_joint_scale_offset = 0.0001f; // 0.1 mm
+	return diff.lengthSquared() > max_joint_scale_offset * max_joint_scale_offset;
+}
+
 //--------------------------------------------------------------------
 // addAttachmentPosOverride()
 //--------------------------------------------------------------------
@@ -407,7 +433,7 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh
         }
 		return;
     }
-	if (!m_attachmentOverrides.count())
+	if (!m_attachmentPosOverrides.count())
 	{
 		if (do_debug_joint(getName()))
 		{
@@ -415,7 +441,7 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh
 		}
 		m_posBeforeOverrides = getPosition();
 	}
-	m_attachmentOverrides.add(mesh_id,pos);
+	m_attachmentPosOverrides.add(mesh_id,pos);
 	if (do_debug_joint(getName()))
 	{
 		LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL;
@@ -432,7 +458,7 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str
 	{
 		return;
 	}
-	if (m_attachmentOverrides.remove(mesh_id))
+	if (m_attachmentPosOverrides.remove(mesh_id))
 	{
 		if (do_debug_joint(getName()))
 		{
@@ -449,7 +475,7 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str
  //--------------------------------------------------------------------
 bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const
 {
-	return m_attachmentOverrides.findActiveOverride(mesh_id,pos);
+	return m_attachmentPosOverrides.findActiveOverride(mesh_id,pos);
 }
 
 //--------------------------------------------------------------------
@@ -457,9 +483,9 @@ bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const
 //--------------------------------------------------------------------
 void LLJoint::clearAttachmentPosOverrides()
 {
-	if (m_attachmentOverrides.count())
+	if (m_attachmentPosOverrides.count())
 	{
-		m_attachmentOverrides.clear();
+		m_attachmentPosOverrides.clear();
 		setPosition(m_posBeforeOverrides);
 		setId( LLUUID::null );
 	}
@@ -473,11 +499,11 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const
     LLVector3 active_override;
     bool has_active_override;
     LLUUID mesh_id;
-    has_active_override = m_attachmentOverrides.findActiveOverride(mesh_id,active_override);
-    U32 count = m_attachmentOverrides.count();
+    has_active_override = m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override);
+    U32 count = m_attachmentPosOverrides.count();
     if (count==1)
     {
-		LLPosOverrideMap::map_type::const_iterator it = m_attachmentOverrides.getMap().begin();
+		LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin();
         std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : "";
         LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName()
                             << " has single attachment pos override " << highlight << "" << it->second << " default " << mDefaultPosition << LL_ENDL;
@@ -486,8 +512,8 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const
     {
         LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment pos overrides" << LL_ENDL;
 		std::set<LLVector3> distinct_offsets;
-        LLPosOverrideMap::map_type::const_iterator it = m_attachmentOverrides.getMap().begin();
-        for (; it != m_attachmentOverrides.getMap().end(); ++it)
+        LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin();
+        for (; it != m_attachmentPosOverrides.getMap().end(); ++it)
         {
             distinct_offsets.insert(it->second);
         }
@@ -515,11 +541,11 @@ void LLJoint::updatePos(const std::string& av_info)
 {
 	LLVector3 pos, found_pos;
 	LLUUID mesh_id;
-	if (m_attachmentOverrides.findActiveOverride(mesh_id,found_pos))
+	if (m_attachmentPosOverrides.findActiveOverride(mesh_id,found_pos))
 	{
         if (do_debug_joint(getName()))
         {
-            LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL;
+            LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentPosOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL;
         }
 		pos = found_pos;
 	}
@@ -534,6 +560,151 @@ void LLJoint::updatePos(const std::string& av_info)
 	setPosition(pos);
 }
 
+//--------------------------------------------------------------------
+// updateScale()
+//--------------------------------------------------------------------
+void LLJoint::updateScale(const std::string& av_info)
+{
+	LLVector3 scale, found_scale;
+	LLUUID mesh_id;
+	if (m_attachmentScaleOverrides.findActiveOverride(mesh_id,found_scale))
+	{
+        if (do_debug_joint(getName()))
+        {
+            LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner of " << m_attachmentScaleOverrides.count() << " is mesh " << mesh_id << " scale " << found_scale << LL_ENDL;
+        }
+		scale = found_scale;
+	}
+	else
+	{
+        if (do_debug_joint(getName()))
+        {
+            LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner is scaleBeforeOverrides " << m_scaleBeforeOverrides << LL_ENDL;
+        }
+		scale = m_scaleBeforeOverrides;
+	}
+	setScale(scale);
+}
+
+//--------------------------------------------------------------------
+// addAttachmentScaleOverride()
+//--------------------------------------------------------------------
+void LLJoint::addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info )
+{
+	if (mesh_id.isNull())
+	{
+		return;
+	}
+    if (!above_joint_scale_threshold(scale-getDefaultScale()))
+    {
+        if (do_debug_joint(getName()))
+        {
+            LL_DEBUGS("Avatar") << "Attachment scale override ignored for " << getName()
+                                << ", scale " << scale << " is same as default scale" << LL_ENDL;
+        }
+		return;
+    }
+	if (!m_attachmentScaleOverrides.count())
+	{
+		if (do_debug_joint(getName()))
+		{
+			LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_scaleBeforeOverrides " << getScale() << LL_ENDL;
+		}
+		m_scaleBeforeOverrides = getScale();
+	}
+	m_attachmentScaleOverrides.add(mesh_id,scale);
+	if (do_debug_joint(getName()))
+	{
+		LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentScaleOverride for mesh " << mesh_id << " scale " << scale << LL_ENDL;
+	}
+	updateScale(av_info);
+}
+
+//--------------------------------------------------------------------
+// removeAttachmentScaleOverride()
+//--------------------------------------------------------------------
+void LLJoint::removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info )
+{
+	if (mesh_id.isNull())
+	{
+		return;
+	}
+	if (m_attachmentScaleOverrides.remove(mesh_id))
+	{
+		if (do_debug_joint(getName()))
+		{
+			LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName()
+								<< " removeAttachmentScaleOverride for " << mesh_id << LL_ENDL;
+			showJointScaleOverrides(*this, "remove", av_info);
+		}
+		updateScale(av_info);
+	}
+}
+
+//--------------------------------------------------------------------
+ // hasAttachmentScaleOverride()
+ //--------------------------------------------------------------------
+bool LLJoint::hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const
+{
+	return m_attachmentScaleOverrides.findActiveOverride(mesh_id,scale);
+}
+
+//--------------------------------------------------------------------
+// clearAttachmentScaleOverrides()
+//--------------------------------------------------------------------
+void LLJoint::clearAttachmentScaleOverrides()
+{
+	if (m_attachmentScaleOverrides.count())
+	{
+		m_attachmentScaleOverrides.clear();
+		setScale(m_scaleBeforeOverrides);
+		setId( LLUUID::null );
+	}
+}
+
+//--------------------------------------------------------------------
+// showAttachmentScaleOverrides()
+//--------------------------------------------------------------------
+void LLJoint::showAttachmentScaleOverrides(const std::string& av_info) const
+{
+    LLVector3 active_override;
+    bool has_active_override;
+    LLUUID mesh_id;
+    has_active_override = m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override);
+    U32 count = m_attachmentScaleOverrides.count();
+    if (count==1)
+    {
+		LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin();
+        std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : "";
+        LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName()
+                            << " has single attachment scale override " << highlight << "" << it->second << " default " << mDefaultScale << LL_ENDL;
+    }
+    else if (count>1)
+    {
+        LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment scale overrides" << LL_ENDL;
+		std::set<LLVector3> distinct_offsets;
+        LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin();
+        for (; it != m_attachmentScaleOverrides.getMap().end(); ++it)
+        {
+            distinct_offsets.insert(it->second);
+        }
+        if (distinct_offsets.size()>1)
+        {
+            LL_DEBUGS("Avatar") << "CONFLICTS, " << distinct_offsets.size() << " different values" << LL_ENDL;
+        }
+        else
+        {
+            LL_DEBUGS("Avatar") << "no conflicts" << LL_ENDL;
+        }
+        std::set<LLVector3>::iterator dit = distinct_offsets.begin();
+        for ( ; dit != distinct_offsets.end(); ++dit)
+        {
+            std::string highlight = (has_active_override && *dit == active_override) ? "*" : "";
+            LL_DEBUGS("Avatar") << "  POS " << highlight << "" << (*dit) << " default " << mDefaultScale << LL_ENDL;
+        }
+	}
+}
+
 // init static
 LLJoint::debug_joint_name_t LLJoint::s_debugJointNames = debug_joint_name_t();
 
@@ -676,8 +847,21 @@ const LLVector3& LLJoint::getScale()
 //--------------------------------------------------------------------
 // setScale()
 //--------------------------------------------------------------------
-void LLJoint::setScale( const LLVector3& scale )
+void LLJoint::setScale( const LLVector3& requested_scale, bool apply_attachment_overrides )
 {
+    LLVector3 scale(requested_scale);
+    LLUUID mesh_id;
+    LLVector3 active_override;
+    if (apply_attachment_overrides && m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override))
+    {  
+        if (scale != active_override && do_debug_joint(getName()))
+        {
+            LLScopedContextString str("setScale");
+            LL_DEBUGS("Avatar") << " joint " << getName() << " requested_scale " << requested_scale
+                                << " overriden by attachment " << active_override << LL_ENDL;
+        }
+        scale = active_override;
+    }
 	if ((mXform.getScale() != scale) && do_debug_joint(getName()))
 	{	
         LLScopedContextString str("setScale");
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index d2c573864b..bee968f249 100644
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -52,12 +52,12 @@ const U32 LL_FACE_JOINT_NUM = (LL_CHARACTER_MAX_ANIMATED_JOINTS-2);
 const S32 LL_CHARACTER_MAX_PRIORITY = 7;
 const F32 LL_MAX_PELVIS_OFFSET = 5.f;
 
-class LLPosOverrideMap
+class LLVector3OverrideMap
 {
 public:
-	LLPosOverrideMap() {}
+	LLVector3OverrideMap() {}
 	bool findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const;
-	void showJointPosOverrides(std::ostringstream& os) const;
+	void showJointVector3Overrides(std::ostringstream& os) const;
 	U32 count() const;
 	void add(const LLUUID& mesh_id, const LLVector3& pos);
 	bool remove(const LLUUID& mesh_id);
@@ -114,6 +114,7 @@ protected:
 	LLUUID				mId;
 
     LLVector3       mDefaultPosition;
+    LLVector3       mDefaultScale;
     
 public:
 	U32				mDirtyFlags;
@@ -140,10 +141,16 @@ public:
     static void setDebugJointNames(const debug_joint_name_t& names);
     static void setDebugJointNames(const std::string& names_string);
 
-	LLPosOverrideMap m_attachmentOverrides;
+    // Position overrides
+	LLVector3OverrideMap m_attachmentPosOverrides;
 	LLVector3 m_posBeforeOverrides;
 
+    // Scale overrides
+	LLVector3OverrideMap m_attachmentScaleOverrides;
+	LLVector3 m_scaleBeforeOverrides;
+
 	void updatePos(const std::string& av_info);
+	void updateScale(const std::string& av_info);
 
 public:
 	LLJoint();
@@ -215,6 +222,10 @@ public:
 	void setDefaultPosition( const LLVector3& pos );
 	const LLVector3& getDefaultPosition() const;
 
+    // Tracks the default scale defined by the skeleton
+	void setDefaultScale( const LLVector3& scale );
+	const LLVector3& getDefaultScale() const;
+
 	// get/set world position
 	LLVector3 getWorldPosition();
 	LLVector3 getLastWorldPosition();
@@ -231,7 +242,7 @@ public:
 
 	// get/set local scale
 	const LLVector3& getScale();
-	void setScale( const LLVector3& scale );
+	void setScale( const LLVector3& scale, bool apply_attachment_overrides = false );
 
 	// get/set world matrix
 	const LLMatrix4 &getWorldMatrix();
@@ -260,6 +271,12 @@ public:
 	void clearAttachmentPosOverrides();
     void showAttachmentPosOverrides(const std::string& av_info) const;
 
+	void addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info );
+	void removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info );
+	bool hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const;
+	void clearAttachmentScaleOverrides();
+    void showAttachmentScaleOverrides(const std::string& av_info) const;
+
 	//Accessor for the joint id
 	LLUUID getId( void ) { return mId; }
 	//Setter for the joints id
-- 
cgit v1.2.3