[8342] | 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 | |
---|
[8346] | 17 | #include "md3_model.h" |
---|
[8342] | 18 | |
---|
[8354] | 19 | #include "md3_data.h" |
---|
[8552] | 20 | #include "md3_mesh.h" |
---|
| 21 | #include "md3_tag.h" |
---|
[8553] | 22 | #include "md3_bone_frame.h" |
---|
[8342] | 23 | |
---|
[8533] | 24 | #include "md3_animation_cfg.h" |
---|
[8342] | 25 | |
---|
[8552] | 26 | #include "material.h" |
---|
[8560] | 27 | #include "quaternion.h" |
---|
[8552] | 28 | |
---|
[8590] | 29 | #include "loading/resource_manager.h" |
---|
| 30 | |
---|
[8562] | 31 | #include "debug.h" |
---|
| 32 | |
---|
[8351] | 33 | namespace md3 |
---|
| 34 | { |
---|
| 35 | |
---|
| 36 | /** |
---|
| 37 | * md3 model |
---|
| 38 | */ |
---|
[8353] | 39 | MD3Model::MD3Model(std::string filename, float scaling) |
---|
| 40 | { |
---|
[8579] | 41 | this->autoAssemblePlayerModel(filename, scaling); |
---|
[8556] | 42 | |
---|
[8579] | 43 | |
---|
| 44 | // create the temporary data to work with (interpolation data) |
---|
[8556] | 45 | this->tmpBoneFrame = new MD3BoneFrame(); |
---|
[8563] | 46 | |
---|
[8566] | 47 | this->tmpMesh = new sVec3D*[this->md3Data->header->meshNum]; |
---|
| 48 | for( int i = 0; i < this->md3Data->header->meshNum; i++) |
---|
[8563] | 49 | this->tmpMesh[i] = new sVec3D[this->md3Data->meshes[i]->header->vertexNum]; |
---|
| 50 | |
---|
[8566] | 51 | this->tmpNormal = new MD3Normal*[this->md3Data->header->meshNum]; |
---|
| 52 | for( int i = 0; i < this->md3Data->header->meshNum; i++) |
---|
[8565] | 53 | this->tmpNormal[i] = new MD3Normal[this->md3Data->meshes[i]->header->vertexNum]; |
---|
[8564] | 54 | |
---|
[8566] | 55 | this->tmpMatrix = new float*[this->md3Data->header->tagNum]; |
---|
| 56 | for( int i = 0; i < this->md3Data->header->tagNum; i++) |
---|
[8564] | 57 | this->tmpMatrix[i] = new float[16]; |
---|
[8567] | 58 | |
---|
| 59 | this->bDrawBones = false; |
---|
| 60 | this->bDrawNormals = false; |
---|
[8353] | 61 | } |
---|
[8351] | 62 | |
---|
| 63 | |
---|
[8353] | 64 | |
---|
[8351] | 65 | MD3Model::~MD3Model() |
---|
[8556] | 66 | { |
---|
| 67 | delete this->tmpBoneFrame; |
---|
[8564] | 68 | // delete [] this->tmpMesh; |
---|
| 69 | |
---|
| 70 | ///TODO deleting mesh |
---|
| 71 | ///TODO deleting matrices |
---|
[8556] | 72 | } |
---|
[8351] | 73 | |
---|
| 74 | |
---|
[8579] | 75 | /** |
---|
| 76 | * auto assemples a player model |
---|
[8590] | 77 | * @param filename is the name to the directory of the modelzzzzzz |
---|
[8579] | 78 | */ |
---|
| 79 | void MD3Model::autoAssemblePlayerModel(std::string filename, float scaling) |
---|
| 80 | { |
---|
[8590] | 81 | // this->md3Data = new MD3Data(filename, filename, scaling); |
---|
[8579] | 82 | // MD3AnimationCfg cfg("/home/boenzlip/tmp/q3/Downloads/MOH/q3mdl-alien3/models/players/alien3/animation.cfg"); |
---|
[8580] | 83 | |
---|
| 84 | |
---|
[8590] | 85 | //first load the torso |
---|
| 86 | std::string name(filename + "/upper.md3"); |
---|
| 87 | PRINTF(0)("data dir: %s\n", ResourceManager::getInstance()->getFullName(name).c_str()); |
---|
| 88 | |
---|
| 89 | // this->md3Data = new MD3Data(name, name, scaling); |
---|
| 90 | this->md3Data = (MD3Data*)ResourceManager::getInstance()->load(name, MD3, RP_GAME, name, scaling); |
---|
| 91 | |
---|
| 92 | |
---|
| 93 | |
---|
[8581] | 94 | // load lower |
---|
| 95 | |
---|
| 96 | |
---|
[8580] | 97 | // load torso |
---|
| 98 | // name = FilenameUtils.getShortFilename(root.loadFilename); |
---|
| 99 | // if( name.find("lower") == 0 && (tagIndex=root.getTagIndexByName("tag_torso")) != -1) { |
---|
| 100 | // filename=searchForPath("upper" + FilenameUtils.getLODPostfix(name) + ".md3", false); |
---|
| 101 | // root=attachModel(root, tagIndex, filename, getInputStreamForPath(filename)); |
---|
| 102 | // } |
---|
| 103 | |
---|
| 104 | // load head |
---|
| 105 | // name=FilenameUtils.getShortFilename(root.loadFilename); |
---|
| 106 | // if (name.toLowerCase().startsWith("upper") && (tagIndex=root.getTagIndexByName("tag_head")) != -1) { |
---|
| 107 | // filename=searchForPath("head" + FilenameUtils.getLODPostfix(name) + ".md3", false); |
---|
| 108 | // attachModel(root, tagIndex, filename, getInputStreamForPath(filename)); |
---|
| 109 | // } |
---|
| 110 | |
---|
[8579] | 111 | } |
---|
[8549] | 112 | |
---|
[8563] | 113 | |
---|
[8579] | 114 | |
---|
[8563] | 115 | void MD3Model::tick(float time) |
---|
| 116 | { |
---|
| 117 | |
---|
[8567] | 118 | this->tick(time, this->md3Data); |
---|
[8563] | 119 | } |
---|
| 120 | |
---|
[8567] | 121 | |
---|
[8563] | 122 | void MD3Model::tick(float time, MD3Data* data) |
---|
| 123 | { |
---|
| 124 | // draw the bones if needed |
---|
| 125 | if( this->bDrawBones) |
---|
| 126 | { |
---|
| 127 | // get bone frame, interpolate if necessary |
---|
| 128 | if( data->animationState.interpolationFraction != 0.0 && |
---|
[8568] | 129 | data->animationState.currentFrame != data->animationState.nextFrame) |
---|
| 130 | { |
---|
[8563] | 131 | //interpolate bone frame |
---|
[8576] | 132 | this->tmpBoneFrame = this->interpolateBoneFrame(data->boneFrames[data->animationState.currentFrame], |
---|
| 133 | data->boneFrames[data->animationState.nextFrame], |
---|
| 134 | data->animationState.interpolationFraction); |
---|
[8568] | 135 | } |
---|
[8576] | 136 | else |
---|
| 137 | { |
---|
| 138 | this->tmpBoneFrame = data->boneFrames[data->animationState.currentFrame]; |
---|
| 139 | } |
---|
[8563] | 140 | } |
---|
| 141 | |
---|
| 142 | //draw all meshes of current frame of this model |
---|
[8566] | 143 | for( int i = 0; i < data->header->meshNum; i++) |
---|
[8563] | 144 | { |
---|
| 145 | MD3Mesh* mesh = data->meshes[i]; |
---|
| 146 | |
---|
| 147 | // get mesh frame, do interpolation if necessary |
---|
| 148 | sVec3D* frame; |
---|
| 149 | if( data->animationState.interpolationFraction != 0.0 && |
---|
[8576] | 150 | data->animationState.currentFrame != data->animationState.nextFrame) |
---|
| 151 | { |
---|
[8563] | 152 | //interpolate mesh frame between the 2 current mesh frames |
---|
| 153 | frame = this->interpolateMeshFrame( data->meshes[data->animationState.currentFrame]->meshFrames, |
---|
| 154 | data->meshes[data->animationState.nextFrame]->meshFrames, |
---|
| 155 | data->animationState.interpolationFraction, mesh, i); |
---|
[8576] | 156 | } |
---|
| 157 | else |
---|
| 158 | { |
---|
| 159 | //no interpolation needed, just draw current frame |
---|
| 160 | frame = &mesh->meshFrames[data->animationState.currentFrame]; |
---|
| 161 | } |
---|
[8577] | 162 | this->tmpMesh[i] = frame; |
---|
[8563] | 163 | |
---|
[8576] | 164 | // draw vertex normals if needed |
---|
| 165 | if( this->bDrawNormals) |
---|
| 166 | { |
---|
| 167 | // get vertex normals, interpolate if necessary |
---|
| 168 | if( data->animationState.interpolationFraction != 0.0 && |
---|
| 169 | data->animationState.currentFrame != data->animationState.nextFrame) |
---|
| 170 | { |
---|
| 171 | //interpolate vertex normals |
---|
| 172 | this->interpolateVertexNormals(&mesh->normals[data->animationState.currentFrame], |
---|
| 173 | &mesh->normals[data->animationState.nextFrame], |
---|
| 174 | data->animationState.interpolationFraction, mesh, i); |
---|
| 175 | } |
---|
| 176 | } |
---|
[8563] | 177 | } |
---|
| 178 | |
---|
| 179 | |
---|
| 180 | // draw all models linked to this model |
---|
| 181 | std::map<int, MD3Data*>::iterator it = data->sortedMap.begin(); |
---|
[8564] | 182 | int i = 0; |
---|
[8563] | 183 | while( it != data->sortedMap.end()) |
---|
| 184 | { |
---|
| 185 | MD3Data* child = it->second; |
---|
| 186 | |
---|
| 187 | //build transformation array m from matrix, interpolate if necessary |
---|
| 188 | float* m = new float[16]; |
---|
| 189 | |
---|
| 190 | MD3Tag* currFrameTag = data->boneFrames[data->animationState.currentFrame]->tags[child->parentTagIndex]; |
---|
| 191 | |
---|
| 192 | if( data->animationState.interpolationFraction != 0.0 && |
---|
| 193 | data->animationState.currentFrame != data->animationState.nextFrame) { |
---|
| 194 | //we need to interpolate |
---|
| 195 | MD3Tag* nextFrameTag = data->boneFrames[data->animationState.nextFrame]->tags[child->parentTagIndex]; |
---|
[8564] | 196 | m = this->interpolateTransformation(currFrameTag, nextFrameTag, data->animationState.interpolationFraction, i); |
---|
[8563] | 197 | } |
---|
| 198 | else { |
---|
[8567] | 199 | //no interpolation needed, stay with last transformation |
---|
| 200 | //OpenGL matrix is in column-major order |
---|
[8563] | 201 | m[0] = currFrameTag->matrix[0][0]; |
---|
| 202 | m[1] = currFrameTag->matrix[1][0]; |
---|
| 203 | m[2] = currFrameTag->matrix[2][0]; |
---|
| 204 | m[3] = 0.0f; |
---|
| 205 | m[4] = currFrameTag->matrix[0][1]; |
---|
| 206 | m[5] = currFrameTag->matrix[1][1]; |
---|
| 207 | m[6] = currFrameTag->matrix[2][1]; |
---|
| 208 | m[7] = 0.0f; |
---|
| 209 | m[8] = currFrameTag->matrix[0][2]; |
---|
| 210 | m[9] = currFrameTag->matrix[1][2]; |
---|
| 211 | m[10]= currFrameTag->matrix[2][2]; |
---|
| 212 | m[11]= 0.0f; |
---|
| 213 | m[12] = currFrameTag->position.x; |
---|
| 214 | m[13] = currFrameTag->position.y; |
---|
| 215 | m[14] = currFrameTag->position.z; |
---|
| 216 | m[15] = 1.0f; |
---|
| 217 | } |
---|
| 218 | |
---|
[8567] | 219 | //switch to child coord system |
---|
[8563] | 220 | glPushMatrix(); |
---|
| 221 | glMultMatrixf(m); |
---|
| 222 | |
---|
[8567] | 223 | // and draw child |
---|
| 224 | this->tick(time, child); |
---|
[8563] | 225 | |
---|
| 226 | glPopMatrix(); |
---|
[8564] | 227 | i++; |
---|
[8563] | 228 | } |
---|
| 229 | } |
---|
| 230 | |
---|
| 231 | |
---|
[8549] | 232 | /** |
---|
| 233 | * this draws the md3 model |
---|
| 234 | */ |
---|
[8565] | 235 | void MD3Model::draw() const |
---|
[8549] | 236 | { |
---|
| 237 | //draw current bone frame |
---|
[8565] | 238 | this->draw(this->md3Data); |
---|
[8550] | 239 | } |
---|
[8549] | 240 | |
---|
| 241 | |
---|
[8550] | 242 | /** |
---|
| 243 | * draw the md3model |
---|
| 244 | * @param data: the data to be drawn |
---|
| 245 | */ |
---|
[8565] | 246 | void MD3Model::draw(MD3Data* data) const |
---|
[8551] | 247 | { |
---|
[8556] | 248 | |
---|
| 249 | // draw the bones if needed |
---|
[8551] | 250 | if( this->bDrawBones) |
---|
| 251 | { |
---|
| 252 | // get bone frame, interpolate if necessary |
---|
| 253 | if( data->animationState.interpolationFraction != 0.0 && |
---|
| 254 | data->animationState.currentFrame != data->animationState.nextFrame) { |
---|
| 255 | //interpolate bone frame |
---|
[8565] | 256 | this->drawBoneFrame(this->tmpBoneFrame); |
---|
[8551] | 257 | } |
---|
| 258 | else { |
---|
| 259 | //stick with current bone frame |
---|
| 260 | this->drawBoneFrame(data->boneFrames[data->animationState.currentFrame]); |
---|
| 261 | } |
---|
| 262 | } |
---|
| 263 | |
---|
[8556] | 264 | |
---|
[8552] | 265 | //draw all meshes of current frame of this model |
---|
[8566] | 266 | for( int i = 0; i < data->header->meshNum; i++) |
---|
[8556] | 267 | { |
---|
[8552] | 268 | MD3Mesh* mesh = data->meshes[i]; |
---|
[8551] | 269 | |
---|
[8552] | 270 | // gl.glBlendFunc(mesh.GLSrcBlendFunc, mesh.GLDstBlendFunc); |
---|
| 271 | // gl.glDepthMask(mesh.GLDepthMask); |
---|
[8551] | 272 | |
---|
[8552] | 273 | if( mesh->header->textureNum > 0 && &mesh->material[0] != NULL) |
---|
| 274 | mesh->material[0].select(); |
---|
| 275 | |
---|
| 276 | // get mesh frame, do interpolation if necessary |
---|
[8565] | 277 | sVec3D* frame = this->tmpMesh[i]; |
---|
[8552] | 278 | |
---|
[8565] | 279 | this->drawMesh(mesh, frame); |
---|
[8564] | 280 | |
---|
[8565] | 281 | |
---|
[8556] | 282 | // draw vertex normals if needed |
---|
[8552] | 283 | if( this->bDrawNormals) { |
---|
| 284 | // get vertex normals, interpolate if necessary |
---|
| 285 | if( data->animationState.interpolationFraction != 0.0 && |
---|
| 286 | data->animationState.currentFrame != data->animationState.nextFrame) { |
---|
| 287 | //interpolate vertex normals |
---|
[8565] | 288 | this->drawVertexNormals(frame, this->tmpNormal[i]); |
---|
| 289 | } |
---|
| 290 | else { |
---|
| 291 | //stick with current vertex normals |
---|
| 292 | this->drawVertexNormals(frame, &mesh->normals[data->animationState.currentFrame]); |
---|
| 293 | } |
---|
[8552] | 294 | } |
---|
| 295 | } |
---|
| 296 | |
---|
| 297 | |
---|
[8556] | 298 | // draw all models linked to this model |
---|
[8565] | 299 | int i = 0; |
---|
[8552] | 300 | std::map<int, MD3Data*>::iterator it = data->sortedMap.begin(); |
---|
[8556] | 301 | while( it != data->sortedMap.end()) |
---|
| 302 | { |
---|
[8552] | 303 | MD3Data* child = it->second; |
---|
| 304 | |
---|
| 305 | //build transformation array m from matrix, interpolate if necessary |
---|
| 306 | float* m = new float[16]; |
---|
| 307 | |
---|
[8553] | 308 | MD3Tag* currFrameTag = data->boneFrames[data->animationState.currentFrame]->tags[child->parentTagIndex]; |
---|
| 309 | |
---|
| 310 | if( data->animationState.interpolationFraction != 0.0 && |
---|
| 311 | data->animationState.currentFrame != data->animationState.nextFrame) { |
---|
| 312 | //we need to interpolate |
---|
[8565] | 313 | m = this->tmpMatrix[i]; |
---|
[8553] | 314 | } |
---|
| 315 | else { |
---|
| 316 | //no interpolation needed, stay with last transformation |
---|
| 317 | //OpenGL matrix is in column-major order |
---|
| 318 | m[0] = currFrameTag->matrix[0][0]; |
---|
| 319 | m[1] = currFrameTag->matrix[1][0]; |
---|
| 320 | m[2] = currFrameTag->matrix[2][0]; |
---|
| 321 | m[3] = 0.0f; |
---|
| 322 | m[4] = currFrameTag->matrix[0][1]; |
---|
| 323 | m[5] = currFrameTag->matrix[1][1]; |
---|
| 324 | m[6] = currFrameTag->matrix[2][1]; |
---|
| 325 | m[7] = 0.0f; |
---|
| 326 | m[8] = currFrameTag->matrix[0][2]; |
---|
| 327 | m[9] = currFrameTag->matrix[1][2]; |
---|
| 328 | m[10]= currFrameTag->matrix[2][2]; |
---|
| 329 | m[11]= 0.0f; |
---|
| 330 | m[12] = currFrameTag->position.x; |
---|
| 331 | m[13] = currFrameTag->position.y; |
---|
| 332 | m[14] = currFrameTag->position.z; |
---|
| 333 | m[15] = 1.0f; |
---|
| 334 | } |
---|
[8556] | 335 | |
---|
| 336 | //switch to child coord system |
---|
| 337 | glPushMatrix(); |
---|
| 338 | glMultMatrixf(m); |
---|
| 339 | |
---|
| 340 | // and draw child |
---|
| 341 | this->draw(child); |
---|
| 342 | |
---|
| 343 | glPopMatrix(); |
---|
[8565] | 344 | i++; |
---|
[8552] | 345 | } |
---|
[8551] | 346 | } |
---|
| 347 | |
---|
| 348 | |
---|
[8552] | 349 | /** |
---|
| 350 | * draws the mesh |
---|
| 351 | */ |
---|
[8565] | 352 | void MD3Model::drawMesh(MD3Mesh* mesh, sVec3D* frame) const |
---|
[8562] | 353 | { |
---|
| 354 | glColor3f(1.0f, 1.0f, 1.0f); |
---|
[8579] | 355 | |
---|
| 356 | glBegin( GL_TRIANGLES); |
---|
[8568] | 357 | glScalef( 0.7f , 0.7f, 0.7f ); |
---|
[8552] | 358 | |
---|
[8565] | 359 | Vector tmpVec1, tmpVec2; |
---|
| 360 | |
---|
[8562] | 361 | // upload all triangles in the frame to OpenGL |
---|
[8579] | 362 | for( int t = 0; t < mesh->header->triangleNum; t++) |
---|
| 363 | { |
---|
[8562] | 364 | // calc normal vector |
---|
[8565] | 365 | tmpVec1.x = frame[mesh->triangles[t].vertexOffset[1]][0] - frame[mesh->triangles[t].vertexOffset[0]][0]; |
---|
[8579] | 366 | tmpVec1.y = frame[mesh->triangles[t].vertexOffset[1]][1] - frame[mesh->triangles[t].vertexOffset[0]][1]; |
---|
| 367 | tmpVec1.z = frame[mesh->triangles[t].vertexOffset[1]][2] - frame[mesh->triangles[t].vertexOffset[0]][2]; |
---|
| 368 | |
---|
[8565] | 369 | tmpVec2.x = frame[mesh->triangles[t].vertexOffset[2]][0] - frame[mesh->triangles[t].vertexOffset[0]][0]; |
---|
| 370 | tmpVec2.y = frame[mesh->triangles[t].vertexOffset[2]][1] - frame[mesh->triangles[t].vertexOffset[0]][1]; |
---|
| 371 | tmpVec2.z = frame[mesh->triangles[t].vertexOffset[2]][2] - frame[mesh->triangles[t].vertexOffset[0]][2]; |
---|
[8562] | 372 | |
---|
[8565] | 373 | Vector normal = tmpVec1.cross(tmpVec2); |
---|
[8562] | 374 | normal.normalize(); |
---|
| 375 | |
---|
[8579] | 376 | // PRINTF(0)("normal: %f, %f, %f\n", normal.x, normal.y, normal.z); |
---|
| 377 | |
---|
[8562] | 378 | glNormal3f(normal.x, normal.y, normal.z); |
---|
| 379 | glTexCoord2fv( mesh->texVecs[mesh->triangles[t].vertexOffset[0]].textureCoord); |
---|
| 380 | glVertex3f( frame[mesh->triangles[t].vertexOffset[0]][0], |
---|
[8578] | 381 | frame[mesh->triangles[t].vertexOffset[0]][2], |
---|
| 382 | frame[mesh->triangles[t].vertexOffset[0]][1]); |
---|
[8579] | 383 | |
---|
| 384 | glNormal3f(normal.x, normal.y, normal.z); |
---|
[8562] | 385 | glTexCoord2fv( mesh->texVecs[mesh->triangles[t].vertexOffset[1]].textureCoord); |
---|
| 386 | glVertex3f( frame[mesh->triangles[t].vertexOffset[1]][0], |
---|
[8578] | 387 | frame[mesh->triangles[t].vertexOffset[1]][2], |
---|
| 388 | frame[mesh->triangles[t].vertexOffset[1]][1]); |
---|
[8579] | 389 | |
---|
| 390 | glNormal3f(normal.x, normal.y, normal.z); |
---|
[8562] | 391 | glTexCoord2fv( mesh->texVecs[mesh->triangles[t].vertexOffset[2]].textureCoord); |
---|
| 392 | glVertex3f( frame[mesh->triangles[t].vertexOffset[2]][0], |
---|
[8578] | 393 | frame[mesh->triangles[t].vertexOffset[2]][2], |
---|
| 394 | frame[mesh->triangles[t].vertexOffset[2]][1]); |
---|
[8562] | 395 | } |
---|
[8579] | 396 | glEnd(); |
---|
[8562] | 397 | |
---|
| 398 | } |
---|
| 399 | |
---|
| 400 | |
---|
[8552] | 401 | /** |
---|
| 402 | * drawo vertex normals |
---|
| 403 | */ |
---|
[8565] | 404 | void MD3Model::drawVertexNormals(sVec3D* frame, MD3Normal* normals) const |
---|
[8552] | 405 | {} |
---|
| 406 | |
---|
| 407 | |
---|
| 408 | /** |
---|
[8557] | 409 | * draw bone frame |
---|
| 410 | */ |
---|
[8565] | 411 | void MD3Model::drawBoneFrame(MD3BoneFrame* frame) const |
---|
[8561] | 412 | { |
---|
| 413 | float x1 = frame->mins.x; |
---|
| 414 | float y1 = frame->mins.y; |
---|
| 415 | float z1 = frame->mins.z; |
---|
| 416 | float x2 = frame->maxs.x; |
---|
| 417 | float y2 = frame->maxs.y; |
---|
| 418 | float z2 = frame->maxs.z; |
---|
[8557] | 419 | |
---|
[8579] | 420 | glPushAttrib(GL_TEXTURE_2D); |
---|
| 421 | glPushAttrib(GL_LIGHTING); |
---|
[8557] | 422 | |
---|
[8561] | 423 | glColor3f(1.0f,0.0f,0.0f); |
---|
| 424 | glPointSize(6.0f); |
---|
| 425 | |
---|
| 426 | glBegin(GL_POINTS); |
---|
| 427 | glVertex3f(frame->position.x, frame->position.y, frame->position.z); |
---|
| 428 | glEnd(); |
---|
| 429 | glPointSize(1.0f); |
---|
| 430 | |
---|
| 431 | glColor3f(0.0f,1.0f,0.0f); |
---|
| 432 | glBegin(GL_LINE_LOOP); |
---|
| 433 | glVertex3f(x1,y1,z1); |
---|
| 434 | glVertex3f(x1,y1,z2); |
---|
| 435 | glVertex3f(x1,y2,z2); |
---|
| 436 | glVertex3f(x1,y2,z1); |
---|
| 437 | glEnd(); |
---|
| 438 | |
---|
| 439 | glBegin(GL_LINE_LOOP); |
---|
| 440 | glVertex3f(x2,y2,z2); |
---|
| 441 | glVertex3f(x2,y1,z2); |
---|
| 442 | glVertex3f(x2,y1,z1); |
---|
| 443 | glVertex3f(x2,y2,z1); |
---|
| 444 | glEnd(); |
---|
| 445 | |
---|
| 446 | glBegin(GL_LINES); |
---|
| 447 | glVertex3f(x1,y1,z1); |
---|
| 448 | glVertex3f(x2,y1,z1); |
---|
| 449 | |
---|
| 450 | glVertex3f(x1,y1,z2); |
---|
| 451 | glVertex3f(x2,y1,z2); |
---|
| 452 | |
---|
| 453 | glVertex3f(x1,y2,z2); |
---|
| 454 | glVertex3f(x2,y2,z2); |
---|
| 455 | |
---|
| 456 | glVertex3f(x1,y2,z1); |
---|
| 457 | glVertex3f(x2,y2,z1); |
---|
| 458 | glEnd(); |
---|
| 459 | |
---|
[8579] | 460 | glPopAttrib(); |
---|
| 461 | glPopAttrib(); |
---|
[8561] | 462 | } |
---|
| 463 | |
---|
| 464 | |
---|
[8557] | 465 | /** |
---|
[8552] | 466 | * interpolate bone frame |
---|
[8556] | 467 | * @param currBoneFrame Start bone frame. |
---|
| 468 | * @param nextBoneFrame End bone frame. |
---|
| 469 | * @param frac Interpolation fraction, in [0,1]. |
---|
[8552] | 470 | */ |
---|
[8553] | 471 | MD3BoneFrame* MD3Model::interpolateBoneFrame(MD3BoneFrame* currBoneFrame, MD3BoneFrame* nextBoneFrame, float frac) |
---|
[8556] | 472 | { |
---|
| 473 | this->tmpBoneFrame->mins.x = (1.0f - frac) * currBoneFrame->mins.x + frac * nextBoneFrame->mins.x; |
---|
| 474 | this->tmpBoneFrame->maxs.x = (1.0f - frac) * currBoneFrame->maxs.x + frac * nextBoneFrame->maxs.x; |
---|
| 475 | this->tmpBoneFrame->position.x = (1.0f - frac) * currBoneFrame->position.x + frac * nextBoneFrame->position.x; |
---|
| 476 | this->tmpBoneFrame->mins.y = (1.0f - frac) * currBoneFrame->mins.y + frac * nextBoneFrame->mins.y; |
---|
| 477 | this->tmpBoneFrame->maxs.y = (1.0f - frac) * currBoneFrame->maxs.y + frac * nextBoneFrame->maxs.y; |
---|
| 478 | this->tmpBoneFrame->position.y = (1.0f - frac) * currBoneFrame->position.y + frac * nextBoneFrame->position.y; |
---|
| 479 | this->tmpBoneFrame->mins.z = (1.0f - frac) * currBoneFrame->mins.z + frac * nextBoneFrame->mins.z; |
---|
| 480 | this->tmpBoneFrame->maxs.z = (1.0f - frac) * currBoneFrame->maxs.z + frac * nextBoneFrame->maxs.z; |
---|
| 481 | this->tmpBoneFrame->position.z = (1.0f - frac) * currBoneFrame->position.z + frac * nextBoneFrame->position.z; |
---|
[8549] | 482 | |
---|
[8556] | 483 | return this->tmpBoneFrame; |
---|
| 484 | } |
---|
| 485 | |
---|
| 486 | |
---|
[8563] | 487 | |
---|
[8552] | 488 | /** |
---|
[8557] | 489 | * interpolate mesh frame |
---|
[8552] | 490 | */ |
---|
[8563] | 491 | sVec3D* MD3Model::interpolateMeshFrame(sVec3D* currMeshFrame, sVec3D* nextMeshFrame, float frac, MD3Mesh* mesh, int i) |
---|
[8557] | 492 | { |
---|
| 493 | int vertexNum = mesh->header->vertexNum; |
---|
[8549] | 494 | |
---|
[8557] | 495 | // calc interpolated vertices |
---|
| 496 | for( int t = 0; t < vertexNum * 3.0f; t++) |
---|
| 497 | { |
---|
[8576] | 498 | |
---|
| 499 | // PRINTF(0)("tmp mesh: %f, %f, %f\n", this->tmpMesh[i][t][0], this->tmpMesh[i][t][1], this->tmpMesh[i][t][2]); |
---|
| 500 | |
---|
[8563] | 501 | this->tmpMesh[i][t][0] = (1.0f - frac) * currMeshFrame[t][0] + frac * nextMeshFrame[t][0]; |
---|
| 502 | this->tmpMesh[i][t][1] = (1.0f - frac) * currMeshFrame[t][1] + frac * nextMeshFrame[t][1]; |
---|
| 503 | this->tmpMesh[i][t][2] = (1.0f - frac) * currMeshFrame[t][2] + frac * nextMeshFrame[t][2]; |
---|
[8557] | 504 | } |
---|
[8549] | 505 | |
---|
[8563] | 506 | return this->tmpMesh[i]; |
---|
[8557] | 507 | } |
---|
[8551] | 508 | |
---|
[8552] | 509 | |
---|
| 510 | /** |
---|
| 511 | * interpolate vertex normal |
---|
| 512 | */ |
---|
[8565] | 513 | MD3Normal* MD3Model::interpolateVertexNormals(MD3Normal* currNormals, MD3Normal* nextNormals, float frac, MD3Mesh* mesh, int i) |
---|
[8558] | 514 | { |
---|
[8565] | 515 | for( int j = 0; j < mesh->header->vertexNum; j++) |
---|
[8558] | 516 | { |
---|
[8565] | 517 | this->tmpNormal[i][j].vertexNormal[0] = (int)((1.0f - frac) * currNormals[j].vertexNormal[0] + frac * nextNormals[j].vertexNormal[0]); |
---|
| 518 | this->tmpNormal[i][j].vertexNormal[1] = (int)((1.0f - frac) * currNormals[j].vertexNormal[1] + frac * nextNormals[j].vertexNormal[1]); |
---|
[8558] | 519 | } |
---|
[8552] | 520 | |
---|
[8565] | 521 | return this->tmpNormal[i]; |
---|
[8558] | 522 | } |
---|
[8552] | 523 | |
---|
[8558] | 524 | |
---|
[8553] | 525 | /** |
---|
| 526 | * interpolate transformation |
---|
| 527 | */ |
---|
[8564] | 528 | float* MD3Model::interpolateTransformation(MD3Tag* currFrameTag, MD3Tag* nextFrameTag, float frac, int i) |
---|
[8560] | 529 | { |
---|
| 530 | // interpolate position |
---|
| 531 | Vector interpolatedPosition = currFrameTag->position * (1.0f - frac) + nextFrameTag->position * frac; |
---|
[8553] | 532 | |
---|
| 533 | |
---|
[8560] | 534 | // interpolate rotation matrix |
---|
| 535 | float currRot[4][4]; |
---|
| 536 | float nextRot[4][4]; |
---|
| 537 | float interpolatedMatrix[4][4]; |
---|
| 538 | |
---|
| 539 | Quaternion currQuat(currFrameTag->matrix); currQuat.matrix(currRot); |
---|
| 540 | Quaternion nextQuat(nextFrameTag->matrix); nextQuat.matrix(nextRot); |
---|
| 541 | |
---|
| 542 | Quaternion interpolatedQuat = Quaternion::quatSlerp(currQuat, nextQuat, frac); interpolatedQuat.matrix(interpolatedMatrix); |
---|
| 543 | |
---|
| 544 | // quaternion code is column based, so use transposed matrix when spitting out to gl |
---|
[8564] | 545 | this->tmpMatrix[i][0] = interpolatedMatrix[0][0]; |
---|
| 546 | this->tmpMatrix[i][4] = interpolatedMatrix[1][0]; |
---|
| 547 | this->tmpMatrix[i][8] = interpolatedMatrix[2][0]; |
---|
| 548 | this->tmpMatrix[i][12] = interpolatedPosition.x; |
---|
| 549 | this->tmpMatrix[i][1] = interpolatedMatrix[0][1]; |
---|
| 550 | this->tmpMatrix[i][5] = interpolatedMatrix[1][1]; |
---|
| 551 | this->tmpMatrix[i][9] = interpolatedMatrix[2][1]; |
---|
| 552 | this->tmpMatrix[i][13] = interpolatedPosition.y; |
---|
| 553 | this->tmpMatrix[i][2] = interpolatedMatrix[0][2]; |
---|
| 554 | this->tmpMatrix[i][6] = interpolatedMatrix[1][2]; |
---|
| 555 | this->tmpMatrix[i][10]= interpolatedMatrix[2][2]; |
---|
| 556 | this->tmpMatrix[i][14] = interpolatedPosition.z; |
---|
| 557 | this->tmpMatrix[i][3] = 0.0f; |
---|
| 558 | this->tmpMatrix[i][7] = 0.0f; |
---|
| 559 | this->tmpMatrix[i][11]= 0.0f; |
---|
| 560 | this->tmpMatrix[i][15] = 1.0f; |
---|
[8560] | 561 | |
---|
[8564] | 562 | return this->tmpMatrix[i]; |
---|
[8560] | 563 | |
---|
| 564 | } |
---|
| 565 | |
---|
| 566 | |
---|
[8351] | 567 | } |
---|