Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: model now gets loaded in an other order first vertex is 0 not 1

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