Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: objModel's materials should now automatically load textures

File size: 6.1 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 char* fileName, float scaling) : Model(fileName)
35{
36  this->objPath = "./";
37
38  this->scaleFactor = scaling;
39
40  this->importFile (fileName);
41
42  this->finalize();
43}
44
45/**
46   \brief deletes an OBJModel.
47
48   Looks if any from model allocated space is still in use, and if so deleted it.
49*/
50OBJModel::~OBJModel()
51{
52  PRINTF(4)("Deleting the obj-names\n");
53  if (this->objPath)
54    delete []this->objPath;
55}
56
57/**
58   \brief Imports a obj file and handles the the relative location
59   \param fileName The file to import
60
61   Splits the FileName from the DirectoryName
62*/
63bool OBJModel::importFile (const char* fileName)
64{
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 = new char[len +2];
75      strncpy(this->objPath, fileName, len);
76      this->objPath[len] = '\0';
77      Material::addTexturePath(this->objPath);
78      PRINTF(1)("Resolved file %s to Path %s.\n", fileName, 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   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
87*/
88bool OBJModel::readFromObjFile(const char* fileName)
89{
90  FILE* stream;
91  if( (stream = fopen (fileName, "r")) == NULL)
92    {
93      printf("Object File Could not be Opened %s\n", fileName);
94      return false;
95    }
96
97  char buffer[PARSELINELENGTH];
98  while(fgets(buffer, PARSELINELENGTH, stream))
99    {
100      // line termiated with \0 not \n
101      if (buffer[strlen(buffer)-1] == '\n')
102        buffer[strlen(buffer)-1] = '\0';
103
104      // case vertice
105      if (!strncmp(buffer, "v ", 2))
106        {
107          this->addVertex(buffer+2);
108        }
109
110      // case face
111      else if (!strncmp(buffer, "f ", 2))
112        {
113          this->addFace (buffer+2);
114        }
115     
116      else if (!strncmp(buffer, "mtllib ", 7))
117        {
118          this->readMtlLib (buffer+7);
119        }
120
121      else if (!strncmp(buffer, "usemtl ", 7))
122        {
123          this->setMaterial (buffer+7);
124        }
125
126      // case VertexNormal
127      else if (!strncmp(buffer, "vn ", 3))
128        {
129          this->addVertexNormal(buffer+3);
130        }
131     
132      // case VertexTextureCoordinate
133      else if (!strncmp(buffer, "vt ", 3))
134        {
135          this->addVertexTexture(buffer+3);
136        }
137      // case group
138      else if (!strncmp(buffer, "g ", 2))
139        {
140          this->addGroup (buffer+2);
141        }
142      else if (!strncmp(buffer, "s ", 2)) //! \todo smoothing groups have to be implemented
143        {
144          PRINTF(2)("smoothing groups not supportet yet. line: %s\n", buffer);
145        }
146    }
147  fclose (stream);
148  return true;
149}
150
151/**
152    \brief Function to read in a mtl File.
153    \param mtlFile The .mtl file to read
154
155    This Function parses all Lines of an mtl File.
156    The reason for it not to be in the materials-class is,
157    that a material does not have to be able to read itself in from a File.
158
159*/
160bool OBJModel::readMtlLib (const char* mtlFile)
161{
162  char* fileName = new char [strlen(this->objPath) + strlen(mtlFile)+1];
163  sprintf(fileName, "%s%s", this->objPath, mtlFile);
164
165  FILE* stream;
166  if( (stream = fopen (fileName, "r")) == NULL)
167    {
168      PRINTF(2)("MaterialLibrary could not be opened %s\n", fileName);
169      delete []fileName;
170      return false;
171    }
172
173  char buffer[PARSELINELENGTH];
174  Material* tmpMat = NULL;
175
176  while(fgets(buffer, PARSELINELENGTH, stream))
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  delete []fileName;
257  return true;
258}
Note: See TracBrowser for help on using the repository browser.