Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/importer/md2Model.cc @ 4276

Last change on this file since 4276 was 4276, checked in by patrick, 19 years ago

orxonox/trunk: cleaned out the md2 model class, there is now only one model again

File size: 9.3 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Patrick Boenzli
13*/
14
15#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
16
17#include "md2Model.h"
18#include "material.h"
19
20#include "resource_manager.h"
21
22#include <fstream>
23#include <string>
24#include <vector>
25
26
27using namespace std;
28
29
30sVec3D MD2Model::anorms[NUM_VERTEX_NORMALS] = {
31 #include "anorms.h"
32};
33
34float MD2Model::anormsDots[SHADEDOT_QUANT][256] = {
35  #include "anormtab.h"
36};
37
38static float *shadeDots = MD2Model::anormsDots[0];
39
40float md2Angle = 0.0f;
41
42
43sAnim MD2Model::animationList[21] =
44  {
45 // begin, end, fps
46    {   0,  39,  9 },   // STAND
47    {  40,  45, 10 },   // RUN
48    {  46,  53, 10 },   // ATTACK
49    {  54,  57,  7 },   // PAIN_A
50    {  58,  61,  7 },   // PAIN_B
51    {  62,  65,  7 },   // PAIN_C
52    {  66,  71,  7 },   // JUMP
53    {  72,  83,  7 },   // FLIP
54    {  84,  94,  7 },   // SALUTE
55    {  95, 111, 10 },   // FALLBACK
56    { 112, 122,  7 },   // WAVE
57    { 123, 134,  6 },   // POINT
58    { 135, 153, 10 },   // CROUCH_STAND
59    { 154, 159,  7 },   // CROUCH_WALK
60    { 160, 168, 10 },   // CROUCH_ATTACK
61    { 196, 172,  7 },   // CROUCH_PAIN
62    { 173, 177,  5 },   // CROUCH_DEATH
63    { 178, 183,  7 },   // DEATH_FALLBACK
64    { 184, 189,  7 },   // DEATH_FALLFORWARD
65    { 190, 197,  7 },   // DEATH_FALLBACKSLOW
66    { 198, 198,  5 },   // BOOM
67  };
68
69
70
71/********************************************************************************
72 *   MD2Model2                                                                  *
73 ********************************************************************************/
74
75MD2Model::MD2Model()
76{
77  this->pVertices = NULL;
78  this->pGLCommands = NULL;
79  this->pLightNormals = NULL; 
80
81  this->numFrames = 0;
82  this->numVertices = 0;
83  this->numGLCommands = 0;
84 
85  this->textureID = 0;
86  this->scaleFactor = 1.0f;
87
88  this->setAnim(BOOM);
89}
90
91
92MD2Model::~MD2Model()
93{
94  delete [] this->pVertices;
95  delete [] this->pGLCommands;
96  delete [] this->pLightNormals;
97}
98
99
100
101bool MD2Model::loadModel(const char* fileName)
102{
103  FILE *pFile;                            //file stream
104  char* buffer;                           //buffer for frame data
105  sFrame* frame;                          //temp frame
106  sVec3D *pVertex;
107  int* pNormals;
108
109  pFile = fopen(fileName, "rb");
110  if( unlikely(!pFile)) 
111    {
112      PRINTF(1)("Couldn't open the MD2 File for loading. Exiting.\n");
113      return false;
114    }
115  this->header = new tMd2Header;
116  fread(this->header, 1, sizeof(tMd2Header), pFile);
117  /* check for the header version: make sure its a md2 file :) */
118  if( unlikely(this->header->version != MD2_VERSION) && unlikely(this->header->ident != MD2_IDENT))
119    {
120      PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName);
121      return false;
122    }
123
124  this->fileName = new char[strlen(fileName)+1];
125  strcpy(this->fileName, fileName);
126  /* got the data: map it to locals */
127  this->numFrames = this->header->numFrames;
128  this->numVertices = this->header->numVertices;
129  this->numTriangles = this->header->numTriangles;
130  this->numGLCommands = this->header->numGlCommands;
131  /* allocate memory for the data storage */
132  this->pVertices = new sVec3D[this->numVertices * this->numFrames];
133  this->pGLCommands = new int[this->numGLCommands];
134  this->pLightNormals = new int[this->numVertices * this->numFrames];
135  buffer = new char[this->numFrames * this->header->frameSize];
136
137  /* read frame data from the file to a temp buffer */
138  fseek(pFile, this->header->offsetFrames, SEEK_SET);
139  fread(buffer, this->header->frameSize, this->numFrames, pFile);
140  /* read opengl commands */
141  fseek(pFile, this->header->offsetGlCommands, SEEK_SET);
142  fread(this->pGLCommands, sizeof(int), this->numGLCommands, pFile);
143
144  for(int i = 0; i < this->numFrames; ++i)
145    {
146      frame = (sFrame*)(buffer + this->header->frameSize * i); 
147      pVertex = this->pVertices + this->numVertices  * i;
148      pNormals = this->pLightNormals + this->numVertices * i;
149
150      for(int j = 0; j < this->numVertices; ++j)
151        {
152          /* SPEEDUP: *(pVerts + i + 0) = (*(frame->pVertices + i + 0)...  */
153          pVertex[j][0] = (frame->pVertices[j].v[0] * frame->scale[0]) + frame->translate[0];
154          pVertex[j][1] = (frame->pVertices[j].v[2] * frame->scale[2]) + frame->translate[2];
155          pVertex[j][2] = -1.0 * (frame->pVertices[j].v[1] * frame->scale[1] + frame->translate[1]);
156         
157          pNormals[j] = frame->pVertices[j].lightNormalIndex;
158        }
159    }
160
161  delete [] buffer;
162  fclose(pFile);
163}
164
165
166bool MD2Model::loadSkin(const char* fileName)
167{
168  this->skinFileName = new char[strlen(fileName)+1];
169  strcpy(this->skinFileName, fileName);
170  this->material = new Material("md2ModelTest");
171  this->material->setDiffuseMap(fileName);
172  this->material->setIllum(3);
173  this->material->setAmbient(1.0, 1.0, 1.0);
174}
175
176
177/**
178   \brief initializes an array of vert with the current frame scaled vertices
179
180   we won't use the pVertices array directly, since its much easier and we need
181   saving of data anyway
182*/
183void MD2Model::interpolate(sVec3D* verticesList)
184{
185  sVec3D* currVec;
186  sVec3D* nextVec;
187
188  currVec = &this->pVertices[this->numVertices * this->animationState.currentFrame];
189  nextVec = &this->pVertices[this->numVertices * this->animationState.nextFrame];
190
191  for(int i = 0; i < this->numFrames; ++i)
192    {
193      verticesList[i][0] = (currVec[i][0] + this->animationState.interpolationState * (nextVec[i][0] - currVec[i][0])) * this->scaleFactor;
194      verticesList[i][1] = (currVec[i][1] + this->animationState.interpolationState * (nextVec[i][1] - currVec[i][1])) * this->scaleFactor;
195      verticesList[i][2] = (currVec[i][2] + this->animationState.interpolationState * (nextVec[i][2] - currVec[i][2])) * this->scaleFactor;
196    }
197}
198
199
200void MD2Model::setAnim(int type)
201{
202  if( (type < 0) || (type > MAX_ANIMATIONS) )
203    type = 0;
204
205  this->animationState.startFrame = animationList[type].firstFrame;
206  this->animationState.endFrame = animationList[type].lastFrame;
207  this->animationState.nextFrame = animationList[type].firstFrame + 1;
208  this->animationState.fps = animationList[type].fps;
209  this->animationState.type = type;
210 
211  this->animationState.interpolationState = 0.0;
212  this->animationState.localTime = 0.0;
213  this->animationState.lastTime = 0.0;
214  this->animationState.currentFrame = animationList[type].firstFrame;
215}
216
217
218void MD2Model::animate()
219{
220  if( this->animationState.localTime - this->animationState.lastTime > (1.0f / this->animationState.fps))
221    {
222      this->animationState.currentFrame = this->animationState.nextFrame;
223      this->animationState.nextFrame++;
224     
225      if( this->animationState.nextFrame > this->animationState.endFrame)
226        this->animationState.nextFrame = this->animationState.startFrame;
227      this->animationState.lastTime = this->animationState.localTime;
228    }
229
230  if( this->animationState.currentFrame > (this->numFrames - 1) )
231    this->animationState.currentFrame = 0;
232  if( this->animationState.nextFrame > (this->numFrames - 1) )
233    this->animationState.nextFrame = 0;
234
235  this->animationState.interpolationState = this->animationState.fps * 
236    (this->animationState.localTime - this->animationState.lastTime);
237}
238
239
240/* hhmmm... id used a very different way to do lightning... */
241void MD2Model::processLighting()
242{
243  shadeDots = anormsDots[((int)(md2Angle*(SHADEDOT_QUANT / 360.0)))&(SHADEDOT_QUANT - 1)];
244}
245
246
247void MD2Model::tick(float time)
248{
249  this->animationState.localTime += time;
250}
251
252
253void MD2Model::draw()
254{
255  if( likely(this->animationState.localTime > 0.0))
256    this->animate();
257
258  glPushMatrix();
259
260  this->renderFrame();
261
262  glPopMatrix();
263} 
264
265
266void MD2Model::renderFrame()
267{
268  static sVec3D verticesList[MD2_MAX_VERTICES]; /* performance: created only once in a lifetime */
269  int* pCommands = this->pGLCommands;
270
271  /* some face culling stuff */
272  glPushAttrib(GL_POLYGON_BIT);
273  glFrontFace(GL_CW);
274  glEnable(GL_CULL_FACE);
275  glCullFace(GL_BACK);
276     
277  this->processLighting();
278  this->interpolate(verticesList);
279  this->material->select();
280
281  /* draw the triangles */
282  while( int i = *(pCommands++)) /* strange looking while loop for maximum performance */
283    {
284      if( i < 0)
285        {
286          glBegin(GL_TRIANGLE_FAN);
287          i = -i;
288        }
289      else
290        {
291          glBegin(GL_TRIANGLE_STRIP);
292        }
293
294      for(; i > 0; i--, pCommands += 3) /* down counting for loop, next 3 gl commands */
295        {
296          glNormal3fv(anorms[this->pLightNormals[pCommands[2]]]);
297          glTexCoord2f( ((float *)pCommands)[0], 1.0-((float *)pCommands)[1] );
298          glVertex3fv(verticesList[pCommands[2]]);
299        }
300      glEnd();
301    }
302  glDisable(GL_CULL_FACE);
303  glPopAttrib();
304}
305
306
307void MD2Model::debug()
308{
309  PRINT(0)("==========================| MD2Model::debug() |===\n");
310  PRINT(0)("=  Model FileName:\t%s\n", this->fileName);
311  PRINT(0)("=  Skin FileName:\t%s\n", this->skinFileName);
312  PRINT(0)("=  Size in Memory:\t%i Bytes\n", this->header->frameSize * this->header->numFrames + 64); // 64bytes is the header size
313  PRINT(0)("=  Number of Vertices:\t%i\n", this->header->numVertices);
314  PRINT(0)("=  Number of Frames: \t%i\n", this->header->numFrames);
315  PRINT(0)("=  Height, Width\t\t%i, %i\n", this->header->skinHeight, this->header->skinWidth);
316  PRINT(0)("===================================================\n\n");
317}
Note: See TracBrowser for help on using the repository browser.