- Timestamp:
- May 24, 2005, 6:32:17 PM (20 years ago)
- Location:
- orxonox/trunk/src/lib/graphics/importer
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
orxonox/trunk/src/lib/graphics/importer/md2Model.cc
r4281 r4282 68 68 69 69 /******************************************************************************** 70 * MD2Model 2*70 * MD2Model * 71 71 ********************************************************************************/ 72 72 73 73 MD2Model::MD2Model() 74 74 { 75 /* 75 /* this creates the data container via ressource manager */ 76 this->data = new MD2Data(); 77 this->scaleFactor = this->data->scaleFactor; 78 79 this->setAnim(BOOM); 80 } 81 82 83 MD2Model::~MD2Model() 84 { 85 86 } 87 88 89 bool MD2Model::loadModel(const char* fileName) 90 { 91 return this->data->loadModel(fileName); 92 } 93 94 95 bool MD2Model::loadSkin(const char* fileName) 96 { 97 return this->data->loadSkin(fileName); 98 } 99 100 101 /** 102 \brief initializes an array of vert with the current frame scaled vertices 103 104 we won't use the pVertices array directly, since its much easier and we need 105 saving of data anyway 106 */ 107 void MD2Model::interpolate(sVec3D* verticesList) 108 { 109 sVec3D* currVec; 110 sVec3D* nextVec; 111 112 currVec = &this->data->pVertices[this->data->numVertices * this->animationState.currentFrame]; 113 nextVec = &this->data->pVertices[this->data->numVertices * this->animationState.nextFrame]; 114 115 for(int i = 0; i < this->data->numFrames; ++i) 116 { 117 verticesList[i][0] = (currVec[i][0] + this->animationState.interpolationState * (nextVec[i][0] - currVec[i][0])) * this->scaleFactor; 118 verticesList[i][1] = (currVec[i][1] + this->animationState.interpolationState * (nextVec[i][1] - currVec[i][1])) * this->scaleFactor; 119 verticesList[i][2] = (currVec[i][2] + this->animationState.interpolationState * (nextVec[i][2] - currVec[i][2])) * this->scaleFactor; 120 } 121 } 122 123 124 void MD2Model::setAnim(int type) 125 { 126 if( (type < 0) || (type > MAX_ANIMATIONS) ) 127 type = 0; 128 129 this->animationState.startFrame = animationList[type].firstFrame; 130 this->animationState.endFrame = animationList[type].lastFrame; 131 this->animationState.nextFrame = animationList[type].firstFrame + 1; 132 this->animationState.fps = animationList[type].fps; 133 this->animationState.type = type; 134 135 this->animationState.interpolationState = 0.0; 136 this->animationState.localTime = 0.0; 137 this->animationState.lastTime = 0.0; 138 this->animationState.currentFrame = animationList[type].firstFrame; 139 } 140 141 142 void MD2Model::tick(float time) 143 { 144 this->animationState.localTime += time; 145 } 146 147 148 void MD2Model::draw() 149 { 150 if( likely(this->animationState.localTime > 0.0)) 151 this->animate(); 152 153 glPushMatrix(); 154 155 this->renderFrame(); 156 157 glPopMatrix(); 158 } 159 160 161 void MD2Model::renderFrame() 162 { 163 static sVec3D verticesList[MD2_MAX_VERTICES]; /* performance: created only once in a lifetime */ 164 int* pCommands = this->data->pGLCommands; 165 166 /* some face culling stuff */ 167 glPushAttrib(GL_POLYGON_BIT); 168 glFrontFace(GL_CW); 169 glEnable(GL_CULL_FACE); 170 glCullFace(GL_BACK); 171 172 this->processLighting(); 173 this->interpolate(verticesList); 174 this->data->material->select(); 175 176 /* draw the triangles */ 177 while( int i = *(pCommands++)) /* strange looking while loop for maximum performance */ 178 { 179 if( i < 0) 180 { 181 glBegin(GL_TRIANGLE_FAN); 182 i = -i; 183 } 184 else 185 { 186 glBegin(GL_TRIANGLE_STRIP); 187 } 188 189 for(; i > 0; i--, pCommands += 3) /* down counting for loop, next 3 gl commands */ 190 { 191 glNormal3fv(anorms[this->data->pLightNormals[pCommands[2]]]); 192 glTexCoord2f( ((float *)pCommands)[0], 1.0-((float *)pCommands)[1] ); 193 glVertex3fv(verticesList[pCommands[2]]); 194 } 195 glEnd(); 196 } 197 glDisable(GL_CULL_FACE); 198 glPopAttrib(); 199 } 200 201 202 void MD2Model::animate() 203 { 204 if( this->animationState.localTime - this->animationState.lastTime > (1.0f / this->animationState.fps)) 205 { 206 this->animationState.currentFrame = this->animationState.nextFrame; 207 this->animationState.nextFrame++; 208 209 if( this->animationState.nextFrame > this->animationState.endFrame) 210 this->animationState.nextFrame = this->animationState.startFrame; 211 this->animationState.lastTime = this->animationState.localTime; 212 } 213 214 if( this->animationState.currentFrame > (this->data->numFrames - 1) ) 215 this->animationState.currentFrame = 0; 216 if( this->animationState.nextFrame > (this->data->numFrames - 1) ) 217 this->animationState.nextFrame = 0; 218 219 this->animationState.interpolationState = this->animationState.fps * 220 (this->animationState.localTime - this->animationState.lastTime); 221 } 222 223 224 /* hhmmm... id used a very different way to do lightning... */ 225 void MD2Model::processLighting() 226 { 227 shadeDots = anormsDots[((int)(md2Angle*(SHADEDOT_QUANT / 360.0)))&(SHADEDOT_QUANT - 1)]; 228 } 229 230 231 void MD2Model::debug() 232 { 233 PRINT(0)("\n==========================| MD2Model::debug() |===\n"); 234 PRINT(0)("= Model FileName:\t%s\n", this->data->fileName); 235 PRINT(0)("= Skin FileName:\t%s\n", this->data->skinFileName); 236 PRINT(0)("= Size in Memory:\t%i Bytes\n", this->data->header->frameSize * this->data->header->numFrames + 64); // 64bytes is the header size 237 PRINT(0)("= Number of Vertices:\t%i\n", this->data->header->numVertices); 238 PRINT(0)("= Number of Frames: \t%i\n", this->data->header->numFrames); 239 PRINT(0)("= Height, Width:\t%i, %i\n", this->data->header->skinHeight, this->data->header->skinWidth); 240 PRINT(0)("===================================================\n\n"); 241 } 242 243 244 /******************************************************************************** 245 * MD2Data * 246 ********************************************************************************/ 247 248 249 MD2Data::MD2Data() 250 { 76 251 this->pVertices = NULL; 77 252 this->pGLCommands = NULL; … … 83 258 84 259 this->scaleFactor = 1.0f; 85 */ 86 87 /* this creates the data container via ressource manager */ 88 this->data = new MD2Data(); 89 90 this->setAnim(BOOM); 91 } 92 93 94 MD2Model::~MD2Model() 95 { 96 /* 260 } 261 262 263 MD2Data::~MD2Data() 264 { 97 265 delete [] this->pVertices; 98 266 delete [] this->pGLCommands; 99 267 delete [] this->pLightNormals; 100 */ 101 } 102 103 104 105 bool MD2Model::loadModel(const char* fileName) 106 { 107 return this->data->loadModel(fileName); 108 109 268 } 269 270 271 272 bool MD2Data::loadModel(const char* fileName) 273 { 110 274 FILE *pFile; //file stream 111 275 char* buffer; //buffer for frame data … … 171 335 172 336 173 bool MD2Model::loadSkin(const char* fileName) 174 { 175 return this->data->loadSkin(fileName); 176 337 bool MD2Data::loadSkin(const char* fileName) 338 { 177 339 this->skinFileName = new char[strlen(fileName)+1]; 178 340 strcpy(this->skinFileName, fileName); 341 179 342 this->material = new Material("md2ModelTest"); 180 343 this->material->setDiffuseMap(fileName); … … 182 345 this->material->setAmbient(1.0, 1.0, 1.0); 183 346 } 184 185 186 /**187 \brief initializes an array of vert with the current frame scaled vertices188 189 we won't use the pVertices array directly, since its much easier and we need190 saving of data anyway191 */192 void MD2Model::interpolate(sVec3D* verticesList)193 {194 sVec3D* currVec;195 sVec3D* nextVec;196 197 currVec = &this->data->pVertices[this->data->numVertices * this->animationState.currentFrame];198 nextVec = &this->data->pVertices[this->data->numVertices * this->animationState.nextFrame];199 200 for(int i = 0; i < this->data->numFrames; ++i)201 {202 verticesList[i][0] = (currVec[i][0] + this->animationState.interpolationState * (nextVec[i][0] - currVec[i][0])) * this->data->scaleFactor;203 verticesList[i][1] = (currVec[i][1] + this->animationState.interpolationState * (nextVec[i][1] - currVec[i][1])) * this->data->scaleFactor;204 verticesList[i][2] = (currVec[i][2] + this->animationState.interpolationState * (nextVec[i][2] - currVec[i][2])) * this->data->scaleFactor;205 }206 }207 208 209 void MD2Model::setAnim(int type)210 {211 if( (type < 0) || (type > MAX_ANIMATIONS) )212 type = 0;213 214 this->animationState.startFrame = animationList[type].firstFrame;215 this->animationState.endFrame = animationList[type].lastFrame;216 this->animationState.nextFrame = animationList[type].firstFrame + 1;217 this->animationState.fps = animationList[type].fps;218 this->animationState.type = type;219 220 this->animationState.interpolationState = 0.0;221 this->animationState.localTime = 0.0;222 this->animationState.lastTime = 0.0;223 this->animationState.currentFrame = animationList[type].firstFrame;224 }225 226 227 void MD2Model::tick(float time)228 {229 this->animationState.localTime += time;230 }231 232 233 void MD2Model::draw()234 {235 if( likely(this->animationState.localTime > 0.0))236 this->animate();237 238 glPushMatrix();239 240 this->renderFrame();241 242 glPopMatrix();243 }244 245 246 void MD2Model::renderFrame()247 {248 static sVec3D verticesList[MD2_MAX_VERTICES]; /* performance: created only once in a lifetime */249 int* pCommands = this->data->pGLCommands;250 251 /* some face culling stuff */252 glPushAttrib(GL_POLYGON_BIT);253 glFrontFace(GL_CW);254 glEnable(GL_CULL_FACE);255 glCullFace(GL_BACK);256 257 this->processLighting();258 this->interpolate(verticesList);259 this->data->material->select();260 261 /* draw the triangles */262 while( int i = *(pCommands++)) /* strange looking while loop for maximum performance */263 {264 if( i < 0)265 {266 glBegin(GL_TRIANGLE_FAN);267 i = -i;268 }269 else270 {271 glBegin(GL_TRIANGLE_STRIP);272 }273 274 for(; i > 0; i--, pCommands += 3) /* down counting for loop, next 3 gl commands */275 {276 glNormal3fv(anorms[this->data->pLightNormals[pCommands[2]]]);277 glTexCoord2f( ((float *)pCommands)[0], 1.0-((float *)pCommands)[1] );278 glVertex3fv(verticesList[pCommands[2]]);279 }280 glEnd();281 }282 glDisable(GL_CULL_FACE);283 glPopAttrib();284 }285 286 287 void MD2Model::animate()288 {289 if( this->animationState.localTime - this->animationState.lastTime > (1.0f / this->animationState.fps))290 {291 this->animationState.currentFrame = this->animationState.nextFrame;292 this->animationState.nextFrame++;293 294 if( this->animationState.nextFrame > this->animationState.endFrame)295 this->animationState.nextFrame = this->animationState.startFrame;296 this->animationState.lastTime = this->animationState.localTime;297 }298 299 if( this->animationState.currentFrame > (this->data->numFrames - 1) )300 this->animationState.currentFrame = 0;301 if( this->animationState.nextFrame > (this->data->numFrames - 1) )302 this->animationState.nextFrame = 0;303 304 this->animationState.interpolationState = this->animationState.fps *305 (this->animationState.localTime - this->animationState.lastTime);306 }307 308 309 /* hhmmm... id used a very different way to do lightning... */310 void MD2Model::processLighting()311 {312 shadeDots = anormsDots[((int)(md2Angle*(SHADEDOT_QUANT / 360.0)))&(SHADEDOT_QUANT - 1)];313 }314 315 316 void MD2Model::debug()317 {318 PRINT(0)("==========================| MD2Model::debug() |===\n");319 PRINT(0)("= Model FileName:\t%s\n", this->data->fileName);320 PRINT(0)("= Skin FileName:\t%s\n", this->data->skinFileName);321 PRINT(0)("= Size in Memory:\t%i Bytes\n", this->data->header->frameSize * this->data->header->numFrames + 64); // 64bytes is the header size322 PRINT(0)("= Number of Vertices:\t%i\n", this->data->header->numVertices);323 PRINT(0)("= Number of Frames: \t%i\n", this->data->header->numFrames);324 PRINT(0)("= Height, Width\t\t%i, %i\n", this->data->header->skinHeight, this->data->header->skinWidth);325 PRINT(0)("===================================================\n\n");326 }327 328 329 330 331 332 MD2Data::MD2Data()333 {334 this->pVertices = NULL;335 this->pGLCommands = NULL;336 this->pLightNormals = NULL;337 338 this->numFrames = 0;339 this->numVertices = 0;340 this->numGLCommands = 0;341 342 this->scaleFactor = 1.0f;343 }344 345 346 MD2Data::~MD2Data()347 {348 delete [] this->pVertices;349 delete [] this->pGLCommands;350 delete [] this->pLightNormals;351 }352 353 354 355 bool MD2Data::loadModel(const char* fileName)356 {357 FILE *pFile; //file stream358 char* buffer; //buffer for frame data359 sFrame* frame; //temp frame360 sVec3D *pVertex;361 int* pNormals;362 363 pFile = fopen(fileName, "rb");364 if( unlikely(!pFile))365 {366 PRINTF(1)("Couldn't open the MD2 File for loading. Exiting.\n");367 return false;368 }369 this->header = new MD2Header;370 fread(this->header, 1, sizeof(MD2Header), pFile);371 /* check for the header version: make sure its a md2 file :) */372 if( unlikely(this->header->version != MD2_VERSION) && unlikely(this->header->ident != MD2_IDENT))373 {374 PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName);375 return false;376 }377 378 this->fileName = new char[strlen(fileName)+1];379 strcpy(this->fileName, fileName);380 /* got the data: map it to locals */381 this->numFrames = this->header->numFrames;382 this->numVertices = this->header->numVertices;383 this->numTriangles = this->header->numTriangles;384 this->numGLCommands = this->header->numGlCommands;385 /* allocate memory for the data storage */386 this->pVertices = new sVec3D[this->numVertices * this->numFrames];387 this->pGLCommands = new int[this->numGLCommands];388 this->pLightNormals = new int[this->numVertices * this->numFrames];389 buffer = new char[this->numFrames * this->header->frameSize];390 391 /* read frame data from the file to a temp buffer */392 fseek(pFile, this->header->offsetFrames, SEEK_SET);393 fread(buffer, this->header->frameSize, this->numFrames, pFile);394 /* read opengl commands */395 fseek(pFile, this->header->offsetGlCommands, SEEK_SET);396 fread(this->pGLCommands, sizeof(int), this->numGLCommands, pFile);397 398 for(int i = 0; i < this->numFrames; ++i)399 {400 frame = (sFrame*)(buffer + this->header->frameSize * i);401 pVertex = this->pVertices + this->numVertices * i;402 pNormals = this->pLightNormals + this->numVertices * i;403 404 for(int j = 0; j < this->numVertices; ++j)405 {406 /* SPEEDUP: *(pVerts + i + 0) = (*(frame->pVertices + i + 0)... */407 pVertex[j][0] = (frame->pVertices[j].v[0] * frame->scale[0]) + frame->translate[0];408 pVertex[j][1] = (frame->pVertices[j].v[2] * frame->scale[2]) + frame->translate[2];409 pVertex[j][2] = -1.0 * (frame->pVertices[j].v[1] * frame->scale[1] + frame->translate[1]);410 411 pNormals[j] = frame->pVertices[j].lightNormalIndex;412 }413 }414 415 delete [] buffer;416 fclose(pFile);417 }418 419 420 bool MD2Data::loadSkin(const char* fileName)421 {422 this->skinFileName = new char[strlen(fileName)+1];423 strcpy(this->skinFileName, fileName);424 425 this->material = new Material("md2ModelTest");426 this->material->setDiffuseMap(fileName);427 this->material->setIllum(3);428 this->material->setAmbient(1.0, 1.0, 1.0);429 } -
orxonox/trunk/src/lib/graphics/importer/md2Model.h
r4281 r4282 164 164 private: 165 165 MD2Data* data; 166 167 int numFrames;168 int numVertices;169 int numTriangles;170 int numGLCommands;171 char* fileName;172 char* skinFileName;173 MD2Header* header;174 166 175 sVec3D* pVertices; 176 int* pGLCommands; 177 int* pLightNormals; 178 glCommandVertex* pGLCommands2; 179 180 181 Material* material; 167 float scaleFactor; 182 168 sAnimState animationState; 183 float scaleFactor;184 169 }; 185 170
Note: See TracChangeset
for help on using the changeset viewer.