Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the spaceshipcontroll branche into the trunk
merged with command
svn merge -r6036:HEAD spaceshipcontrol/ ../trunk/
no conflicts

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