Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/terrain/src/lib/graphics/importer/obj/objModel.cc @ 10613

Last change on this file since 10613 was 10033, checked in by patrick, 18 years ago

moved some of the importer sources, probably will need to rebuild the project

File size: 8.4 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 <string.h>
21#include "loading/resource_manager.h"
22
23#define PARSELINELENGTH 8192
24
25#include "debug.h"
26#include "compiler.h"
27
28ObjectListDefinition(OBJModel);
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 std::string& fileName, float scaling)
35  : StaticModel(fileName)
36{
37  this->registerObject(this, OBJModel::_objectList);
38
39  this->objPath = "./";
40
41  this->setScaleFactor(scaling);
42
43  this->importFile (fileName);
44
45  this->finalize();
46}
47
48/**
49 * @brief deletes an OBJModel.
50 */
51OBJModel::~OBJModel()
52{ }
53
54/**
55 *  Imports a obj file and handles the the relative location
56 * @param fileName The file to import
57
58   Splits the FileName from the DirectoryName
59*/
60bool OBJModel::importFile (const std::string& fileNameInput)
61{
62  const char* fileName = fileNameInput.c_str();
63  PRINTF(4)("preparing to read in file: %s\n", fileName);
64  // splitting the
65  char* split = NULL;
66
67  if (!(split = strrchr(fileName, '/')))
68    split = strrchr(fileName, '\\'); // windows Case
69  if (split)
70    {
71      int len = split - fileName+1;
72      this->objPath =  fileName;
73      this->objPath.erase(len, this->objPath.size());
74      this->objPath[len] = '\0';
75      PRINTF(4)("Resolved file %s to Path %s.\n", fileName, this->objPath.c_str());
76    }
77  else
78    this->objPath = "./";
79  Resources::ResourceManager::getInstance()->addResourcePath("Texture", this->objPath);
80
81  this->readFromObjFile (fileName);
82  return true;
83}
84
85/**
86 * @brief Reads in the .obj File and sets all the Values.
87 * @param fileName the FileName of the Model.
88 *
89 * This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
90 */
91bool OBJModel::readFromObjFile(const std::string& fileName)
92{
93  FILE* stream;
94  if( (stream = fopen (fileName.c_str(), "r")) == NULL)
95    {
96      PRINTF(2)("Object File Could not be Opened %s\n", fileName.c_str());
97      return false;
98    }
99
100  char buffer[PARSELINELENGTH];
101  while(fgets(buffer, PARSELINELENGTH, stream))
102    {
103      // line termiated with \0 not \n
104      if (buffer[strlen(buffer)-1] == '\n')
105        buffer[strlen(buffer)-1] = '\0';
106
107      // case vertice
108      if (!strncmp(buffer, "v ", 2))
109        {
110          this->addVertex(buffer+2);
111        }
112
113      // case face
114      else if (!strncmp(buffer, "f ", 2))
115        {
116          this->addFace (buffer+2);
117        }
118
119      else if (!strncmp(buffer, "mtllib ", 7))
120        {
121          this->readMtlLib (buffer+7);
122        }
123
124      else if (!strncmp(buffer, "usemtl ", 7))
125        {
126          this->setMaterial (buffer+7);
127        }
128
129      // case VertexNormal
130      else if (!strncmp(buffer, "vn ", 3))
131        {
132          this->addVertexNormal(buffer+3);
133        }
134
135      // case VertexTextureCoordinate
136      else if (!strncmp(buffer, "vt ", 3))
137        {
138          this->addVertexTexture(buffer+3);
139        }
140      // case group
141      else if (!strncmp(buffer, "g ", 2))
142        {
143          this->addGroup (buffer+2);
144        }
145      else if (!strncmp(buffer, "s ", 2)) //! @todo smoothing groups have to be implemented
146        {
147          PRINTF(3)("smoothing groups not supportet yet. line: %s\n", buffer);
148        }
149    }
150  fclose (stream);
151  return true;
152}
153
154/**
155 * @brief Function to read in a mtl File.
156 * @param mtlFile The .mtl file to read
157 *
158 * This Function parses all Lines of an mtl File.
159 * The reason for it not to be in the materials-class is,
160 * that a material does not have to be able to read itself in from a File.
161 */
162bool OBJModel::readMtlLib (const std::string& mtlFile)
163{
164  std::string fileName = this->objPath + mtlFile;
165
166  FILE* stream;
167  if( (stream = fopen (fileName.c_str(), "r")) == NULL)
168    {
169      PRINTF(2)("MaterialLibrary could not be opened %s\n", fileName.c_str());
170      return false;
171    }
172
173  char buffer[PARSELINELENGTH];
174  Material* tmpMat = NULL;
175
176  while(fgets(buffer, PARSELINELENGTH, stream) != NULL)
177    {
178      PRINTF(5)("found line in mtlFile: %s\n", buffer);
179
180      // line termiated with \0 not \n
181      if (buffer[strlen(buffer)-1] == '\n')
182        buffer[strlen(buffer)-1] = '\0';
183
184      // create new Material
185      if (!strncmp(buffer, "newmtl ", 7))
186        {
187          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
188        }
189      // setting a illumMode
190      else if (!strncmp(buffer, "illum ", 6))
191        {
192          if (likely(tmpMat != NULL))
193            setIllum(tmpMat, buffer+6);
194
195        }
196      // setting Diffuse Color
197      else if (!strncmp(buffer, "Kd ", 3))
198        {
199          if (likely(tmpMat != NULL))
200            setDiffuse(tmpMat, buffer+3);
201        }
202      // setting Ambient Color
203      else if (!strncmp(buffer, "Ka ", 3))
204        {
205          if (likely(tmpMat != NULL))
206            setAmbient(tmpMat, buffer+3);
207        }
208      // setting Specular Color
209      else if (!strncmp(buffer, "Ks ", 3))
210        {
211          if (likely(tmpMat != NULL))
212            setSpecular(tmpMat, buffer+3);
213        }
214      // setting The Specular Shininess
215      else if (!strncmp(buffer, "Ns ", 3))
216        {
217          if (likely(tmpMat != NULL))
218            setShininess(tmpMat, buffer+3);
219        }
220      // setting up transparency
221      else if (!strncmp(buffer, "d ", 2))
222        {
223          if (likely(tmpMat != NULL))
224            setTransparency(tmpMat, buffer+2);
225        }
226      else if (!strncmp(buffer, "Tf ", 3))
227        {
228          if (likely(tmpMat != NULL))
229            setTransparency(tmpMat, buffer+3);
230        }
231
232      else if (!strncmp(buffer, "map_Kd ", 7))
233        {
234          if (likely(tmpMat != NULL))
235            tmpMat->setDiffuseMap(buffer+7);
236        }
237      else if (!strncmp(buffer, "map_Ka ", 7))
238        {
239          if (likely(tmpMat != NULL))
240            tmpMat->setAmbientMap(buffer+7);
241        }
242      else if (!strncmp(buffer, "map_Ks ", 7))
243        {
244          if (likely(tmpMat != NULL))
245            tmpMat->setSpecularMap(buffer+7);
246        }
247      else if (!strncmp(buffer, "bump ", 5))
248        {
249          if (likely(tmpMat != NULL))
250            tmpMat->setBump(buffer+7);
251        }
252
253
254    }
255  fclose(stream);
256  return true;
257}
258
259
260/**
261 * @brief Sets the Material Illumination Model.
262 * @param material: the Material to apply the change to.
263 * @param illu: illumination Model in char* form
264 */
265void OBJModel::setIllum (Material* material, const char* illum)
266{
267  material->setIllum (atoi(illum));
268}
269
270/**
271 * @brief Sets the Material Diffuse Color.
272 * @param material: the Material to apply the change to.
273 * @param rgb The red, green, blue channel in char format (with spaces between them)
274 */
275void OBJModel::setDiffuse (Material* material, const char* rgb)
276{
277  float r,g,b;
278  sscanf (rgb, "%f %f %f", &r, &g, &b);
279  material->setDiffuse (r, g, b);
280}
281
282/**
283 * @brief Sets the Material Ambient Color.
284 * @param material: the Material to apply the change to.
285 * @param rgb The red, green, blue channel in char format (with spaces between them)
286 */
287void OBJModel::setAmbient (Material* material, const char* rgb)
288{
289  float r,g,b;
290  sscanf (rgb, "%f %f %f", &r, &g, &b);
291  material->setAmbient (r, g, b);
292}
293
294/**
295 * @brief Sets the Material Specular Color.
296 * @param material: the Material to apply the change to.
297 * @param rgb The red, green, blue channel in char format (with spaces between them)
298 */
299void OBJModel::setSpecular (Material* material, const char* rgb)
300{
301  float r,g,b;
302  sscanf (rgb, "%f %f %f", &r, &g, &b);
303  material->setSpecular (r, g, b);
304}
305
306/**
307 * @brief Sets the Material Shininess.
308 * @param material: the Material to apply the change to.
309 * @param shini stes the Shininess from char*.
310 */
311void OBJModel::setShininess (Material* material, const char* shini)
312{
313  material->setShininess (atof(shini));
314}
315
316/**
317 * @brief Sets the Material Transparency.
318 * @param material: the Material to apply the change to.
319 * @param trans stes the Transparency from char*.
320 */
321void OBJModel::setTransparency (Material* material, const char* trans)
322{
323  material->setTransparency (atof(trans));
324}
Note: See TracBrowser for help on using the repository browser.