Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: small discrepancy

File size: 6.0 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{
[4117]36  this->objPath = "./";
37
[3396]38  this->scaleFactor = scaling;
39
40  this->importFile (fileName);
41
[3911]42  this->finalize();
[3396]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
[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);
[4117]66  // splitting the
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    }
[4117]79  this->readFromObjFile (fileName);
[3396]80  return true;
81}
82
83/**
84   \brief Reads in the .obj File and sets all the Values.
85   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
86*/
[4117]87bool OBJModel::readFromObjFile(const char* fileName)
[3396]88{
[3908]89  FILE* stream;
90  if( (stream = fopen (fileName, "r")) == NULL)
[3396]91    {
[4117]92      printf("Object File Could not be Opened %s\n", fileName);
[3396]93      return false;
94    }
95
[3908]96  char buffer[PARSELINELENGTH];
[3910]97  while(fgets(buffer, PARSELINELENGTH, stream))
98    {
99      // line termiated with \0 not \n
100      if (buffer[strlen(buffer)-1] == '\n')
101        buffer[strlen(buffer)-1] = '\0';
102
[3396]103      // case vertice
[3908]104      if (!strncmp(buffer, "v ", 2))
[3396]105        {
[3908]106          this->addVertex(buffer+2);
[3396]107        }
108
109      // case face
[3908]110      else if (!strncmp(buffer, "f ", 2))
[3396]111        {
[3908]112          this->addFace (buffer+2);
[3396]113        }
114     
[3908]115      else if (!strncmp(buffer, "mtllib ", 7))
[3396]116        {
[3908]117          this->readMtlLib (buffer+7);
[3396]118        }
119
[3908]120      else if (!strncmp(buffer, "usemtl ", 7))
[3396]121        {
[3913]122          this->setMaterial (buffer+7);
[3396]123        }
124
125      // case VertexNormal
[3908]126      else if (!strncmp(buffer, "vn ", 3))
[3396]127        {
[3908]128          this->addVertexNormal(buffer+3);
[3396]129        }
130     
131      // case VertexTextureCoordinate
[3908]132      else if (!strncmp(buffer, "vt ", 3))
[3396]133        {
[3908]134          this->addVertexTexture(buffer+3);
[3396]135        }
136      // case group
[3908]137      else if (!strncmp(buffer, "g ", 2))
[3396]138        {
[3908]139          this->addGroup (buffer+2);
[3396]140        }
[3908]141      else if (!strncmp(buffer, "s ", 2)) //! \todo smoothing groups have to be implemented
[3396]142        {
[3908]143          PRINTF(2)("smoothing groups not supportet yet. line: %s\n", buffer);
[3396]144        }
145    }
[3908]146  fclose (stream);
[3396]147  return true;
148}
149
150/**
151    \brief Function to read in a mtl File.
152    \param mtlFile The .mtl file to read
153
154    This Function parses all Lines of an mtl File.
155    The reason for it not to be in the materials-class is,
156    that a material does not have to be able to read itself in from a File.
157
158*/
[3916]159bool OBJModel::readMtlLib (const char* mtlFile)
[3396]160{
[4117]161  char* fileName = new char [strlen(this->objPath) + strlen(mtlFile)+1];
162  sprintf(fileName, "%s%s", this->objPath, mtlFile);
[3396]163
[3909]164  FILE* stream;
165  if( (stream = fopen (fileName, "r")) == NULL)
[3396]166    {
[4117]167      PRINTF(2)("MaterialLibrary could not be opened %s\n", fileName);
168      delete []fileName;
[3396]169      return false;
170    }
[3909]171
172  char buffer[PARSELINELENGTH];
[3915]173  Material* tmpMat = NULL;
[3911]174
[3910]175  while(fgets(buffer, PARSELINELENGTH, stream))
[3396]176    {
[3908]177      PRINTF(5)("found line in mtlFile: %s\n", buffer);
[3396]178
[3910]179      // line termiated with \0 not \n
180      if (buffer[strlen(buffer)-1] == '\n')
181        buffer[strlen(buffer)-1] = '\0';
182
[3396]183      // create new Material
[3908]184      if (!strncmp(buffer, "newmtl ", 7))
[3396]185        {
[3914]186          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
[3396]187        }
188      // setting a illumMode
[3908]189      else if (!strncmp(buffer, "illum ", 6))
[3396]190        {
[3915]191          if (likely(tmpMat != NULL))
192            tmpMat->setIllum(buffer+6);
[3396]193
194        }
195      // setting Diffuse Color
[3908]196      else if (!strncmp(buffer, "Kd ", 3))
[3396]197        {
[3915]198          if (likely(tmpMat != NULL))
199            tmpMat->setDiffuse(buffer+3);
[3396]200        }
201      // setting Ambient Color
[3908]202      else if (!strncmp(buffer, "Ka ", 3))
[3396]203        {
[3915]204          if (likely(tmpMat != NULL))
205            tmpMat->setAmbient(buffer+3);
[3396]206        }
207      // setting Specular Color
[3908]208      else if (!strncmp(buffer, "Ks ", 3))
[3396]209        {
[3915]210          if (likely(tmpMat != NULL))
211            tmpMat->setSpecular(buffer+3);
[3396]212        }
213      // setting The Specular Shininess
[3908]214      else if (!strncmp(buffer, "Ns ", 3))
[3396]215        {
[3915]216          if (likely(tmpMat != NULL))
217            tmpMat->setShininess(buffer+3);
[3396]218        }
219      // setting up transparency
[3908]220      else if (!strncmp(buffer, "d ", 2))
[3396]221        {
[3915]222          if (likely(tmpMat != NULL))
223            tmpMat->setTransparency(buffer+2);
[3396]224        }
[3908]225      else if (!strncmp(buffer, "Tf ", 3))
[3396]226        {
[3915]227          if (likely(tmpMat != NULL))
228            tmpMat->setTransparency(buffer+3);
[3396]229        }
230     
[3908]231      else if (!strncmp(buffer, "map_Kd ", 7))
[3396]232        {
[3915]233          if (likely(tmpMat != NULL))
234            tmpMat->setDiffuseMap(buffer+7);
[3396]235        }
[3908]236      else if (!strncmp(buffer, "map_Ka ", 7))
[3396]237        {
[3915]238          if (likely(tmpMat != NULL))
239            tmpMat->setAmbientMap(buffer+7);
[3396]240        }
[3908]241      else if (!strncmp(buffer, "map_Ks ", 7))
[3396]242        {
[3915]243          if (likely(tmpMat != NULL))
244            tmpMat->setSpecularMap(buffer+7);
[3396]245        }
[3908]246      else if (!strncmp(buffer, "bump ", 5))
[3396]247        {
[3915]248          if (likely(tmpMat != NULL))
249            tmpMat->setBump(buffer+7);
[3396]250        }
251     
252
253    }
[3909]254  fclose(stream);
[3396]255  delete []fileName;
256  return true;
257}
Note: See TracBrowser for help on using the repository browser.