From be11d020ca6b941ec86622718c9eeafd5fddb7b5 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Mon, 9 Nov 2015 14:57:00 -0500
Subject: [PATCH] SL-266 WIP - removed obsolete rigParityWithScene code, set
 legacy and joint offset upload based on AND-ing state of all meshes in file.

---
 indra/llprimitive/lldaeloader.cpp       | 69 ++++++++++--------
 indra/llprimitive/llmodelloader.cpp     | 96 ++++++++++---------------
 indra/llprimitive/llmodelloader.h       |  5 --
 indra/newview/llfloatermodelpreview.cpp |  1 -
 indra/newview/llfloatermodelpreview.h   |  3 -
 5 files changed, 77 insertions(+), 97 deletions(-)

diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index ab38973dfe7..7e2cf67297f 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -1187,6 +1187,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
 							extractTranslation( pTranslateA, workingTransform );
 						}
 						else
+                        {
 							if ( pTranslateB )
 							{
 								extractTranslation( pTranslateB, workingTransform );
@@ -1211,9 +1212,10 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
 									}
 
 							}
+                        }
 
-							//Store the joint transform w/respect to it's name.
-							mJointList[(*jointIt).second.c_str()] = workingTransform;
+                        //Store the joint transform w/respect to its name.
+                        mJointList[(*jointIt).second.c_str()] = workingTransform;
 					}
 				}
 
@@ -1319,35 +1321,40 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
 
 		if ( !missingSkeletonOrScene )
 		{
-			//Set the joint translations on the avatar - if it's a full mapping
-			//The joints are reset in the dtor
-			if ( getRigWithSceneParity() )
-			{	
-				JointMap :: const_iterator masterJointIt = mJointMap.begin();
-				JointMap :: const_iterator masterJointItEnd = mJointMap.end();
-				for (;masterJointIt!=masterJointItEnd;++masterJointIt )
-				{
-					std::string lookingForJoint = (*masterJointIt).first.c_str();
-
-					if ( mJointList.find( lookingForJoint ) != mJointList.end() )
-					{
-						//LL_INFOS()<<"joint "<<lookingForJoint.c_str()<<LL_ENDL;
-						LLMatrix4 jointTransform = mJointList[lookingForJoint];
-						LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData);
-						if ( pJoint )
-						{   
-							LLUUID fake_mesh_id;
-							fake_mesh_id.generate();
-							pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, "");
-						}
-						else
-						{
-							//Most likely an error in the asset.
-							LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL;
-						}
-					}
-				}
-			}
+			//Set the joint translations on the avatar
+            JointMap :: const_iterator masterJointIt = mJointMap.begin();
+            JointMap :: const_iterator masterJointItEnd = mJointMap.end();
+            for (;masterJointIt!=masterJointItEnd;++masterJointIt )
+            {
+                std::string lookingForJoint = (*masterJointIt).first.c_str();
+
+                if ( mJointList.find( lookingForJoint ) != mJointList.end() )
+                {
+                    //LL_INFOS()<<"joint "<<lookingForJoint.c_str()<<LL_ENDL;
+                    LLMatrix4 jointTransform = mJointList[lookingForJoint];
+                    LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData);
+                    if ( pJoint )
+                    {   
+                        // FIXME: mesh_id is used to determine which
+                        // mesh gets to set the joint offset, in the
+                        // event of a conflict. Since we don't know
+                        // the mesh id yet, we can't guarantee that
+                        // joint offsets will be applied with the same
+                        // priority as in the uploaded model. If the
+                        // file contains multiple meshes with
+                        // conflicting joint offsets, preview may be
+                        // incorrect.
+                        LLUUID fake_mesh_id;
+                        fake_mesh_id.generate();
+                        pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, "");
+                    }
+                    else
+                    {
+                        //Most likely an error in the asset.
+                        LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL;
+                    }
+                }
+            }
 		} //missingSkeletonOrScene
 
 		//We need to construct the alternate bind matrix (which contains the new joint positions)
diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp
index 4acf695f221..b12d1042da4 100644
--- a/indra/llprimitive/llmodelloader.cpp
+++ b/indra/llprimitive/llmodelloader.cpp
@@ -126,9 +126,8 @@ LLModelLoader::LLModelLoader(
 , mTextureLoadFunc(texture_load_func)
 , mStateCallback(state_cb)
 , mOpaqueData(opaque_userdata)
-, mRigParityWithScene(false)
-, mRigValidJointUpload(false)
-, mLegacyRigValid(false)
+, mRigValidJointUpload(true)
+, mLegacyRigValid(true)
 , mNoNormalize(false)
 , mNoOptimize(false)
 , mCacheOnlyHitIfRigged(false)
@@ -461,15 +460,6 @@ void LLModelLoader::loadModelCallback()
 //-----------------------------------------------------------------------------
 void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset )
 {
-	critiqueJointToNodeMappingFromScene();
-
-    if (jointListFromAsset.size()>mMaxJointsPerMesh)
-    {
-        LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL;
-        LL_WARNS() << "Skinning disabled" << LL_ENDL;
-        return;
-    }
-
 	//Determines the following use cases for a rig:
 	//1. It is suitable for upload with skin weights & joint positions, or
 	//2. It is suitable for upload as standard av with just skin weights
@@ -477,59 +467,27 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::st
 	bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset );
 	bool isRigLegacyOK			 = isRigLegacy( jointListFromAsset );
 
