Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: finaly moved the *#\!3i& chars out of Material

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 <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 std::string& fileName, float scaling)
35  : StaticModel(fileName)
36{
37  this->setClassID(CL_OBJ_MODEL, "OBJModel");
38
39  this->objPath = "./";
40
41  this->scaleFactor = 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  Material::addTexturePath(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.