Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/importer/model.cc @ 3917

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

orxonox/trunk: minor

File size: 24.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#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
17
18#include "model.h"
19
20#include <math.h>
21#include <stdarg.h>
22
23#include "array.h"
24#include "vector.h"
25#include "list.h"
26
27using namespace std;
28
29//////////////////
30// DE-CONSTRUCT //
31//////////////////
32/**
33   \brief Creates a 3D-Model. and assigns it a Name.
34*/
35Model::Model(const char* modelName, MODEL_TYPE type)
36{
37  PRINTF(4)("new 3D-Model is being created\n"); 
38  this->name = NULL;
39  this->setName(modelName);
40  this->type = type;
41
42  this->finalized = false;
43  // setting the start group;
44  this->firstGroup = new Group;
45  this->currentGroup = this->firstGroup;
46  this->groupCount = 0;
47 
48  this->initGroup (this->currentGroup);
49  this->scaleFactor = 1;
50
51  this->vertices = new Array();
52  this->vTexture = new Array();
53  this->normals = new Array();
54
55  this->materialList = new tList<Material>;
56
57  if (this->type == MODEL_VERTEX_ARRAY)
58    glEnableClientState(GL_VERTEX_ARRAY | GL_NORMAL_ARRAY | GL_TEXTURE_COORD_ARRAY);
59}
60
61/**
62   \brief deletes an Model.
63
64   Looks if any from model allocated space is still in use, and if so deleted it.
65*/
66Model::~Model(void)
67{
68  PRINTF(4)("Deleting Model ");
69  if (this->name)
70    {
71      PRINT(4)("%s\n", this->name);
72      delete []this->name;
73    }
74  else
75      PRINT(4)("\n");
76
77  PRINTF(5)("Deleting display Lists.\n");
78  Group* walker = this->firstGroup;
79  while (walker != NULL)
80    {
81      glDeleteLists (walker->listNumber, 1);
82      Group* delWalker = walker;
83      walker = walker->next;
84      delete delWalker;
85    }
86
87  // deleting Arrays
88  this->deleteArrays();
89
90  // deleting the MaterialList
91  PRINTF(5)("Deleting Materials.\n");
92  tIterator<Material>* tmpIt = this->materialList->getIterator();
93  Material* material = tmpIt->nextElement();
94  while(material)
95    {
96      delete material;
97      material = tmpIt->nextElement();
98    }
99  delete tmpIt;
100  delete materialList;
101}
102
103/**
104   \brief Finalizes an Object. This can be done outside of the Class.
105*/
106void Model::finalize(void)
107{
108  // this creates the display List.
109  this->importToDisplayList();
110 
111
112  // deletes everything we allocated.
113  if (this->type == MODEL_DISPLAY_LIST)
114    this->deleteArrays();
115  this->cleanup();
116
117  this->finalized = true;
118}
119
120//////////
121// DRAW //
122//////////
123/**
124   \brief Draws the Models of all Groups.
125   It does this by just calling the Lists that must have been created earlier.
126*/
127void Model::draw (void) const
128{
129  PRINTF(4)("drawing the 3D-Models\n"); 
130  Group* walker = this->firstGroup;
131  while (walker != NULL)
132    {
133      PRINTF(5)("Drawing model %s\n", walker->name);
134      glCallList (walker->listNumber);
135      walker = walker->next;
136    }
137}
138
139/**
140   \brief Draws the Model number groupNumber
141   \param groupNumber The number of the group that will be displayed.
142
143   It does this by just calling the List that must have been created earlier.
144*/
145void Model::draw (int groupNumber) const 
146{
147  if (groupNumber >= this->groupCount)
148    {
149      PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount);
150      return;
151    }
152  PRINTF(4)("drawing the requested 3D-Models if found.\n"); 
153  Group* walker = this->firstGroup;
154  int counter = 0;
155  while (walker != NULL)
156    {
157      if (counter == groupNumber)
158        {
159          PRINTF(4)("Drawing model number %i named %s\n", counter, walker->name);
160          glCallList (walker->listNumber);
161          return;
162        }
163      ++counter;
164      walker = walker->next;
165    }
166  PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->name);
167  return;
168
169}
170
171/**
172   \brief Draws the Model with a specific groupName
173   \param groupName The name of the group that will be displayed.
174
175   It does this by just calling the List that must have been created earlier.
176*/
177void Model::draw (char* groupName) const
178{
179  PRINTF(4)("drawing the requested 3D-Models if found.\n"); 
180  Group* walker = this->firstGroup;
181  while (walker != NULL)
182    {
183      if (!strcmp(walker->name, groupName))
184        {
185          PRINTF(4)("Drawing model %s\n", walker->name);
186          glCallList (walker->listNumber);
187          return;
188        }
189      walker = walker->next;
190    }
191  PRINTF(2)("Model Named %s in %s not Found.\n", groupName, this->name);
192  return;
193}
194
195/**
196   \returns Count of the Models in this File
197*/
198int Model::getGroupCount (void) const
199{
200  return this->groupCount;
201}
202
203//////////
204// INIT //
205//////////
206/**
207   \brief sets a name to the Model
208   \param name The name to set to this Model
209*/
210void Model::setName(const char* name)
211{
212  if (this->name) 
213    delete this->name;
214  if (name)
215    {
216      this->name = new char[strlen(name)+1];
217      strcpy(this->name, name);
218    }
219  else 
220    this->name = NULL;
221}
222
223/**
224   \brief initializes a new Group model
225   \param group the group that should be initialized.
226   \todo Maybe Group should be a Class, because it does a lot of stuff
227   
228*/
229bool Model::initGroup(Group* group)
230{
231  PRINTF(4)("Adding new Group\n");
232  group->name = "";
233  group->faceMode = -1;
234  group->faceCount = 0; 
235  group->next = NULL;
236
237  group->firstFace = new Face;
238  this->initFace (group->firstFace);
239  group->currentFace = group->firstFace;
240}
241
242/**
243   \brief initializes a new Face. (sets default Values)
244   \param face The face to initialize
245*/
246bool Model::initFace (Face* face)
247{
248  face->vertexCount = 0;
249
250  face->firstElem = NULL;
251 
252  face->material = NULL;
253 
254  face->next = NULL;
255
256  return true;
257}
258
259/**
260   \brief deletes all the arrays
261*/
262bool Model::deleteArrays(void)
263{
264  if (this->vertices)
265    delete this->vertices;
266  if (this->vTexture)
267    delete this->vTexture;
268  if (this->normals)
269    delete this->normals;
270  this->vertices = NULL;
271  this->vTexture = NULL;
272  this->normals = NULL;
273}
274
275/**
276   \brief finalizes an Model.
277   This funcion is needed, to delete all the Lists, and arrays that are no more needed because they are already imported into openGL. This will be applied at the end of the importing Process.
278*/
279bool Model::cleanup(void)
280{
281  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
282  this->cleanupGroup(this->firstGroup);
283  return true; 
284}
285
286/**
287   \brief Cleans up all groups starting from group.
288   \param group the first Group to clean
289*/
290bool Model::cleanupGroup (Group* group)
291{
292  PRINTF(5)("Cleaning up group\n");
293  if (group->firstFace != NULL)
294    {
295      cleanupFace (group->firstFace);
296      delete group->firstFace;
297    }
298
299  if (group->next !=NULL)
300    cleanupGroup (group->next);
301  return true;
302}
303
304/**
305   \brief Cleans up all Faces starting from face until NULL is reached.
306   \param face the first face to clean.
307*/
308bool Model::cleanupFace (Face* face)
309{
310  PRINTF(5)("Cleaning up Face\n");
311
312  if (face->firstElem != NULL)
313    {
314      this->cleanupFaceElement(face->firstElem);
315      delete face->firstElem;
316    }
317     
318  if (face->next != NULL)
319    {
320      this->cleanupFace (face->next);
321      delete face->next;
322    }
323}
324
325/**
326   \brief Cleans up all FaceElements starting from faceElem.
327   \param faceElem the first FaceElement to clean.
328*/
329bool Model::cleanupFaceElement(FaceElement* faceElem)
330{
331  if (faceElem->next != NULL)
332    {
333      this->cleanupFaceElement (faceElem->next);
334      delete faceElem->next;
335    }
336}
337
338//////////
339// MESH //
340//////////
341/**
342   \brief adds a new Material to the Material List
343   \param material the Material to add
344   \returns the added material
345
346   !! beware the Material will be deleted when the Model gets deleted
347*/
348Material* Model::addMaterial(Material* material)
349{
350  this->materialList->add(material);
351  return material;
352}
353
354/**
355   \brief adds a new Material to the Material List
356   \param material the name of the Material to add
357   \returns the added material
358*/
359Material* Model::addMaterial(const char* materialName)
360{
361 
362  Material* newMat = new Material();
363  newMat->setName(materialName);
364
365  // adding material to the List of materials
366  this->materialList->add(newMat); 
367  return newMat;
368}
369
370/**
371   \brief finds a Material by its name and returns it
372   \param materialName the Name of the material to search for.
373   \returns the Material if found, NULL otherwise
374*/
375Material* Model::findMaterialByName(const char* materialName)
376{
377  tIterator<Material>* tmpIt = this->materialList->getIterator();
378  Material* material = tmpIt->nextElement();
379  while(material)
380    {
381      if (!strcmp(material->getName(), materialName))
382        {
383          delete tmpIt;
384          return material;
385        }
386      material = tmpIt->nextElement();
387    }
388  delete tmpIt;
389  return NULL;
390}
391
392/**
393   \brief parses a group String
394   \param groupString the new Group to create
395
396   This function initializes a new Group.
397   With it you should be able to import .obj-files with more than one Models inside.
398*/
399bool Model::addGroup (const char* groupString)
400{
401  PRINTF(5)("Read Group: %s.\n", groupString);
402  if (this->groupCount != 0 && this->currentGroup->faceCount>0)
403    {
404      //      finalizeGroup(currentGroup);
405      this->currentGroup = this->currentGroup->next = new Group;
406      this->initGroup(this->currentGroup);
407    }
408  // setting the group name if not default.
409  if (strcmp(groupString, "default"))
410    {
411      this->currentGroup->name = new char [strlen(groupString)+1];
412      strcpy(this->currentGroup->name, groupString);
413    }
414  ++this->groupCount;
415}
416
417/**
418   \brief parses a vertex-String
419   \param vertexString The String that will be parsed.
420
421   If a vertex line is found this function will inject it into the vertex-Array
422*/
423bool Model::addVertex (const char* vertexString)
424{
425  float subbuffer1;
426  float subbuffer2;
427  float subbuffer3;
428  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
429  PRINTF(5)("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
430  this->vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
431  return true;
432}
433
434/**
435   \brief parses a vertex-String
436   \param x the X-coordinate of the Vertex to add.
437   \param y the Y-coordinate of the Vertex to add.
438   \param z the Z-coordinate of the Vertex to add.
439   
440*/
441bool Model::addVertex(float x, float y, float z)
442{
443  PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
444  this->vertices->addEntry(x*scaleFactor, y*scaleFactor, z*scaleFactor);
445  return true;
446}
447
448/**
449   \brief parses a vertexNormal-String
450   \param normalString The String that will be parsed.
451
452   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
453*/
454bool Model::addVertexNormal (const char* normalString)
455{
456  float subbuffer1;
457  float subbuffer2;
458  float subbuffer3;
459  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
460  PRINTF(5)("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
461  this->normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
462  return true;
463}
464
465/**
466   \brief adds a VertexNormal.
467   \param x The x coordinate of the Normal.
468   \param y The y coordinate of the Normal.
469   \param z The z coordinate of the Normal.
470
471   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
472*/
473bool Model::addVertexNormal(float x, float y, float z)
474{
475  PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
476  this->normals->addEntry(x, y, z);
477}
478
479/**
480   \brief parses a vertexTextureCoordinate-String
481   \param vTextureString The String that will be parsed.
482
483   If a vertexTextureCoordinate line is found,
484   this function will inject it into the vertexTexture-Array
485*/
486bool Model::addVertexTexture (const char* vTextureString)
487{
488  float subbuffer1;
489  float subbuffer2;
490  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
491  PRINTF(5)("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
492  this->vTexture->addEntry(subbuffer1);
493  this->vTexture->addEntry(subbuffer2);
494  return true;
495}
496
497/**
498   \brief adds a Texture Coordinate
499   \param u The u coordinate of the TextureCoordinate.
500   \param v The y coordinate of the TextureCoordinate.
501
502   If a TextureCoordinate line is found this function will inject it into the TextureCoordinate-Array
503*/
504bool Model::addVertexTexture(float u, float v)
505{
506  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
507  this->vTexture->addEntry(u);
508  this->vTexture->addEntry(v);
509}
510
511/**
512   \brief parses a face-string
513   \param faceString The String that will be parsed.
514
515   If a face line is found this function will add it to the glList.
516*/
517bool Model::addFace (const char* faceString)
518{
519  if (this->currentGroup->faceCount >0)
520    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
521  this->initFace (this->currentGroup->currentFace);
522
523  FaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new FaceElement;
524  tmpElem->next = NULL;
525  while(strcmp (faceString, "\0"))
526    {
527      if (this->currentGroup->currentFace->vertexCount>0)
528          tmpElem = tmpElem->next = new FaceElement;
529      tmpElem->next = NULL;
530
531      char tmpValue [50];
532      int tmpLen;
533      char* vertex = NULL;
534      char* texture = NULL;
535      char* normal = NULL;
536
537      sscanf (faceString, "%s", tmpValue);
538      tmpLen = strlen(tmpValue);
539      vertex = tmpValue;
540
541      if ((texture = strstr (vertex, "/")) != NULL)
542        {
543          texture[0] = '\0';
544          texture ++;
545         
546          if ((normal = strstr (texture, "/")) !=NULL)
547            {
548              normal[0] = '\0';
549              normal ++;
550            }     
551        }
552      if (vertex)
553        tmpElem->vertexNumber = atoi(vertex)-1;
554      else
555        tmpElem->vertexNumber = -1;
556      if (texture)
557        tmpElem->texCoordNumber = atoi(texture)-1;
558      else
559        tmpElem->texCoordNumber = -1;
560      if (normal)
561        tmpElem->normalNumber = atoi(normal)-1;
562      else
563        tmpElem->normalNumber = -1;
564
565      faceString += tmpLen;
566      if (strcmp (faceString, "\0"))
567        faceString++;
568      this->currentGroup->currentFace->vertexCount++;
569    }
570
571  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
572}
573
574/**
575   \brief adds a new Face
576   \param faceElemCount the number of Vertices to add to the Face.
577   \param type 0: vertex only, 1: vertex and normal, 2: vertex and Texture, 3 vertex, normal and texture
578*/
579bool Model::addFace(int faceElemCount, VERTEX_FORMAT type, ...)
580{
581   if (this->currentGroup->faceCount > 0)
582    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
583  this->initFace (this->currentGroup->currentFace);
584
585  FaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new FaceElement;
586  tmpElem->next = NULL;
587 
588  va_list itemlist;
589  va_start (itemlist, type);
590
591  for (int i = 0; i < faceElemCount; i++)
592    {
593      if (this->currentGroup->currentFace->vertexCount>0)
594          tmpElem = tmpElem->next = new FaceElement;
595      tmpElem->next = NULL;
596
597      tmpElem->vertexNumber = va_arg (itemlist, int) -1;
598      if (type & TEXCOORD)
599        tmpElem->texCoordNumber = va_arg (itemlist, int) -1;
600      if (type & NORMAL)
601        tmpElem->normalNumber = va_arg(itemlist, int) -1;
602      this->currentGroup->currentFace->vertexCount++;
603    }
604  va_end(itemlist);
605
606  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2;
607}
608
609/**
610   \brief Function that selects a material, if changed in the obj file.
611   \param matString the Material that will be set.
612*/
613bool Model::setMaterial(const char* matString)
614{
615  if (this->currentGroup->faceCount > 0)
616    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
617  this->initFace (this->currentGroup->currentFace);
618 
619  this->currentGroup->currentFace->material = this->findMaterialByName(matString);
620
621  if (this->currentGroup->faceCount == 0)
622    this->currentGroup->faceCount ++;
623}
624
625/**
626   \brief Function that selects a material, if changed in the obj file.
627   \param mtl the Material that will be set.
628*/
629bool Model::setMaterial(Material* mtl)
630{
631  if (this->currentGroup->faceCount > 0)
632    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
633  this->initFace (this->currentGroup->currentFace);
634 
635  this->currentGroup->currentFace->material = mtl;
636
637  if (this->currentGroup->faceCount == 0)
638    this->currentGroup->faceCount ++;
639}
640
641/**
642   \brief A routine that is able to create normals.
643
644   The algorithm does the following:
645   1. It calculates creates Vectors for each normale, and sets them to zero.
646   2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
647   3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
648   4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
649*/
650bool Model::buildVertexNormals ()
651{ 
652  PRINTF(4)("Normals are being calculated.\n");
653
654  Vector* normArray = new Vector [vertices->getCount()/3];
655  for (int i=0; i<vertices->getCount()/3;i++)
656    normArray[i] = Vector(.0,.0,.0);
657 
658  int firstTouch;
659  int secondTouch;
660  Vector prevV;
661  Vector nextV;
662  Vector curV;
663
664  Group* tmpGroup = firstGroup;
665  while (tmpGroup)
666    {
667      Face* tmpFace = tmpGroup->firstFace;
668      while (tmpFace)
669        {
670          if (tmpFace->firstElem)
671            {
672              FaceElement* firstElem = tmpFace->firstElem;
673              FaceElement* prevElem;
674              FaceElement* curElem = firstElem;
675              FaceElement* nextElem;
676              FaceElement* lastElem;
677              // find last Element of the Chain. !! IMPORTANT:the last Element of the Chain must point to NULL, or it will resolv into an infinity-loop.
678              while (curElem)
679                {
680                  prevElem = curElem;
681                  curElem = curElem->next;
682                }
683              lastElem = prevElem;
684             
685              curElem = firstElem;
686              for (int j=0; j<tmpFace->vertexCount; j++)
687                {
688                  if (!(nextElem = curElem->next))
689                    nextElem = firstElem;
690                  curElem->normalNumber = curElem->vertexNumber;
691                 
692                  curV = Vector (vertices->getArray()[curElem->vertexNumber*3], vertices->getArray()[curElem->vertexNumber*3+1], vertices->getArray()[curElem->vertexNumber*3+2]);
693                  prevV = Vector (vertices->getArray()[prevElem->vertexNumber*3], vertices->getArray()[prevElem->vertexNumber*3+1], vertices->getArray()[prevElem->vertexNumber*3+2]) - curV;
694                  nextV = Vector (vertices->getArray()[nextElem->vertexNumber*3], vertices->getArray()[nextElem->vertexNumber*3+1], vertices->getArray()[nextElem->vertexNumber*3+2]) - curV;
695                  normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
696
697                  prevElem = curElem;
698                  curElem = curElem->next;
699                }
700            }
701          tmpFace = tmpFace->next;
702        }
703      tmpGroup = tmpGroup->next;
704    }
705
706  for (int i=0; i<vertices->getCount()/3;i++)
707    {
708      normArray[i].normalize();
709      PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
710     
711      this->normals->addEntry(normArray[i].x, normArray[i].y, normArray[i].z);
712
713    }
714  delete []normArray; 
715}
716
717////////////
718// openGL //
719////////////
720/**
721   \brief reads and includes the Faces/Materials into the openGL state Machine
722*/
723bool Model::importToDisplayList(void)
724{
725  // finalize the Arrays
726  this->vertices->finalizeArray();
727  this->vTexture->finalizeArray();
728  if (normals->getCount() == 0) // vertices-Array must be built for this
729    this->buildVertexNormals();
730  this->normals->finalizeArray();
731
732  this->currentGroup = this->firstGroup;
733
734  while (this->currentGroup != NULL)
735    {
736
737      // creating a glList for the Group
738      if ((this->currentGroup->listNumber = glGenLists(1)) == 0)
739        {
740          PRINTF(2)("glList could not be created for this Model\n");
741          return false;
742        }
743      glNewList (this->currentGroup->listNumber, GL_COMPILE);
744
745      // Putting Faces to GL
746      Face* tmpFace = this->currentGroup->firstFace;
747      while (tmpFace != NULL)
748        {
749          if (tmpFace->vertexCount == 0 && tmpFace->material != NULL)
750            {
751              if (this->currentGroup->faceMode != -1)
752                glEnd();
753              this->currentGroup->faceMode = 0;
754              Material* tmpMat;
755              if (tmpFace->material != NULL)
756                {
757                  tmpFace->material->select();
758                  PRINTF(5)("using material %s for coming Faces.\n", tmpFace->material->getName());
759                }
760            }
761
762          else if (tmpFace->vertexCount == 3)
763            {
764              if (this->currentGroup->faceMode != 3)
765                {
766                  if (this->currentGroup->faceMode != -1)
767                    glEnd();
768                  glBegin(GL_TRIANGLES);
769                }
770             
771              this->currentGroup->faceMode = 3;
772              PRINTF(5)("found triag.\n");
773            }
774         
775          else if (tmpFace->vertexCount == 4)
776            {
777              if (this->currentGroup->faceMode != 4)
778                {
779                  if (this->currentGroup->faceMode != -1)
780                    glEnd();
781                  glBegin(GL_QUADS);
782                }
783              this->currentGroup->faceMode = 4;
784              PRINTF(5)("found quad.\n");
785            }
786         
787          else if (tmpFace->vertexCount > 4)
788            {
789              if (this->currentGroup->faceMode != -1)
790                glEnd();
791              glBegin(GL_POLYGON);
792              PRINTF(5)("Polygon with %i faces found.", tmpFace->vertexCount);
793              this->currentGroup->faceMode = tmpFace->vertexCount;
794            }
795         
796          FaceElement* tmpElem = tmpFace->firstElem;
797          while (tmpElem != NULL)
798            {
799              //      PRINTF(2)("%s\n", tmpElem->value);
800              this->addGLElement(tmpElem);
801              tmpElem = tmpElem->next;
802            }
803          tmpFace = tmpFace->next;
804        }
805      glEnd();
806      glEndList();
807
808      this->currentGroup = this->currentGroup->next;
809    } 
810}
811
812/**
813   \brief reads and includes the Faces/Materials into the openGL state Machine
814*/
815bool Model::importToVertexArray(void)
816{
817  // finalize the Arrays
818  this->vertices->finalizeArray();
819  this->vTexture->finalizeArray();
820  if (normals->getCount() == 0) // vertices-Array must be built for this
821    this->buildVertexNormals();
822  this->normals->finalizeArray();
823
824  this->currentGroup = this->firstGroup;
825  glVertexPointer(3, GL_FLOAT, 0, this->vertices->getArray());
826  glNormalPointer(3, 0, this->normals->getArray());
827  glTexCoordPointer(2, GL_FLOAT, 0, this->vTexture->getArray());
828
829}
830
831
832
833/**
834   \brief Adds a Face-element (one vertex of a face) with all its information.
835   \param elem The FaceElement to add to the OpenGL-environment.
836
837   It does this by searching:
838   1. The Vertex itself
839   2. The VertexNormale
840   3. The VertexTextureCoordinate
841   merging this information, the face will be drawn.
842*/
843bool Model::addGLElement (FaceElement* elem)
844{
845  PRINTF(5)("importing grafical Element to openGL.\n");
846
847  if (elem->texCoordNumber != -1)
848    glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
849  if (elem->normalNumber != -1)
850    glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
851  if (elem->vertexNumber != -1)
852    glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
853
854}
855
856/**
857   \brief Includes a default model
858
859   This will inject a Cube, because this is the most basic model.
860*/
861void Model::cubeModel(void)
862{
863  this->addVertex (-0.5, -0.5, 0.5);
864  this->addVertex (0.5, -0.5, 0.5);
865  this->addVertex (-0.5, 0.5, 0.5);
866  this->addVertex (0.5, 0.5, 0.5);
867  this->addVertex (-0.5, 0.5, -0.5);
868  this->addVertex (0.5, 0.5, -0.5);
869  this->addVertex (-0.5, -0.5, -0.5);
870  this->addVertex (0.5, -0.5, -0.5);
871
872  this->addVertexTexture (0.0, 0.0);
873  this->addVertexTexture (1.0, 0.0);
874  this->addVertexTexture (0.0, 1.0);
875  this->addVertexTexture (1.0, 1.0);
876  this->addVertexTexture (0.0, 2.0);
877  this->addVertexTexture (1.0, 2.0);
878  this->addVertexTexture (0.0, 3.0);
879  this->addVertexTexture (1.0, 3.0);
880  this->addVertexTexture (0.0, 4.0);
881  this->addVertexTexture (1.0, 4.0);
882  this->addVertexTexture (2.0, 0.0);
883  this->addVertexTexture (2.0, 1.0);
884  this->addVertexTexture (-1.0, 0.0);
885  this->addVertexTexture (-1.0, 1.0);
886
887  this->addVertexNormal (0.0, 0.0, 1.0);
888  this->addVertexNormal (0.0, 0.0, 1.0);
889  this->addVertexNormal (0.0, 0.0, 1.0);
890  this->addVertexNormal (0.0, 0.0, 1.0);
891  this->addVertexNormal (0.0, 1.0, 0.0);
892  this->addVertexNormal (0.0, 1.0, 0.0);
893  this->addVertexNormal (0.0, 1.0, 0.0);
894  this->addVertexNormal (0.0, 1.0, 0.0);
895  this->addVertexNormal (0.0, 0.0, -1.0);
896  this->addVertexNormal (0.0, 0.0, -1.0);
897  this->addVertexNormal (0.0, 0.0, -1.0);
898  this->addVertexNormal (0.0, 0.0, -1.0);
899  this->addVertexNormal (0.0, -1.0, 0.0);
900  this->addVertexNormal (0.0, -1.0, 0.0);
901  this->addVertexNormal (0.0, -1.0, 0.0);
902  this->addVertexNormal (0.0, -1.0, 0.0);
903  this->addVertexNormal (1.0, 0.0, 0.0);
904  this->addVertexNormal (1.0, 0.0, 0.0);
905  this->addVertexNormal (1.0, 0.0, 0.0);
906  this->addVertexNormal (1.0, 0.0, 0.0);
907  this->addVertexNormal (-1.0, 0.0, 0.0);
908  this->addVertexNormal (-1.0, 0.0, 0.0);
909  this->addVertexNormal (-1.0, 0.0, 0.0);
910  this->addVertexNormal (-1.0, 0.0, 0.0);
911
912  /* normaleLess-testingMode
913  this->addFace ("1 2 4 3");
914  this->addFace ("3 4 6 5");
915  this->addFace ("5 6 8 7");
916  this->addFace ("7 8 2 1");
917  this->addFace ("2 8 6 4");
918  this->addFace ("7 1 3 5");
919  */
920
921  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,1, 2,2,2, 4,4,3, 3,3,4);
922  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 3,3,5, 4,4,6, 6,6,7, 5,5,8);
923  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 5,5,9, 6,6,10, 8,8,11, 7,7,12);
924  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,7,13, 8,8,14, 2,10,15, 1,9,16);
925  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,17, 8,11,18, 6,12,19, 4,4,20);
926  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,13,21, 1,1,22, 3,3,23, 5,14,24);
927
928}
Note: See TracBrowser for help on using the repository browser.