/** 载入MD2文件 */ bool CMD2Loader::ImportMD2(t3DModel *pModel, char *strFileName, char *strTexture) { char strMessage[255] = {0}; /** 打开文件 */ m_FilePointer = fopen(strFileName, "rb"); /** 检查文件指针 */ if(!m_FilePointer) { sprintf(strMessage, "打开文件: %s错误!", strFileName); MessageBox(NULL, strMessage, "Error", MB_OK); return false; } /** 读取文件头 */ fread(&m_Header, 1, sizeof(tMd2Header), m_FilePointer); /** 检查版本号 */ if(m_Header.version != 8) { sprintf(strMessage, "Invalid file format (Version not 8): %s!", strFileName); MessageBox(NULL, strMessage, "Error", MB_OK); return false; } /** 读取MD2文件数据 */ ReadMD2Data(); /** 将MD2数据转换为模型结构 */ ConvertDataStructures(pModel); /** 如果具有纹理文件 */ if(strTexture) { /** 材质信息结构体 */ tMaterialInfo texture; /** 复制文件名 */ strcpy(texture.strFile, strTexture); /** 纹理ID号为0 */ texture.texureId = 0; texture.uTile = texture.uTile = 1; /** 模型材质数为1 */ pModel->numOfMaterials = 1; /** 添加材质信息 */ pModel->pMaterials.push_back(texture); } /** 释放内存 */ CleanUp(); return true; /**< 成功返回 */ }
void CLoadMD3::ReadMD3Data(t3DModel *pModel) { int i = 0; m_pBones = new tMd3Bone [m_Header.numFrames]; fread(m_pBones, sizeof(tMd3Bone), m_Header.numFrames, m_FilePointer); delete [] m_pBones; pModel->pTags = new tMd3Tag [m_Header.numFrames * m_Header.numTags]; fread(pModel->pTags, sizeof(tMd3Tag), m_Header.numFrames * m_Header.numTags, m_FilePointer); pModel->numOfTags = m_Header.numTags; pModel->pLinks = (t3DModel **) malloc(sizeof(t3DModel) * m_Header.numTags); for (i = 0; i < m_Header.numTags; i++) pModel->pLinks[i] = NULL; long meshOffset = ftell(m_FilePointer); tMd3MeshInfo meshHeader; for (i = 0; i < m_Header.numMeshes; i++) { fseek(m_FilePointer, meshOffset, SEEK_SET); fread(&meshHeader, sizeof(tMd3MeshInfo), 1, m_FilePointer); m_pSkins = new tMd3Skin [meshHeader.numSkins]; m_pTexCoords = new tMd3TexCoord [meshHeader.numVertices]; m_pTriangles = new tMd3Face [meshHeader.numTriangles]; m_pVertices = new tMd3Triangle [meshHeader.numVertices * meshHeader.numMeshFrames]; fread(m_pSkins, sizeof(tMd3Skin), meshHeader.numSkins, m_FilePointer); fseek(m_FilePointer, meshOffset + meshHeader.triStart, SEEK_SET); fread(m_pTriangles, sizeof(tMd3Face), meshHeader.numTriangles, m_FilePointer); fseek(m_FilePointer, meshOffset + meshHeader.uvStart, SEEK_SET); fread(m_pTexCoords, sizeof(tMd3TexCoord), meshHeader.numVertices, m_FilePointer); fseek(m_FilePointer, meshOffset + meshHeader.vertexStart, SEEK_SET); fread(m_pVertices, sizeof(tMd3Triangle), meshHeader.numMeshFrames * meshHeader.numVertices, m_FilePointer); ConvertDataStructures(pModel, meshHeader); delete [] m_pSkins; delete [] m_pTexCoords; delete [] m_pTriangles; delete [] m_pVertices; meshOffset += meshHeader.meshSize; } }
bool CLoadMD2::ImportMD2(t3DModel *pModel, char *strFileName, char *strTexture) { char strMessage[255] = {0}; // Open the MD2 file in binary m_FilePointer = fopen(strFileName, "rb"); // Make sure we have a valid file pointer (we found the file) if(!m_FilePointer) { // Display an error message and don't load anything if no file was found sprintf(strMessage, "Unable to find the file: %s!", strFileName); MessageBox(NULL, strMessage, "Error", MB_OK); return false; } // Read the header data and store it in our m_Header member variable fread(&m_Header, 1, sizeof(tMd2Header), m_FilePointer); // Make sure the version is this crazy number '8' or else it's a bad egg if(m_Header.version != 8) { // Display an error message for bad file format, then stop loading. sprintf(strMessage, "Invalid file format (Version not 8): %s!", strFileName); MessageBox(NULL, strMessage, "Error", MB_OK); return false; } // Read in the model and animation data ReadMD2Data(); // Here we pass in our model structure so it can store and read Quake data // in our own model and object structure data. ConvertDataStructures(pModel); // If there is a valid texture name passed in, we want to set the texture data if(strTexture) { // Create a local material info structure tMaterialInfo texture; // Copy the name of the file into our texture file name variable strcpy(texture.strFile, strTexture); // Since there is only one texture for a .Md2 file, the ID is always 0 texture.texureId = 0; // The tile or scale for the UV's is 1 to 1 (but Quake saves off a 0-256 ratio) texture.uTile = texture.uTile = 1; // We only have 1 material for a model pModel->numOfMaterials = 1; // Add the local material info to our model's material list pModel->pMaterials.push_back(texture); } // Clean up after everything CleanUp(); // Return a success return true; }
bool CLoadMD2::ImportMD2(t3DModel *pModel, char *strFileName, char *strTexture) { char strMessage[255] = {0}; // Open the MD2 file in binary m_FilePointer = fopen(strFileName, "rb"); // Make sure we have a valid file pointer (we found the file) if(!m_FilePointer) { // Display an error message and don't load anything if no file was found sprintf(strMessage, "Unable to find the file: %s!", strFileName); MessageBox(NULL, strMessage, "Error", MB_OK); return false; } // Just like most file formats, there is a header that needs to be read // from the .MD2 format. If you look at the tMd2Header structure you will // find all the data that will be read in. It's nice to know up front about // the data that we will be reading. This makes it easy to just to large // binary reads using fread, instead of counting and reading chunks. // Read the header data and store it in our m_Header member variable fread(&m_Header, 1, sizeof(tMd2Header), m_FilePointer); // For some reason, .Md2 files MUST have a version of 8. I am not sure why, // but if it doesn't there is something wrong and the header was read in // incorrectly, or perhaps the file format is bad. if(m_Header.version != 8) { // Display an error message for bad file format, then stop loading sprintf(strMessage, "Invalid file format (Version not 8): %s!", strFileName); MessageBox(NULL, strMessage, "Error", MB_OK); return false; } // Now that we made sure the header had correct data, we want to read in the // rest of the data. Once the data is read in, we need to convert it to our structures. // Since we are only reading in the first frame of animation, there will only // be ONE object in our t3DObject structure, held within our pModel variable. ReadMD2Data(); // Here we pass in our model structure to it can store the read Quake data // in our own model and object structure data. ConvertDataStructures(pModel); // After we have read the whole MD2 file, we want to calculate our own vertex normals. ComputeNormals(pModel); // If there is a valid texture name passed in, we want to set the texture data. if(strTexture) { // Create a local material info structure tMaterialInfo texture; // Copy the name of the file into our texture file name variable strcpy(texture.strFile, strTexture); // Since there is only one texture for a .MD2 file, the ID is always 0 texture.texureId = 0; // The tile or scale for the UV's is 1 to 1 (but Quake saves off a 0-256 ratio) texture.uTile = texture.uTile = 1; // We only have 1 material for a model pModel->numOfMaterials = 1; // Add the local material info to our model's material list pModel->pMaterials.push_back(texture); } // Clean up after everything CleanUp(); // Return a success return true; }
void CLoadGTF::ReadGTFData(t3DModel *pModel) { // Read in the number of objects for this scene int numObjects = 0; fread(&numObjects, sizeof(int), 1, m_FilePointer); // Go through all of the objects in the scene for(int i = 0; i < numObjects; i++) { // Create a structure to hold the size of the data lists tMeshInfo meshInfo = {0}; // In our loading code we first want to load in all of the materials. // First we load the number of materials in the file. fread(&meshInfo.numMaterials, sizeof(int), 1, m_FilePointer); // Go through all of our materials and load them for(int m = 0; m < meshInfo.numMaterials; m++) { // Load in only MAX_FILE_NAME characters for the texture name char szMaterial[MAX_FILE_NAME] = {0}; fread(szMaterial, sizeof(char), MAX_FILE_NAME, m_FilePointer); // Create a material structure instance and store the material info tMaterialInfo newMaterial; strcpy(newMaterial.strFile, szMaterial); newMaterial.texureId = (int)pModel->pMaterials.size(); // Add a new material pModel->pMaterials.push_back(newMaterial); } // Read the number of vertices, allocate memory and read them from the file. fread(&meshInfo.numVertices, sizeof(int), 1, m_FilePointer); m_pVertices = new CVector3 [meshInfo.numVertices]; fread(m_pVertices, sizeof(CVector3), meshInfo.numVertices, m_FilePointer); // Read the number of indices, allocate memory and read them from the file. fread(&meshInfo.numIndices, sizeof(int), 1, m_FilePointer); m_pIndices = new int [meshInfo.numIndices]; fread(m_pIndices, sizeof(int), meshInfo.numIndices, m_FilePointer); // Read the number of UV coordinates, allocate memory and read them from the file. fread(&meshInfo.numTexCoords, sizeof(int), 1, m_FilePointer); m_pTexCoords = new CVector3 [meshInfo.numTexCoords]; fread(m_pTexCoords, sizeof(CVector3), meshInfo.numTexCoords, m_FilePointer); // Read the number of UV indices, allocate memory and read them from the file. fread(&meshInfo.numTexIndices, sizeof(int), 1, m_FilePointer); m_pTexIndices = new int [meshInfo.numTexIndices]; fread(m_pTexIndices, sizeof(int), meshInfo.numTexIndices, m_FilePointer); // Now that we have the data, let's convert it to our model structure ConvertDataStructures(pModel, meshInfo); //////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** //////////////////// // Everything below in this *NEW* block is for loading the animation // and bone data. First we grab a pointer to our current object. t3DObject *pObject = &pModel->pObject[pModel->numOfObjects-1]; // Grab the boolean that tells us if there is animation or not fread(&pObject->bAnimated, sizeof(bool), 1, m_FilePointer); // If there is animation let's load it if(pObject->bAnimated) { // We need to go through every vertice and load the corresponding // weight-influence data. for(int w = 0; w < meshInfo.numVertices; w++) { // Create an instance of our weight info class to hold weights tWeightInfo weightInfo; // Read in the number of blend links for this vertex and add it to our list fread(&weightInfo.numBlendLinks, sizeof(int), 1, m_FilePointer); pObject->vWeightInfo.push_back(weightInfo); // Since we are working with pointers, just to be safe we wanted to add // the weight info to our list first, and then grab a pointer to it. // We can then use that pointer to allocate memory for a list of all the // blend links (weight influences). Then we will read in the links into // our pWeightInfo pointer that is allocated. // Grab a pointer to the last weight info in our list (that was just added). tWeightInfo *pWeightInfo = &(pObject->vWeightInfo[pObject->vWeightInfo.size() - 1]); // Allocate memory for the weight links. It's a CVector3 because we store // the bone index and the weight value (between 0 and 1). pWeightInfo->pWeightInfo = new CVector2 [pWeightInfo->numBlendLinks]; // Read in all the influences for the weight according to this vertex. fread(pWeightInfo->pWeightInfo, sizeof(CVector2), pWeightInfo->numBlendLinks, m_FilePointer); } // Read in the number of bones, animation frame rate and number of anim frames. fread(&pObject->numBones, sizeof(int), 1, m_FilePointer); fread(&pModel->animSpeed, sizeof(int), 1, m_FilePointer); fread(&pObject->numFrames, sizeof(int), 1, m_FilePointer); // Now we will go through every frame of animation and get the matrix data for(int a = 0; a < pObject->numFrames; a++) { // Create a structure to hold the matrix information tBoneInfo boneInfo; // Store the number of bones so we know how big the list is, then // add our structure to the list of vBoneInfo. boneInfo.numBones = pObject->numBones; pObject->vBoneInfo.push_back(boneInfo); // Just like when we loaded our weight influences we want to grab // a pointer to the last item we just added to our list. We then // allocate memory for the matrix information for each bone and // read in the data. tBoneInfo *pBoneInfo = &pObject->vBoneInfo[pObject->vBoneInfo.size() - 1]; pBoneInfo->pBoneMatrices = new tBoneMatrix [pObject->numBones]; fread(pBoneInfo->pBoneMatrices, sizeof(tBoneMatrix), pObject->numBones, m_FilePointer); } } //////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** //////////////////// // Free all the memory for this mesh since we just converted it to our structures delete [] m_pVertices; delete [] m_pIndices; delete [] m_pTexCoords; delete [] m_pTexIndices; } //////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** //////////////////// // Make sure the current frame of animation is set to 0 pModel->currentFrame = 0; //////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** //////////////////// }