//--------------------------------- const SidTreeNode* DocumentProcessor::resolveSidInInstance( const SidTreeNode* instancingElement, const SidAddress& sidAddress, size_t firstSidIndex) { // the sid address we use to resolve the sid in the instantiated element const COLLADABU::URI* uri = 0; //check if instancingElement instantiates an element switch ( instancingElement->getTargetType() ) { case SidTreeNode::TARGETTYPECLASS_INTERMEDIATETARGETABLE: { IntermediateTargetable* iTargetable = instancingElement->getIntermediateTargetableTarget(); switch ( iTargetable->getClassId() ) { case INTERMEDIATETARGETABLE_TYPE::KINEMATICS_INSTANCE: { KinematicInstance* ki = intermediateTargetableSafeCast<KinematicInstance>(iTargetable); uri = &ki->getUrl(); break; } } } // case SidTreeNode::TARGETTYPECLASS_OBJECT: // { // COLLADAFW::Object* iObject = instancingElement->getObjectTarget(); // switch ( iObject->getClassId() ) // { // case COLLADAFW::COLLADA_TYPE::JOINT: // { // KinematicInstance* ki = (KinematicInstance*) iObject; // uri = &ki->getUrl(); // } // } // } } if ( !uri ) { // we could not find an instantiated element return 0; } SidAddress newSidAddress( *uri ); const SidAddress::SidList& allSids = sidAddress.getSids(); size_t allSidsCount = allSids.size(); for ( size_t i = firstSidIndex; i < allSidsCount; ++i) { newSidAddress.appendSid( allSids[i] ); } newSidAddress.setFirstIndex( sidAddress.getFirstIndex() ); newSidAddress.setSecondIndex( sidAddress.getSecondIndex() ); newSidAddress.setMemberSelection( sidAddress.getMemberSelection() ); newSidAddress.setMemberSelectionName( sidAddress.getMemberSelectionName() ); return resolveSid( newSidAddress ); }
//----------------------------- void PostProcessor::createMissingAnimationList( const Loader::AnimationSidAddressBinding& binding ) { const SidTreeNode* sidTreeNode = resolveSid( binding.sidAddress); if ( sidTreeNode ) { if ( sidTreeNode->getTargetType() == SidTreeNode::TARGETTYPECLASS_ANIMATABLE ) { COLLADAFW::Animatable* animatable = sidTreeNode->getAnimatableTarget(); COLLADAFW::UniqueId animationListUniqueId = animatable->getAnimationList(); if ( !animationListUniqueId.isValid() ) { animationListUniqueId = createUniqueId( COLLADAFW::AnimationList::ID() ); animatable->setAnimationList( animationListUniqueId ); } COLLADAFW::AnimationList*& animationList = getAnimationListByUniqueId(animationListUniqueId); if ( !animationList ) { animationList = new COLLADAFW::AnimationList( animationListUniqueId ); } // TODO handle this for arrays COLLADAFW::AnimationList::AnimationBinding animationBinding; animationBinding.animation = binding.animationInfo.uniqueId; animationBinding.animationClass = binding.animationInfo.animationClass; switch ( binding.sidAddress.getMemberSelection() ) { case SidAddress::MEMBER_SELECTION_ONE_INDEX: animationBinding.firstIndex = binding.sidAddress.getFirstIndex(); animationBinding.secondIndex = 0; animationBinding.animationClass = COLLADAFW::AnimationList::ARRAY_ELEMENT_1D; break; case SidAddress::MEMBER_SELECTION_TWO_INDICES: animationBinding.firstIndex = binding.sidAddress.getFirstIndex(); animationBinding.secondIndex = binding.sidAddress.getSecondIndex(); animationBinding.animationClass = COLLADAFW::AnimationList::ARRAY_ELEMENT_2D; break; default: animationBinding.firstIndex = 0; animationBinding.secondIndex = 0; } animationList->getAnimationBindings().append( animationBinding ); } } }
//----------------------------- bool DocumentProcessor::createAndWriteSkinController( const Loader::InstanceControllerData& instanceControllerData, const COLLADAFW::UniqueId& controllerDataUniqueId, const COLLADAFW::UniqueId& sourceUniqueId, const StringList& sidsOrIds, bool resolveIds) { if ( !controllerDataUniqueId.isValid() ) return false; const URIList& skeletonRoots = instanceControllerData.skeletonRoots; NodeList joints; for ( StringList::const_iterator it = sidsOrIds.begin(); it != sidsOrIds.end(); ++it) { const String sidOrId = *it; bool jointFound = false; if ( resolveIds ) { const SidTreeNode* joint = resolveSid( sidOrId ); if ( joint ) { // the joint could be found if ( joint->getTargetType() == SidTreeNode::TARGETTYPECLASS_OBJECT ) { const COLLADAFW::Object* object = joint->getObjectTarget(); if ( object->getClassId() == COLLADAFW::Node::ID() ) { joints.push_back( (COLLADAFW::Node*)object ); jointFound = true; //search for the next joint } else { // we could resolve the sid, but is not a joint/node } } else { // we could resolve the sid, but is not a joint/node } } } else { for ( URIList::const_iterator skeletonIt = skeletonRoots.begin(); skeletonIt != skeletonRoots.end(); ++skeletonIt) { const COLLADABU::URI& skeletonUri = *skeletonIt; SidAddress sidAddress( skeletonUri, sidOrId ); const SidTreeNode* joint = resolveSid( sidAddress ); if ( joint ) { // the joint could be found if ( joint->getTargetType() != SidTreeNode::TARGETTYPECLASS_OBJECT ) { // we could resolve the sid, but is not a joint/node break; } const COLLADAFW::Object* object = joint->getObjectTarget(); if ( object->getClassId() != COLLADAFW::Node::ID() ) { // we could resolve the sid, but is not a joint/node break; } joints.push_back( (COLLADAFW::Node*)object ); jointFound = true; //search for the next joint break; } } } if ( !jointFound ) { std::stringstream msg; msg << "Could not resolve " << (resolveIds ? "id" : "sid") << " \""; msg << sidOrId << "\" referenced in skin controller."; if ( handleFWLError( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, msg.str() )) { return false; } } } COLLADAFW::SkinController skinController( createUniqueId(COLLADAFW::SkinController::ID())); COLLADAFW::UniqueIdArray &jointsUniqueIds = skinController.getJoints(); jointsUniqueIds.allocMemory( joints.size() ); jointsUniqueIds.setCount(joints.size()); size_t i = 0; NodeList::const_iterator it = joints.begin(); for ( ; it != joints.end(); ++it, ++i ) { const COLLADAFW::Node* node = *it; jointsUniqueIds[i] = node->getUniqueId(); } skinController.setSkinControllerData(controllerDataUniqueId); skinController.setSource(sourceUniqueId); bool success = true; // Check if we have already wrote a skin controller that describes the same controller, i.e. has same // source, skin data and joints. If so, do not write it again and reference the previously used in the // scene graph const COLLADAFW::SkinController* skinControllerToWrite = 0; Loader::SkinControllerSet::const_iterator skinControllerIt = mSkinControllerSet.find( skinController ); if ( skinControllerIt == mSkinControllerSet.end() ) { skinControllerToWrite = &skinController; success = writer()->writeController(skinControllerToWrite); mSkinControllerSet.insert( skinController ); } else { skinControllerToWrite = &(*skinControllerIt); } instanceControllerData.instanceController->setInstanciatedObjectId( skinControllerToWrite->getUniqueId() ); return success; }
//--------------------------------- const SidTreeNode* DocumentProcessor::resolveSid( const COLLADABU::URI& id, const String& sid) { SidAddress sidAddress(id, sid); return resolveSid(sidAddress); }