📄 loader.cpp
字号:
// allocate a new core keyframe instance CalCoreKeyframe *pCoreKeyframe = new CalCoreKeyframe(); if(pCoreKeyframe == 0) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return 0; } // create the core keyframe instance if(!pCoreKeyframe->create()) { delete pCoreKeyframe; return 0; } // set all attributes of the keyframe pCoreKeyframe->setTime(time); pCoreKeyframe->setTranslation(CalVector(tx, ty, tz)); pCoreKeyframe->setRotation(CalQuaternion(rx, ry, rz, rw)); return pCoreKeyframe;} /*****************************************************************************//** Loads a core submesh instance. * * This function loads a core submesh instance from a data source. * * @param dataSrc The data source to load the core submesh instance from. * * @return One of the following values: * \li a pointer to the core submesh * \li \b 0 if an error happened *****************************************************************************/CalCoreSubmesh *CalLoader::loadCoreSubmesh(CalDataSource& dataSrc){ if(!dataSrc.ok()) { dataSrc.setError(); return 0; } // get the material thread id of the submesh int coreMaterialThreadId; dataSrc.readInteger(coreMaterialThreadId); // get the number of vertices, faces, level-of-details and springs int vertexCount; dataSrc.readInteger(vertexCount); int faceCount; dataSrc.readInteger(faceCount); int lodCount; dataSrc.readInteger(lodCount); int springCount; dataSrc.readInteger(springCount); // get the number of texture coordinates per vertex int textureCoordinateCount; dataSrc.readInteger(textureCoordinateCount); // check if an error happened if(!dataSrc.ok()) { dataSrc.setError(); return 0; } // allocate a new core submesh instance CalCoreSubmesh *pCoreSubmesh; 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__); delete pCoreSubmesh; return 0; } // load the tangent space enable flags. int textureCoordinateId; for (textureCoordinateId = 0; textureCoordinateId < textureCoordinateCount; textureCoordinateId++) { pCoreSubmesh->enableTangents(textureCoordinateId, false); } // load all vertices and their influences int vertexId; for(vertexId = 0; vertexId < vertexCount; ++vertexId) { CalCoreSubmesh::Vertex vertex; // load data of the vertex dataSrc.readFloat(vertex.position.x); dataSrc.readFloat(vertex.position.y); dataSrc.readFloat(vertex.position.z); dataSrc.readFloat(vertex.normal.x); dataSrc.readFloat(vertex.normal.y); dataSrc.readFloat(vertex.normal.z); dataSrc.readInteger(vertex.collapseId); dataSrc.readInteger(vertex.faceCollapseCount); // check if an error happened if(!dataSrc.ok()) { dataSrc.setError(); delete pCoreSubmesh; return 0; } // load all texture coordinates of the vertex int textureCoordinateId; for(textureCoordinateId = 0; textureCoordinateId < textureCoordinateCount; ++textureCoordinateId) { CalCoreSubmesh::TextureCoordinate textureCoordinate; // load data of the influence dataSrc.readFloat(textureCoordinate.u); dataSrc.readFloat(textureCoordinate.v); if (loadingMode & LOADER_INVERT_V_COORD) { textureCoordinate.v = 1.0f - textureCoordinate.v; } // check if an error happened if(!dataSrc.ok()) { dataSrc.setError(); delete pCoreSubmesh; return 0; } // set texture coordinate in the core submesh instance pCoreSubmesh->setTextureCoordinate(vertexId, textureCoordinateId, textureCoordinate); } // get the number of influences int influenceCount; if(!dataSrc.readInteger(influenceCount) || (influenceCount < 0)) { dataSrc.setError(); delete pCoreSubmesh; return 0; } // reserve memory for the influences in the vertex vertex.vectorInfluence.reserve(influenceCount); vertex.vectorInfluence.resize(influenceCount); // load all influences of the vertex int influenceId; for(influenceId = 0; influenceId < influenceCount; ++influenceId) { // load data of the influence dataSrc.readInteger(vertex.vectorInfluence[influenceId].boneId), dataSrc.readFloat(vertex.vectorInfluence[influenceId].weight); // check if an error happened if(!dataSrc.ok()) { dataSrc.setError(); delete pCoreSubmesh; return 0; } } // set vertex in the core submesh instance pCoreSubmesh->setVertex(vertexId, vertex); // load the physical property of the vertex if there are springs in the core submesh if(springCount > 0) { CalCoreSubmesh::PhysicalProperty physicalProperty; // load data of the physical property dataSrc.readFloat(physicalProperty.weight); // check if an error happened if(!dataSrc.ok()) { dataSrc.setError(); delete pCoreSubmesh; return 0; } // set the physical property in the core submesh instance pCoreSubmesh->setPhysicalProperty(vertexId, physicalProperty); } } // load all springs int springId; for(springId = 0; springId < springCount; ++springId) { CalCoreSubmesh::Spring spring; // load data of the spring dataSrc.readInteger(spring.vertexId[0]); dataSrc.readInteger(spring.vertexId[1]); dataSrc.readFloat(spring.springCoefficient); dataSrc.readFloat(spring.idleLength); // check if an error happened if(!dataSrc.ok()) { dataSrc.setError(); delete pCoreSubmesh; return 0; } // set spring in the core submesh instance pCoreSubmesh->setSpring(springId, spring); } // load all faces int faceId; int justOnce = 0; bool flipModel = false; for(faceId = 0; faceId < faceCount; ++faceId) { CalCoreSubmesh::Face face; // load data of the face int tmp[4]; dataSrc.readInteger(tmp[0]); dataSrc.readInteger(tmp[1]); dataSrc.readInteger(tmp[2]); if(sizeof(CalIndex)==2) { if(tmp[0]>65535 || tmp[1]>65535 || tmp[2]>65535) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__); delete pCoreSubmesh; return 0; } } face.vertexId[0]=tmp[0]; face.vertexId[1]=tmp[1]; face.vertexId[2]=tmp[2]; // check if an error happened if(!dataSrc.ok()) { dataSrc.setError(); delete pCoreSubmesh; return 0; } // check if left-handed coord system is used by the object // can be done only once since the object has one system for all faces if (justOnce==0) { // get vertexes of first face std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pCoreSubmesh->getVectorVertex(); CalCoreSubmesh::Vertex& v1 = vectorVertex[tmp[0]]; CalCoreSubmesh::Vertex& v2 = vectorVertex[tmp[1]]; CalCoreSubmesh::Vertex& v3 = vectorVertex[tmp[2]]; CalVector point1 = CalVector(v1.position.x, v1.position.y, v1.position.z); CalVector point2 = CalVector(v2.position.x, v2.position.y, v2.position.z); CalVector point3 = CalVector(v3.position.x, v3.position.y, v3.position.z); // gets vectors (v1-v2) and (v3-v2) CalVector vect1 = point1 - point2; CalVector vect2 = point3 - point2; // calculates normal of face CalVector cross = vect1 % vect2; CalVector faceNormal = cross / cross.length(); // compare the calculated normal with the normal of a vertex CalVector maxNorm = v1.normal; // if the two vectors point to the same direction then the poly needs flipping // so if the dot product > 0 it needs flipping if (faceNormal*maxNorm>0) flipModel = true; // flip the winding order if the loading flags request it if (loadingMode & LOADER_FLIP_WINDING) flipModel = !flipModel; justOnce = 1; } // flip if needed if (flipModel) { tmp[3] = face.vertexId[1]; face.vertexId[1]=face.vertexId[2]; face.vertexId[2]=tmp[3]; } // set face in the core submesh instance pCoreSubmesh->setFace(faceId, face); } return pCoreSubmesh;} /*****************************************************************************//** Loads a core track instance. * * This function loads a core track instance from a data source. * * @param dataSrc The data source to load the core track instance from. * * @return One of the following values: * \li a pointer to the core track * \li \b 0 if an error happened *****************************************************************************/CalCoreTrack *CalLoader::loadCoreTrack(CalDataSource& dataSrc, CalCoreSkeleton *skel, float duration){ if(!dataSrc.ok()) { dataSrc.setError(); return 0; } // read the bone id int coreBoneId; if(!dataSrc.readInteger(coreBoneId) || (coreBoneId < 0)) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__); return 0; } // allocate a new core track instance 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; } // link the core track to the appropriate core bone instance pCoreTrack->setCoreBoneId(coreBoneId); // read the number of keyframes int keyframeCount; if(!dataSrc.readInteger(keyframeCount) || (keyframeCount <= 0)) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__); return 0; } // load all core keyframes int keyframeId; for(keyframeId = 0; keyframeId < keyframeCount; ++keyframeId) { // load the core keyframe CalCoreKeyframe *pCoreKeyframe = loadCoreKeyframe(dataSrc); if(pCoreKeyframe == 0) { pCoreTrack->destroy(); delete pCoreTrack; return 0; } 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 vec = pCoreKeyframe->getTranslation(); vec *= x_axis_90; pCoreKeyframe->setTranslation(vec); } } // add the core keyframe to the core track instance pCoreTrack->addCoreKeyframe(pCoreKeyframe); } return pCoreTrack;} /*****************************************************************************//** Loads a core skeleton instance from a XML file. * * This function loads a core skeleton instance from a XML file. * * @param strFilename The name of the file to load the core skeleton instance * from. * * @return One of the following values: * \li a pointer to the core skeleton * \li \b 0 if an error happened *****************************************************************************/CalCoreSkeletonPtr CalLoader::loadXmlCoreSkeleton(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*skeleton = doc.FirstChildElement(); if(!skeleton) { CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -