//------------------------------ bool SceneGraphCreator::recursivelyCloneINode( ImpNode* parentImportNode, INode* nodeToClone ) { ImpNode* newImportNode = getMaxImportInterface()->CreateNode(); getMaxImportInterface()->AddNodeToScene(newImportNode); INode* newNode = newImportNode->GetINode(); Object* object = nodeToClone->GetObjectRef(); newImportNode->Reference(object); newNode->SetTMController(nodeToClone->GetTMController()); newImportNode->SetName(nodeToClone->GetName()); //used to assign material addClonedINodeOriginalINodePair(newNode, nodeToClone); INode* parentNode = parentImportNode->GetINode(); parentNode->AttachChild(newNode, TRUE); /* If the node to clone references an object, the cloned one must references the same object.*/ COLLADAFW::UniqueId id = getUniqueIdByObjectINode(nodeToClone); if ( id.isValid() ) { addUniqueIdObjectINodePair(id, newNode); addObjectINodeUniqueIdPair(newNode, id); } // Clone the children for ( int i = 0, count = nodeToClone->NumberOfChildren(); i < count; ++i) recursivelyCloneINode(newImportNode, nodeToClone->GetChildNode(i)); return true; }
//----------------------------- bool DocumentProcessor::createAndWriteSkinController( const Loader::InstanceControllerData& instanceControllerData, const COLLADAFW::UniqueId& controllerDataUniqueId, const COLLADAFW::UniqueId& sourceUniqueId) { if ( !controllerDataUniqueId.isValid() ) return false; const Loader::JointSidsOrIds& sidsOrIds = getJointSidsOrIdsBySkinDataUniqueId( controllerDataUniqueId ); return createAndWriteSkinController( instanceControllerData, controllerDataUniqueId, sourceUniqueId, sidsOrIds.sidsOrIds, sidsOrIds.areIds ); }
//----------------------------- 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 ); } } }
//-------------------------------------------------------------------- Math::matrix44 Nebula3Writer::getGeometryMatrix(const COLLADAFW::UniqueId& nodeId) { Math::matrix44 matTemp = Math::matrix44::identity(); const Math::matrix44 scalealeMatrix = Math::matrix44::scaling(1,1,-1); if( !this->mNodeMaps.Contains(nodeId)) return matTemp; NodeData& nodeData = this->mNodeMaps[nodeId]; matTemp = Math::matrix44::multiply(matTemp,nodeData.bind_matrix); COLLADAFW::UniqueId parentUniqueId = nodeData.parentUniqueId; while( parentUniqueId.isValid()) { if( !this->mNodeMaps.Contains(parentUniqueId)) break; NodeData& parentNodeData = this->mNodeMaps[parentUniqueId]; matTemp = Math::matrix44::multiply(matTemp,parentNodeData.bind_matrix); parentUniqueId = parentNodeData.parentUniqueId; }///end while Math::matrix44 matR = Math::matrix44::rotationx( -90.0f/180.0f * PI ); matTemp = Math::matrix44::multiply(matTemp,matR); matR = Math::matrix44::rotationy( 90.0f/180.0f * PI); matTemp = Math::matrix44::multiply(matTemp,matR); return matTemp; }
//----------------------------- 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; }