Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 22, 2006, 3:14:58 PM (19 years ago)
Author:
bensch
Message:

merged the bsp-model-stuff back here

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/graphics/importer/md3/md3_model.cc

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