diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2016-04-19 11:48:06 -0400 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2016-04-19 11:48:06 -0400 |
commit | b092147a0be579e102c9210c6c99110862e9ad02 (patch) | |
tree | 74e75eb3131f74e393878997cd2b6c1b19e8b215 /indra | |
parent | 223f0907092966e595890830be76ddf77776e123 (diff) |
SL-372 - handle dae models with multiple skeleton roots
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llprimitive/lldaeloader.cpp | 186 |
1 files changed, 95 insertions, 91 deletions
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 50875669fa..df69607404 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1152,28 +1152,29 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do //Some collada setup for accessing the skeleton - daeElement* pElement = 0; - dae->getDatabase()->getElement( &pElement, 0, 0, "skeleton" ); + U32 skeleton_count = dae->getDatabase()->getElementCount( NULL, "skeleton" ); + std::vector<domInstance_controller::domSkeleton*> skeletons; + for (S32 i=0; i<skeleton_count; i++) + { + daeElement* pElement = 0; + dae->getDatabase()->getElement( &pElement, i, 0, "skeleton" ); - //Try to get at the skeletal instance controller - domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); + //Try to get at the skeletal instance controller + domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); + daeElement* pSkeletonRootNode = NULL; + if (pSkeleton) + { + pSkeletonRootNode = pSkeleton->getValue().getElement(); + } + if (pSkeleton && pSkeletonRootNode) + { + skeletons.push_back(pSkeleton); + } + } bool missingSkeletonOrScene = false; //If no skeleton, do a breadth-first search to get at specific joints - bool rootNode = false; - - //Need to test for a skeleton that does not have a root node - //This occurs when your instance controller does not have an associated scene - if ( pSkeleton ) - { - daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); - if ( pSkeletonRootNode ) - { - rootNode = true; - } - - } - if ( !pSkeleton || !rootNode ) + if ( skeletons.size() == 0 ) { daeElement* pScene = root->getDescendant("visual_scene"); if ( !pScene ) @@ -1200,85 +1201,88 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } } else - //Has Skeleton - { - //Get the root node of the skeleton - daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); - if ( pSkeletonRootNode ) - { - //Once we have the root node - start acccessing it's joint components - const int jointCnt = mJointMap.size(); - JointMap :: const_iterator jointIt = mJointMap.begin(); - - //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. - for ( int i=0; i<jointCnt; ++i, ++jointIt ) - { - //Build a joint for the resolver to work with - char str[64]={0}; - sprintf(str,"./%s",(*jointIt).first.c_str() ); - //LL_WARNS()<<"Joint "<< str <<LL_ENDL; - - //Setup the resolver - daeSIDResolver resolver( pSkeletonRootNode, str ); + //Has one or more skeletons + for (std::vector<domInstance_controller::domSkeleton*>::iterator skel_it = skeletons.begin(); + skel_it != skeletons.end(); ++skel_it) + { + domInstance_controller::domSkeleton* pSkeleton = *skel_it; + //Get the root node of the skeleton + daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); + if ( pSkeletonRootNode ) + { + //Once we have the root node - start acccessing it's joint components + const int jointCnt = mJointMap.size(); + JointMap :: const_iterator jointIt = mJointMap.begin(); - //Look for the joint - domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() ); - if ( pJoint ) - { - //Pull out the translate id and store it in the jointTranslations map - daeSIDResolver jointResolverA( pJoint, "./translate" ); - domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() ); - daeSIDResolver jointResolverB( pJoint, "./location" ); - domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() ); + //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. + for ( int i=0; i<jointCnt; ++i, ++jointIt ) + { + //Build a joint for the resolver to work with + char str[64]={0}; + sprintf(str,"./%s",(*jointIt).first.c_str() ); + //LL_WARNS()<<"Joint "<< str <<LL_ENDL; - LLMatrix4 workingTransform; + //Setup the resolver + daeSIDResolver resolver( pSkeletonRootNode, str ); - //Translation via SID - if ( pTranslateA ) - { - extractTranslation( pTranslateA, workingTransform ); - } - else + //Look for the joint + domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() ); + if ( pJoint ) { - if ( pTranslateB ) - { - extractTranslation( pTranslateB, workingTransform ); - } - else - { - //Translation via child from element - daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); - if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) - { - LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL; - missingSkeletonOrScene = true; - } - else - if ( pTranslateElement ) - { - extractTranslationViaElement( pTranslateElement, workingTransform ); - } - else - { - extractTranslationViaSID( pJoint, workingTransform ); - } - - } + //Pull out the translate id and store it in the jointTranslations map + daeSIDResolver jointResolverA( pJoint, "./translate" ); + domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() ); + daeSIDResolver jointResolverB( pJoint, "./location" ); + domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() ); + + LLMatrix4 workingTransform; + + //Translation via SID + if ( pTranslateA ) + { + extractTranslation( pTranslateA, workingTransform ); + } + else + { + if ( pTranslateB ) + { + extractTranslation( pTranslateB, workingTransform ); + } + else + { + //Translation via child from element + daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); + if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) + { + LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL; + missingSkeletonOrScene = true; + } + else + if ( pTranslateElement ) + { + extractTranslationViaElement( pTranslateElement, workingTransform ); + } + else + { + extractTranslationViaSID( pJoint, workingTransform ); + } + + } + } + + //Store the joint transform w/respect to its name. + mJointList[(*jointIt).second.c_str()] = workingTransform; } + } - //Store the joint transform w/respect to its name. - mJointList[(*jointIt).second.c_str()] = workingTransform; - } - } - - //If anything failed in regards to extracting the skeleton, joints or translation id, - //mention it - if ( missingSkeletonOrScene ) - { - LL_WARNS()<< "Partial jointmap found in asset - did you mean to just have a partial map?" << LL_ENDL; - } - }//got skeleton? - } + //If anything failed in regards to extracting the skeleton, joints or translation id, + //mention it + if ( missingSkeletonOrScene ) + { + LL_WARNS()<< "Partial jointmap found in asset - did you mean to just have a partial map?" << LL_ENDL; + } + }//got skeleton? + } domSkin::domJoints* joints = skin->getJoints(); |