Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/shared_lib/src/lib/graphics/importer/objModel.cc @ 7952

Last change on this file since 7952 was 7221, checked in by bensch, 19 years ago

orxonox/trunk: merged the std-branche back, it runs on windows and Linux

svn merge https://svn.orxonox.net/orxonox/branches/std . -r7202:HEAD

File size: 6.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 <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 *  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 *  deletes an OBJModel.
50
51   Looks if any from model allocated space is still in use, and if so deleted it.
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);
78    }
79  else
80    this->objPath = "./";
81  Material::addTexturePath(this->objPath);
82
83  this->readFromObjFile (fileName);
84  return true;
85}
86
87/**
88 *  Reads in the .obj File and sets all the Values.
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 * 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            tmpMat->setIllum(buffer+6);
194
195        }
196      // setting Diffuse Color
197      else if (!strncmp(buffer, "Kd ", 3))
198        {
199          if (likely(tmpMat != NULL))
200            tmpMat->setDiffuse(buffer+3);
201        }
202      // setting Ambient Color
203      else if (!strncmp(buffer, "Ka ", 3))
204        {
205          if (likely(tmpMat != NULL))
206            tmpMat->setAmbient(buffer+3);
207        }
208      // setting Specular Color
209      else if (!strncmp(buffer, "Ks ", 3))
210        {
211          if (likely(tmpMat != NULL))
212            tmpMat->setSpecular(buffer+3);
213        }
214      // setting The Specular Shininess
215      else if (!strncmp(buffer, "Ns ", 3))
216        {
217          if (likely(tmpMat != NULL))
218            tmpMat->setShininess(buffer+3);
219        }
220      // setting up transparency
221      else if (!strncmp(buffer, "d ", 2))
222        {
223          if (likely(tmpMat != NULL))
224            tmpMat->setTransparency(buffer+2);
225        }
226      else if (!strncmp(buffer, "Tf ", 3))
227        {
228          if (likely(tmpMat != NULL))
229            tmpMat->setTransparency(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}
Note: See TracBrowser for help on using the repository browser.