📄 loader.cpp
字号:
if(stricmp(skeleton->Value(),"HEADER")==0) { if(stricmp(skeleton->Attribute("MAGIC"),Cal::SKELETON_XMLFILE_MAGIC)!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(atoi(skeleton->Attribute("VERSION")) < Cal::EARLIEST_COMPATIBLE_FILE_VERSION ) { CalError::setLastError(CalError::INCOMPATIBLE_FILE_VERSION, __FILE__, __LINE__, strFilename); return false; } skeleton = skeleton->NextSiblingElement(); } if(!skeleton || stricmp(skeleton->Value(),"SKELETON")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(skeleton->Attribute("MAGIC")!=NULL && stricmp(skeleton->Attribute("MAGIC"),Cal::SKELETON_XMLFILE_MAGIC)!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(skeleton->Attribute("VERSION")!=NULL && atoi(skeleton->Attribute("VERSION")) < Cal::EARLIEST_COMPATIBLE_FILE_VERSION ) { CalError::setLastError(CalError::INCOMPATIBLE_FILE_VERSION, __FILE__, __LINE__, strFilename); return false; } // allocate a new core skeleton instance CalCoreSkeletonPtr pCoreSkeleton = new CalCoreSkeleton(); if(!pCoreSkeleton) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return 0; } TiXmlElement* bone; for( bone = skeleton->FirstChildElement();bone;bone = bone->NextSiblingElement() ) { if(stricmp(bone->Value(),"BONE")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } std::string strName=bone->Attribute("NAME"); // get the translation of the bone TiXmlElement* translation = bone->FirstChildElement(); if(!translation || stricmp( translation->Value(),"TRANSLATION")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } float tx, ty, tz; node = translation->FirstChild(); if(!node) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* translationdata = node->ToText(); if(!translationdata) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } str.clear(); str << translationdata->Value(); str >> tx >> ty >> tz; // get the rotation of the bone TiXmlElement* rotation = translation->NextSiblingElement(); if(!rotation || stricmp(rotation->Value(),"ROTATION")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } float rx, ry, rz, rw; node = rotation->FirstChild(); if(!node) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* rotationdata = node->ToText(); if(!rotationdata) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } str.clear(); str << rotationdata->Value(); str >> rx >> ry >> rz >> rw; // get the bone space translation of the bone TiXmlElement* translationBoneSpace = rotation->NextSiblingElement(); if(!rotation || stricmp(translationBoneSpace->Value(),"LOCALTRANSLATION")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } float txBoneSpace, tyBoneSpace, tzBoneSpace; node = translationBoneSpace->FirstChild(); if(!node) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* translationBoneSpacedata = node->ToText(); if(!translationBoneSpacedata) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } str.clear(); str << translationBoneSpacedata->Value(); str >> txBoneSpace >> tyBoneSpace >> tzBoneSpace; // get the bone space rotation of the bone TiXmlElement* rotationBoneSpace = translationBoneSpace->NextSiblingElement(); if(!rotationBoneSpace || stricmp(rotationBoneSpace->Value(),"LOCALROTATION")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } float rxBoneSpace, ryBoneSpace, rzBoneSpace, rwBoneSpace; node = rotationBoneSpace->FirstChild(); if(!node) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* rotationBoneSpacedata = node->ToText(); if(!rotationBoneSpacedata) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } str.clear(); str << rotationBoneSpacedata->Value(); str >> rxBoneSpace >> ryBoneSpace >> rzBoneSpace >> rwBoneSpace; // get the parent bone id TiXmlElement* parent = rotationBoneSpace->NextSiblingElement(); if(!parent ||stricmp(parent->Value(),"PARENTID")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } int parentId; node = parent->FirstChild(); if(!node) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* parentid = node->ToText(); if(!parentid) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } parentId = atoi(parentid->Value()); // allocate a new core bone instance CalCoreBone *pCoreBone = new CalCoreBone(strName); if(pCoreBone == 0) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return 0; } // set the parent of the bone pCoreBone->setParentId(parentId); // set all attributes of the bone CalVector trans = CalVector(tx, ty, tz); CalQuaternion rot = CalQuaternion(rx, ry, rz, rw); if (loadingMode & LOADER_ROTATE_X_AXIS) { if (parentId == -1) // only root bone necessary { // Root bone must have quaternion rotated CalQuaternion x_axis_90(0.7071067811f,0.0f,0.0f,0.7071067811f); rot *= x_axis_90; // Root bone must have translation rotated also trans *= x_axis_90; } } pCoreBone->setTranslation(trans); pCoreBone->setRotation(rot); pCoreBone->setTranslationBoneSpace(CalVector(txBoneSpace, tyBoneSpace, tzBoneSpace)); pCoreBone->setRotationBoneSpace(CalQuaternion(rxBoneSpace, ryBoneSpace, rzBoneSpace, rwBoneSpace)); TiXmlElement* child; for( child = parent->NextSiblingElement();child;child = child->NextSiblingElement() ) { if(stricmp(child->Value(),"CHILDID")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); delete pCoreBone; return false; } TiXmlNode *node= child->FirstChild(); if(!node) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); delete pCoreBone; return false; } TiXmlText* childid = node->ToText(); if(!childid) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); delete pCoreBone; return false; } int childId = atoi(childid->Value()); pCoreBone->addChildId(childId); } // set the core skeleton of the core bone instance pCoreBone->setCoreSkeleton(pCoreSkeleton.get()); // add the core bone to the core skeleton instance pCoreSkeleton->addCoreBone(pCoreBone); } doc.Clear(); pCoreSkeleton->calculateState(); return pCoreSkeleton;} /*****************************************************************************//** Loads a core animation instance from a XML file. * * This function loads a core animation instance from a XML file. * * @param strFilename The name of the file to load the core animation instance * from. * * @return One of the following values: * \li a pointer to the core animation * \li \b 0 if an error happened *****************************************************************************/CalCoreAnimationPtr CalLoader::loadXmlCoreAnimation(const std::string& strFilename, CalCoreSkeleton *skel){ std::stringstream str; TiXmlDocument doc(strFilename); if(!doc.LoadFile()) { CalError::setLastError(CalError::FILE_NOT_FOUND, __FILE__, __LINE__, strFilename); return 0; } TiXmlNode* node; TiXmlElement*animation = doc.FirstChildElement(); if(!animation) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(stricmp(animation->Value(),"HEADER")==0) { if(stricmp(animation->Attribute("MAGIC"),Cal::ANIMATION_XMLFILE_MAGIC)!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(atoi(animation->Attribute("VERSION")) < Cal::EARLIEST_COMPATIBLE_FILE_VERSION ) { CalError::setLastError(CalError::INCOMPATIBLE_FILE_VERSION, __FILE__, __LINE__, strFilename); return false; } animation = animation->NextSiblingElement(); } if(!animation || stricmp(animation->Value(),"ANIMATION")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(animation->Attribute("MAGIC") !=NULL && stricmp(animation->Attribute("MAGIC"),Cal::ANIMATION_XMLFILE_MAGIC)!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(animation->Attribute("VERSION")!=NULL && atoi(animation->Attribute("VERSION")) < Cal::EARLIEST_COMPATIBLE_FILE_VERSION ) { CalError::setLastError(CalError::INCOMPATIBLE_FILE_VERSION, __FILE__, __LINE__, strFilename); return false; } int trackCount= atoi(animation->Attribute("NUMTRACKS")); float duration= (float) atof(animation->Attribute("DURATION")); // allocate a new core animation instance CalCoreAnimation *pCoreAnimation; pCoreAnimation = new CalCoreAnimation(); if(pCoreAnimation == 0) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return 0; } // check for a valid duration if(duration <= 0.0f) { CalError::setLastError(CalError::INVALID_ANIMATION_DURATION, __FILE__, __LINE__, strFilename); return 0; } // set the duration in the core animation instance pCoreAnimation->setDuration(duration); TiXmlElement* track=animation->FirstChildElement(); // load all core bones int trackId; for(trackId = 0; trackId < trackCount; ++trackId) { if(!track || stricmp(track->Value(),"TRACK")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; } CalCoreTrack *pCoreTrack; pCoreTrack = new CalCoreTrack(); if(pCoreTrack == 0) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return 0; } // create the core track instance if(!pCoreTrack->create()) { delete pCoreTrack; return 0; } int coreBoneId = atoi(track->Attribute("BONEID")); // link the core track to the appropriate core bone instance pCoreTrack->setCoreBoneId(coreBoneId); // read the number of keyframes int keyframeCount= atoi(track->Attribute("NUMKEYFRAMES")); if(keyframeCount <= 0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; } TiXmlElement* keyframe= track->FirstChildElement(); // load all core keyframes int keyframeId; for(keyframeId = 0; keyframeId < keyframeCount; ++keyframeId) { // load the core keyframe if(!keyframe|| stricmp(keyframe->Value(),"KEYFRAME")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; } float time= (float) atof(keyframe->Attribute("TIME")); TiXmlElement* translation = keyframe->FirstChildElement(); if(!translation || stricmp(translation->Value(),"TRANSLATION")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; } float tx, ty, tz; node = translation->FirstChild(); if(!node) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; } TiXmlText* translationdata = node->ToText(); if(!translationdata) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; } str.clear(); str << translationdata->Value(); str >> tx >> ty >> tz; TiXmlElement* rotation = translation->NextSiblingElement(); if(!rotation || stricmp(rotation->Value(),"ROTATION")!=0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -