Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/importer/object.cc @ 2846

Last change on this file since 2846 was 2846, checked in by bensch, 20 years ago

orxonox/trunk/importer: bug-fix. closed file at the wrong position

File size: 12.7 KB
Line 
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
16#include "object.h"
17
18/**
19   \brief Creates a 3D-Object, but does not load any 3D-models
20   pretty useless
21*/
22Object::Object ()
23{
24
25  initialize();
26  //  importFile ("");
27  BoxObject();
28
29  finalize();
30}
31
32/**
33   \brief Crates a 3D-Object and loads in a File
34   \param fileName file to parse and load (must be a .obj file)
35*/
36Object::Object(char* fileName)
37{
38  initialize();
39
40  importFile (fileName);
41
42  finalize();
43}
44
45/**
46   \brief Crates a 3D-Object, loads in a File and scales it.
47   \param fileName file to parse and load (must be a .obj file)
48   \param scaling The factor that the object will be scaled with.
49*/
50
51Object::Object(char* fileName, float scaling)
52{
53  initialize();
54  scaleFactor = scaling;
55
56  importFile (fileName);
57
58  finalize();
59}
60
61/**
62    \brief initializes the Object
63    This Function initializes all the needed arrays, Lists and clientStates
64*/
65bool Object::initialize (void)
66{
67  if (verbose >=3)
68    printf("new 3D-Object is being created\n"); 
69  faceMode = -1;
70  if ( (listNumber = glGenLists(1)) == 0 )
71    {
72      printf ("list could not be created for this Object\n");
73      return false;
74    }
75
76  mtlFileName = "";
77  scaleFactor = 1;
78  vertices = new Array();
79  normals = new Array();
80  vTexture = new Array();
81
82  glNewList (listNumber, GL_COMPILE);
83  glEnableClientState (GL_VERTEX_ARRAY);
84  glEnableClientState (GL_NORMAL_ARRAY);
85  //  glEnableClientState (GL_TEXTURE_COORD_ARRAY);
86
87  return true;
88}
89
90/**
91   \brief Imports a obj file and handles the the relative location
92   \param fileName The file to import
93*/
94bool Object::importFile (char* fileName)
95{
96  if (verbose >=3)
97    printf("preparing to read in file: %s\n", fileName);   
98  objFileName = fileName;
99  this->readFromObjFile (objFileName);
100  return true;
101}
102
103/**
104   \brief finalizes an Object.
105   This funcion is needed, to close the glList and all the other lists.
106*/
107bool Object::finalize(void)
108{
109  if (verbose >=3)
110    printf("finalizing the 3D-Object\n"); 
111  glEnd();
112  glEndList();
113  return true;
114}
115
116/**
117   \brief Draws the Object
118   It does this by just calling the List that must have been created earlier.
119*/
120void Object::draw (void)
121{
122  if (verbose >=3)
123    printf("drawing the 3D-Object\n"); 
124  glCallList (listNumber);
125}
126
127/**
128   \brief Reads in the .obj File and sets all the Values.
129   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
130   \param fileName the File that will be parsed (.obj-file)
131*/
132bool Object::readFromObjFile (char* fileName)
133{
134  OBJ_FILE = new ifstream(fileName);
135  if (!OBJ_FILE->is_open())
136    {
137      if (verbose >=1)
138        printf ("unable to open .OBJ file: %s\n Loading Box Object instead.\n", fileName);
139      BoxObject();
140      return false;
141    }
142  objFileName = fileName;
143  char Buffer[500];
144  while(!OBJ_FILE->eof())
145    {
146      OBJ_FILE->getline(Buffer, 500);
147      if (verbose >=4)
148        printf ("Read input line: %s\n",Buffer);
149     
150
151      // case vertice
152      if (!strncmp(Buffer, "v ", 2))
153        {
154          readVertex(Buffer+2);
155        }
156
157      // case face
158      else if (!strncmp(Buffer, "f ", 2))
159        {
160          readFace (Buffer+2);
161        }
162     
163      else if (!strncmp(Buffer, "mtllib", 6))
164        {
165          readMtlLib (Buffer+7);
166        }
167
168      else if (!strncmp(Buffer, "usemtl", 6))
169        {
170          readUseMtl (Buffer+7);
171        }
172
173      // case VertexNormal
174      else if (!strncmp(Buffer, "vn ", 2))
175      {
176        readVertexNormal(Buffer+3);
177      }
178
179      // case vt
180      else if (!strncmp(Buffer, "vt ", 2))
181      {
182        readVertexTexture(Buffer+3);
183      }
184    }
185  OBJ_FILE->close();
186
187}
188
189/**
190   \brief parses a vertex-String
191   If a vertex line is found this function will inject it into the vertex-Array
192   \param vertexString The String that will be parsed.
193*/
194bool Object::readVertex (char* vertexString)
195{
196  readVertices = true;
197  char subbuffer1[20];
198  char subbuffer2[20];
199  char subbuffer3[20];
200  sscanf (vertexString, "%s %s %s", subbuffer1, subbuffer2, subbuffer3);
201  if (verbose >= 3)
202    printf ("reading in a vertex: %s %s %s\n", subbuffer1, subbuffer2, subbuffer3);
203  vertices->addEntry(atof(subbuffer1)*scaleFactor, atof(subbuffer2)*scaleFactor, atof(subbuffer3)*scaleFactor);
204  return true;
205}
206
207/**
208   \brief parses a face-string
209   If a face line is found this function will add it to the glList.
210   The function makes a difference between QUADS and TRIANGLES, and will if changed re-open, set and re-close the gl-processe.
211   \param faceString The String that will be parsed.
212*/
213bool Object::readFace (char* faceString)
214{
215  if (readVertices == true)
216    {
217      vertices->finalizeArray();
218      glVertexPointer(3, GL_FLOAT, 0, vertices->getArray());
219      normals->finalizeArray();
220      glNormalPointer(GL_FLOAT, 0, normals->getArray());
221      vTexture->finalizeArray();
222    }
223
224  readVertices = false;
225  char subbuffer1[20];
226  char subbuffer2[20];
227  char subbuffer3[20];
228  char subbuffer4[20] ="";
229  sscanf (faceString, "%s %s %s %s", subbuffer1, subbuffer2, subbuffer3, subbuffer4);
230  if (!strcmp(subbuffer4, ""))
231    {
232      if (faceMode != 3)
233        {
234          if (faceMode != -1)
235            glEnd();
236          glBegin(GL_TRIANGLES);
237        }
238     
239      faceMode = 3;
240      if (verbose >=3)
241        printf ("found triag: %s, %s, %s\n", subbuffer1, subbuffer2, subbuffer3);
242      addGLElement(subbuffer1);
243      addGLElement(subbuffer2);
244      addGLElement(subbuffer3);
245      return true;
246    }
247  else
248    {
249      if (faceMode != 4)
250        {
251          if (faceMode != -1)
252            glEnd();
253          glBegin(GL_QUADS);
254        }
255      faceMode = 4;
256      if (verbose >=3 )
257        printf ("found quad: %s, %s, %s, %s\n", subbuffer1, subbuffer2, subbuffer3, subbuffer4);
258      addGLElement(subbuffer1);
259      addGLElement(subbuffer2);
260      addGLElement(subbuffer3);
261      addGLElement(subbuffer4);
262      return true;
263    }
264}
265
266/**
267   \brief Adds a Face-element (one vertex of a face) with all its information.
268   It does this by searching:
269   1. The Vertex itself
270   2. The VertexNormale
271   3. The VertexTextureCoordinate
272   merging this information, the face will be drawn.
273
274*/
275bool Object::addGLElement (char* elementString)
276{
277  if (verbose >=3)
278    printf ("importing grafical Element.... including to openGL\n");
279  char* vertex = elementString;
280
281  char* texture;
282  texture = strstr (vertex, "/");
283  texture[0] = '\0';
284  texture ++;
285  glTexCoord2fv(vTexture->getArray()+(atoi(texture)-1)*2);
286
287  char* normal;
288  if ((normal = strstr (texture, "/")) !=NULL)
289    {
290      normal[0] = '\0';
291      normal ++;
292      //glArrayElement(atoi(vertex)-1);
293      glNormal3fv(normals->getArray() +(atoi(normal)-1)*3);
294    }
295  glVertex3fv(vertices->getArray() +(atoi(vertex)-1)*3);
296
297}
298
299/**
300   \brief parses a vertexNormal-String
301   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
302   \param normalString The String that will be parsed.
303*/
304bool Object::readVertexNormal (char* normalString)
305{
306  readVertices = true;
307  char subbuffer1[20];
308  char subbuffer2[20];
309  char subbuffer3[20];
310  sscanf (normalString, "%s %s %s", subbuffer1, subbuffer2, subbuffer3);
311  if (verbose >=3 )
312    printf("found vertex-Normal %s, %s, %s\n", subbuffer1,subbuffer2,subbuffer3);
313  normals->addEntry(atof(subbuffer1), atof(subbuffer2), atof(subbuffer3));
314  return true;
315}
316
317/**
318   \brief parses a vertexTextureCoordinate-String
319   If a vertexTextureCoordinate line is found this function will inject it into the vertexTexture-Array
320   \param vTextureString The String that will be parsed.
321*/
322bool Object::readVertexTexture (char* vTextureString)
323{
324  readVertices = true;
325  char subbuffer1[20];
326  char subbuffer2[20];
327  sscanf (vTextureString, "%s %s", subbuffer1, subbuffer2);
328  if (verbose >=3 )
329    printf("found vertex-Texture %s, %s\n", subbuffer1,subbuffer2);
330  vTexture->addEntry(atof(subbuffer1));
331  vTexture->addEntry(atof(subbuffer2));
332  return true;
333}
334
335/**
336    \brief Function to read in a mtl File.
337    this Function parses all Lines of an mtl File
338    \param mtlFile The .mtl file to read
339*/
340bool Object::readMtlLib (char* mtlFile)
341{
342  MTL_FILE = new ifstream (mtlFile);
343  if (!MTL_FILE->is_open())
344    {
345      if (verbose >= 1)
346        printf ("unable to open file: %s\n", mtlFile);
347      return false;
348    }
349  mtlFileName = mtlFile;
350  if (verbose >=2)
351    printf ("Opening mtlFile: %s\n", mtlFileName);
352  char Buffer[500];
353  vertices = new Array();
354  material = new Material();
355  Material* tmpMat = material;
356  while(!MTL_FILE->eof())
357    {
358      MTL_FILE->getline(Buffer, 500);
359      if (verbose >= 4)
360        printf("found line in mtlFile: %s\n", Buffer);
361     
362
363      // create new Material
364      if (!strncmp(Buffer, "newmtl ", 2))
365        {
366          tmpMat = tmpMat->addMaterial(Buffer+7);
367          //      printf ("%s, %p\n", tmpMat->getName(), tmpMat);
368        }
369      // setting a illumMode
370      else if (!strncmp(Buffer, "illum", 5))
371        {
372          tmpMat->setIllum(Buffer+6);
373
374        }
375      // setting Diffuse Color
376      else if (!strncmp(Buffer, "Kd", 2))
377        {
378          tmpMat->setDiffuse(Buffer+3);
379        }
380      // setting Ambient Color
381      else if (!strncmp(Buffer, "Ka", 2))
382        {
383          tmpMat->setAmbient(Buffer+3);
384        }
385      // setting Specular Color
386      else if (!strncmp(Buffer, "Ks", 2))
387        {
388          tmpMat->setSpecular(Buffer+3);
389        }
390      // setting The Specular Shininess
391      else if (!strncmp(Buffer, "Ns", 2))
392        {
393          tmpMat->setShininess(Buffer+3);
394        }
395      // setting up transparency
396      else if (!strncmp(Buffer, "d", 1))
397        {
398          tmpMat->setTransparency(Buffer+2);
399        }
400      else if (!strncpy(Buffer, "Tf", 2))
401        {
402          tmpMat->setTransparency(Buffer+3);
403        }
404
405    }
406  return true;
407}
408
409/**
410   \brief Function that selects a material, if changed in the obj file.
411   \param matString the Material that will be set.
412*/
413
414bool Object::readUseMtl (char* matString)
415{
416  if (!strcmp (mtlFileName, ""))
417    {
418      if (verbose >= 1)
419        printf ("Not using new defined material, because no mtlFile found yet\n");
420      return false;
421    }
422     
423  if (faceMode != -1)
424    glEnd();
425  faceMode = 0;
426  if (verbose >= 2)
427    printf ("using material %s for coming Faces.\n", matString);
428  material->search(matString)->select();
429}
430
431/**
432   \brief Includes a default object
433   This will inject a Cube, because this is the most basic object.
434*/
435void Object::BoxObject(void)
436{
437  readVertex ("-0.500000 -0.500000 0.500000");
438  readVertex ("0.500000 -0.500000 0.500000");
439  readVertex ("-0.500000 0.500000 0.500000");
440  readVertex ("0.500000 0.500000 0.500000");
441  readVertex ("-0.500000 0.500000 -0.500000");
442  readVertex ("0.500000 0.500000 -0.500000");
443  readVertex ("-0.500000 -0.500000 -0.500000");
444  readVertex ("0.500000 -0.500000 -0.500000");
445  readVertexTexture ("0.000000 0.000000");
446  readVertexTexture ("1.000000 0.000000");
447  readVertexTexture ("0.000000 1.000000");
448  readVertexTexture ("1.000000 1.000000");
449  readVertexTexture ("0.000000 2.000000");
450  readVertexTexture ("1.000000 2.000000");
451  readVertexTexture ("0.000000 3.000000");
452  readVertexTexture ("1.000000 3.000000");
453  readVertexTexture ("0.000000 4.000000");
454  readVertexTexture ("1.000000 4.000000");
455  readVertexTexture ("2.000000 0.000000");
456  readVertexTexture ("2.000000 1.000000");
457  readVertexTexture ("-1.000000 0.000000");
458  readVertexTexture ("-1.000000 1.000000");
459 
460  readVertexNormal ("0.000000 0.000000 1.000000");
461  readVertexNormal ("0.000000 0.000000 1.000000");
462  readVertexNormal ("0.000000 0.000000 1.000000");
463  readVertexNormal ("0.000000 0.000000 1.000000");
464  readVertexNormal ("0.000000 1.000000 0.000000");
465  readVertexNormal ("0.000000 1.000000 0.000000");
466  readVertexNormal ("0.000000 1.000000 0.000000");
467  readVertexNormal ("0.000000 1.000000 0.000000");
468  readVertexNormal ("0.000000 0.000000 -1.000000");
469  readVertexNormal ("0.000000 0.000000 -1.000000");
470  readVertexNormal ("0.000000 0.000000 -1.000000");
471  readVertexNormal ("0.000000 0.000000 -1.000000");
472  readVertexNormal ("0.000000 -1.000000 0.000000");
473  readVertexNormal ("0.000000 -1.000000 0.000000");
474  readVertexNormal ("0.000000 -1.000000 0.000000");
475  readVertexNormal ("0.000000 -1.000000 0.000000");
476  readVertexNormal ("1.000000 0.000000 0.000000");
477  readVertexNormal ("1.000000 0.000000 0.000000");
478  readVertexNormal ("1.000000 0.000000 0.000000");
479  readVertexNormal ("1.000000 0.000000 0.000000");
480  readVertexNormal ("-1.000000 0.000000 0.000000");
481  readVertexNormal ("-1.000000 0.000000 0.000000");
482  readVertexNormal ("-1.000000 0.000000 0.000000");
483  readVertexNormal ("-1.000000 0.000000 0.000000");
484
485  readFace ("1/1/1 2/2/2 4/4/3 3/3/4");
486  readFace ("3/3/5 4/4/6 6/6/7 5/5/8");
487  readFace ("5/5/9 6/6/10 8/8/11 7/7/12");
488  readFace ("7/7/13 8/8/14 2/10/15 1/9/16");
489  readFace ("2/2/17 8/11/18 6/12/19 4/4/20");
490  readFace ("7/13/21 1/1/22 3/3/23 5/14/24");
491}
Note: See TracBrowser for help on using the repository browser.