Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/graphics/importer/objModel.cc @ 9831

Last change on this file since 9831 was 9831, checked in by bensch, 18 years ago

added resource_obj for new resource managed obj-loader

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