Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/bsp_model/src/lib/graphics/importer/md3/md3_data.cc @ 8637

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

bsp: all md3 submodels are now correctly drawn, fixed the bug. now trying to do some nicer drawing and right model assembling

File size: 14.8 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_data.h"
18
19#include "md3_bone_frame.h"
20#include "md3_tag.h"
21#include "md3_mesh.h"
22
23#include "material.h"
24
25#include "debug.h"
26
27namespace md3
28{
29
30/********************************************************************************
31 *   MD3Data                                                                    *
32 ********************************************************************************/
33
34/**
35  \brief simple constructor
36*/
37MD3Data::MD3Data(const std::string& modelFileName, const std::string& skinFileName, float scale)
38{
39  this->filename = filename;
40
41  this->parentTagIndex = -1;
42  this->parent = NULL;
43
44  this->animationState.currentFrame = 0;
45  this->animationState.nextFrame = 1;
46  this->animationState.interpolationFraction = 0.0f;
47
48  this->loadModel(modelFileName);
49//   this->loadSkin(skinFileName);
50  this->init();
51}
52
53
54/**
55  \brief simple destructor
56
57  this will clean out all the necessary data for a specific md2model
58*/
59MD3Data::~MD3Data()
60{
61  delete this->header;
62}
63
64
65/**
66 * init data
67 */
68void MD3Data::init()
69{
70  // create the temporary data to work with (interpolation data)
71  this->tmpBoneFrame = new MD3BoneFrame();
72
73  this->tmpMesh = new sVec3D*[this->header->meshNum];
74  for( int i = 0; i < this->header->meshNum; i++)
75    this->tmpMesh[i] = new sVec3D[this->meshes[i]->header->vertexNum];
76
77  this->tmpNormal = new MD3Normal*[this->header->meshNum];
78  for( int i = 0; i < this->header->meshNum; i++)
79    this->tmpNormal[i] = new MD3Normal[this->meshes[i]->header->vertexNum];
80
81  this->tmpMatrix = new float*[this->header->tagNum];
82  for( int i = 0; i < this->header->tagNum; i++)
83    this->tmpMatrix[i] = new float[16];
84
85}
86
87
88/**
89 * link a model at the specified tag position to this model. if the position is already
90 * occupied, the old submodel will be replaced
91 *
92 *  @param tagIndex: tag to link the submodel to
93 *  @param child: the submodel that should be linked to this model
94 */
95void MD3Data::addLinkedModel(int tagIndex, MD3Data* child)
96{
97  this->sortedMap[tagIndex] = child;
98  child->parentTagIndex = tagIndex;
99}
100
101
102
103/**
104 * Return the index of the tag with the given name for this model.
105 *
106 * This will return -1 if their is no such tag.
107 */
108 int MD3Data::getTagIndexByName(std::string tagName)
109{
110   int res = -1;
111
112   if( this->header->boneFrameNum > 0) {
113     MD3Tag** tags = this->boneFrames[0]->tags;
114     for( int i = 0; i < this->header->tagNum; i++)
115       if( tags[i]->name.find(tagName) == std::string::npos)
116         return i;
117   }
118
119   return res;
120 }
121
122
123
124/**
125  \brief this will load the whole model data (vertices, opengl command list, ...)
126* @param fileName: the name of the model file
127  \return true if success
128*/
129bool MD3Data::loadModel(const std::string& fileName)
130{
131  FILE *pFile;                            //file stream
132//  char* buffer;                           //buffer for frame data
133  int fileOffset = 0;                     // file data offset
134
135
136  //! @todo this chek should include deleting a loaded model (eventually)
137  if (fileName.empty())
138    return false;
139
140  PRINTF(0)("opening file: %s\n", fileName.c_str());
141  pFile = fopen(fileName.c_str(), "rb");
142  if( unlikely(!pFile))
143    {
144      PRINTF(1)("Couldn't open the MD3 File for loading. Exiting.\n");
145      return false;
146    }
147  fileOffset += this->readHeader(pFile, fileOffset);
148  /* check for the header version: make sure its a md2 file :) */
149  if( unlikely(this->header->version != MD3_VERSION) && unlikely(this->header->ident != MD3_IDENT))
150    {
151      PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName.c_str());
152      return false;
153    }
154
155
156    // check if the filesize is correct
157    if( this->header->fileSize > this->header->tagStart &&
158        this->header->fileSize >= this->header->meshStart)
159    {
160      bool bBoneFrames, bTags, bMeshes;
161      bBoneFrames = ( this->header->boneFrameNum == 0);
162      bTags = ( this->header->tagNum == 0);
163      bMeshes = ( this->header->meshNum == 0);
164
165      // read different parts of the model in correct order
166      while( !(bBoneFrames && bTags && bMeshes))
167      {
168        printf("while, fileOffset = %i\n", fileOffset);
169        if( fileOffset == this->header->boneFrameStart && !bBoneFrames)
170        {
171          fileOffset += this->readBoneFrames(pFile, fileOffset);
172          bBoneFrames = true;
173        }
174        else if( fileOffset == this->header->tagStart && !bTags)
175        {
176          fileOffset += this->readTags(pFile, fileOffset);
177          bTags = true;
178        }
179        else if( fileOffset == this->header->meshStart && !bMeshes)
180        {
181          fileOffset += this->readMeshes(pFile, fileOffset);
182          bMeshes = true;
183        }
184      }
185
186    }
187
188  fclose(pFile);
189
190  return true;
191}
192
193
194/**
195  \brief loads the skin/material stuff
196* @param fileName: name of the skin file
197  \return true if success
198*/
199bool MD3Data::loadSkin(const std::string& fileName)
200{
201//   if( fileName.empty())
202//     {
203//       this->skinFileName = "";
204//       return false;
205//     }
206//
207//   this->skinFileName = fileName;
208//
209//   this->material.setName("md2ModelMaterial");
210//   this->material.setDiffuseMap(fileName);
211//   this->material.setIllum(3);
212//   this->material.setAmbient(1.0, 1.0, 1.0);
213
214  return true;
215}
216
217
218/**
219 * read heaader
220 */
221int MD3Data::readHeader(FILE* pFile, int fileOffset)
222{
223  PRINTF(0)("Reading Header\n");
224
225  this->header = new MD3Header;
226  fread(this->header, 1, sizeof(MD3Header), pFile);
227
228    //header debug:
229  PRINTF(0)("MD3 Header debug section======================================\n");
230  printf("ident: %i\n", this->header->ident);
231  printf("version: %i\n", this->header->version);
232  printf("filename: %s\n", this->header->filename);
233  printf("boneFrameNum: %i\n", this->header->boneFrameNum);
234  printf("tag number: %i\n", this->header->tagNum);
235  printf("mesh number: %i\n", this->header->meshNum);
236  printf("max tex num: %i\n", this->header->maxTexNum);
237  printf("bone frame start: %i\n", this->header->boneFrameStart);
238  printf("tag start: %i\n", this->header->tagStart);
239  printf("mesh start: %i\n", this->header->meshStart);
240  printf("fileSize: %i\n", this->header->fileSize);
241
242  return sizeof(MD3Header);
243}
244
245
246/**
247 * read bone frames
248 */
249int MD3Data::readBoneFrames(FILE* pFile, int fileOffset)
250{
251  PRINTF(0)("Reading Bone Frames\n");
252
253  this->boneFrames = new MD3BoneFrame*[this->header->boneFrameNum];
254
255  for( int i = 0; i < this->header->boneFrameNum; i++)
256  {
257    this->boneFrames[i] = new MD3BoneFrame(i);
258
259    MD3BoneFrameData* md = new MD3BoneFrameData;
260    fread(md, 1, sizeof(MD3BoneFrameData), pFile);
261    this->boneFrames[i]->data = md;
262  }
263
264  return this->header->boneFrameNum * sizeof(MD3BoneFrameData);
265}
266
267
268/**
269 * read the tags
270 */
271int MD3Data::readTags(FILE* pFile, int fileOffset)
272{
273  PRINTF(0)("Reading Tags\n");
274
275  for( int i = 0; i < this->header->boneFrameNum; i++)
276  {
277    this->boneFrames[i]->tags = new MD3Tag*[this->header->tagNum];
278
279    for( int j = 0; j < this->header->tagNum; j++)
280    {
281      this->boneFrames[i]->tags[j] = new MD3Tag();
282      MD3TagData* md = new MD3TagData;
283      fread(md, 1, sizeof(MD3TagData), pFile);
284      this->boneFrames[i]->tags[j]->data = md;
285
286      this->boneFrames[i]->tags[j]->name = std::string(this->boneFrames[i]->tags[j]->data->name);
287      this->boneFrames[i]->tags[j]->position = Vector( this->boneFrames[i]->tags[j]->data->position[0],
288                                                       this->boneFrames[i]->tags[j]->data->position[1],
289                                                       this->boneFrames[i]->tags[j]->data->position[2]);
290      for( int k = 0; k < 3; k++)
291        for( int l = 0; l < 3; l++)
292          this->boneFrames[i]->tags[j]->matrix[k][l] = this->boneFrames[i]->tags[j]->data->matrix[k][l];
293
294      //PRINTF(0)("Tag name: %s\n", this->boneFrames[i]->tags[j]->name.c_str());
295    }
296  }
297
298  return this->header->boneFrameNum * this->header->tagNum * sizeof(MD3TagData);
299}
300
301
302/**
303 * read meshes
304 */
305int MD3Data::readMeshes(FILE* pFile, int fileOffset)
306{
307  PRINTF(0)("Reading Mesh Data\n");
308
309  fileOffset = 0;
310
311  this->meshes = new MD3Mesh*[this->header->meshNum];
312
313  for( int i = 0; i < this->header->meshNum; i++)
314  {
315    this->meshes[i] = new MD3Mesh();
316
317    int localFileOffset = 0;
318    bool   bTriangles, bTexVecs, bVertices, bTextures;            //!< the parts that have been read so far
319
320    //start reading mesh data
321    MD3MeshHeader* md = new MD3MeshHeader;
322    fread(md, 1, sizeof(MD3MeshHeader), pFile);
323    this->meshes[i]->header = md;
324    localFileOffset += sizeof(MD3MeshHeader);
325
326    PRINTF(0)("MD3 Mesh Header debug section\n");
327    printf("ident: %i\n", md->id);
328    printf("filename: %s\n", md->name);
329    printf("meshFrameNum: %i\n", md->meshFrameNum);
330    printf("textureNum: %i\n", md->textureNum);
331    printf("vertexNum: %i \n", md->vertexNum);
332    printf("triangleNum: %i\n", md->triangleNum);
333    printf("triangleStart: %i\n", md->triangleStart);
334    printf("textureStart: %i\n", md->textureStart);
335    printf("texVecStart: %i\n", md->texVecStart);
336    printf("vertexStart: %i\n", md->vertexStart);
337    printf("fileSize: %i\n", md->meshSize);
338
339    if( unlikely(this->meshes[i]->header->id != MD3_IDENT))
340    {
341      PRINTF(1)("Wrong MD3 mesh file tag, file %s could be corrupt\n", this->filename.c_str());
342      return false;
343    }
344
345    // check which parts to be loaded
346    bTriangles = ( this->meshes[i]->header->triangleNum == 0);
347    bTexVecs = ( this->meshes[i]->header->vertexNum == 0);
348    bVertices = ( this->meshes[i]->header->meshFrameNum == 0);
349    bTextures = ( this->meshes[i]->header->textureNum == 0);
350
351    // now read the data block whise
352    while( !(bTriangles && bTexVecs && bVertices && bTextures))
353    {
354      PRINTF(0)("while2: localOffset = %i\n", localFileOffset);
355      if( localFileOffset == this->meshes[i]->header->triangleStart  && !bTriangles)
356      {
357        localFileOffset += this->readMeshTriangles(pFile, localFileOffset, i);
358        bTriangles = true;
359      }
360      else if( localFileOffset == this->meshes[i]->header->textureStart && !bTextures)
361      {
362        localFileOffset += this->readMeshTextures(pFile, localFileOffset, i);
363        bTextures = true;
364      }
365      else if( localFileOffset == this->meshes[i]->header->texVecStart && !bTexVecs)
366      {
367        localFileOffset += this->readMeshTexVecs(pFile, localFileOffset, i);
368        bTexVecs = true;
369      }
370      else if( localFileOffset == this->meshes[i]->header->vertexStart && !bVertices)
371      {
372        localFileOffset += this->readMeshVertices(pFile, localFileOffset, i);
373        bVertices = true;
374      }
375    }
376    fileOffset += localFileOffset;
377    PRINTF(0)("finished reading mesh %i, got %i of %i byes\n", i, localFileOffset, md->meshSize);
378  }
379  return fileOffset;
380}
381
382
383
384/**
385 * reading in the mesh triangles
386 */
387int MD3Data::readMeshTriangles(FILE* pFile, int fileOffset, int mesh)
388{
389  PRINTF(0)("Reading Mesh Triangles\n");
390  // create the memomry to save the triangles
391  this->meshes[mesh]->triangles = new MD3Triangle[this->meshes[mesh]->header->triangleNum];
392  fread(this->meshes[mesh]->triangles, 1, sizeof(MD3Triangle) * this->meshes[mesh]->header->triangleNum, pFile);
393
394//   for( int i = 0; i < this->meshes[mesh]->header->triangleNum; i++) {
395//     PRINTF(0)("Triangle read: %i, %i, %i\n", this->meshes[mesh]->triangles[i].vertexOffset[0], this->meshes[mesh]->triangles[i].vertexOffset[1]
396//         , this->meshes[mesh]->triangles[i].vertexOffset[2]);
397//   }
398
399  return this->meshes[mesh]->header->triangleNum * sizeof(MD3Triangle);
400}
401
402
403/**
404 * reading in the mesh textures
405 */
406int MD3Data::readMeshTextures(FILE* pFile, int fileOffset, int mesh)
407{
408  PRINTF(0)("Reading Mesh Textures\n");
409
410  // create the textures
411  this->meshes[mesh]->material = new Material[this->meshes[mesh]->header->textureNum];
412
413  MD3Texture* tex = new MD3Texture[this->meshes[mesh]->header->textureNum];
414  fread(tex, 1, sizeof(MD3Texture) * this->meshes[mesh]->header->textureNum, pFile);
415
416  for( int i = 0; i < this->meshes[mesh]->header->textureNum; i++) {
417    PRINTF(0)(" texture file: %s\n", tex[i].fileName);
418#warning texture stuff hard coded. make this again
419    std::string path("/home/boenzlip/tmp/q3/Downloads/MOH/q3mdl-alien3/");
420    std::string path1(tex[i].fileName);
421    std::string fullPath( path + path1);
422    this->meshes[mesh]->material[i].setDiffuseMap(/*tex[i].fileName*/ /*fullPath.c_str()*/ "maps/creatures/gork/gorkup.tga");
423    this->meshes[mesh]->material[i].setAmbient(1, 1, 1);
424  }
425
426  return this->meshes[mesh]->header->textureNum * sizeof(MD3Texture);
427}
428
429
430/**
431 * reading in the mesh tex vecs
432 */
433int MD3Data::readMeshTexVecs(FILE* pFile, int fileOffset, int mesh)
434{
435  PRINTF(0)("Reading Mesh TexVecs\n");
436
437  this->meshes[mesh]->texVecs = new MD3TexVecs[this->meshes[mesh]->header->vertexNum];
438  fread(this->meshes[mesh]->texVecs, 1, sizeof(MD3TexVecs) * this->meshes[mesh]->header->vertexNum, pFile);
439
440//   for( int i = 0; i < this->meshes[mesh]->header->vertexNum; i++)  {
441//     PRINTF(0)("TexVec read: %f, %f\n", this->meshes[mesh]->texVecs[i].textureCoord[0], this->meshes[mesh]->texVecs[i].textureCoord[0]);
442//   }
443
444  return this->meshes[mesh]->header->vertexNum * sizeof(MD3TexVecs);
445}
446
447
448/**
449 * reading in the mesh vertices
450 */
451int MD3Data::readMeshVertices(FILE* pFile, int fileOffset, int mesh)
452{
453  PRINTF(0)("Reading Mesh Vertices\n");
454
455  // reserver memory for the vertex informations
456  this->meshes[mesh]->meshFrames = new sVec3D[this->meshes[mesh]->header->meshFrameNum * this->meshes[mesh]->header->vertexNum];
457  this->meshes[mesh]->normals = new MD3Normal[this->meshes[mesh]->header->meshFrameNum * this->meshes[mesh]->header->vertexNum];
458
459  for( int i = 0; i < this->meshes[mesh]->header->meshFrameNum * this->meshes[mesh]->header->vertexNum; i++)
460  {
461    // read out the compressed data
462    MD3VertexCompressed* vc = new MD3VertexCompressed;
463    fread(vc, 1, sizeof(MD3VertexCompressed), pFile);
464
465    this->meshes[mesh]->meshFrames[i][0] = (float)vc->vector[0] / 64.0f;
466    this->meshes[mesh]->meshFrames[i][1] = (float)vc->vector[1] / 64.0f;
467    this->meshes[mesh]->meshFrames[i][2] = (float)vc->vector[2] / 64.0f;
468
469    this->meshes[mesh]->normals[i].vertexNormal[0] = (int)vc->vertexNormal[0];
470    this->meshes[mesh]->normals[i].vertexNormal[1] = (int)vc->vertexNormal[1];
471
472//     PRINTF(0)("nr: %i, meshframes: %f, %f, %f, normal: %f, %f\n", i, this->meshes[mesh]->meshFrames[i][0], this->meshes[mesh]->meshFrames[i][1],
473//     this->meshes[mesh]->meshFrames[i][2], this->meshes[mesh]->normals[i].vertexNormal[0], this->meshes[mesh]->normals[i].vertexNormal[1]);
474
475    delete vc;
476  }
477
478  return this->meshes[mesh]->header->meshFrameNum * this->meshes[mesh]->header->vertexNum * sizeof(MD3VertexCompressed);
479}
480
481
482
483}
484
485
486
487
488
489
490
Note: See TracBrowser for help on using the repository browser.