Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/importer/objModel.cc @ 4038

Last change on this file since 4038 was 4038, checked in by bensch, 20 years ago

orxonox/trunk: seg-fault-prevention, and cleanup of model.cc

File size: 6.9 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: Benjamin Grauer
13   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
17
18#include "objModel.h"
19
20#include <stdio.h>
21#include <string.h>
22#include <stdlib.h>
23
24#define PARSELINELENGTH 8192
25
26#include "debug.h"
27#include "compiler.h"
28
29/**
30   \brief Crates a 3D-Model, loads in a File and scales it.
31   \param fileName file to parse and load (must be a .obj file)
32   \param scaling The factor that the model will be scaled with.
33*/
34OBJModel::OBJModel(const char* fileName, float scaling) : Model(fileName)
35{
36  this->initializeOBJ();
37  this->scaleFactor = scaling;
38
39  this->importFile (fileName);
40
41  this->finalize();
42}
43
44/**
45   \brief deletes an OBJModel.
46
47   Looks if any from model allocated space is still in use, and if so deleted it.
48*/
49OBJModel::~OBJModel()
50{
51  PRINTF(4)("Deleting the obj-names\n");
52  if (this->objPath)
53    delete []this->objPath;
54  if (this->objFileName)
55    delete []this->objFileName;
56  if (this->mtlFileName)
57    delete []this->mtlFileName;
58}
59
60/**
61   \brief Initializes an obj-model
62*/
63void OBJModel::initializeOBJ(void)
64{
65  this->objPath = NULL;
66  this->objFileName = NULL;
67  this->mtlFileName = NULL;
68}
69
70/**
71   \brief Imports a obj file and handles the the relative location
72   \param fileName The file to import
73*/
74bool OBJModel::importFile (const char* fileName)
75{
76  PRINTF(4)("preparing to read in file: %s\n", fileName);
77
78
79#ifdef __WIN32__
80  // win32 path reading
81  char pathSplitter= '\\';
82#else /* __WIN32__ */
83  // unix path reading
84  char pathSplitter='/';
85#endif /* __WIN32__ */
86  char* tmpName;
87  strcpy(tmpName, fileName);
88  if (tmpName[0] == pathSplitter)
89    tmpName++;
90  char* name = tmpName;
91  while (( tmpName = strchr (tmpName+1, pathSplitter)))
92    {
93      name = tmpName+1;
94    }
95  this->objPath = new char[name-fileName+1];
96  strncpy(this->objPath, fileName, name-fileName);
97  this->objPath[name-fileName] = '\0';
98  if (strlen(objPath)> 0)
99    PRINTF(5)("Resolved file %s to folder: %s.\n", name, objPath);
100  else
101    PRINTF(5)("Resolved file %s.\n", name);
102 
103  this->setName(name);
104
105  this->objFileName = new char[strlen(name)+1];
106  strcpy (this->objFileName, name);
107  this->readFromObjFile ();
108  return true;
109}
110
111/**
112   \brief Reads in the .obj File and sets all the Values.
113   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
114*/
115bool OBJModel::readFromObjFile (void)
116{
117  char* fileName = new char [strlen(objPath)+strlen(objFileName)+1];
118  if (this->objFileName != NULL && !strcmp(this->objFileName, ""))
119    return false;
120  strcpy(fileName, this->objPath);
121  strcat(fileName, this->objFileName);
122
123  FILE* stream;
124  if( (stream = fopen (fileName, "r")) == NULL)
125    {
126      printf("IniParser could not open %s\n", fileName);
127      return false;
128    }
129
130  char buffer[PARSELINELENGTH];
131  while(fgets(buffer, PARSELINELENGTH, stream))
132    {
133      // line termiated with \0 not \n
134      if (buffer[strlen(buffer)-1] == '\n')
135        buffer[strlen(buffer)-1] = '\0';
136
137      // case vertice
138      if (!strncmp(buffer, "v ", 2))
139        {
140          this->addVertex(buffer+2);
141        }
142
143      // case face
144      else if (!strncmp(buffer, "f ", 2))
145        {
146          this->addFace (buffer+2);
147        }
148     
149      else if (!strncmp(buffer, "mtllib ", 7))
150        {
151          this->readMtlLib (buffer+7);
152        }
153
154      else if (!strncmp(buffer, "usemtl ", 7))
155        {
156          this->setMaterial (buffer+7);
157        }
158
159      // case VertexNormal
160      else if (!strncmp(buffer, "vn ", 3))
161        {
162          this->addVertexNormal(buffer+3);
163        }
164     
165      // case VertexTextureCoordinate
166      else if (!strncmp(buffer, "vt ", 3))
167        {
168          this->addVertexTexture(buffer+3);
169        }
170      // case group
171      else if (!strncmp(buffer, "g ", 2))
172        {
173          this->addGroup (buffer+2);
174        }
175      else if (!strncmp(buffer, "s ", 2)) //! \todo smoothing groups have to be implemented
176        {
177          PRINTF(2)("smoothing groups not supportet yet. line: %s\n", buffer);
178        }
179    }
180  fclose (stream);
181  delete []fileName;
182  return true;
183}
184
185/**
186    \brief Function to read in a mtl File.
187    \param mtlFile The .mtl file to read
188
189    This Function parses all Lines of an mtl File.
190    The reason for it not to be in the materials-class is,
191    that a material does not have to be able to read itself in from a File.
192
193*/
194bool OBJModel::readMtlLib (const char* mtlFile)
195{
196  this->mtlFileName = new char [strlen(mtlFile)+1];
197  strcpy(this->mtlFileName, mtlFile);
198  char* fileName = new char [strlen(this->objPath) + strlen(this->mtlFileName)+1];
199  sprintf(fileName, "%s%s", this->objPath, this->mtlFileName);
200 
201
202  FILE* stream;
203  if( (stream = fopen (fileName, "r")) == NULL)
204    {
205      printf("IniParser could not open %s\n", fileName);
206      return false;
207    }
208
209  char buffer[PARSELINELENGTH];
210  Material* tmpMat = NULL;
211
212  while(fgets(buffer, PARSELINELENGTH, stream))
213    {
214      PRINTF(5)("found line in mtlFile: %s\n", buffer);
215
216      // line termiated with \0 not \n
217      if (buffer[strlen(buffer)-1] == '\n')
218        buffer[strlen(buffer)-1] = '\0';
219
220      // create new Material
221      if (!strncmp(buffer, "newmtl ", 7))
222        {
223          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
224        }
225      // setting a illumMode
226      else if (!strncmp(buffer, "illum ", 6))
227        {
228          if (likely(tmpMat != NULL))
229            tmpMat->setIllum(buffer+6);
230
231        }
232      // setting Diffuse Color
233      else if (!strncmp(buffer, "Kd ", 3))
234        {
235          if (likely(tmpMat != NULL))
236            tmpMat->setDiffuse(buffer+3);
237        }
238      // setting Ambient Color
239      else if (!strncmp(buffer, "Ka ", 3))
240        {
241          if (likely(tmpMat != NULL))
242            tmpMat->setAmbient(buffer+3);
243        }
244      // setting Specular Color
245      else if (!strncmp(buffer, "Ks ", 3))
246        {
247          if (likely(tmpMat != NULL))
248            tmpMat->setSpecular(buffer+3);
249        }
250      // setting The Specular Shininess
251      else if (!strncmp(buffer, "Ns ", 3))
252        {
253          if (likely(tmpMat != NULL))
254            tmpMat->setShininess(buffer+3);
255        }
256      // setting up transparency
257      else if (!strncmp(buffer, "d ", 2))
258        {
259          if (likely(tmpMat != NULL))
260            tmpMat->setTransparency(buffer+2);
261        }
262      else if (!strncmp(buffer, "Tf ", 3))
263        {
264          if (likely(tmpMat != NULL))
265            tmpMat->setTransparency(buffer+3);
266        }
267     
268      else if (!strncmp(buffer, "map_Kd ", 7))
269        {
270          if (likely(tmpMat != NULL))
271            tmpMat->setDiffuseMap(buffer+7);
272        }
273      else if (!strncmp(buffer, "map_Ka ", 7))
274        {
275          if (likely(tmpMat != NULL))
276            tmpMat->setAmbientMap(buffer+7);
277        }
278      else if (!strncmp(buffer, "map_Ks ", 7))
279        {
280          if (likely(tmpMat != NULL))
281            tmpMat->setSpecularMap(buffer+7);
282        }
283      else if (!strncmp(buffer, "bump ", 5))
284        {
285          if (likely(tmpMat != NULL))
286            tmpMat->setBump(buffer+7);
287        }
288     
289
290    }
291  fclose(stream);
292  delete []fileName;
293  return true;
294}
Note: See TracBrowser for help on using the repository browser.