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 | |
| parent | 223f0907092966e595890830be76ddf77776e123 (diff) | |
SL-372 - handle dae models with multiple skeleton roots
| -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(); | 
