Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: prepare for VertexArrays

File size: 6.9 KB
RevLine 
[3396]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
[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/**
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*/
[3916]34OBJModel::OBJModel(const char* fileName, float scaling) : Model(fileName)
[3396]35{
36  this->initializeOBJ();
37  this->scaleFactor = scaling;
38
39  this->importFile (fileName);
40
[3911]41  this->finalize();
[3396]42}
43
44/**
45   \brief deletes an OBJModel.
46
47   Looks if any from model allocated space is still in use, and if so deleted it.
48*/
49OBJModel::~OBJModel()
50{
51  PRINTF(4)("Deleting the obj-names\n");
52  if (this->objPath)
53    delete []this->objPath;
54  if (this->objFileName)
55    delete []this->objFileName;
56  if (this->mtlFileName)
57    delete []this->mtlFileName;
58}
59
60/**
61   \brief Initializes an obj-model
62*/
63void OBJModel::initializeOBJ(void)
64{
65  this->objPath = NULL;
66  this->objFileName = NULL;
67  this->mtlFileName = NULL;
68}
69
70/**
71   \brief Imports a obj file and handles the the relative location
72   \param fileName The file to import
73*/
[3916]74bool OBJModel::importFile (const char* fileName)
[3396]75{
[3548]76  PRINTF(4)("preparing to read in file: %s\n", fileName);
[3396]77
78
79#ifdef __WIN32__
80  // win32 path reading
81  char pathSplitter= '\\';
82#else /* __WIN32__ */
83  // unix path reading
84  char pathSplitter='/';
85#endif /* __WIN32__ */
[3916]86  char* tmpName;
87  strcpy(tmpName, fileName);
[3396]88  if (tmpName[0] == pathSplitter)
89    tmpName++;
90  char* name = tmpName;
91  while (( tmpName = strchr (tmpName+1, pathSplitter)))
92    {
93      name = tmpName+1;
94    }
95  this->objPath = new char[name-fileName+1];
96  strncpy(this->objPath, fileName, name-fileName);
97  this->objPath[name-fileName] = '\0';
[3548]98  if (strlen(objPath)> 0)
99    PRINTF(5)("Resolved file %s to folder: %s.\n", name, objPath);
100  else
101    PRINTF(5)("Resolved file %s.\n", name);
[3396]102 
[3398]103  this->setName(name);
[3915]104
[3396]105  this->objFileName = new char[strlen(name)+1];
106  strcpy (this->objFileName, name);
107  this->readFromObjFile ();
108  return true;
109}
110
111/**
112   \brief Reads in the .obj File and sets all the Values.
113   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
114*/
115bool OBJModel::readFromObjFile (void)
116{
117  char* fileName = new char [strlen(objPath)+strlen(objFileName)+1];
118  if (this->objFileName != NULL && !strcmp(this->objFileName, ""))
119    return false;
120  strcpy(fileName, this->objPath);
121  strcat(fileName, this->objFileName);
122
[3908]123  FILE* stream;
124  if( (stream = fopen (fileName, "r")) == NULL)
[3396]125    {
[3908]126      printf("IniParser could not open %s\n", fileName);
[3396]127      return false;
128    }
129
[3908]130  char buffer[PARSELINELENGTH];
[3910]131  while(fgets(buffer, PARSELINELENGTH, stream))
132    {
133      // line termiated with \0 not \n
134      if (buffer[strlen(buffer)-1] == '\n')
135        buffer[strlen(buffer)-1] = '\0';
136
[3396]137      // case vertice
[3908]138      if (!strncmp(buffer, "v ", 2))
[3396]139        {
[3908]140          this->addVertex(buffer+2);
[3396]141        }
142
143      // case face
[3908]144      else if (!strncmp(buffer, "f ", 2))
[3396]145        {
[3908]146          this->addFace (buffer+2);
[3396]147        }
148     
[3908]149      else if (!strncmp(buffer, "mtllib ", 7))
[3396]150        {
[3908]151          this->readMtlLib (buffer+7);
[3396]152        }
153
[3908]154      else if (!strncmp(buffer, "usemtl ", 7))
[3396]155        {
[3913]156          this->setMaterial (buffer+7);
[3396]157        }
158
159      // case VertexNormal
[3908]160      else if (!strncmp(buffer, "vn ", 3))
[3396]161        {
[3908]162          this->addVertexNormal(buffer+3);
[3396]163        }
164     
165      // case VertexTextureCoordinate
[3908]166      else if (!strncmp(buffer, "vt ", 3))
[3396]167        {
[3908]168          this->addVertexTexture(buffer+3);
[3396]169        }
170      // case group
[3908]171      else if (!strncmp(buffer, "g ", 2))
[3396]172        {
[3908]173          this->addGroup (buffer+2);
[3396]174        }
[3908]175      else if (!strncmp(buffer, "s ", 2)) //! \todo smoothing groups have to be implemented
[3396]176        {
[3908]177          PRINTF(2)("smoothing groups not supportet yet. line: %s\n", buffer);
[3396]178        }
179    }
[3908]180  fclose (stream);
[3396]181  delete []fileName;
182  return true;
183}
184
185/**
186    \brief Function to read in a mtl File.
187    \param mtlFile The .mtl file to read
188
189    This Function parses all Lines of an mtl File.
190    The reason for it not to be in the materials-class is,
191    that a material does not have to be able to read itself in from a File.
192
193*/
[3916]194bool OBJModel::readMtlLib (const char* mtlFile)
[3396]195{
196  this->mtlFileName = new char [strlen(mtlFile)+1];
197  strcpy(this->mtlFileName, mtlFile);
198  char* fileName = new char [strlen(objPath) + strlen(this->mtlFileName)+1];
199  strcpy(fileName, this->objPath);
200  strcat(fileName, this->mtlFileName);
201 
202
[3909]203  FILE* stream;
204  if( (stream = fopen (fileName, "r")) == NULL)
[3396]205    {
[3909]206      printf("IniParser could not open %s\n", fileName);
[3396]207      return false;
208    }
[3909]209
210  char buffer[PARSELINELENGTH];
[3915]211  Material* tmpMat = NULL;
[3911]212
[3910]213  while(fgets(buffer, PARSELINELENGTH, stream))
[3396]214    {
[3908]215      PRINTF(5)("found line in mtlFile: %s\n", buffer);
[3396]216
[3910]217      // line termiated with \0 not \n
218      if (buffer[strlen(buffer)-1] == '\n')
219        buffer[strlen(buffer)-1] = '\0';
220
[3396]221      // create new Material
[3908]222      if (!strncmp(buffer, "newmtl ", 7))
[3396]223        {
[3914]224          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
[3396]225        }
226      // setting a illumMode
[3908]227      else if (!strncmp(buffer, "illum ", 6))
[3396]228        {
[3915]229          if (likely(tmpMat != NULL))
230            tmpMat->setIllum(buffer+6);
[3396]231
232        }
233      // setting Diffuse Color
[3908]234      else if (!strncmp(buffer, "Kd ", 3))
[3396]235        {
[3915]236          if (likely(tmpMat != NULL))
237            tmpMat->setDiffuse(buffer+3);
[3396]238        }
239      // setting Ambient Color
[3908]240      else if (!strncmp(buffer, "Ka ", 3))
[3396]241        {
[3915]242          if (likely(tmpMat != NULL))
243            tmpMat->setAmbient(buffer+3);
[3396]244        }
245      // setting Specular Color
[3908]246      else if (!strncmp(buffer, "Ks ", 3))
[3396]247        {
[3915]248          if (likely(tmpMat != NULL))
249            tmpMat->setSpecular(buffer+3);
[3396]250        }
251      // setting The Specular Shininess
[3908]252      else if (!strncmp(buffer, "Ns ", 3))
[3396]253        {
[3915]254          if (likely(tmpMat != NULL))
255            tmpMat->setShininess(buffer+3);
[3396]256        }
257      // setting up transparency
[3908]258      else if (!strncmp(buffer, "d ", 2))
[3396]259        {
[3915]260          if (likely(tmpMat != NULL))
261            tmpMat->setTransparency(buffer+2);
[3396]262        }
[3908]263      else if (!strncmp(buffer, "Tf ", 3))
[3396]264        {
[3915]265          if (likely(tmpMat != NULL))
266            tmpMat->setTransparency(buffer+3);
[3396]267        }
268     
[3908]269      else if (!strncmp(buffer, "map_Kd ", 7))
[3396]270        {
[3915]271          if (likely(tmpMat != NULL))
272            tmpMat->setDiffuseMap(buffer+7);
[3396]273        }
[3908]274      else if (!strncmp(buffer, "map_Ka ", 7))
[3396]275        {
[3915]276          if (likely(tmpMat != NULL))
277            tmpMat->setAmbientMap(buffer+7);
[3396]278        }
[3908]279      else if (!strncmp(buffer, "map_Ks ", 7))
[3396]280        {
[3915]281          if (likely(tmpMat != NULL))
282            tmpMat->setSpecularMap(buffer+7);
[3396]283        }
[3908]284      else if (!strncmp(buffer, "bump ", 5))
[3396]285        {
[3915]286          if (likely(tmpMat != NULL))
287            tmpMat->setBump(buffer+7);
[3396]288        }
289     
290
291    }
[3909]292  fclose(stream);
[3396]293  delete []fileName;
294  return true;
295}
Note: See TracBrowser for help on using the repository browser.