Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/importer: doxygen tags added

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