Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/new_class_id: Static Model splitted up into Data and Logic part

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