Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/md2_loader: got segfault, assuming problem in the verticesList interpolation

File size: 24.1 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  tMd2Header header;
535  char* buffer;                           //buffer for frame data
536  sFrame* frame;                          //temp frame
537  sVec3D *pVertex;
538  int* pNormals;
539
540  pFile = fopen(fileName, "rb");
541  if( unlikely(!pFile)) 
542    {
543      PRINTF(1)("Couldn't open the MD2 File for loading. Exiting.\n");
544      return false;
545    }
546  fread(&header, 1, sizeof(tMd2Header), pFile);
547  /* check for the header version: make sure its a md2 file :) */
548  if( unlikely(header.version != MD2_VERSION) && unlikely(header.ident != MD2_IDENT))
549    {
550      PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName);
551      return false;
552    }
553
554  /* got the data: map it to locals */
555  this->numFrames = header.numFrames;
556  this->numVertices = header.numVertices;
557  this->numTriangles = header.numTriangles;
558  this->numGLCommands = header.numGlCommands;
559  /* allocate memory for the data storage */
560  this->pVertices = new sVec3D[this->numVertices * this->numFrames];
561  this->pGLCommands = new int[this->numGLCommands];
562  this->pLightNormals = new int[this->numVertices * this->numFrames];
563  buffer = new char[this->numFrames * header.frameSize];
564
565  /* read frame data from the file to a temp buffer */
566  fseek(pFile, header.offsetFrames, SEEK_SET);
567  fread(buffer, header.frameSize, this->numFrames, pFile);
568  /* read opengl commands */
569  fseek(pFile, header.offsetGlCommands, SEEK_SET);
570  fread(this->pGLCommands, sizeof(int), this->numGLCommands, pFile);
571
572  for(int i = 0; i < this->numFrames; ++i)
573    {
574      /*
575      faster but evt. buggy
576      frame = (sFrame*)(buffer + header.frameSize * i);
577      pVertex = this->pVertices + this->numVertices  * i;
578      pNormals = this->pLightNormals + this->numVertices * i;
579      */
580      frame = (sFrame *)&buffer[header.frameSize * i];
581      pVertex = &this->pVertices[this->numVertices * i];
582      pNormals = &this->pLightNormals[this->numVertices * i];
583
584      for(int j = 0; j < this->numVertices; ++j)
585        {
586          /* SPEEDUP: *(pVerts + i + 0) = (*(frame->pVertices + i + 0)...  */
587          pVertex[j][0] = (frame->pVertices[j].v[0] * frame->scale[0]) + frame->translate[0];
588          pVertex[j][1] = (frame->pVertices[j].v[1] * frame->scale[1]) + frame->translate[1];
589          pVertex[j][2] = (frame->pVertices[j].v[2] * frame->scale[2]) + frame->translate[2];
590         
591          //printf("pVertex %f, %f, %f\n", pVertex[j][0], pVertex[j][1], pVertex[j][2]);
592
593          pNormals[j] = frame->pVertices[j].lightNormalIndex;
594        }
595    }
596
597  delete [] buffer;
598  fclose(pFile);
599}
600
601
602bool MD2Model2::loadSkin(const char* fileName)
603{
604  this->material = new Material("md2ModelTest");
605  this->material->setDiffuseMap(fileName);
606  this->material->setIllum(3);
607  this->material->setAmbient(1.0, 1.0, 1.0);
608}
609
610
611/**
612   \brief initializes an array of vert with the current frame scaled vertices
613
614   we won't use the pVertices array directly, since its much easier and we need
615   saving of data anyway
616*/
617void MD2Model2::interpolate(sVec3D* verticesList)
618{
619  sVec3D* currVec;
620  sVec3D* nextVec;
621
622  currVec = &this->pVertices[this->numVertices * this->animationState.currentFrame];
623  nextVec = &this->pVertices[this->numVertices * this->animationState.nextFrame];
624
625  //printf("currVec: %f, %f, %f\n", currVec[0][0], currVec[0][1], currVec[0][2]);
626  //printf("nextVec: %f, %f, %f\n", nextVec[0][0], nextVec[1][1], nextVec[2][2]);
627 
628  //printf("numFrames: %i\n", this->numFrames);
629  // printf("currentFrame: %i\n", this->animationState.currentFrame);
630 
631    //for(int i = 0; i < this->numFrames; ++i)
632    for(int i = 0; i < this->numVertices; ++i)
633      { 
634        /*
635        verticesList[i][0] = this->pVertices[i + (this->numFrames * this->animationState.currentFrame)][0] * this->scaleFactor;
636        verticesList[i][1] = this->pVertices[i + (this->numFrames * this->animationState.currentFrame)][1] * this->scaleFactor;
637        verticesList[i][2] = this->pVertices[i + (this->numFrames * this->animationState.currentFrame)][2] * this->scaleFactor;
638        */
639
640
641        verticesList[i][0] = (currVec[i][0] + this->animationState.interpolationState * (nextVec[i][0] - currVec[i][0])) * this->scaleFactor;
642        verticesList[i][1] = (currVec[i][1] + this->animationState.interpolationState * (nextVec[i][1] - currVec[i][1])) * this->scaleFactor;
643        verticesList[i][2] = (currVec[i][2] + this->animationState.interpolationState * (nextVec[i][2] - currVec[i][2])) * this->scaleFactor;
644
645
646        //printf("  pVertices %f, %f, %f\n", pVertices[i][0], pVertices[i][1], pVertices[i][2]);
647        //printf("  list:     %f, %f, %f \n", verticesList[i][0], verticesList[i][1], verticesList[i][2]);     
648      }
649}
650
651
652void MD2Model2::setAnim(int type)
653{
654  if( (type < 0) || (type > MAX_ANIMATIONS) )
655    type = 0;
656
657  this->animationState.startFrame = animationList[type].firstFrame;
658  this->animationState.endFrame = animationList[type].lastFrame;
659  this->animationState.nextFrame = animationList[type].firstFrame + 1;
660  this->animationState.fps = animationList[type].fps;
661  this->animationState.type = type;
662 
663  this->animationState.interpolationState = 0.0;
664  this->animationState.localTime = 0.0;
665  this->animationState.lastTime = 0.0;
666  this->animationState.currentFrame = animationList[type].firstFrame;
667}
668
669
670void MD2Model2::animate()
671{
672  if( this->animationState.localTime - this->animationState.lastTime > (1.0f / this->animationState.fps))
673    {
674      this->animationState.currentFrame = this->animationState.nextFrame;
675      this->animationState.nextFrame++;
676     
677      if( this->animationState.nextFrame > this->animationState.endFrame)
678        this->animationState.nextFrame = this->animationState.startFrame;
679      this->animationState.lastTime = this->animationState.localTime;
680    }
681
682  if( this->animationState.currentFrame > (this->numFrames - 1) )
683    this->animationState.currentFrame = 0;
684  if( this->animationState.nextFrame > (this->numFrames - 1) )
685    this->animationState.nextFrame = 0;
686
687  this->animationState.interpolationState = this->animationState.fps * 
688    (this->animationState.localTime - this->animationState.lastTime);
689}
690
691
692/* hhmmm... id used a very different way to do lightning... */
693void MD2Model2::processLighting()
694{
695  shadeDots = anormsDots[((int)(md2Angle*(SHADEDOT_QUANT / 360.0)))&(SHADEDOT_QUANT - 1)];
696}
697
698
699void MD2Model2::tick(float time)
700{
701  this->animationState.localTime += time;
702}
703
704
705void MD2Model2::draw()
706{
707  if( likely(this->animationState.localTime > 0.0))
708    this->animate();
709
710  glPushMatrix();
711  /* rotate because id software uses another orientation then the openGL default */
712  /* \todo: rotate the axis already when loading... easy :) */
713  glRotatef(-90.0, 1.0, 0.0, 0.0);
714  glRotatef(-90.0, 0.0, 0.0, 1.0);
715
716  this->renderFrame();
717
718  glPopMatrix();
719}
720
721
722void MD2Model2::draw2()
723{
724  glBegin(GL_TRIANGLES);
725  for(int j = 0; j < this->numTriangles; j++)
726    {
727      for(int whichVertex = 0; whichVertex < 3; whichVertex++)
728        {
729          /*
730          int index = pObject->pFaces[j].vertIndex[whichVertex];
731          int index2 = pObject->pFaces[j].coordIndex[whichVertex];
732          glNormal3f(-pObject->pNormals[index].x, -pObject->pNormals[index].y, -pObject->pNormals[index].z);
733         
734          if( likely(pObject->pTexVerts != NULL))
735            {
736              glTexCoord2f(pObject->pTexVerts[index2].x, pObject->pTexVerts[index2].y);
737            }
738          glVertex3f(pObject->pVerts[index].x, pObject->pVerts[index].y, pObject->pVerts[index].z);
739          */
740        }
741    }
742  glEnd();
743}
744
745
746void MD2Model2::renderFrame()
747{
748  static sVec3D verticesList[MD2_MAX_VERTICES]; /* performance: created only once in a lifetime */
749  int* pCommands = this->pGLCommands;
750
751  /* some face culling stuff */
752  glPushAttrib(GL_POLYGON_BIT);
753  glFrontFace(GL_CW);
754  glEnable(GL_CULL_FACE);
755  glCullFace(GL_BACK);
756     
757  this->processLighting();
758  this->interpolate(verticesList);
759  this->material->select();
760
761  /* draw the triangles */
762  /* \todo: take int i out of while loop */
763  while( int i = *(pCommands++)) /* strange looking while loop for maximum performance */
764    {
765      int i;
766      if( i < 0)
767        {
768          glBegin(GL_TRIANGLE_FAN);
769          i = -i;
770        }
771      else
772        {
773          glBegin(GL_TRIANGLE_STRIP);
774        }
775
776      for(; i > 0; i--, pCommands += 3) /* down counting for loop, next 3 gl commands */
777        {
778          /* for quake2 lighting */
779          //float l = shadeDots[this->pLightNormals[pCommands[2]]];
780          //glColor3f(l * lcolor[0], l * lcolor[1], l * lcolor[2]);
781
782          glNormal3fv(anorms[this->pLightNormals[pCommands[2]]]);
783          glTexCoord2f( ((float *)pCommands)[0], ((float *)pCommands)[1] );
784          glVertex3fv(verticesList[pCommands[2]]);
785
786          printf("draw vert: %f, %f, %f\n", verticesList[pCommands[2]][0], verticesList[pCommands[2]][1], verticesList[pCommands[2]][2] );
787        }
788      glEnd();
789    }
790  glDisable(GL_CULL_FACE);
791  glPopAttrib();
792}
793
Note: See TracBrowser for help on using the repository browser.