IZ_BOOL CColladaAnimation::ReadJoint(domVisual_scene* pScene) { size_t nNodeCnt = pScene->getNode_array().getCount(); for (size_t i = 0; i < nNodeCnt; i++) { domNodeRef pNode = pScene->getNode_array().get(i); VRETURN(ReadJoint(pNode)); } return IZ_TRUE; }
IZ_BOOL CColladaAnimation::ReadJoint(domNodeRef pNode) { domNodeType type = pNode->getType(); if (type == NODETYPE_JOINT) { SJoint sJoint; sJoint.name = pNode->getName(); for (size_t n = 0; n < pNode->getContents().getCount(); n++) { domElement* pContent = pNode->getContents().get(n); daeString strType = pContent->getTypeName(); if (izanagi::tool::CString::CmpStr(strType, "node")) { // terminate... continue; } SJointTransform sTransform; sTransform.type = GetTransformType(strType); switch (sTransform.type) { case E_TRANSFROM_TYPE_TRANSLATE: GetTransform<domTranslate, 3>(pContent, sTransform); break; case E_TRANSFROM_TYPE_QUARTANION: GetTransform<domRotate, 4>(pContent, sTransform); break; case E_TRANSFROM_TYPE_SCALE: GetTransform<domScale, 3>(pContent, sTransform); break; default: VRETURN(IZ_FALSE); break; } sJoint.transforms.push_back(sTransform); } if (!sJoint.transforms.empty()) { m_Joints.push_back(sJoint); } } size_t nChildNodeCnt = pNode->getNode_array().getCount(); for (size_t n = 0; n < nChildNodeCnt; n++) { domNodeRef node = pNode->getNode_array().get(n); VRETURN(ReadJoint(node)); } return IZ_TRUE; }
/* ============= MD5Model::ReadJoints Reads all joints from a char buffer. Stores them in joints member variable. Returns a pointer to where the buffer should continue reading. ============= */ char* MD5Model::ReadJoints( char* startingPosition ) { char* nextLine = NULL; char* currentLine = strtok_s( startingPosition, "\n", &nextLine ); char* nextToken = NULL; int jointIndex = 0; while ( currentLine[0] != '}' ) { ReadJoint( currentLine, joints[jointIndex] ); ++jointIndex; currentLine = strtok_s( NULL, "\n", &nextLine ); } return nextLine; }
IZ_BOOL CColladaAnimation::Begin( domCOLLADA* pRoot, domVisual_scene* pScene, IZ_UINT nAnmLibIdx) { VRETURN(ReadJoint(pScene)); m_AnmNodes.resize(m_Joints.size()); for (size_t i = 0; i < m_AnmNodes.size(); i++) { m_AnmNodes[i].nameJoint = m_Joints[i].name.c_str(); m_AnmNodes[i].idxJoint = static_cast<IZ_UINT>(i); } domLibrary_animationsRef pAnmLib = pRoot->getLibrary_animations_array().get(nAnmLibIdx); size_t nAnmNum = pAnmLib->getAnimation_array().getCount(); for (size_t nAnmCnt = 0; nAnmCnt < nAnmNum; nAnmCnt++) { domAnimationRef pAnm = pAnmLib->getAnimation_array().get(nAnmCnt); SAnmChannel sAnmChannel; { // Set initial value... sAnmChannel.interp = izanagi::E_ANM_INTERP_TYPE_LINEAR; } IZ_ASSERT(pAnm->getChannel_array().getCount() == 1); domChannelRef pChannel = pAnm->getChannel_array().get(0); VRETURN(GetAnmTarget(pChannel, sAnmChannel)); // Find target joint. std::vector<SAnmNode>::iterator it = std::find( m_AnmNodes.begin(), m_AnmNodes.end(), sAnmChannel.joint); if (it == m_AnmNodes.end()) { // Not find target joint... continue; } IZ_ASSERT(pAnm->getSampler_array().getCount() == 1); domSamplerRef pSmpl = pAnm->getSampler_array().get(0); size_t nInputNum = pSmpl->getInput_array().getCount(); sAnmChannel.inputs.resize(nInputNum); for (size_t nInputCnt = 0; nInputCnt < nInputNum; nInputCnt++) { SAnmInput& sAnmInput = sAnmChannel.inputs[nInputCnt]; domInputLocalRef pInput = pSmpl->getInput_array().get(nInputCnt); daeString strSemantic = pInput->getSemantic(); sAnmInput.semantic = ConvSemanticFromString(strSemantic); VRETURN(sAnmInput.semantic < E_INPUT_SEMANTIC_NUM); if (sAnmInput.semantic == E_INPUT_SEMANTIC_INTERPOLATION) { // Get interpolation type. VRETURN(GetInterpType(pInput, sAnmChannel)); } else { VRETURN( GetAnmInputParams( pInput, sAnmChannel, sAnmInput)); } } size_t nNodeIdx = std::distance(m_AnmNodes.begin(), it); m_AnmNodes[nNodeIdx].channels.push_back(sAnmChannel); } // Remove node which has no animation channel. std::vector<SAnmNode>::iterator it = m_AnmNodes.begin(); for (; it != m_AnmNodes.end();) { const SAnmNode& sNode = *it; if (sNode.channels.empty()) { it = m_AnmNodes.erase(it); } else { it++; } } for (IZ_UINT i = 0; i < m_AnmNodes.size(); i++) { VRETURN(CreateSlerp(i)); } return IZ_TRUE; }