Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/graphics/importer/objModel.cc @ 9831

Last change on this file since 9831 was 9831, checked in by bensch, 18 years ago

added resource_obj for new resource managed obj-loader

File size: 8.3 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 <string.h>
21
22#define PARSELINELENGTH 8192
23
[3475]24#include "debug.h"
[3915]25#include "compiler.h"
[3427]26
[9715]27ObjectListDefinition(OBJModel);
[3396]28/**
[8369]29 * @brief Crates a 3D-Model, loads in a File and scales it.
[4836]30 * @param fileName file to parse and load (must be a .obj file)
31 * @param scaling The factor that the model will be scaled with.
[3396]32*/
[7221]33OBJModel::OBJModel(const std::string& fileName, float scaling)
34  : StaticModel(fileName)
[3396]35{
[9684]36  this->registerObject(this, OBJModel::_objectList);
[6162]37
[4117]38  this->objPath = "./";
39
[9830]40  this->setScaleFactor(scaling);
[3396]41
42  this->importFile (fileName);
43
[3911]44  this->finalize();
[3396]45}
46
47/**
[8369]48 * @brief deletes an OBJModel.
49 */
[3396]50OBJModel::~OBJModel()
[7221]51{ }
[3396]52
53/**
[4836]54 *  Imports a obj file and handles the the relative location
55 * @param fileName The file to import
[4117]56
57   Splits the FileName from the DirectoryName
[3396]58*/
[7221]59bool OBJModel::importFile (const std::string& fileNameInput)
[3396]60{
[7221]61  const char* fileName = fileNameInput.c_str();
[3548]62  PRINTF(4)("preparing to read in file: %s\n", fileName);
[5014]63  // splitting the
[4117]64  char* split = NULL;
[3396]65
[4117]66  if (!(split = strrchr(fileName, '/')))
67    split = strrchr(fileName, '\\'); // windows Case
68  if (split)
[3396]69    {
[4117]70      int len = split - fileName+1;
[7221]71      this->objPath =  fileName;
72      this->objPath.erase(len, this->objPath.size());
[4118]73      this->objPath[len] = '\0';
[7677]74      PRINTF(4)("Resolved file %s to Path %s.\n", fileName, this->objPath.c_str());
[3396]75    }
[4371]76  else
77    this->objPath = "./";
78  Material::addTexturePath(this->objPath);
79
[4117]80  this->readFromObjFile (fileName);
[3396]81  return true;
82}
83
84/**
[8369]85 * @brief Reads in the .obj File and sets all the Values.
86 * @param fileName the FileName of the Model.
87 *
88 * This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
89 */
[7221]90bool OBJModel::readFromObjFile(const std::string& fileName)
[3396]91{
[3908]92  FILE* stream;
[7221]93  if( (stream = fopen (fileName.c_str(), "r")) == NULL)
[3396]94    {
[7221]95      PRINTF(2)("Object File Could not be Opened %s\n", fileName.c_str());
[3396]96      return false;
97    }
98
[3908]99  char buffer[PARSELINELENGTH];
[3910]100  while(fgets(buffer, PARSELINELENGTH, stream))
101    {
102      // line termiated with \0 not \n
103      if (buffer[strlen(buffer)-1] == '\n')
[5014]104        buffer[strlen(buffer)-1] = '\0';
[3910]105
[3396]106      // case vertice
[3908]107      if (!strncmp(buffer, "v ", 2))
[5014]108        {
109          this->addVertex(buffer+2);
110        }
[3396]111
112      // case face
[3908]113      else if (!strncmp(buffer, "f ", 2))
[5014]114        {
115          this->addFace (buffer+2);
116        }
117
[3908]118      else if (!strncmp(buffer, "mtllib ", 7))
[5014]119        {
120          this->readMtlLib (buffer+7);
121        }
[3396]122
[3908]123      else if (!strncmp(buffer, "usemtl ", 7))
[5014]124        {
125          this->setMaterial (buffer+7);
126        }
[3396]127
128      // case VertexNormal
[3908]129      else if (!strncmp(buffer, "vn ", 3))
[5014]130        {
131          this->addVertexNormal(buffer+3);
132        }
133
[3396]134      // case VertexTextureCoordinate
[3908]135      else if (!strncmp(buffer, "vt ", 3))
[5014]136        {
137          this->addVertexTexture(buffer+3);
138        }
[3396]139      // case group
[3908]140      else if (!strncmp(buffer, "g ", 2))
[5014]141        {
142          this->addGroup (buffer+2);
143        }
[4836]144      else if (!strncmp(buffer, "s ", 2)) //! @todo smoothing groups have to be implemented
[5014]145        {
[5300]146          PRINTF(3)("smoothing groups not supportet yet. line: %s\n", buffer);
[5014]147        }
[3396]148    }
[3908]149  fclose (stream);
[3396]150  return true;
151}
152
[5014]153/**
[8369]154 * @brief Function to read in a mtl File.
[5300]155 * @param mtlFile The .mtl file to read
156 *
157 * This Function parses all Lines of an mtl File.
158 * The reason for it not to be in the materials-class is,
159 * that a material does not have to be able to read itself in from a File.
160 */
[7221]161bool OBJModel::readMtlLib (const std::string& mtlFile)
[3396]162{
[7221]163  std::string fileName = this->objPath + mtlFile;
[3396]164
[3909]165  FILE* stream;
[7221]166  if( (stream = fopen (fileName.c_str(), "r")) == NULL)
[3396]167    {
[7221]168      PRINTF(2)("MaterialLibrary could not be opened %s\n", fileName.c_str());
[3396]169      return false;
170    }
[3909]171
172  char buffer[PARSELINELENGTH];
[3915]173  Material* tmpMat = NULL;
[3911]174
[5319]175  while(fgets(buffer, PARSELINELENGTH, stream) != NULL)
[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')
[5014]181        buffer[strlen(buffer)-1] = '\0';
[3910]182
[3396]183      // create new Material
[3908]184      if (!strncmp(buffer, "newmtl ", 7))
[5014]185        {
186          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
187        }
[3396]188      // setting a illumMode
[3908]189      else if (!strncmp(buffer, "illum ", 6))
[5014]190        {
191          if (likely(tmpMat != NULL))
[8369]192            setIllum(tmpMat, buffer+6);
[3396]193
[5014]194        }
[3396]195      // setting Diffuse Color
[3908]196      else if (!strncmp(buffer, "Kd ", 3))
[5014]197        {
198          if (likely(tmpMat != NULL))
[8369]199            setDiffuse(tmpMat, buffer+3);
[5014]200        }
[3396]201      // setting Ambient Color
[3908]202      else if (!strncmp(buffer, "Ka ", 3))
[5014]203        {
204          if (likely(tmpMat != NULL))
[8369]205            setAmbient(tmpMat, buffer+3);
[5014]206        }
[3396]207      // setting Specular Color
[3908]208      else if (!strncmp(buffer, "Ks ", 3))
[5014]209        {
210          if (likely(tmpMat != NULL))
[8369]211            setSpecular(tmpMat, buffer+3);
[5014]212        }
[3396]213      // setting The Specular Shininess
[3908]214      else if (!strncmp(buffer, "Ns ", 3))
[5014]215        {
216          if (likely(tmpMat != NULL))
[8369]217            setShininess(tmpMat, buffer+3);
[5014]218        }
[3396]219      // setting up transparency
[3908]220      else if (!strncmp(buffer, "d ", 2))
[5014]221        {
222          if (likely(tmpMat != NULL))
[8369]223            setTransparency(tmpMat, buffer+2);
[5014]224        }
[3908]225      else if (!strncmp(buffer, "Tf ", 3))
[5014]226        {
227          if (likely(tmpMat != NULL))
[8369]228            setTransparency(tmpMat, buffer+3);
[5014]229        }
230
[3908]231      else if (!strncmp(buffer, "map_Kd ", 7))
[5014]232        {
233          if (likely(tmpMat != NULL))
234            tmpMat->setDiffuseMap(buffer+7);
235        }
[3908]236      else if (!strncmp(buffer, "map_Ka ", 7))
[5014]237        {
238          if (likely(tmpMat != NULL))
239            tmpMat->setAmbientMap(buffer+7);
240        }
[3908]241      else if (!strncmp(buffer, "map_Ks ", 7))
[5014]242        {
243          if (likely(tmpMat != NULL))
244            tmpMat->setSpecularMap(buffer+7);
245        }
[3908]246      else if (!strncmp(buffer, "bump ", 5))
[5014]247        {
248          if (likely(tmpMat != NULL))
249            tmpMat->setBump(buffer+7);
250        }
[3396]251
[5014]252
[3396]253    }
[3909]254  fclose(stream);
[3396]255  return true;
256}
[8369]257
258
259/**
260 * @brief Sets the Material Illumination Model.
261 * @param material: the Material to apply the change to.
262 * @param illu: illumination Model in char* form
263 */
264void OBJModel::setIllum (Material* material, const char* illum)
265{
266  material->setIllum (atoi(illum));
267}
268
269/**
270 * @brief Sets the Material Diffuse Color.
271 * @param material: the Material to apply the change to.
272 * @param rgb The red, green, blue channel in char format (with spaces between them)
273 */
274void OBJModel::setDiffuse (Material* material, const char* rgb)
275{
276  float r,g,b;
277  sscanf (rgb, "%f %f %f", &r, &g, &b);
278  material->setDiffuse (r, g, b);
279}
280
281/**
282 * @brief Sets the Material Ambient Color.
283 * @param material: the Material to apply the change to.
284 * @param rgb The red, green, blue channel in char format (with spaces between them)
285 */
286void OBJModel::setAmbient (Material* material, const char* rgb)
287{
288  float r,g,b;
289  sscanf (rgb, "%f %f %f", &r, &g, &b);
290  material->setAmbient (r, g, b);
291}
292
293/**
294 * @brief Sets the Material Specular Color.
295 * @param material: the Material to apply the change to.
296 * @param rgb The red, green, blue channel in char format (with spaces between them)
297 */
298void OBJModel::setSpecular (Material* material, const char* rgb)
299{
300  float r,g,b;
301  sscanf (rgb, "%f %f %f", &r, &g, &b);
302  material->setSpecular (r, g, b);
303}
304
305/**
306 * @brief Sets the Material Shininess.
307 * @param material: the Material to apply the change to.
308 * @param shini stes the Shininess from char*.
309 */
310void OBJModel::setShininess (Material* material, const char* shini)
311{
312  material->setShininess (atof(shini));
313}
314
315/**
316 * @brief Sets the Material Transparency.
317 * @param material: the Material to apply the change to.
318 * @param trans stes the Transparency from char*.
319 */
320void OBJModel::setTransparency (Material* material, const char* trans)
321{
322  material->setTransparency (atof(trans));
323}
Note: See TracBrowser for help on using the repository browser.