Changeset 8724 in orxonox.OLD for trunk/src/lib/graphics/importer/md3/md3_model.cc
- Timestamp:
- Jun 22, 2006, 3:14:58 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/graphics/importer/md3/md3_model.cc
r8490 r8724 18 18 19 19 #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" 21 33 22 34 namespace md3 … … 28 40 MD3Model::MD3Model(std::string filename, float scaling) 29 41 { 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); 31 51 } 32 52 … … 34 54 35 55 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 36 383 {} 37 384 38 385 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 39 717 }
Note: See TracChangeset
for help on using the changeset viewer.