Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: prepare for VertexArrays

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(objPath) + strlen(this->mtlFileName)+1];
199  strcpy(fileName, this->objPath);
200  strcat(fileName, this->mtlFileName);
201 
202
203  FILE* stream;
204  if( (stream = fopen (fileName, "r")) == NULL)
205    {
206      printf("IniParser could not open %s\n", fileName);
207      return false;
208    }
209
210  char buffer[PARSELINELENGTH];
211  Material* tmpMat = NULL;
212
213  while(fgets(buffer, PARSELINELENGTH, stream))
214    {
215      PRINTF(5)("found line in mtlFile: %s\n", buffer);
216
217      // line termiated with \0 not \n
218      if (buffer[strlen(buffer)-1] == '\n')
219        buffer[strlen(buffer)-1] = '\0';
220
221      // create new Material
222      if (!strncmp(buffer, "newmtl ", 7))
223        {
224          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
225        }
226      // setting a illumMode
227      else if (!strncmp(buffer, "illum ", 6))
228        {
229          if (likely(tmpMat != NULL))
230            tmpMat->setIllum(buffer+6);
231
232        }
233      // setting Diffuse Color
234      else if (!strncmp(buffer, "Kd ", 3))
235        {
236          if (likely(tmpMat != NULL))
237            tmpMat->setDiffuse(buffer+3);
238        }
239      // setting Ambient Color
240      else if (!strncmp(buffer, "Ka ", 3))
241        {
242          if (likely(tmpMat != NULL))
243            tmpMat->setAmbient(buffer+3);
244        }
245      // setting Specular Color
246      else if (!strncmp(buffer, "Ks ", 3))
247        {
248          if (likely(tmpMat != NULL))
249            tmpMat->setSpecular(buffer+3);
250        }
251      // setting The Specular Shininess
252      else if (!strncmp(buffer, "Ns ", 3))
253        {
254          if (likely(tmpMat != NULL))
255            tmpMat->setShininess(buffer+3);
256        }
257      // setting up transparency
258      else if (!strncmp(buffer, "d ", 2))
259        {
260          if (likely(tmpMat != NULL))
261            tmpMat->setTransparency(buffer+2);
262        }
263      else if (!strncmp(buffer, "Tf ", 3))
264        {
265          if (likely(tmpMat != NULL))
266            tmpMat->setTransparency(buffer+3);
267        }
268     
269      else if (!strncmp(buffer, "map_Kd ", 7))
270        {
271          if (likely(tmpMat != NULL))
272            tmpMat->setDiffuseMap(buffer+7);
273        }
274      else if (!strncmp(buffer, "map_Ka ", 7))
275        {
276          if (likely(tmpMat != NULL))
277            tmpMat->setAmbientMap(buffer+7);
278        }
279      else if (!strncmp(buffer, "map_Ks ", 7))
280        {
281          if (likely(tmpMat != NULL))
282            tmpMat->setSpecularMap(buffer+7);
283        }
284      else if (!strncmp(buffer, "bump ", 5))
285        {
286          if (likely(tmpMat != NULL))
287            tmpMat->setBump(buffer+7);
288        }
289     
290
291    }
292  fclose(stream);
293  delete []fileName;
294  return true;
295}
Note: See TracBrowser for help on using the repository browser.