Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10240 was 10147, checked in by patrick, 18 years ago

merged the mount_point branche back to trunk to use the new std::* based obj file importer

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