/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Patrick Boenzli */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER #include "md3_data.h" #include "md3_bone_frame.h" namespace md3 { /******************************************************************************** * MD3Data * ********************************************************************************/ /** \brief simple constructor */ MD3Data::MD3Data(const std::string& modelFileName, const std::string& skinFileName, float scale) { this->loadModel(modelFileName); // this->loadSkin(skinFileName); } /** \brief simple destructor this will clean out all the necessary data for a specific md2model */ MD3Data::~MD3Data() { delete this->header; } /** \brief this will load the whole model data (vertices, opengl command list, ...) * @param fileName: the name of the model file \return true if success */ bool MD3Data::loadModel(const std::string& fileName) { FILE *pFile; //file stream // char* buffer; //buffer for frame data int fileOffset = 0; // file data offset //! @todo this chek should include deleting a loaded model (eventually) if (fileName.empty()) return false; PRINTF(0)("opening file: %s\n", fileName.c_str()); pFile = fopen(fileName.c_str(), "rb"); if( unlikely(!pFile)) { PRINTF(1)("Couldn't open the MD3 File for loading. Exiting.\n"); return false; } fileOffset += this->readHeader(pFile, fileOffset); /* check for the header version: make sure its a md2 file :) */ if( unlikely(this->header->version != MD3_VERSION) && unlikely(this->header->ident != MD3_IDENT)) { PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName.c_str()); return false; } // check if the filesize is correct if( this->header->fileSize > this->header->tagStart && this->header->fileSize >= this->header->meshStart) { bool bBoneFrames, bTags, bMeshes; bBoneFrames = ( this->header->boneFrameNum == 0); bTags = ( this->header->tagNum == 0); bMeshes = ( this->header->meshNum == 0); // read different parts of the model in correct order while( !(bBoneFrames && bTags && bMeshes)) { printf("while\n"); if( fileOffset == this->header->boneFrameStart && !bBoneFrames) { fileOffset += this->readBoneFrames(pFile, fileOffset); bBoneFrames = true; } else if( fileOffset == this->header->tagStart && !bTags) { fileOffset += this->readTags(pFile, fileOffset); bTags = true; } else if( fileOffset == this->header->meshStart && !bMeshes) { fileOffset += this->readMeshes(pFile, fileOffset); bMeshes = true; } } } #if 0 this->fileName =fileName; /* got the data: map it to locals */ this->numFrames = this->header->numFrames; this->numVertices = this->header->numVertices; this->numTriangles = this->header->numTriangles; this->numGLCommands = this->header->numGlCommands; this->numTexCoor = this->header->numTexCoords; /* allocate memory for the data storage */ this->pVertices = new sVec3D[this->numVertices * this->numFrames]; this->pGLCommands = new int[this->numGLCommands]; this->pLightNormals = new int[this->numVertices * this->numFrames]; this->pTriangles = new sTriangle[this->numTriangles]; this->pTexCoor = new sTexCoor[this->numTexCoor]; buffer = new char[this->numFrames * this->header->frameSize]; /* read frame data from the file to a temp buffer */ fseek(pFile, this->header->offsetFrames, SEEK_SET); fread(buffer, this->header->frameSize, this->numFrames, pFile); /* read opengl commands */ fseek(pFile, this->header->offsetGlCommands, SEEK_SET); fread(this->pGLCommands, sizeof(int), this->numGLCommands, pFile); /* triangle list */ fseek(pFile, this->header->offsetTriangles, SEEK_SET); fread(this->pTriangles, sizeof(sTriangle), this->numTriangles, pFile); /* read in texture coordinates */ fseek(pFile, this->header->offsetTexCoords, SEEK_SET); fread(this->pTexCoor, sizeof(sTexCoor), this->numTexCoor, pFile); for(int i = 0; i < this->numFrames; ++i) { frame = (sFrame*)(buffer + this->header->frameSize * i); pVertex = this->pVertices + this->numVertices * i; pNormals = this->pLightNormals + this->numVertices * i; for(int j = 0; j < this->numVertices; ++j) { /* SPEEDUP: *(pVerts + i + 0) = (*(frame->pVertices + i + 0)... */ pVertex[j][0] = ((frame->pVertices[j].v[0] * frame->scale[0] ) + frame->translate[0] )* this->scaleFactor; pVertex[j][1] = ((frame->pVertices[j].v[2] * frame->scale[2]) + frame->translate[2]) * this->scaleFactor; pVertex[j][2] = (-1.0 * (frame->pVertices[j].v[1] * frame->scale[1] + frame->translate[1])) * this->scaleFactor; //printf("vertex %i/%i: (%f, %f, %f)\n", j, this->numVertices, pVertex[j][0], pVertex[j][1], pVertex[j][2]); pNormals[j] = frame->pVertices[j].lightNormalIndex; } } PRINTF(4)("Finished loading the md2 file\n"); #endif //delete [] buffer; fclose(pFile); return true; } /** \brief loads the skin/material stuff * @param fileName: name of the skin file \return true if success */ bool MD3Data::loadSkin(const std::string& fileName) { // if( fileName.empty()) // { // this->skinFileName = ""; // return false; // } // // this->skinFileName = fileName; // // this->material.setName("md2ModelMaterial"); // this->material.setDiffuseMap(fileName); // this->material.setIllum(3); // this->material.setAmbient(1.0, 1.0, 1.0); return true; } /** * read heaader */ int MD3Data::readHeader(FILE* pFile, int fileOffset) { this->header = new MD3Header; fread(this->header, 1, sizeof(MD3Header), pFile); //header debug: PRINTF(0)("MD3 Header debug section======================================\n"); printf("ident: %i\n", this->header->ident); printf("version: %i\n", this->header->version); printf("filename: %s\n", this->header->filename); printf("boneFrameNum: %i\n", this->header->boneFrameNum); printf("tag number: %i\n", this->header->tagNum); printf("mesh number: %i\n", this->header->meshNum); printf("max tex num: %i\n", this->header->maxTexNum); printf("bone frame start: %i\n", this->header->boneFrameStart); printf("tag start: %i\n", this->header->tagStart); printf("mesh start: %i\n", this->header->meshStart); printf("fileSize: %i\n", this->header->fileSize); return sizeof(MD3Header); } /** * read bone frames */ int MD3Data::readBoneFrames(FILE* pFile, int fileOffset) { this->boneFrames = new MD3BoneFrame*[this->header->boneFrameNum]; for( int i = 0; i < this->header->boneFrameNum; i++) { this->boneFrames[i] = new MD3BoneFrame(i); MD3BoneFrameData* md = new MD3BoneFrameData; fread(md, 1, sizeof(MD3BoneFrameData), pFile); } return this->header->boneFrameNum * sizeof(MD3BoneFrameData); } /** * read the tags */ int MD3Data::readTags(FILE* pFile, int fileOffset) { return 0; } /** * read meshes */ int MD3Data::readMeshes(FILE* pFile, int fileOffset) { return 0; } }