📄 loader.cpp
字号:
CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; } float rx, ry, rz, rw; node = rotation->FirstChild(); if(!node) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; } TiXmlText* rotationdata = node->ToText(); if(!rotationdata) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; } str.clear(); str << rotationdata->Value(); str >> rx >> ry >> rz >> rw; // allocate a new core keyframe instance CalCoreKeyframe *pCoreKeyframe; pCoreKeyframe = new CalCoreKeyframe(); if(pCoreKeyframe == 0) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return 0; } // create the core keyframe instance if(!pCoreKeyframe->create()) { return 0; } // set all attributes of the keyframe pCoreKeyframe->setTime(time); pCoreKeyframe->setTranslation(CalVector(tx, ty, tz)); pCoreKeyframe->setRotation(CalQuaternion(rx, ry, rz, rw)); if (loadingMode & LOADER_ROTATE_X_AXIS) { // Check for anim rotation if (skel && skel->getCoreBone(coreBoneId)->getParentId() == -1) // root bone { // rotate root bone quaternion CalQuaternion rot = pCoreKeyframe->getRotation(); CalQuaternion x_axis_90(0.7071067811f,0.0f,0.0f,0.7071067811f); rot *= x_axis_90; pCoreKeyframe->setRotation(rot); // rotate root bone displacement CalVector trans = pCoreKeyframe->getTranslation(); trans *= x_axis_90; pCoreKeyframe->setTranslation(trans); } } // add the core keyframe to the core track instance pCoreTrack->addCoreKeyframe(pCoreKeyframe); keyframe = keyframe->NextSiblingElement(); } pCoreAnimation->addCoreTrack(pCoreTrack); track=track->NextSiblingElement(); } // explicitly close the file doc.Clear(); return pCoreAnimation;} /*****************************************************************************//** Loads a core mesh instance from a Xml file. * * This function loads a core mesh instance from a Xml file. * * @param strFilename The name of the file to load the core mesh instance from. * * @return One of the following values: * \li a pointer to the core mesh * \li \b 0 if an error happened *****************************************************************************/CalCoreMeshPtr CalLoader::loadXmlCoreMesh(const std::string& strFilename){ std::stringstream str; TiXmlDocument doc(strFilename); if(!doc.LoadFile()) { CalError::setLastError(CalError::FILE_NOT_FOUND, __FILE__, __LINE__, strFilename); return 0; } TiXmlNode* node; TiXmlElement*mesh = doc.FirstChildElement(); if(!mesh) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(stricmp(mesh->Value(),"HEADER")==0) { if(stricmp(mesh->Attribute("MAGIC"),Cal::MESH_XMLFILE_MAGIC)!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(atoi(mesh->Attribute("VERSION")) < Cal::EARLIEST_COMPATIBLE_FILE_VERSION ) { CalError::setLastError(CalError::INCOMPATIBLE_FILE_VERSION, __FILE__, __LINE__, strFilename); return false; } mesh = mesh->NextSiblingElement(); } if(!mesh || stricmp(mesh->Value(),"MESH")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(mesh->Attribute("MAGIC")!=NULL && stricmp(mesh->Attribute("MAGIC"),Cal::MESH_XMLFILE_MAGIC)!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } if(mesh->Attribute("VERSION")!=NULL && atoi(mesh->Attribute("VERSION")) < Cal::EARLIEST_COMPATIBLE_FILE_VERSION ) { CalError::setLastError(CalError::INCOMPATIBLE_FILE_VERSION, __FILE__, __LINE__, strFilename); return false; } // get the number of submeshes int submeshCount = atoi(mesh->Attribute("NUMSUBMESH")); // allocate a new core mesh instance CalCoreMeshPtr pCoreMesh = new CalCoreMesh; if(!pCoreMesh) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return 0; } TiXmlElement*submesh = mesh->FirstChildElement(); // load all core submeshes int submeshId; for(submeshId = 0; submeshId < submeshCount; ++submeshId) { if(!submesh || stricmp(submesh->Value(),"SUBMESH")!=0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } // get the material thread id of the submesh int coreMaterialThreadId = atoi(submesh->Attribute("MATERIAL")); // get the number of vertices, faces, level-of-details and springs int vertexCount = atoi(submesh->Attribute("NUMVERTICES")); int faceCount = atoi(submesh->Attribute("NUMFACES")); int lodCount = atoi(submesh->Attribute("NUMLODSTEPS")); int springCount = atoi(submesh->Attribute("NUMSPRINGS")); int textureCoordinateCount = atoi(submesh->Attribute("NUMTEXCOORDS")); // allocate a new core submesh instance CalCoreSubmesh *pCoreSubmesh = new CalCoreSubmesh(); if(pCoreSubmesh == 0) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return 0; } // set the LOD step count pCoreSubmesh->setLodCount(lodCount); // set the core material id pCoreSubmesh->setCoreMaterialThreadId(coreMaterialThreadId); // reserve memory for all the submesh data if(!pCoreSubmesh->reserve(vertexCount, textureCoordinateCount, faceCount, springCount)) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__, strFilename); delete pCoreSubmesh; return 0; } TiXmlElement *vertex = submesh->FirstChildElement(); // load all vertices and their influences int vertexId; for(vertexId = 0; vertexId < vertexCount; ++vertexId) { if(!vertex || stricmp(vertex->Value(),"VERTEX")!=0) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } CalCoreSubmesh::Vertex Vertex; TiXmlElement *pos= vertex->FirstChildElement(); if(!pos || stricmp(pos->Value(),"POS")!=0) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } node = pos->FirstChild(); if(!node) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* posdata = node->ToText(); if(!posdata) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } str.clear(); str << posdata->Value(); str >> Vertex.position.x >> Vertex.position.y >> Vertex.position.z; TiXmlElement *norm= pos->NextSiblingElement(); if(!norm||stricmp(norm->Value(),"NORM")!=0) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } node = norm->FirstChild(); if(!norm) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* normdata = node->ToText(); if(!normdata) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } str.clear(); str << normdata->Value(); str >> Vertex.normal.x >> Vertex.normal.y >> Vertex.normal.z; TiXmlElement *collapse= norm->NextSiblingElement(); if(collapse && stricmp(collapse->Value(),"COLLAPSEID")==0) { node = collapse->FirstChild(); if(!node) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* collapseid = node->ToText(); if(!collapseid) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } Vertex.collapseId = atoi(collapseid->Value()); TiXmlElement *collapseCount= collapse->NextSiblingElement(); if(!collapseCount|| stricmp(collapseCount->Value(),"COLLAPSECOUNT")!=0) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } node = collapseCount->FirstChild(); if(!node) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* collapseCountdata = node->ToText(); if(!collapseCountdata) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } Vertex.faceCollapseCount= atoi(collapseCountdata->Value()); collapse = collapseCount->NextSiblingElement(); } else { Vertex.collapseId=-1; Vertex.faceCollapseCount=0; } TiXmlElement *texcoord = collapse; // load all texture coordinates of the vertex int textureCoordinateId; for(textureCoordinateId = 0; textureCoordinateId < textureCoordinateCount; ++textureCoordinateId) { CalCoreSubmesh::TextureCoordinate textureCoordinate; // load data of the influence if(!texcoord || stricmp(texcoord->Value(),"TEXCOORD")!=0) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } node = texcoord->FirstChild(); if(!node) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* texcoorddata = node->ToText(); if(!texcoorddata) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } str.clear(); str << texcoorddata->Value(); str >> textureCoordinate.u >> textureCoordinate.v; if (loadingMode & LOADER_INVERT_V_COORD) { textureCoordinate.v = 1.0f - textureCoordinate.v; } // set texture coordinate in the core submesh instance pCoreSubmesh->setTextureCoordinate(vertexId, textureCoordinateId, textureCoordinate); texcoord = texcoord->NextSiblingElement(); } // get the number of influences int influenceCount= atoi(vertex->Attribute("NUMINFLUENCES")); if(influenceCount < 0) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); delete pCoreSubmesh; return 0; } // reserve memory for the influences in the vertex Vertex.vectorInfluence.reserve(influenceCount); Vertex.vectorInfluence.resize(influenceCount); TiXmlElement *influence = texcoord; // load all influences of the vertex int influenceId; for(influenceId = 0; influenceId < influenceCount; ++influenceId) { if(!influence ||stricmp(influence->Value(),"INFLUENCE")!=0) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } node = influence->FirstChild(); if(!node) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* influencedata = node->ToText(); if(!influencedata) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } Vertex.vectorInfluence[influenceId].boneId = atoi(influence->Attribute("ID")); Vertex.vectorInfluence[influenceId].weight = (float) atof(influencedata->Value()); influence=influence->NextSiblingElement(); } // set vertex in the core submesh instance pCoreSubmesh->setVertex(vertexId, Vertex); TiXmlElement *physique = influence; // load the physical property of the vertex if there are springs in the core submesh if(springCount > 0) { CalCoreSubmesh::PhysicalProperty physicalProperty; if(!physique || stricmp(physique->Value(),"PHYSIQUE")!=0) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } node = physique->FirstChild(); if(!node) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } TiXmlText* physiquedata = node->ToText(); if(!physiquedata) { delete pCoreSubmesh; CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return false; } physicalProperty.weight = (float) atof(physiquedata->Value()); // set the physical property in the core submesh instance pCoreSubmesh->setPhysicalPropert
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -