Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3915 was 3915, checked in by bensch, 19 years ago

orxonox/trunk: material is now only dependent on tList<Material>* in model

File size: 6.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: 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(char* fileName, float scaling)
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 (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 = fileName;
87  if (tmpName[0] == pathSplitter)
88    tmpName++;
89  char* name = tmpName;
90  while (( tmpName = strchr (tmpName+1, pathSplitter)))
91    {
92      name = tmpName+1;
93    }
94  this->objPath = new char[name-fileName+1];
95  strncpy(this->objPath, fileName, name-fileName);
96  this->objPath[name-fileName] = '\0';
97  if (strlen(objPath)> 0)
98    PRINTF(5)("Resolved file %s to folder: %s.\n", name, objPath);
99  else
100    PRINTF(5)("Resolved file %s.\n", name);
101 
102  this->setName(name);
103
104  this->objFileName = new char[strlen(name)+1];
105  strcpy (this->objFileName, name);
106  this->readFromObjFile ();
107  return true;
108}
109
110/**
111   \brief Reads in the .obj File and sets all the Values.
112   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
113*/
114bool OBJModel::readFromObjFile (void)
115{
116  char* fileName = new char [strlen(objPath)+strlen(objFileName)+1];
117  if (this->objFileName != NULL && !strcmp(this->objFileName, ""))
118    return false;
119  strcpy(fileName, this->objPath);
120  strcat(fileName, this->objFileName);
121
122  FILE* stream;
123  if( (stream = fopen (fileName, "r")) == NULL)
124    {
125      printf("IniParser could not open %s\n", fileName);
126      return false;
127    }
128
129  char buffer[PARSELINELENGTH];
130  while(fgets(buffer, PARSELINELENGTH, stream))
131    {
132      // line termiated with \0 not \n
133      if (buffer[strlen(buffer)-1] == '\n')
134        buffer[strlen(buffer)-1] = '\0';
135
136      // case vertice
137      if (!strncmp(buffer, "v ", 2))
138        {
139          this->addVertex(buffer+2);
140        }
141
142      // case face
143      else if (!strncmp(buffer, "f ", 2))
144        {
145          this->addFace (buffer+2);
146        }
147     
148      else if (!strncmp(buffer, "mtllib ", 7))
149        {
150          this->readMtlLib (buffer+7);
151        }
152
153      else if (!strncmp(buffer, "usemtl ", 7))
154        {
155          this->setMaterial (buffer+7);
156        }
157
158      // case VertexNormal
159      else if (!strncmp(buffer, "vn ", 3))
160        {
161          this->addVertexNormal(buffer+3);
162        }
163     
164      // case VertexTextureCoordinate
165      else if (!strncmp(buffer, "vt ", 3))
166        {
167          this->addVertexTexture(buffer+3);
168        }
169      // case group
170      else if (!strncmp(buffer, "g ", 2))
171        {
172          this->addGroup (buffer+2);
173        }
174      else if (!strncmp(buffer, "s ", 2)) //! \todo smoothing groups have to be implemented
175        {
176          PRINTF(2)("smoothing groups not supportet yet. line: %s\n", buffer);
177        }
178    }
179  fclose (stream);
180  delete []fileName;
181  return true;
182}
183
184/**
185    \brief Function to read in a mtl File.
186    \param mtlFile The .mtl file to read
187
188    This Function parses all Lines of an mtl File.
189    The reason for it not to be in the materials-class is,
190    that a material does not have to be able to read itself in from a File.
191
192*/
193bool OBJModel::readMtlLib (char* mtlFile)
194{
195  this->mtlFileName = new char [strlen(mtlFile)+1];
196  strcpy(this->mtlFileName, mtlFile);
197  char* fileName = new char [strlen(objPath) + strlen(this->mtlFileName)+1];
198  strcpy(fileName, this->objPath);
199  strcat(fileName, 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.