Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/md2_loader/src/lib/graphics/importer/md2Model.cc @ 4229

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

orxonox/branches/md2_loader: fixed some compiler errors, added the header to the model

File size: 25.4 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 <fstream>
21#include <string>
22#include <vector>
23
24
25using namespace std;
26
27
28sVec3D MD2Model2::anorms[NUM_VERTEX_NORMALS] = {
29 #include "anorms.h"
30};
31
32float MD2Model2::anormsDots[SHADEDOT_QUANT][256] = {
33  #include "anormtab.h"
34};
35
36static float *shadeDots = MD2Model2::anormsDots[0];
37
38float md2Angle = 0.0f;
39
40
41sAnim MD2Model2::animationList[21] =
42  {
43 // begin, end, fps
44    {   0,  39,  9 },   // STAND
45    {  40,  45, 10 },   // RUN
46    {  46,  53, 10 },   // ATTACK
47    {  54,  57,  7 },   // PAIN_A
48    {  58,  61,  7 },   // PAIN_B
49    {  62,  65,  7 },   // PAIN_C
50    {  66,  71,  7 },   // JUMP
51    {  72,  83,  7 },   // FLIP
52    {  84,  94,  7 },   // SALUTE
53    {  95, 111, 10 },   // FALLBACK
54    { 112, 122,  7 },   // WAVE
55    { 123, 134,  6 },   // POINT
56    { 135, 153, 10 },   // CROUCH_STAND
57    { 154, 159,  7 },   // CROUCH_WALK
58    { 160, 168, 10 },   // CROUCH_ATTACK
59    { 196, 172,  7 },   // CROUCH_PAIN
60    { 173, 177,  5 },   // CROUCH_DEATH
61    { 178, 183,  7 },   // DEATH_FALLBACK
62    { 184, 189,  7 },   // DEATH_FALLFORWARD
63    { 190, 197,  7 },   // DEATH_FALLBACKSLOW
64    { 198, 198,  5 },   // BOOM
65  };
66
67
68/********************************************************************************
69 *   MD2MODEL                                                                   *
70 ********************************************************************************/
71
72/**
73   \brief standard constructor
74   
75   creates a new model
76*/
77MD2Model::MD2Model () 
78{
79  this->setClassName ("MD2Model");
80
81  MD2Loader* md2loader = new MD2Loader();
82  this->model = new t3DModel;
83  md2loader->importMD2(this->model, "../data/models/tris.md2");
84  delete md2loader;
85}
86
87
88/**
89   \brief standard deconstructor
90
91*/
92MD2Model::~MD2Model () 
93{
94  // delete what has to be deleted here
95}
96
97
98void MD2Model::animate()
99{
100  if( unlikely(this->model->objectList.size() <= 0)) return;
101  /* get current animation from the list */
102  tAnimationInfo *pAnim = &(this->model->animationList[this->model->currentAnim]);
103
104  int nextFrame = (this->model->currentFrame + 1) % pAnim->endFrame;
105  if( unlikely(nextFrame == 0)) 
106    nextFrame =  pAnim->startFrame;
107
108  t3DObject *pFrame = &this->model->objectList[this->model->currentFrame];
109  t3DObject *pNextFrame = &this->model->objectList[nextFrame];
110
111  /* we have stored the texture and face information only in the first frame */
112  t3DObject *pFirstFrame = &this->model->objectList[0];
113
114  /* get the current time as a value in the domain [0..1] :)) */
115  float t = this->getCurrentTime(this->model, nextFrame);
116
117  glBegin(GL_TRIANGLES);
118  for(int j = 0; j < pFrame->numOfFaces; j++)
119    {
120      for(int whichVertex = 0; whichVertex < 3; whichVertex++)
121        {
122          int vertIndex = pFirstFrame->pFaces[j].vertIndex[whichVertex];
123          int texIndex  = pFirstFrame->pFaces[j].coordIndex[whichVertex];
124                                               
125          if( likely(pFirstFrame->pTexVerts != NULL)) 
126            {
127              glTexCoord2f(pFirstFrame->pTexVerts[texIndex].x, 
128                           pFirstFrame->pTexVerts[texIndex].y);
129            }
130                       
131          /* here comes the interpolation part */
132          CVector3 vPoint1 = pFrame->pVerts[vertIndex];
133          CVector3 vPoint2 = pNextFrame->pVerts[vertIndex];
134          glVertex3f(vPoint1.x + t * (vPoint2.x - vPoint1.x), 
135                     vPoint1.y + t * (vPoint2.y - vPoint1.y),
136                     vPoint1.z + t * (vPoint2.z - vPoint1.z));
137        }
138    }
139  glEnd();
140}
141
142
143float MD2Model::getCurrentTime(t3DModel *pModel, int nextFrame)
144{
145  /* stretch the time with animation speed (and make seconds out of it) */
146  //float t = this->dtS / kAnimationSpeed;
147       
148  if ( unlikely(this->localTime*1000.0 >=  1000.0/kAnimationSpeed) )
149    {
150      pModel->currentFrame = nextFrame;
151      this->localTime = 0.0f;
152    }
153  return (this->localTime / kAnimationSpeed);
154}
155
156
157void MD2Model::tick(float dtS)
158{
159  this->localTime += dtS;
160}
161
162/**
163   \brief draw function
164 
165   these function will take NO argument in the final version, just for testing
166*/
167void MD2Model::draw()
168{
169  if( this->model->objectList.size() <= 0) return;
170
171  t3DObject *pObject = &this->model->objectList[0];
172  glBegin(GL_TRIANGLES);
173  for(int j = 0; j < pObject->numOfFaces; j++)
174    {
175      for(int whichVertex = 0; whichVertex < 3; whichVertex++)
176        {
177          int index = pObject->pFaces[j].vertIndex[whichVertex];
178          int index2 = pObject->pFaces[j].coordIndex[whichVertex];
179          /* we invert the normals since the md2 file format uses different style */
180          /* FIX FIX FIX: ther are actualy no reasons to compute the normals every frame: change this later*/
181          glNormal3f(-pObject->pNormals[index].x, -pObject->pNormals[index].y, -pObject->pNormals[index].z);
182
183          if( likely(pObject->pTexVerts != NULL)) 
184            {
185              glTexCoord2f(pObject->pTexVerts[index2].x, pObject->pTexVerts[index2].y);
186            }
187          glVertex3f(pObject->pVerts[index].x, pObject->pVerts[index].y, pObject->pVerts[index].z);
188        }
189    }
190  glEnd();
191}
192
193/********************************************************************************
194 *   MD2LOADER                                                                  *
195 ********************************************************************************/
196
197/**
198   \brief standard deconstructor
199   creates a new model loader
200*/
201MD2Loader::MD2Loader()
202{
203  this->setClassName ("MD2Loader");
204  /* initialize all data to initial state */
205  memset(&this->header, 0, sizeof(tMd2Header));
206  this->pSkins = NULL;
207  this->pTexCoords = NULL;
208  this->pTriangles = NULL;
209  this->pFrames = NULL;
210}
211
212/**
213   \brief standard deconstructor
214*/
215MD2Loader::~MD2Loader()
216{}
217 
218
219/**
220   \brief this is called by the client to open the .Md2 file, read it, then clean up
221   \param model to load in
222   \param file name to load
223   \param texture name to load
224*/
225bool MD2Loader::importMD2(t3DModel *pModel, char *fileName, char *textureName)
226{
227  this->pFile = fopen(fileName, "rb");
228  if( unlikely(!pFile)) 
229    {
230      PRINTF(1)("Couldn't open the MD2 File for loading. Exiting.\n");
231      return false;
232    }
233  fread(&this->header, 1, sizeof(tMd2Header), pFile);
234  /* check for the header version: make sure its a md2 file :) */
235  if( likely(this->header.version != 8))
236    {
237      PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName);
238      return false;
239    }
240       
241  this->readMD2Data();
242  this->convertDataStructures(pModel);
243  this->computeNormals(pModel);
244
245  if( likely((int)textureName))
246    {
247      tMaterialInfo textureInfo;
248      strcpy(textureInfo.strFile, textureName);
249      /* since there is only one texture for a .Md2 file, the ID is always 0 */
250      textureInfo.texureId = 0;
251      textureInfo.uTile = 1;
252      /* we only have 1 material for a model */
253      pModel->numOfMaterials = 1;
254      pModel->materialList.push_back(textureInfo);
255    }
256       
257  this->cleanUp();
258  return true;
259}
260
261
262/**
263   \brief This function reads in all of the model's data, except the animation frames
264*/
265void MD2Loader::readMD2Data()
266{
267  unsigned char buffer[MD2_MAX_FRAMESIZE];
268  this->pSkins     = new tMd2Skin[this->header.numSkins];
269  this->pTexCoords = new tMd2TexCoord[this->header.numTexCoords];
270  this->pTriangles = new tMd2Face[this->header.numTriangles];
271  this->pFrames    = new tMd2Frame[this->header.numFrames];
272
273  /* we read the skins */
274  fseek(this->pFile, this->header.offsetSkins, SEEK_SET);
275  fread(this->pSkins, sizeof(tMd2Skin), this->header.numSkins, this->pFile);
276  /* read all vertex data */
277  fseek(this->pFile, this->header.offsetTexCoords, SEEK_SET);
278  fread(this->pTexCoords, sizeof(tMd2TexCoord), this->header.numTexCoords, this->pFile);
279  /* read face data for each triangle (normals) */
280  fseek(this->pFile, this->header.offsetTriangles, SEEK_SET);
281  fread(this->pTriangles, sizeof(tMd2Face), this->header.numTriangles, this->pFile);
282  /* reading all frame data */
283  fseek(this->pFile, this->header.offsetFrames, SEEK_SET);
284  for( int i = 0; i < this->header.numFrames; i++)
285    {
286      tMd2AliasFrame *pFrame = (tMd2AliasFrame *) buffer;
287      this->pFrames[i].pVertices = new tMd2Triangle [this->header.numVertices];
288
289      /* read the frame animation data */
290      fread(pFrame, 1, this->header.frameSize, this->pFile);
291      strcpy(this->pFrames[i].strName, pFrame->name);
292      tMd2Triangle *pVertices = this->pFrames[i].pVertices;
293      /*
294         scale translations, store vertices: since id used a non-opengl xyz notation, we have to swap y and z
295         and negate z axis
296      */
297      for( int j = 0; j < this->header.numVertices; j++)
298        {
299          pVertices[j].vertex[0] = pFrame->aliasVertices[j].vertex[0] * pFrame->scale[0] + pFrame->translate[0];
300          pVertices[j].vertex[2] = -1 * (pFrame->aliasVertices[j].vertex[1] * pFrame->scale[1] + pFrame->translate[1]);
301          pVertices[j].vertex[1] = pFrame->aliasVertices[j].vertex[2] * pFrame->scale[2] + pFrame->translate[2];
302
303          printf("vertices %i --- %f, %f, %f\n",j, pVertices[j].vertex[0], pVertices[j].vertex[1], pVertices[j].vertex[2]);
304        }
305    }
306}
307
308
309/**
310   \brief this function fills in the animation list for each animation by name and frame
311   \param model
312*/
313void MD2Loader::parseAnimations(t3DModel *pModel)
314{
315  tAnimationInfo animationInfo;
316  string strLastName = "";
317
318  /* the animation parse process looks a little bit wired: this is because there are no
319     fix bounds for the animation lengths, so the frames are destingushed using their names
320     which is normaly composed of <animationname><number>
321  */
322
323  for(int i = 0; i < pModel->numOfObjects; i++)
324    {
325      string strName  = this->pFrames[i].strName;
326      int frameNum = 0;
327       
328      /* erease the frame number from the frame-name */
329      for(unsigned int j = 0; j < strName.length(); j++)
330        {
331          if( isdigit(strName[j]) && j >= strName.length() - 2)
332            {
333              frameNum = atoi(&strName[j]);
334              strName.erase(j, strName.length() - j);
335              break;
336            }
337        }
338
339      printf("current: %s, last: %s\n", strName.c_str(), strLastName.c_str());
340
341      /* animations are sorted through their names: this is how its been done: */
342      if( strName != strLastName || i == pModel->numOfObjects - 1)
343        {
344          if( strLastName != "")
345            {
346              strcpy(animationInfo.strName, strLastName.c_str());
347              animationInfo.endFrame = i;
348              pModel->animationList.push_back(animationInfo);
349              memset(&animationInfo, 0, sizeof(tAnimationInfo));
350              pModel->numOfAnimations++;
351            }
352          animationInfo.startFrame = frameNum - 1 + i;
353        }
354      strLastName = strName;
355    }
356}
357
358
359/**
360   \brief this function converts the .md2 structures to our own model and object structures: decompress
361   \param model
362*/
363void MD2Loader::convertDataStructures(t3DModel *pModel)
364{
365  int j = 0, i = 0;
366       
367  memset(pModel, 0, sizeof(t3DModel));
368  pModel->numOfObjects = this->header.numFrames;
369
370  this->parseAnimations(pModel);
371
372  for (i = 0; i < pModel->numOfObjects; i++)
373    {
374      t3DObject currentFrame;
375
376      currentFrame.numOfVerts = this->header.numVertices;
377      currentFrame.numTexVertex = this->header.numTexCoords;
378      currentFrame.numOfFaces = this->header.numTriangles;
379
380      currentFrame.pVerts = new CVector3[currentFrame.numOfVerts];
381
382      for (j = 0; j < currentFrame.numOfVerts; j++)
383        {
384          currentFrame.pVerts[j].x = this->pFrames[i].pVertices[j].vertex[0];
385          currentFrame.pVerts[j].y = this->pFrames[i].pVertices[j].vertex[1];
386          currentFrame.pVerts[j].z = this->pFrames[i].pVertices[j].vertex[2];
387        }
388
389      delete this->pFrames[i].pVertices;
390
391      if( likely(i > 0))
392        {
393          pModel->objectList.push_back(currentFrame);
394          continue;
395        }
396                       
397      currentFrame.pTexVerts = new CVector2[currentFrame.numTexVertex];
398      currentFrame.pFaces = new tFace[currentFrame.numOfFaces];
399
400      for(j = 0; j < currentFrame.numTexVertex; j++)
401        {
402          currentFrame.pTexVerts[j].x = this->pTexCoords[j].u / float(this->header.skinWidth);
403          currentFrame.pTexVerts[j].y = 1 - this->pTexCoords[j].v / float(this->header.skinHeight);
404        }
405
406      for(j = 0; j < currentFrame.numOfFaces; j++)
407        {
408          currentFrame.pFaces[j].vertIndex[0] = this->pTriangles[j].vertexIndices[0];
409          currentFrame.pFaces[j].vertIndex[1] = this->pTriangles[j].vertexIndices[1];
410          currentFrame.pFaces[j].vertIndex[2] = this->pTriangles[j].vertexIndices[2];
411
412          currentFrame.pFaces[j].coordIndex[0] = this->pTriangles[j].textureIndices[0];
413          currentFrame.pFaces[j].coordIndex[1] = this->pTriangles[j].textureIndices[1];
414          currentFrame.pFaces[j].coordIndex[2] = this->pTriangles[j].textureIndices[2];
415        }
416      pModel->objectList.push_back(currentFrame);
417    }
418}
419
420
421/**
422   \brief this function conputes the normals of the model
423   \param model
424*/
425void MD2Loader::computeNormals(t3DModel *pModel)
426{
427  CVector3 vVector1, vVector2, vNormal, vPoly[3];
428
429  if( unlikely(pModel->numOfObjects <= 0))
430    return;
431  /* now computing face normals: this means just averaging the vertex normals of a face */
432  /* so for every object: */
433  for(int index = 0; index < pModel->numOfObjects; index++)
434    {
435      t3DObject *pObject = &(pModel->objectList[index]);
436
437      /* allocate all the memory we need to calculate the normals */
438      CVector3 *pNormals = new CVector3 [pObject->numOfFaces];
439      CVector3 *pTempNormals = new CVector3 [pObject->numOfFaces];
440      pObject->pNormals = new CVector3 [pObject->numOfVerts];
441
442      for(int i=0; i < pObject->numOfFaces; i++)
443        {
444          /* cache the points to make coding easier :) */
445          vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];
446          vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];
447          vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];
448
449          vVector1 = MathHelp::VectorDiff(vPoly[0], vPoly[2]);         
450          vVector2 = MathHelp::VectorDiff(vPoly[2], vPoly[1]);         
451                       
452          vNormal  = MathHelp::CrossProduct(vVector1, vVector2);               
453          pTempNormals[i] = vNormal;                                   
454          vNormal  = MathHelp::NormalizeVector(vNormal);                               
455
456          pNormals[i] = vNormal;
457        }
458
459      /* now calculating vertex normals */
460      CVector3 vSum = {0.0, 0.0, 0.0};
461      CVector3 vZero = vSum;
462      int shared=0;
463
464      for (int i = 0; i < pObject->numOfVerts; i++)                     
465        {
466          for (int j = 0; j < pObject->numOfFaces; j++) 
467            {                                                                                           
468              if (pObject->pFaces[j].vertIndex[0] == i || 
469                  pObject->pFaces[j].vertIndex[1] == i || 
470                  pObject->pFaces[j].vertIndex[2] == i)
471                {
472                  vSum = MathHelp::AddVector(vSum, pTempNormals[j]);
473                  shared++;                                                                                             }
474            }     
475          pObject->pNormals[i] = MathHelp::DivideVectorByScaler(vSum, float(-shared));
476          pObject->pNormals[i] = MathHelp::NormalizeVector(pObject->pNormals[i]);       
477
478          vSum = vZero;                                                                 
479          shared = 0;                                                                           
480        }
481      delete [] pTempNormals;
482      delete [] pNormals;
483    }
484}
485
486
487/**
488   \brief This function cleans up our allocated memory and closes the file
489*/
490void MD2Loader::cleanUp()
491{
492  fclose(this->pFile);                 
493       
494  if( this->pSkins) delete [] this->pSkins;             
495  if( this->pTexCoords) delete this->pTexCoords;
496  if( this->pTriangles) delete this->pTriangles;
497  if( this->pFrames) delete this->pFrames;
498}
499
500
501/********************************************************************************
502 *   MD2LOADER2                                                                 *
503 ********************************************************************************/
504
505MD2Model2::MD2Model2()
506{
507  this->pVertices = NULL;
508  this->pGLCommands = NULL;
509  this->pLightNormals = NULL; 
510
511  this->numFrames = 0;
512  this->numVertices = 0;
513  this->numGLCommands = 0;
514 
515  this->textureID = 0;
516  this->scaleFactor = 1.0f;
517
518  this->setAnim(STAND);
519}
520
521
522MD2Model2::~MD2Model2()
523{
524  delete [] this->pVertices;
525  delete [] this->pGLCommands;
526  delete [] this->pLightNormals;
527}
528
529
530
531bool MD2Model2::loadModel(const char *fileName)
532{
533  FILE *pFile;                            //file stream
534  char* buffer;                           //buffer for frame data
535  sFrame* frame;                          //temp frame
536  sVec3D *pVertex;
537  int* pNormals;
538
539  pFile = fopen(fileName, "rb");
540  if( unlikely(!pFile)) 
541    {
542      PRINTF(1)("Couldn't open the MD2 File for loading. Exiting.\n");
543      return false;
544    }
545  fread(this->header, 1, sizeof(tMd2Header), pFile);
546  /* check for the header version: make sure its a md2 file :) */
547  if( unlikely(this->header->version != MD2_VERSION) && unlikely(this->header->ident != MD2_IDENT))
548    {
549      PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName);
550      return false;
551    }
552
553  /* got the data: map it to locals */
554  this->numFrames = this->header->numFrames;
555  this->numVertices = this->header->numVertices;
556  this->numTriangles = this->header->numTriangles;
557  this->numGLCommands = this->header->numGlCommands;
558  /* allocate memory for the data storage */
559  this->pVertices = new sVec3D[this->numVertices * this->numFrames];
560  this->pGLCommands = new int[this->numGLCommands];
561  this->pLightNormals = new int[this->numVertices * this->numFrames];
562  buffer = new char[this->numFrames * this->header->frameSize];
563
564  /* read frame data from the file to a temp buffer */
565  fseek(pFile, this->header->offsetFrames, SEEK_SET);
566  fread(buffer, this->header->frameSize, this->numFrames, pFile);
567  /* read opengl commands */
568  fseek(pFile, this->header->offsetGlCommands, SEEK_SET);
569  fread(this->pGLCommands, sizeof(int), this->numGLCommands, pFile);
570
571  for(int i = 0; i < this->numFrames; ++i)
572    {
573      /*
574      faster but evt. buggy
575      frame = (sFrame*)(buffer + this->header->frameSize * i);
576      pVertex = this->pVertices + this->numVertices  * i;
577      pNormals = this->pLightNormals + this->numVertices * i;
578      */
579      frame = (sFrame *)&buffer[this->header->frameSize * i];
580      pVertex = &this->pVertices[this->numVertices * i];
581      pNormals = &this->pLightNormals[this->numVertices * i];
582
583      for(int j = 0; j < this->numVertices; ++j)
584        {
585          /* SPEEDUP: *(pVerts + i + 0) = (*(frame->pVertices + i + 0)...  */
586          pVertex[j][0] = (frame->pVertices[j].v[0] * frame->scale[0]) + frame->translate[0];
587          pVertex[j][1] = (frame->pVertices[j].v[1] * frame->scale[1]) + frame->translate[1];
588          pVertex[j][2] = (frame->pVertices[j].v[2] * frame->scale[2]) + frame->translate[2];
589         
590          //printf("pVertex %f, %f, %f\n", pVertex[j][0], pVertex[j][1], pVertex[j][2]);
591
592          pNormals[j] = frame->pVertices[j].lightNormalIndex;
593        }
594    }
595
596  delete [] buffer;
597  fclose(pFile);
598}
599
600
601bool MD2Model2::loadSkin(const char* fileName)
602{
603  this->material = new Material("md2ModelTest");
604  this->material->setDiffuseMap(fileName);
605  this->material->setIllum(3);
606  this->material->setAmbient(1.0, 1.0, 1.0);
607}
608
609
610/**
611   \brief initializes an array of vert with the current frame scaled vertices
612
613   we won't use the pVertices array directly, since its much easier and we need
614   saving of data anyway
615*/
616void MD2Model2::interpolate(sVec3D* verticesList)
617{
618  sVec3D* currVec;
619  sVec3D* nextVec;
620
621  currVec = &this->pVertices[this->numVertices * this->animationState.currentFrame];
622  nextVec = &this->pVertices[this->numVertices * this->animationState.nextFrame];
623
624  //printf("currVec: %f, %f, %f\n", currVec[0][0], currVec[0][1], currVec[0][2]);
625  //printf("nextVec: %f, %f, %f\n", nextVec[0][0], nextVec[1][1], nextVec[2][2]);
626 
627  //printf("numFrames: %i\n", this->numFrames);
628  // printf("currentFrame: %i\n", this->animationState.currentFrame);
629 
630    //for(int i = 0; i < this->numFrames; ++i)
631    for(int i = 0; i < this->numVertices; ++i)
632      { 
633        /*
634        verticesList[i][0] = this->pVertices[i + (this->numFrames * this->animationState.currentFrame)][0] * this->scaleFactor;
635        verticesList[i][1] = this->pVertices[i + (this->numFrames * this->animationState.currentFrame)][1] * this->scaleFactor;
636        verticesList[i][2] = this->pVertices[i + (this->numFrames * this->animationState.currentFrame)][2] * this->scaleFactor;
637        */
638
639
640        verticesList[i][0] = (currVec[i][0] + this->animationState.interpolationState * (nextVec[i][0] - currVec[i][0])) * this->scaleFactor;
641        verticesList[i][1] = (currVec[i][1] + this->animationState.interpolationState * (nextVec[i][1] - currVec[i][1])) * this->scaleFactor;
642        verticesList[i][2] = (currVec[i][2] + this->animationState.interpolationState * (nextVec[i][2] - currVec[i][2])) * this->scaleFactor;
643
644
645        //printf("  pVertices %f, %f, %f\n", pVertices[i][0], pVertices[i][1], pVertices[i][2]);
646        printf("  list:     %f, %f, %f \n", verticesList[i][0], verticesList[i][1], verticesList[i][2]);     
647      }
648}
649
650
651void MD2Model2::setAnim(int type)
652{
653  if( (type < 0) || (type > MAX_ANIMATIONS) )
654    type = 0;
655
656  this->animationState.startFrame = animationList[type].firstFrame;
657  this->animationState.endFrame = animationList[type].lastFrame;
658  this->animationState.nextFrame = animationList[type].firstFrame + 1;
659  this->animationState.fps = animationList[type].fps;
660  this->animationState.type = type;
661 
662  this->animationState.interpolationState = 0.0;
663  this->animationState.localTime = 0.0;
664  this->animationState.lastTime = 0.0;
665  this->animationState.currentFrame = animationList[type].firstFrame;
666}
667
668
669void MD2Model2::animate()
670{
671  if( this->animationState.localTime - this->animationState.lastTime > (1.0f / this->animationState.fps))
672    {
673      this->animationState.currentFrame = this->animationState.nextFrame;
674      this->animationState.nextFrame++;
675     
676      if( this->animationState.nextFrame > this->animationState.endFrame)
677        this->animationState.nextFrame = this->animationState.startFrame;
678      this->animationState.lastTime = this->animationState.localTime;
679    }
680
681  if( this->animationState.currentFrame > (this->numFrames - 1) )
682    this->animationState.currentFrame = 0;
683  if( this->animationState.nextFrame > (this->numFrames - 1) )
684    this->animationState.nextFrame = 0;
685
686  this->animationState.interpolationState = this->animationState.fps * 
687    (this->animationState.localTime - this->animationState.lastTime);
688}
689
690
691/* hhmmm... id used a very different way to do lightning... */
692void MD2Model2::processLighting()
693{
694  shadeDots = anormsDots[((int)(md2Angle*(SHADEDOT_QUANT / 360.0)))&(SHADEDOT_QUANT - 1)];
695}
696
697
698void MD2Model2::tick(float time)
699{
700  this->animationState.localTime += time;
701}
702
703
704void MD2Model2::draw()
705{
706  if( likely(this->animationState.localTime > 0.0))
707    this->animate();
708
709  glPushMatrix();
710  /* rotate because id software uses another orientation then the openGL default */
711  /* \todo: rotate the axis already when loading... easy :) */
712  glRotatef(-90.0, 1.0, 0.0, 0.0);
713  glRotatef(-90.0, 0.0, 0.0, 1.0);
714
715  this->renderFrame();
716
717  glPopMatrix();
718}
719
720
721void MD2Model2::draw2()
722{
723  glBegin(GL_TRIANGLES);
724  for(int j = 0; j < this->numTriangles; j++)
725    {
726      for(int whichVertex = 0; whichVertex < 3; whichVertex++)
727        {
728          /*
729          int index = pObject->pFaces[j].vertIndex[whichVertex];
730          int index2 = pObject->pFaces[j].coordIndex[whichVertex];
731          glNormal3f(-pObject->pNormals[index].x, -pObject->pNormals[index].y, -pObject->pNormals[index].z);
732         
733          if( likely(pObject->pTexVerts != NULL))
734            {
735              glTexCoord2f(pObject->pTexVerts[index2].x, pObject->pTexVerts[index2].y);
736            }
737          glVertex3f(pObject->pVerts[index].x, pObject->pVerts[index].y, pObject->pVerts[index].z);
738          */
739        }
740    }
741  glEnd();
742}
743
744
745void MD2Model2::renderFrame()
746{
747  static sVec3D verticesList[MD2_MAX_VERTICES]; /* performance: created only once in a lifetime */
748  int* pCommands = this->pGLCommands;
749
750  /* some face culling stuff */
751  glPushAttrib(GL_POLYGON_BIT);
752  glFrontFace(GL_CW);
753  glEnable(GL_CULL_FACE);
754  glCullFace(GL_BACK);
755     
756  this->processLighting();
757  this->interpolate(verticesList);
758  this->material->select();
759
760  /* draw the triangles */
761  /* \todo: take int i out of while loop */
762  while( int i = *(pCommands++)) /* strange looking while loop for maximum performance */
763    {
764      int i;
765      if( i < 0)
766        {
767          glBegin(GL_TRIANGLE_FAN);
768          i = -i;
769        }
770      else
771        {
772          glBegin(GL_TRIANGLE_STRIP);
773        }
774
775      for(; i > 0; i--, pCommands += 3) /* down counting for loop, next 3 gl commands */
776        {
777          /* for quake2 lighting */
778          //float l = shadeDots[this->pLightNormals[pCommands[2]]];
779          //glColor3f(l * lcolor[0], l * lcolor[1], l * lcolor[2]);
780
781          glNormal3fv(anorms[this->pLightNormals[pCommands[2]]]);
782          glTexCoord2f( ((float *)pCommands)[0], ((float *)pCommands)[1] );
783          glVertex3fv(verticesList[pCommands[2]]);
784
785          printf("draw vert: %f, %f, %f\n", verticesList[pCommands[2]][0], verticesList[pCommands[2]][1], verticesList[pCommands[2]][2] );
786        }
787      glEnd();
788    }
789  glDisable(GL_CULL_FACE);
790  glPopAttrib();
791}
792
793
794void MD2Model2::debug()
795{
796  PRINT(0)("==========================| MD2Model2::debug() |===");
797  //PRINT(0)("= Model Name: %s", this->header->);
798  PRINT(0)("= ");
799}
800/*
801
802  int ident;                            //!< This is used to identify the file
803   int version;                         //!< The version number of the file (Must be 8)
804   
805   int skinWidth;                       //!< The skin width in pixels
806   int skinHeight;                      //!< The skin height in pixels
807   int frameSize;                       //!< The size in bytes the frames are
808   
809   int numSkins;                        //!< The number of skins associated with the model
810   int numVertices;                     //!< The number of vertices (constant for each frame)
811   int numTexCoords;                    //!< The number of texture coordinates
812   int numTriangles;                    //!< The number of faces (polygons)
813   int numGlCommands;                   //!< The number of gl commands
814   int numFrames;                       //!< The number of animation frames
815   
816   int offsetSkins;                     //!< The offset in the file for the skin data
817   int offsetTexCoords;                 //!< The offset in the file for the texture data
818   int offsetTriangles;                 //!< The offset in the file for the face data
819   int offsetFrames;                    //!< The offset in the file for the frames data
820   int offsetGlCommands;                //!< The offset in the file for the gl commands data
821   int offsetEnd;                       //!< The end of the file offset
822*/
Note: See TracBrowser for help on using the repository browser.