Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5014 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
RevLine 
[5014]1/*
[3396]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
[3590]16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
17
[3396]18#include "objModel.h"
19
[3908]20#include <stdio.h>
21#include <string.h>
22#include <stdlib.h>
23
24#define PARSELINELENGTH 8192
25
[3475]26#include "debug.h"
[3915]27#include "compiler.h"
[3427]28
[3396]29/**
[4836]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.
[3396]33*/
[3916]34OBJModel::OBJModel(const char* fileName, float scaling) : Model(fileName)
[3396]35{
[4117]36  this->objPath = "./";
37
[3396]38  this->scaleFactor = scaling;
39
40  this->importFile (fileName);
41
[3911]42  this->finalize();
[3396]43}
44
45/**
[4836]46 *  deletes an OBJModel.
[3396]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/**
[4836]58 *  Imports a obj file and handles the the relative location
59 * @param fileName The file to import
[4117]60
61   Splits the FileName from the DirectoryName
[3396]62*/
[3916]63bool OBJModel::importFile (const char* fileName)
[3396]64{
[3548]65  PRINTF(4)("preparing to read in file: %s\n", fileName);
[5014]66  // splitting the
[4117]67  char* split = NULL;
[3396]68
[4117]69  if (!(split = strrchr(fileName, '/')))
70    split = strrchr(fileName, '\\'); // windows Case
71  if (split)
[3396]72    {
[4117]73      int len = split - fileName+1;
74      this->objPath = new char[len +2];
75      strncpy(this->objPath, fileName, len);
[4118]76      this->objPath[len] = '\0';
77      PRINTF(1)("Resolved file %s to Path %s.\n", fileName, this->objPath);
[3396]78    }
[4371]79  else
80    this->objPath = "./";
81  Material::addTexturePath(this->objPath);
82
[4117]83  this->readFromObjFile (fileName);
[3396]84  return true;
85}
86
87/**
[4836]88 *  Reads in the .obj File and sets all the Values.
[3396]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*/
[4117]91bool OBJModel::readFromObjFile(const char* fileName)
[3396]92{
[3908]93  FILE* stream;
94  if( (stream = fopen (fileName, "r")) == NULL)
[3396]95    {
[4117]96      printf("Object File Could not be Opened %s\n", fileName);
[3396]97      return false;
98    }
99
[3908]100  char buffer[PARSELINELENGTH];
[3910]101  while(fgets(buffer, PARSELINELENGTH, stream))
102    {
103      // line termiated with \0 not \n
104      if (buffer[strlen(buffer)-1] == '\n')
[5014]105        buffer[strlen(buffer)-1] = '\0';
[3910]106
[3396]107      // case vertice
[3908]108      if (!strncmp(buffer, "v ", 2))
[5014]109        {
110          this->addVertex(buffer+2);
111        }
[3396]112
113      // case face
[3908]114      else if (!strncmp(buffer, "f ", 2))
[5014]115        {
116          this->addFace (buffer+2);
117        }
118
[3908]119      else if (!strncmp(buffer, "mtllib ", 7))
[5014]120        {
121          this->readMtlLib (buffer+7);
122        }
[3396]123
[3908]124      else if (!strncmp(buffer, "usemtl ", 7))
[5014]125        {
126          this->setMaterial (buffer+7);
127        }
[3396]128
129      // case VertexNormal
[3908]130      else if (!strncmp(buffer, "vn ", 3))
[5014]131        {
132          this->addVertexNormal(buffer+3);
133        }
134
[3396]135      // case VertexTextureCoordinate
[3908]136      else if (!strncmp(buffer, "vt ", 3))
[5014]137        {
138          this->addVertexTexture(buffer+3);
139        }
[3396]140      // case group
[3908]141      else if (!strncmp(buffer, "g ", 2))
[5014]142        {
143          this->addGroup (buffer+2);
144        }
[4836]145      else if (!strncmp(buffer, "s ", 2)) //! @todo smoothing groups have to be implemented
[5014]146        {
147          PRINTF(2)("smoothing groups not supportet yet. line: %s\n", buffer);
148        }
[3396]149    }
[3908]150  fclose (stream);
[3396]151  return true;
152}
153
[5014]154/**
[4836]155  *  Function to read in a mtl File.
156  * @param mtlFile The .mtl file to read
[3396]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*/
[3916]163bool OBJModel::readMtlLib (const char* mtlFile)
[3396]164{
[4117]165  char* fileName = new char [strlen(this->objPath) + strlen(mtlFile)+1];
166  sprintf(fileName, "%s%s", this->objPath, mtlFile);
[3396]167
[3909]168  FILE* stream;
169  if( (stream = fopen (fileName, "r")) == NULL)
[3396]170    {
[4117]171      PRINTF(2)("MaterialLibrary could not be opened %s\n", fileName);
172      delete []fileName;
[3396]173      return false;
174    }
[3909]175
176  char buffer[PARSELINELENGTH];
[3915]177  Material* tmpMat = NULL;
[3911]178
[3910]179  while(fgets(buffer, PARSELINELENGTH, stream))
[3396]180    {
[3908]181      PRINTF(5)("found line in mtlFile: %s\n", buffer);
[3396]182
[3910]183      // line termiated with \0 not \n
184      if (buffer[strlen(buffer)-1] == '\n')
[5014]185        buffer[strlen(buffer)-1] = '\0';
[3910]186
[3396]187      // create new Material
[3908]188      if (!strncmp(buffer, "newmtl ", 7))
[5014]189        {
190          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
191        }
[3396]192      // setting a illumMode
[3908]193      else if (!strncmp(buffer, "illum ", 6))
[5014]194        {
195          if (likely(tmpMat != NULL))
196            tmpMat->setIllum(buffer+6);
[3396]197
[5014]198        }
[3396]199      // setting Diffuse Color
[3908]200      else if (!strncmp(buffer, "Kd ", 3))
[5014]201        {
202          if (likely(tmpMat != NULL))
203            tmpMat->setDiffuse(buffer+3);
204        }
[3396]205      // setting Ambient Color
[3908]206      else if (!strncmp(buffer, "Ka ", 3))
[5014]207        {
208          if (likely(tmpMat != NULL))
209            tmpMat->setAmbient(buffer+3);
210        }
[3396]211      // setting Specular Color
[3908]212      else if (!strncmp(buffer, "Ks ", 3))
[5014]213        {
214          if (likely(tmpMat != NULL))
215            tmpMat->setSpecular(buffer+3);
216        }
[3396]217      // setting The Specular Shininess
[3908]218      else if (!strncmp(buffer, "Ns ", 3))
[5014]219        {
220          if (likely(tmpMat != NULL))
221            tmpMat->setShininess(buffer+3);
222        }
[3396]223      // setting up transparency
[3908]224      else if (!strncmp(buffer, "d ", 2))
[5014]225        {
226          if (likely(tmpMat != NULL))
227            tmpMat->setTransparency(buffer+2);
228        }
[3908]229      else if (!strncmp(buffer, "Tf ", 3))
[5014]230        {
231          if (likely(tmpMat != NULL))
232            tmpMat->setTransparency(buffer+3);
233        }
234
[3908]235      else if (!strncmp(buffer, "map_Kd ", 7))
[5014]236        {
237          if (likely(tmpMat != NULL))
238            tmpMat->setDiffuseMap(buffer+7);
239        }
[3908]240      else if (!strncmp(buffer, "map_Ka ", 7))
[5014]241        {
242          if (likely(tmpMat != NULL))
243            tmpMat->setAmbientMap(buffer+7);
244        }
[3908]245      else if (!strncmp(buffer, "map_Ks ", 7))
[5014]246        {
247          if (likely(tmpMat != NULL))
248            tmpMat->setSpecularMap(buffer+7);
249        }
[3908]250      else if (!strncmp(buffer, "bump ", 5))
[5014]251        {
252          if (likely(tmpMat != NULL))
253            tmpMat->setBump(buffer+7);
254        }
[3396]255
[5014]256
[3396]257    }
[3909]258  fclose(stream);
[3396]259  delete []fileName;
260  return true;
261}
Note: See TracBrowser for help on using the repository browser.