Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: changed (void) → ()

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