Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/importer/md3/md3_data.cc @ 8697

Last change on this file since 8697 was 8490, checked in by patrick, 18 years ago

merged the bsp branche back to trunk

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