Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/bsp_model/src/lib/graphics/importer/md3/md3_model.cc @ 8645

Last change on this file since 8645 was 8645, checked in by patrick, 18 years ago

bsp: md3 model animation doesn't work yet ,flush

File size: 21.6 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 "md3_model.h"
18
19#include "md3_data.h"
20#include "md3_mesh.h"
21#include "md3_tag.h"
22#include "md3_bone_frame.h"
23#include "md3_animation.h"
24
25#include "md3_animation_cfg.h"
26
27#include "material.h"
28#include "quaternion.h"
29
30#include "loading/resource_manager.h"
31
32#include "debug.h"
33
34namespace md3
35{
36
37  /**
38   * md3 model
39   */
40  MD3Model::MD3Model(std::string filename, float scaling)
41  {
42    this->autoAssemblePlayerModel(filename, scaling);
43
44    this->bDrawBones = false;
45    this->bDrawNormals = false;
46  }
47
48
49
50  MD3Model::~MD3Model()
51  {
52//     delete this->tmpBoneFrame;
53//     delete [] this->tmpMesh;
54
55    ///TODO deleting mesh
56    ///TODO deleting matrices
57  }
58
59
60  /**
61   * auto assemples a player model
62   * @param filename is the name to the directory of the modelzzzzzz
63   */
64  void MD3Model::autoAssemblePlayerModel(std::string filename, float scaling)
65  {
66    // loading the config file
67    std::string cfgName(filename + "/animation.cfg");
68    this->config = (MD3AnimationCfg*)ResourceManager::getInstance()->load(cfgName, MD3_CONFIG, RP_GAME);
69
70    //first load the torso or the upper part
71    std::string nameUpper(filename + "/upper.md3");
72    if( (this->md3Data = (MD3Data*)ResourceManager::getInstance()->load(nameUpper, MD3, RP_GAME, nameUpper, scaling)) == NULL)
73    {
74      std::string nameTorso(filename + "/torso.md3");
75      this->md3Data = (MD3Data*)ResourceManager::getInstance()->load(nameTorso, MD3, RP_GAME, nameTorso, scaling);
76    }
77
78    if( this->md3Data == NULL)
79    {
80      PRINTF(1)("Problems loading the MD3Model. Abording\n");
81      return;
82    }
83
84    // load lower
85    std::string nameLower(filename + "/lower.md3");
86    MD3Data* lower = (MD3Data*)ResourceManager::getInstance()->load(nameLower, MD3, RP_GAME, nameLower, scaling);
87    if( lower != NULL)
88    {
89      int tag = this->md3Data->getTagIndexByName("tag_lower");
90      PRINTF(0)("Loaded the %s model on index %i\n", nameLower.c_str(), tag);
91      if( tag >= 0)
92       this->md3Data->addLinkedModel(tag, lower);
93      else
94        PRINTF(0)("Could not add %s\n", nameLower.c_str());
95    }
96
97
98    // load head
99    std::string nameHead(filename + "/head.md3");
100    MD3Data* head = (MD3Data*)ResourceManager::getInstance()->load(nameHead, MD3, RP_GAME, nameLower, scaling);
101    if( head != NULL)
102    {
103      int tag = this->md3Data->getTagIndexByName("tag_head");
104      PRINTF(0)("Loaded the %s model on index %i\n", nameHead.c_str(), tag);
105      if( tag >= 0)
106        this->md3Data->addLinkedModel(tag, head);
107      else
108        PRINTF(0)("Could not add %s\n", nameHead.c_str());
109    }
110
111  }
112
113
114
115  /**
116   * tick float
117   * @param time: time elapsed
118   */
119  void MD3Model::tick(float time)
120  {
121
122    this->visit(this->md3Data);
123
124    this->tick(time, this->md3Data);
125  }
126
127
128  /**
129   * tick each data
130   */
131  void MD3Model::tick(float time, MD3Data* data)
132  {
133    // draw the bones if needed
134    if( this->bDrawBones)
135    {
136      // get bone frame, interpolate if necessary
137      if( data->animationState.interpolationFraction != 0.0 &&
138          data->animationState.currentFrame != data->animationState.nextFrame)
139      {
140        //interpolate bone frame
141        data->tmpBoneFrame = this->interpolateBoneFrame(data, data->boneFrames[data->animationState.currentFrame],
142                                                        data->boneFrames[data->animationState.nextFrame],
143                                                        data->animationState.interpolationFraction);
144      }
145      else
146      {
147        data->tmpBoneFrame = data->boneFrames[data->animationState.currentFrame];
148      }
149    }
150
151    //draw all meshes of current frame of this model
152    for( int i = 0;  i < data->header->meshNum; i++)
153    {
154      MD3Mesh* mesh = data->meshes[i];
155
156      // get mesh frame, do interpolation if necessary
157      sVec3D* frame;
158      if( data->animationState.interpolationFraction != 0.0 &&
159          data->animationState.currentFrame != data->animationState.nextFrame)
160      {
161        //interpolate mesh frame between the 2 current mesh frames
162        frame = this->interpolateMeshFrame( data, data->meshes[data->animationState.currentFrame]->meshFrames,
163                                            data->meshes[data->animationState.nextFrame]->meshFrames,
164                                            data->animationState.interpolationFraction, mesh, i);
165      }
166      else
167      {
168        //no interpolation needed, just draw current frame
169        frame = &mesh->meshFrames[data->animationState.currentFrame];
170      }
171      data->tmpMesh[i] = frame;
172
173      // draw vertex normals if needed
174      if( this->bDrawNormals)
175      {
176        // get vertex normals, interpolate if necessary
177        if( data->animationState.interpolationFraction != 0.0 &&
178            data->animationState.currentFrame != data->animationState.nextFrame)
179        {
180          //interpolate vertex normals
181          this->interpolateVertexNormals(data, &mesh->normals[data->animationState.currentFrame],
182                                         &mesh->normals[data->animationState.nextFrame],
183                                         data->animationState.interpolationFraction, mesh, i);
184        }
185      }
186    }
187
188
189    // draw all models linked to this model
190    std::map<int, MD3Data*>::iterator it = data->sortedMap.begin();
191    int i = 0;
192    while( it != data->sortedMap.end())
193    {
194      MD3Data* child = it->second;
195
196      //build transformation array m from matrix, interpolate if necessary
197
198      MD3Tag* currFrameTag = data->boneFrames[data->animationState.currentFrame]->tags[child->parentTagIndex];
199
200      if( data->animationState.interpolationFraction != 0.0 &&
201          data->animationState.currentFrame != data->animationState.nextFrame)
202      {
203        //we need to interpolate
204        MD3Tag* nextFrameTag = data->boneFrames[data->animationState.nextFrame]->tags[child->parentTagIndex];
205        this->interpolateTransformation(child, currFrameTag, nextFrameTag, data->animationState.interpolationFraction, i);
206      }
207      else
208      {
209        //no interpolation needed, stay with last transformation
210        //OpenGL matrix is in column-major order
211        data->tmpMatrix[i][0] = currFrameTag->matrix[0][0];
212        data->tmpMatrix[i][1] = currFrameTag->matrix[1][0];
213        data->tmpMatrix[i][2] = currFrameTag->matrix[2][0];
214        data->tmpMatrix[i][3] = 0.0f;
215        data->tmpMatrix[i][4] = currFrameTag->matrix[0][1];
216        data->tmpMatrix[i][5] = currFrameTag->matrix[1][1];
217        data->tmpMatrix[i][6] = currFrameTag->matrix[2][1];
218        data->tmpMatrix[i][7] = 0.0f;
219        data->tmpMatrix[i][8] = currFrameTag->matrix[0][2];
220        data->tmpMatrix[i][9] = currFrameTag->matrix[1][2];
221        data->tmpMatrix[i][10]= currFrameTag->matrix[2][2];
222        data->tmpMatrix[i][11]= 0.0f;
223        data->tmpMatrix[i][12] = currFrameTag->position.x;
224        data->tmpMatrix[i][13] = currFrameTag->position.y;
225        data->tmpMatrix[i][14] = currFrameTag->position.z;
226        data->tmpMatrix[i][15] = 1.0f;
227      }
228
229      // switch to child coord system
230
231      // and tick child
232      this->tick(time, child);
233
234      i++;
235      it++;
236    }
237  }
238
239
240  /**
241   * this draws the md3 model
242   */
243  void MD3Model::draw() const
244  {
245    PRINTF(0)("\ndraw========================\n");
246    //draw current bone frame
247    this->draw(this->md3Data);
248  }
249
250
251  /**
252   * draw the md3model
253   * @param data: the data to be drawn
254   */
255  void MD3Model::draw(MD3Data* data) const
256  {
257
258    // draw the bones if needed
259    if( this->bDrawBones)
260    {
261      // get bone frame, interpolate if necessary
262      if( data->animationState.interpolationFraction != 0.0 &&
263          data->animationState.currentFrame != data->animationState.nextFrame) {
264        //interpolate bone frame
265        this->drawBoneFrame(data->tmpBoneFrame);
266      }
267      else {
268        //stick with current bone frame
269        this->drawBoneFrame(data->boneFrames[data->animationState.currentFrame]);
270      }
271    }
272
273
274    //draw all meshes of current frame of this model
275    for( int i = 0;  i < data->header->meshNum; i++)
276    {
277      MD3Mesh* mesh = data->meshes[i];
278
279      if( mesh->header->textureNum > 0 && &mesh->material[0] != NULL)
280        mesh->material[0].select();
281
282      // get mesh frame, do interpolation if necessary
283      sVec3D* frame = data->tmpMesh[i];
284
285      this->drawMesh(mesh, frame);
286
287      // draw vertex normals if needed
288      if( this->bDrawNormals)
289      {
290        // get vertex normals, interpolate if necessary
291        if( data->animationState.interpolationFraction != 0.0 &&
292            data->animationState.currentFrame != data->animationState.nextFrame)
293        {
294          //interpolate vertex normals
295          this->drawVertexNormals(frame, data->tmpNormal[i]);
296        }
297        else {
298          //stick with current vertex normals
299          this->drawVertexNormals(frame, &mesh->normals[data->animationState.currentFrame]);
300        }
301      }
302    }
303
304
305    // draw all models linked to this model
306    int i = 0;
307    std::map<int, MD3Data*>::iterator it = data->sortedMap.begin();
308    while( it != data->sortedMap.end())
309    {
310      MD3Data* child = it->second;
311
312      //switch to child coord system
313      glPushMatrix();
314      glMultMatrixf(data->tmpMatrix[i]);
315
316      // and draw child
317      this->draw(child);
318
319      glPopMatrix();
320
321      i++;
322      it++;
323    }
324
325  }
326
327
328  /**
329   * draws the mesh
330   */
331  void MD3Model::drawMesh(MD3Mesh* mesh, sVec3D* frame) const
332  {
333    PRINTF(0)("drawMesh: %s\n", mesh->header->name);
334    Vector tmpVec1, tmpVec2;
335
336    glColor3f(1.0f, 1.0f, 1.0f);
337    glBegin( GL_TRIANGLES);
338
339    // upload all triangles in the frame to OpenGL
340    for( int t = 0; t < mesh->header->triangleNum; t++)
341    {
342      // calc normal vector
343      tmpVec1.x = frame[mesh->triangles[t].vertexOffset[1]][0] - frame[mesh->triangles[t].vertexOffset[0]][0];
344      tmpVec1.y = frame[mesh->triangles[t].vertexOffset[1]][1] - frame[mesh->triangles[t].vertexOffset[0]][1];
345      tmpVec1.z = frame[mesh->triangles[t].vertexOffset[1]][2] - frame[mesh->triangles[t].vertexOffset[0]][2];
346
347      tmpVec2.x = frame[mesh->triangles[t].vertexOffset[2]][0] - frame[mesh->triangles[t].vertexOffset[0]][0];
348      tmpVec2.y = frame[mesh->triangles[t].vertexOffset[2]][1] - frame[mesh->triangles[t].vertexOffset[0]][1];
349      tmpVec2.z = frame[mesh->triangles[t].vertexOffset[2]][2] - frame[mesh->triangles[t].vertexOffset[0]][2];
350
351      Vector normal = tmpVec1.cross(tmpVec2);
352      normal.normalize();
353
354//       PRINTF(0)("normal: %f, %f, %f\n", normal.x, normal.y, normal.z);
355
356      glNormal3f(normal.x, normal.y, normal.z);
357      glTexCoord2fv( mesh->texVecs[mesh->triangles[t].vertexOffset[0]].textureCoord);
358      glVertex3f( frame[mesh->triangles[t].vertexOffset[0]][0],
359                  frame[mesh->triangles[t].vertexOffset[0]][2],
360                  frame[mesh->triangles[t].vertexOffset[0]][1]);
361
362      glNormal3f(normal.x, normal.y, normal.z);
363      glTexCoord2fv( mesh->texVecs[mesh->triangles[t].vertexOffset[1]].textureCoord);
364      glVertex3f( frame[mesh->triangles[t].vertexOffset[1]][0],
365                  frame[mesh->triangles[t].vertexOffset[1]][2],
366                  frame[mesh->triangles[t].vertexOffset[1]][1]);
367
368      glNormal3f(normal.x, normal.y, normal.z);
369      glTexCoord2fv( mesh->texVecs[mesh->triangles[t].vertexOffset[2]].textureCoord);
370      glVertex3f( frame[mesh->triangles[t].vertexOffset[2]][0],
371                  frame[mesh->triangles[t].vertexOffset[2]][2],
372                  frame[mesh->triangles[t].vertexOffset[2]][1]);
373    }
374    glEnd();
375  }
376
377
378  /**
379   *  drawo vertex normals
380   */
381  void MD3Model::drawVertexNormals(sVec3D* frame, MD3Normal* normals) const
382  {}
383
384
385  /**
386   * draw bone frame
387   */
388  void MD3Model::drawBoneFrame(MD3BoneFrame* frame) const
389  {
390    float x1 = frame->mins.x;
391    float y1 = frame->mins.y;
392    float z1 = frame->mins.z;
393    float x2 = frame->maxs.x;
394    float y2 = frame->maxs.y;
395    float z2 = frame->maxs.z;
396
397    glPushAttrib(GL_TEXTURE_2D);
398    glPushAttrib(GL_LIGHTING);
399
400    glColor3f(1.0f,0.0f,0.0f);
401    glPointSize(6.0f);
402
403    glBegin(GL_POINTS);
404    glVertex3f(frame->position.x, frame->position.y, frame->position.z);
405    glEnd();
406    glPointSize(1.0f);
407
408    glColor3f(0.0f,1.0f,0.0f);
409    glBegin(GL_LINE_LOOP);
410    glVertex3f(x1,y1,z1);
411    glVertex3f(x1,y1,z2);
412    glVertex3f(x1,y2,z2);
413    glVertex3f(x1,y2,z1);
414    glEnd();
415
416    glBegin(GL_LINE_LOOP);
417    glVertex3f(x2,y2,z2);
418    glVertex3f(x2,y1,z2);
419    glVertex3f(x2,y1,z1);
420    glVertex3f(x2,y2,z1);
421    glEnd();
422
423    glBegin(GL_LINES);
424    glVertex3f(x1,y1,z1);
425    glVertex3f(x2,y1,z1);
426
427    glVertex3f(x1,y1,z2);
428    glVertex3f(x2,y1,z2);
429
430    glVertex3f(x1,y2,z2);
431    glVertex3f(x2,y2,z2);
432
433    glVertex3f(x1,y2,z1);
434    glVertex3f(x2,y2,z1);
435    glEnd();
436
437     glPopAttrib();
438     glPopAttrib();
439  }
440
441
442  /**
443   *  interpolate bone frame
444   * @param currBoneFrame Start bone frame.
445   * @param nextBoneFrame End bone frame.
446   * @param frac Interpolation fraction, in [0,1].
447   */
448  MD3BoneFrame* MD3Model::interpolateBoneFrame(MD3Data* data, MD3BoneFrame* currBoneFrame, MD3BoneFrame* nextBoneFrame, float frac)
449  {
450    data->tmpBoneFrame->mins.x      = (1.0f - frac) * currBoneFrame->mins.x       + frac * nextBoneFrame->mins.x;
451    data->tmpBoneFrame->maxs.x      = (1.0f - frac) * currBoneFrame->maxs.x       + frac * nextBoneFrame->maxs.x;
452    data->tmpBoneFrame->position.= (1.0f - frac) * currBoneFrame->position.x   + frac * nextBoneFrame->position.x;
453    data->tmpBoneFrame->mins.y      = (1.0f - frac) * currBoneFrame->mins.y       + frac * nextBoneFrame->mins.y;
454    data->tmpBoneFrame->maxs.y      = (1.0f - frac) * currBoneFrame->maxs.y       + frac * nextBoneFrame->maxs.y;
455    data->tmpBoneFrame->position.= (1.0f - frac) * currBoneFrame->position.y   + frac * nextBoneFrame->position.y;
456    data->tmpBoneFrame->mins.z      = (1.0f - frac) * currBoneFrame->mins.z       + frac * nextBoneFrame->mins.z;
457    data->tmpBoneFrame->maxs.z      = (1.0f - frac) * currBoneFrame->maxs.z       + frac * nextBoneFrame->maxs.z;
458    data->tmpBoneFrame->position.= (1.0f - frac) * currBoneFrame->position.z   + frac * nextBoneFrame->position.z;
459
460    return data->tmpBoneFrame;
461  }
462
463
464
465  /**
466   * interpolate mesh frame
467   */
468  sVec3D* MD3Model::interpolateMeshFrame(MD3Data* data, sVec3D* currMeshFrame, sVec3D* nextMeshFrame, float frac, MD3Mesh* mesh, int i)
469  {
470    int vertexNum = mesh->header->vertexNum;
471
472    // calc interpolated vertices
473    for( int t = 0; t < vertexNum * 3.0f; t++)
474    {
475      data->tmpMesh[i][t][0]  = (1.0f - frac)   * currMeshFrame[t][0]  + frac * nextMeshFrame[t][0];
476      data->tmpMesh[i][t][1]  = (1.0f - frac)   * currMeshFrame[t][1]  + frac * nextMeshFrame[t][1];
477      data->tmpMesh[i][t][2]  = (1.0f - frac)   * currMeshFrame[t][2]  + frac * nextMeshFrame[t][2];
478    }
479
480    return data->tmpMesh[i];
481  }
482
483
484  /**
485   * interpolate vertex normal
486   */
487  MD3Normal* MD3Model::interpolateVertexNormals(MD3Data* data, MD3Normal* currNormals, MD3Normal* nextNormals, float frac, MD3Mesh* mesh, int i)
488  {
489    for( int j = 0; j < mesh->header->vertexNum; j++)
490    {
491      data->tmpNormal[i][j].vertexNormal[0] = (int)((1.0f - frac) * currNormals[j].vertexNormal[0] + frac * nextNormals[j].vertexNormal[0]);
492      data->tmpNormal[i][j].vertexNormal[1] = (int)((1.0f - frac) * currNormals[j].vertexNormal[1] + frac * nextNormals[j].vertexNormal[1]);
493    }
494
495    return data->tmpNormal[i];
496  }
497
498
499  /**
500   * interpolate transformation
501   */
502  float* MD3Model::interpolateTransformation(MD3Data* data, MD3Tag* currFrameTag, MD3Tag* nextFrameTag, float frac, int i)
503  {
504    // interpolate position
505    Vector interpolatedPosition = currFrameTag->position * (1.0f - frac) + nextFrameTag->position * frac;
506
507
508    // interpolate rotation matrix
509    float  currRot[4][4];
510    float  nextRot[4][4];
511    float  interpolatedMatrix[4][4];
512
513    Quaternion currQuat(currFrameTag->matrix); currQuat.matrix(currRot);
514    Quaternion nextQuat(nextFrameTag->matrix); nextQuat.matrix(nextRot);
515
516    Quaternion interpolatedQuat = Quaternion::quatSlerp(currQuat, nextQuat, frac); interpolatedQuat.matrix(interpolatedMatrix);
517
518    // quaternion code is column based, so use transposed matrix when spitting out to gl
519    data->tmpMatrix[i][0] = interpolatedMatrix[0][0];
520    data->tmpMatrix[i][4] = interpolatedMatrix[1][0];
521    data->tmpMatrix[i][8] = interpolatedMatrix[2][0];
522    data->tmpMatrix[i][12] = interpolatedPosition.x;
523    data->tmpMatrix[i][1] = interpolatedMatrix[0][1];
524    data->tmpMatrix[i][5] = interpolatedMatrix[1][1];
525    data->tmpMatrix[i][9] = interpolatedMatrix[2][1];
526    data->tmpMatrix[i][13] = interpolatedPosition.y;
527    data->tmpMatrix[i][2] = interpolatedMatrix[0][2];
528    data->tmpMatrix[i][6] = interpolatedMatrix[1][2];
529    data->tmpMatrix[i][10]= interpolatedMatrix[2][2];
530    data->tmpMatrix[i][14] = interpolatedPosition.z;
531    data->tmpMatrix[i][3] = 0.0f;
532    data->tmpMatrix[i][7] = 0.0f;
533    data->tmpMatrix[i][11]= 0.0f;
534    data->tmpMatrix[i][15] = 1.0f;
535
536    return data->tmpMatrix[i];
537
538  }
539
540
541
542  /**
543   * visit the model
544   */
545  void MD3Model::visit(MD3Data* data)
546  {
547    if ( (data->filename.find("lower") == std::string::npos &&
548          (data->animation->type == LEGS || data->animation->type == BOTH)) // this is the LEGS model and the animation is applicable
549          ||
550          (data->filename.find("upper") == std::string::npos &&
551          (data->animation->type == TORSO || data->animation->type == BOTH)) // this is the TORSO model and the animation is applicable
552          ||
553          data->animation->type == ALL // the animation is allways applicable
554       )
555      this->doOp(data);
556
557    // visit children
558    std::map<int, MD3Data*>::iterator it = data->sortedMap.begin();
559    while( it != data->sortedMap.end())
560    {
561      this->visit(it->second);
562      it++;
563    }
564  }
565
566
567  /**
568   * Create a new visitor to apply an animation operation (NEXT, REWIND, ...)
569   * to a MD3 model. The operation is executed in the context of the specified
570   * animation.
571   *
572   * @param anim The animation that provides the context for the operation.
573   * @param op The operation to apply.
574   * @param interpolate Should interpolation be done?
575   */
576  void MD3Model::interpolate(MD3Data* data, MD3Animation* anim, int op, bool bInterpolate)
577  {
578     data->animation = anim;
579     if( data->op == NEXT || data->op == PREVIOUS || data->op == REWIND)
580      data->op = op;
581
582     data->bInterpolate = bInterpolate;
583  }
584
585
586  /**
587   * calc next frame number
588   */
589  int MD3Model::next(MD3Data* data, int nr)
590  {
591    if( nr < (data->upperBound - 1))
592      return nr + 1;
593    else
594    { //rewind needed
595      if( data->animation->numFrames < 0)
596        return data->animation->first;
597      else {
598        nr = (data->animation->numLoopFrames != 0)?(data->animation->numFrames - data->animation->numLoopFrames):0;
599        return data->animation->first + nr;
600      }
601    }
602  }
603
604
605  /**
606   * calc prev frame number
607   */
608  int MD3Model::prev(MD3Data* data, int nr)
609  {
610    if( nr == data->animation->first)
611      return data->upperBound - 1;
612    else
613      return nr - 1;
614  }
615
616
617  /**
618   * apply the specified operation to the animation state data members of the model
619   * taking the specified animation into account
620   *
621   * @param data: the data of the model
622   */
623  void MD3Model::doOp(MD3Data* data)
624  {
625    return;
626    // animation to be applied could have illegal data with respect to this model,
627    // ignore anim in this case
628    if( data->animation->first >= data->header->boneFrameNum || data->animation->first < 0)
629      return;
630
631    //calc upper bound for animation frames in this model
632    if( data->animation->numFrames < 0)
633      data->upperBound = data->header->boneFrameNum; //use all available frames
634    else
635      data->upperBound = data->header->boneFrameNum <
636          (data->animation->first + data->animation->numFrames)?data->header->boneFrameNum:(data->animation->first +
637          data->animation->numFrames);
638
639    switch( data->op) {
640
641      case NEXT:
642        if( data->bInterpolate)
643        {
644          data->animationState.interpolationFraction += FRACTION;
645          if( data->animationState.interpolationFraction >= 1.0f)
646          {
647            data->animationState.currentFrame = data->animationState.nextFrame;
648            data->animationState.nextFrame = next(data, data->animationState.nextFrame);
649            data->animationState.interpolationFraction = 0.0f;
650          }
651        }
652        else {
653          data->animationState.currentFrame = data->animationState.nextFrame;
654          data->animationState.nextFrame = next(data, data->animationState.nextFrame);
655        }
656        break;
657
658      case PREVIOUS:
659        if( data->bInterpolate)
660        {
661          data->animationState.interpolationFraction -= FRACTION;
662          if( data->animationState.interpolationFraction < 0.0f)
663          {
664            data->animationState.nextFrame = data->animationState.currentFrame;
665            data->animationState.currentFrame = prev(data, data->animationState.currentFrame);
666            data->animationState.interpolationFraction = 0.8f;
667          }
668        }
669        else
670        {
671          data->animationState.nextFrame = data->animationState.currentFrame;
672          data->animationState.currentFrame = prev(data, data->animationState.currentFrame);
673        }
674        break;
675
676      case REWIND:
677        data->animationState.currentFrame = data->animation->first;
678        data->animationState.nextFrame = next(data, data->animationState.currentFrame);
679        data->animationState.interpolationFraction = 0.0f;
680        break;
681    }
682  }
683
684
685}
Note: See TracBrowser for help on using the repository browser.