-	//It's OK that both could end up being true, both default to false
-	if ( isJointPositionUploadOK )
+	// It's OK that both could end up being true.
+
+    // Both start out as true and are forced to false if any mesh in
+    // the model file is not vald by that criterion. Note that a file
+    // can contain multiple meshes.
+	if ( !isJointPositionUploadOK )
 	{
-		setRigValidForJointPositionUpload( true );
+        // This starts out true, becomes false if false for any loaded
+        // model. May be multiple loaded models.
+		setRigValidForJointPositionUpload( false );
 	}
 
-	if ( isRigLegacyOK) 
+	if ( !isRigLegacyOK) 
 	{	
-		setLegacyRigValid( true );
+        // This starts out true, becomes false if false for any loaded
+        // model. May be multiple loaded models.
+		setLegacyRigValid( false );
 	}
 
 }
-//-----------------------------------------------------------------------------
-// critiqueJointToNodeMappingFromScene()
-//-----------------------------------------------------------------------------
-void LLModelLoader::critiqueJointToNodeMappingFromScene( void  )
-{
-	//Do the actual nodes back the joint listing from the dae?
-	//if yes then this is a fully rigged asset, otherwise it's just a partial rig
-	
-	JointNameSet::iterator jointsFromNodeIt = mJointsFromNode.begin();
-	JointNameSet::iterator jointsFromNodeEndIt = mJointsFromNode.end();
-	bool result = true;
 
-	if ( !mJointsFromNode.empty() )
-	{
-		for ( ;jointsFromNodeIt!=jointsFromNodeEndIt;++jointsFromNodeIt )
-		{
-			std::string name = *jointsFromNodeIt;
-			if ( mJointTransformMap.find( name ) != mJointTransformMap.end() )
-			{
-				continue;
-			}
-			else
-			{
-				LL_INFOS() <<"critiqueJointToNodeMappingFromScene is missing a: " << name << LL_ENDL;
-				result = false;				
-			}
-		}
-	}
-	else
-	{
-		result = false;
-	}
-
-	//Determines the following use cases for a rig:
-	//1. Full av rig  w/1-1 mapping from the scene and joint array
-	//2. Partial rig but w/o parity between the scene and joint array
-	if ( result )
-	{		
-		setRigWithSceneParity( true );
-	}	
-}
 //-----------------------------------------------------------------------------
 // isRigLegacy()
 //-----------------------------------------------------------------------------
@@ -541,6 +499,30 @@ bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAs
 		return false;
 	}
 
+    // Too many joints in asset
+    if (jointListFromAsset.size()>mMaxJointsPerMesh)
+    {
+        LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL;
+        LL_WARNS() << "Skinning disabled" << LL_ENDL;
+        return false;
+    }
+
+    // Unknown joints in asset
+    S32 unknown_joint_count = 0;
+    for (std::vector<std::string>::const_iterator it = jointListFromAsset.begin();
+         it != jointListFromAsset.end(); ++it)
+    {
+        if (mJointMap.find(*it)==mJointMap.end())
+        {
+            LL_WARNS() << "Rig to unrecognized name " << *it << ", isRigLegacy() will fail" << LL_ENDL;
+            unknown_joint_count++;
+        }
+    }
+    if (unknown_joint_count>0)
+    {
+        return false;
+    }
+
 	bool result = false;
 
 	JointNameSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin();	
diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h
index 0b5d7168fad..ad8372f0774 100644
--- a/indra/llprimitive/llmodelloader.h
+++ b/indra/llprimitive/llmodelloader.h
@@ -161,7 +161,6 @@ class LLModelLoader : public LLThread
 
 	//Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps)
 	void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset );
-	void critiqueJointToNodeMappingFromScene( void  );
 
 	//Determines if a rig is a legacy from the joint list
 	bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );
@@ -169,9 +168,6 @@ class LLModelLoader : public LLThread
 	//Determines if a rig is suitable for upload
 	bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
 
-	void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; }
-	const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; }
-
 	const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
 	void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
 
@@ -194,7 +190,6 @@ class LLModelLoader : public LLThread
 	LLModelLoader::state_callback_t		mStateCallback;
 	void*								mOpaqueData;
 
-	bool		mRigParityWithScene;
 	bool		mRigValidJointUpload;
 	bool		mLegacyRigValid;
 
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index dac49aa0b3c..8c3c12291e1 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1184,7 +1184,6 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
 , mPhysicsSearchLOD( LLModel::LOD_PHYSICS )
 , mResetJoints( false )
 , mModelNoErrors( true )
-, mRigParityWithScene( false )
 , mLastJointUpdate( false )
 {
 	mNeedsUpdate = TRUE;
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index d9351029ec7..2a39f54e922 100755
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -297,8 +297,6 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
 	
 	void setLoadState( U32 state ) { mLoadState = state; }
 	U32 getLoadState() { return mLoadState; }
-	void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; }
-	const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; }
 	
 	static bool 		sIgnoreLoadedCallback;
 
@@ -346,7 +344,6 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
 	bool		mLoading;
 	U32			mLoadState;
 	bool		mResetJoints;
-	bool		mRigParityWithScene;
 	bool		mModelNoErrors;
 
 	std::map<std::string, bool> mViewOption;
-- 
GitLab