Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: implemented a new kind of ini-parser
this parser first reads the file, and then one can search through without accessing the file anymore

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 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 *  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 *  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      PRINTF(1)("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 char* fileName)
92{
93  FILE* stream;
94  if( (stream = fopen (fileName, "r")) == NULL)
95    {
96      printf("Object File Could not be Opened %s\n", fileName);
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(2)("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
162*/
163bool OBJModel::readMtlLib (const char* mtlFile)
164{
165  char* fileName = new char [strlen(this->objPath) + strlen(mtlFile)+1];
166  sprintf(fileName, "%s%s", this->objPath, mtlFile);
167
168  FILE* stream;
169  if( (stream = fopen (fileName, "r")) == NULL)
170    {
171      PRINTF(2)("MaterialLibrary could not be opened %s\n", fileName);
172      delete []fileName;
173      return false;
174    }
175
176  char buffer[PARSELINELENGTH];
177  Material* tmpMat = NULL;
178
179  while(fgets(buffer, PARSELINELENGTH, stream))
180    {
181      PRINTF(5)("found line in mtlFile: %s\n", buffer);
182
183      // line termiated with \0 not \n
184      if (buffer[strlen(buffer)-1] == '\n')
185        buffer[strlen(buffer)-1] = '\0';
186
187      // create new Material
188      if (!strncmp(buffer, "newmtl ", 7))
189        {
190          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
191        }
192      // setting a illumMode
193      else if (!strncmp(buffer, "illum ", 6))
194        {
195          if (likely(tmpMat != NULL))
196            tmpMat->setIllum(buffer+6);
197
198        }
199      // setting Diffuse Color
200      else if (!strncmp(buffer, "Kd ", 3))
201        {
202          if (likely(tmpMat != NULL))
203            tmpMat->setDiffuse(buffer+3);
204        }
205      // setting Ambient Color
206      else if (!strncmp(buffer, "Ka ", 3))
207        {
208          if (likely(tmpMat != NULL))
209            tmpMat->setAmbient(buffer+3);
210        }
211      // setting Specular Color
212      else if (!strncmp(buffer, "Ks ", 3))
213        {
214          if (likely(tmpMat != NULL))
215            tmpMat->setSpecular(buffer+3);
216        }
217      // setting The Specular Shininess
218      else if (!strncmp(buffer, "Ns ", 3))
219        {
220          if (likely(tmpMat != NULL))
221            tmpMat->setShininess(buffer+3);
222        }
223      // setting up transparency
224      else if (!strncmp(buffer, "d ", 2))
225        {
226          if (likely(tmpMat != NULL))
227            tmpMat->setTransparency(buffer+2);
228        }
229      else if (!strncmp(buffer, "Tf ", 3))
230        {
231          if (likely(tmpMat != NULL))
232            tmpMat->setTransparency(buffer+3);
233        }
234
235      else if (!strncmp(buffer, "map_Kd ", 7))
236        {
237          if (likely(tmpMat != NULL))
238            tmpMat->setDiffuseMap(buffer+7);
239        }
240      else if (!strncmp(buffer, "map_Ka ", 7))
241        {
242          if (likely(tmpMat != NULL))
243            tmpMat->setAmbientMap(buffer+7);
244        }
245      else if (!strncmp(buffer, "map_Ks ", 7))
246        {
247          if (likely(tmpMat != NULL))
248            tmpMat->setSpecularMap(buffer+7);
249        }
250      else if (!strncmp(buffer, "bump ", 5))
251        {
252          if (likely(tmpMat != NULL))
253            tmpMat->setBump(buffer+7);
254        }
255
256
257    }
258  fclose(stream);
259  delete []fileName;
260  return true;
261}
Note: See TracBrowser for help on using the repository browser.