diff options
author | Aura Linden <aura@lindenlab.com> | 2015-11-13 04:12:13 -0800 |
---|---|---|
committer | Aura Linden <aura@lindenlab.com> | 2015-11-13 04:12:13 -0800 |
commit | 99219cbe80d56dbd9d6f75689304ce2759592868 (patch) | |
tree | edddfd8003e918e5f922c500560b4ffcc2dd0689 /indra/llprimitive | |
parent | 146919fa764bed09bfa5e27bc30d02ce2afb6188 (diff) | |
parent | b72480ddb9b01202f1bbe4bfb84595549faeacf3 (diff) |
Eliminated joint_offset file. Added aliases attrib to bones in avatar_skeleton.xml.
Diffstat (limited to 'indra/llprimitive')
-rw-r--r-- | indra/llprimitive/lldaeloader.cpp | 85 | ||||
-rw-r--r-- | indra/llprimitive/lldaeloader.h | 4 | ||||
-rwxr-xr-x | indra/llprimitive/llmodel.h | 2 | ||||
-rw-r--r-- | indra/llprimitive/llmodelloader.cpp | 187 | ||||
-rw-r--r-- | indra/llprimitive/llmodelloader.h | 10 |
5 files changed, 120 insertions, 168 deletions
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 63457512ff..400b8563c1 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -810,8 +810,8 @@ LLDAELoader::LLDAELoader( void* opaque_userdata, JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, - JointNameSet& legalJointNames, - std::string jointAliasesFilename, + std::map<std::string, std::string>& jointAliasMap, + U32 maxJointsPerMesh, U32 modelLimit) : LLModelLoader( filename, @@ -823,8 +823,8 @@ LLDAELoader::LLDAELoader( opaque_userdata, jointTransformMap, jointsFromNodes, - legalJointNames, - jointAliasesFilename), + jointAliasMap, + maxJointsPerMesh), mGeneratedModelLimit(modelLimit) { } @@ -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; } } @@ -1259,8 +1261,6 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - // BENTO this does not appear to be used anywhere. - // model->mSkinInfo.mJointMap[name] = j; } } else @@ -1278,8 +1278,6 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - // BENTO not used? - // model->mSkinInfo.mJointMap[name] = j; } } } @@ -1323,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) @@ -1373,7 +1376,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } else { - LL_WARNS()<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<LL_ENDL; + LL_DEBUGS("Mesh")<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<"] "<<LL_ENDL; } } @@ -1820,7 +1823,7 @@ daeElement* LLDAELoader::getChildFromElement( daeElement* pElement, std::string { return pChildOfElement; } - LL_WARNS()<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL; + LL_DEBUGS("Mesh")<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL; return NULL; } diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 52ad9d4705..f8965d1d5d 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -56,8 +56,8 @@ public: void* opaque_userdata, JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, - JointNameSet& legalJointNames, - std::string jointAliasesFilename, + std::map<std::string, std::string>& jointAliasMap, + U32 maxJointsPerMesh, U32 modelLimit); virtual ~LLDAELoader() ; diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 56844ac16d..5f98942340 100755 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -47,8 +47,6 @@ public: std::vector<LLMatrix4> mInvBindMatrix; std::vector<LLMatrix4> mAlternateBindMatrix; std::vector<U32> mJointRemap; - // BENTO not used? - //std::map<std::string, U32> mJointMap; LLMeshSkinInfo() { } LLMeshSkinInfo(LLSD& data); diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index b4bd467c64..9bfd6dc3e6 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -111,13 +111,14 @@ LLModelLoader::LLModelLoader( void* opaque_userdata, JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, - JointNameSet& legalJointNames, - std::string jointAliasFilename) + JointMap& legalJointNamesMap, + U32 maxJointsPerMesh) : mJointList( jointTransformMap ) , mJointsFromNode( jointsFromNodes ) , LLThread("Model Loader") , mFilename(filename) , mLod(lod) +, mTrySLM(false) , mFirstTransform(TRUE) , mNumOfFetchingTextures(0) , mLoadCallback(load_cb) @@ -125,38 +126,14 @@ LLModelLoader::LLModelLoader( , mTextureLoadFunc(texture_load_func) , mStateCallback(state_cb) , mOpaqueData(opaque_userdata) +, mRigValidJointUpload(true) +, mLegacyRigValid(true) , mNoNormalize(false) , mNoOptimize(false) , mCacheOnlyHitIfRigged(false) -{ - // Recognize all names we've been told are legal. - for (JointNameSet::iterator joint_name_it = legalJointNames.begin(); - joint_name_it != legalJointNames.end(); ++joint_name_it) - { - const std::string& name = *joint_name_it; - mJointMap[name] = name; - } - - - // Also support various legacy aliases for commonly used joints - LLSD aliases_sd; - llifstream input_stream; - input_stream.open(jointAliasFilename.c_str(), std::ios::in | std::ios::binary); - - if(input_stream.is_open()) - { - LLSDSerialize::fromXML(aliases_sd, input_stream); - for(LLSD::map_iterator alias_iter = aliases_sd.beginMap(); - alias_iter != aliases_sd.endMap(); - ++alias_iter) - { - LLSD::String alias_name = alias_iter->first; - LLSD::String joint_name = alias_iter->second; - mJointMap[ alias_name ] = joint_name; - } - input_stream.close(); - } - +, mMaxJointsPerMesh(maxJointsPerMesh) +, mJointMap(legalJointNamesMap) +{ //move into joint mapper class //1. joints for joint offset verification mMasterJointList.push_front("mPelvis"); @@ -426,8 +403,6 @@ void LLModelLoader::loadModelCallback() //----------------------------------------------------------------------------- void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ) { - critiqueJointToNodeMappingFromScene(); - //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 @@ -435,59 +410,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 + // mesh. + setRigValidForJointPositionUpload( false ); } - if ( isRigLegacyOK) + if ( !isRigLegacyOK) { - setLegacyRigValid( true ); + // This starts out true, becomes false if false for any loaded + // mesh. + 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() //----------------------------------------------------------------------------- @@ -499,68 +442,80 @@ bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAs return false; } - bool result = 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 due to too many joints" << 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() << "Rigged to unrecognized joint name " << *it << LL_ENDL; + unknown_joint_count++; + } + } + if (unknown_joint_count>0) + { + LL_WARNS() << "Skinning disabled due to unknown joints" << LL_ENDL; + return false; + } + // Note that this is basically the same code as + // isRigSuitableForJointPositionUpload(), but the set of joints is + // different. JointNameSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin(); JointNameSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end(); std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin(); std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end(); - + + S32 missing_joint_count = 0; for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) { - result = false; - modelJointIt = jointListFromAsset.begin(); - - for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) - { - if ( *masterJointIt == *modelJointIt ) - { - result = true; - break; - } - } - if ( !result ) - { - LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL; - break; - } + if (std::find(modelJointIt,modelJointItEnd,*masterJointIt)==modelJointItEnd) + { + LL_INFOS() <<" Asset did not contain a joint required for skinned mesh upload: " << *masterJointIt<< LL_ENDL; + missing_joint_count++; + } } - return result; + if (missing_joint_count>0) + { + LL_WARNS() << "Skinning disabled due to missing joints" << LL_ENDL; + } + return missing_joint_count==0; } //----------------------------------------------------------------------------- // isRigSuitableForJointPositionUpload() //----------------------------------------------------------------------------- bool LLModelLoader::isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ) { - bool result = false; - JointNameSet :: const_iterator masterJointIt = mMasterJointList.begin(); JointNameSet :: const_iterator masterJointEndIt = mMasterJointList.end(); std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin(); std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end(); + S32 missing_joint_count = 0; for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) { - result = false; - modelJointIt = jointListFromAsset.begin(); - - for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) - { - if ( *masterJointIt == *modelJointIt ) - { - result = true; - break; - } - } - if ( !result ) - { - LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL; - break; - } + if (std::find(modelJointIt,modelJointItEnd,*masterJointIt)==modelJointItEnd) + { + LL_INFOS() <<" Asset did not contain a joint required for joint position upload: " << *masterJointIt<< LL_ENDL; + missing_joint_count++; + } } - return result; + if (missing_joint_count>0) + { + LL_WARNS() << "Joint upload disabled due to missing joints" << LL_ENDL; + } + return missing_joint_count==0; } diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 20c3aee649..568b3ead4e 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -117,6 +117,7 @@ public: JointMap mJointMap; JointTransformMap& mJointList; JointNameSet& mJointsFromNode; + U32 mMaxJointsPerMesh; LLModelLoader( std::string filename, @@ -128,8 +129,8 @@ public: void* opaque_userdata, JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, - JointNameSet& legalJointNames, - std::string jointAliasFilename); + JointMap& legalJointNamesMap, + U32 maxJointsPerMesh); virtual ~LLModelLoader() ; virtual void setNoNormalize() { mNoNormalize = true; } @@ -160,7 +161,6 @@ public: //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 ); @@ -168,9 +168,6 @@ public: //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; } @@ -193,7 +190,6 @@ protected: LLModelLoader::state_callback_t mStateCallback; void* mOpaqueData; - bool mRigParityWithScene; bool mRigValidJointUpload; bool mLegacyRigValid; |