Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

bsp: bone frame animation, slow start

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