Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/importer: delete [] array only if finalized. Typo.

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