Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: model even saver now

File size: 24.9 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->next = NULL;
39}
40
41/**
42   \brief destroys a ModelFaceElement
43*/
44ModelFaceElement::~ModelFaceElement()
45{
46  if (this->next)
47    delete this->next;
48}
49
50/**
51   \brief creates a new ModelFace
52*/
53ModelFace::ModelFace()
54{
55  this->vertexCount = 0;
56
57  this->firstElem = NULL;
58 
59  this->material = NULL;
60 
61  this->next = NULL;
62
63}
64
65/**
66   \brief deletes a ModelFace
67*/
68ModelFace::~ModelFace()
69{
70  PRINTF(5)("Cleaning up Face\n");
71
72  if (this->firstElem != NULL)
73    delete this->firstElem;
74 
75  if (this->next != NULL)
76    delete this->next;
77}
78
79/**
80   \brief Creates a new ModelGroup
81*/
82ModelGroup::ModelGroup()
83{
84  PRINTF(4)("Adding new Group\n");
85  this->name = "";
86  this->faceMode = -1;
87  this->faceCount = 0; 
88  this->next = NULL;
89 
90  this->firstFace = new ModelFace;
91  this->currentFace = this->firstFace;
92}
93
94/**
95   \brief deletes a ModelGroup
96*/
97ModelGroup::~ModelGroup()
98{
99  PRINTF(5)("Cleaning up group\n");
100  if (this->firstFace != NULL)
101    delete this->firstFace;
102
103  if (this->next !=NULL)
104    delete this->next;
105}
106
107/**
108   \brief cleans up a ModelGroup
109
110   actually does the same as the delete Operator, but does not delete the predecessing group
111*/
112void ModelGroup::cleanup(void)
113{
114  PRINTF(5)("Cleaning up group\n");
115  if (this->firstFace)
116    delete this->firstFace;
117  this->firstFace = NULL;
118  if (this->next)
119    this->next->cleanup();
120}
121
122
123/////////////
124/// MODEL ///
125/////////////
126/**
127   \brief Creates a 3D-Model.
128
129   assigns it a Name and a Type
130*/
131Model::Model(const char* modelName, MODEL_TYPE type)
132{
133  PRINTF(4)("new 3D-Model is being created\n"); 
134  this->name = NULL;
135  this->setName(modelName);
136  this->type = type;
137
138  this->finalized = false;
139  // setting the start group;
140  this->currentGroup = this->firstGroup = new ModelGroup;
141  this->groupCount = 0;
142  this->vertexCount = 0;
143  this->normalCount = 0;
144  this->texCoordCount = 0;
145 
146  this->scaleFactor = 1;
147
148  this->vertices = new Array();
149  this->vTexture = new Array();
150  this->normals = new Array();
151
152  this->materialList = new tList<Material>;
153
154  if (this->type == MODEL_VERTEX_ARRAY)
155    glEnableClientState(GL_VERTEX_ARRAY | GL_NORMAL_ARRAY | GL_TEXTURE_COORD_ARRAY);
156}
157
158/**
159   \brief deletes an Model.
160
161   Looks if any from model allocated space is still in use, and if so deleted it.
162*/
163Model::~Model(void)
164{
165  PRINTF(4)("Deleting Model ");
166  if (this->name)
167    {
168      PRINT(4)("%s\n", this->name);
169      delete []this->name;
170    }
171  else
172      PRINT(4)("\n");
173
174  PRINTF(5)("Deleting display Lists.\n");
175  delete this->firstGroup;
176
177  // deleting Arrays
178  this->deleteArrays();
179
180  // deleting the MaterialList
181  PRINTF(5)("Deleting Materials.\n");
182  tIterator<Material>* tmpIt = this->materialList->getIterator();
183  Material* material = tmpIt->nextElement();
184
185  //! \todo do we really have to delete this material??
186  while(material)
187    {
188      delete material;
189      material = tmpIt->nextElement();
190    }
191  delete tmpIt;
192  delete materialList;
193}
194
195/**
196   \brief Finalizes an Object. This can be done outside of the Class.
197*/
198void Model::finalize(void)
199{
200  // this creates the display List.
201  this->importToDisplayList();
202 
203
204  // deletes everything we allocated.
205  if (this->type == MODEL_DISPLAY_LIST)
206    this->deleteArrays();
207  this->cleanup();
208
209  this->finalized = true;
210}
211
212//////////
213// DRAW //
214//////////
215/**
216   \brief Draws the Models of all Groups.
217   It does this by just calling the Lists that must have been created earlier.
218*/
219void Model::draw (void) const
220{
221  PRINTF(4)("drawing the 3D-Models\n"); 
222  ModelGroup* tmpGroup = this->firstGroup;
223  while (tmpGroup != NULL)
224    {
225      PRINTF(5)("Drawing model %s\n", tmpGroup->name);
226      glCallList (tmpGroup->listNumber);
227      tmpGroup = tmpGroup->next;
228    }
229}
230
231/**
232   \brief Draws the Model number groupNumber
233   \param groupNumber The number of the group that will be displayed.
234
235   It does this by just calling the List that must have been created earlier.
236*/
237void Model::draw (int groupNumber) const 
238{
239  if (groupNumber >= this->groupCount)
240    {
241      PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount);
242      return;
243    }
244  PRINTF(4)("drawing the requested 3D-Models if found.\n"); 
245  ModelGroup* tmpGroup = this->firstGroup;
246  int counter = 0;
247  while (tmpGroup != NULL)
248    {
249      if (counter == groupNumber)
250        {
251          PRINTF(4)("Drawing model number %i named %s\n", counter, tmpGroup->name);
252          glCallList (tmpGroup->listNumber);
253          return;
254        }
255      ++counter;
256      tmpGroup = tmpGroup->next;
257    }
258  PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->name);
259  return;
260
261}
262
263/**
264   \brief Draws the Model with a specific groupName
265   \param groupName The name of the group that will be displayed.
266
267   It does this by just calling the List that must have been created earlier.
268*/
269void Model::draw (char* groupName) const
270{
271  PRINTF(4)("drawing the requested 3D-Models if found.\n"); 
272  ModelGroup* tmpGroup = this->firstGroup;
273  while (tmpGroup != NULL)
274    {
275      if (!strcmp(tmpGroup->name, groupName))
276        {
277          PRINTF(4)("Drawing model %s\n", tmpGroup->name);
278          glCallList (tmpGroup->listNumber);
279          return;
280        }
281      tmpGroup = tmpGroup->next;
282    }
283  PRINTF(2)("Model Named %s in %s not Found.\n", groupName, this->name);
284  return;
285}
286
287//////////
288// INIT //
289//////////
290/**
291   \brief sets a name to the Model
292   \param name The name to set to this Model
293*/
294void Model::setName(const char* name)
295{
296  if (this->name)
297    delete []this->name;
298  if (name)
299    {
300      this->name = new char[strlen(name)+1];
301      strcpy(this->name, name);
302    }
303  else 
304    this->name = NULL;
305}
306
307/**
308   \brief deletes all the arrays
309*/
310bool Model::deleteArrays(void)
311{
312  if (this->vertices)
313    delete this->vertices;
314  if (this->vTexture)
315    delete this->vTexture;
316  if (this->normals)
317    delete this->normals;
318
319  this->vertices = NULL;
320  this->vTexture = NULL;
321  this->normals = NULL;
322}
323
324/**
325   \brief finalizes an Model.
326   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.
327*/
328bool Model::cleanup(void)
329{
330  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
331  this->firstGroup->cleanup();
332  return true; 
333}
334
335
336
337//////////
338// MESH //
339//////////
340/**
341   \brief adds a new Material to the Material List
342   \param material the Material to add
343   \returns the added material
344
345   !! beware the Material will be deleted when the Model gets deleted
346*/
347Material* Model::addMaterial(Material* material)
348{
349  this->materialList->add(material);
350  return material;
351}
352
353/**
354   \brief adds a new Material to the Material List
355   \param materialName the name of the Material to add
356   \returns the added material
357*/
358Material* Model::addMaterial(const char* materialName)
359{
360  Material* newMat = new Material();
361  newMat->setName(materialName);
362
363  // adding material to the List of materials
364  this->materialList->add(newMat); 
365  return newMat;
366}
367
368/**
369   \brief finds a Material by its name and returns it
370   \param materialName the Name of the material to search for.
371   \returns the Material if found, NULL otherwise
372*/
373Material* Model::findMaterialByName(const char* materialName)
374{
375  tIterator<Material>* tmpIt = this->materialList->getIterator();
376  Material* material = tmpIt->nextElement();
377  while(material)
378    {
379      if (!strcmp(material->getName(), materialName))
380        {
381          delete tmpIt;
382          return material;
383        }
384      material = tmpIt->nextElement();
385    }
386  delete tmpIt;
387  return NULL;
388}
389
390/**
391   \brief parses a group String
392   \param groupString the new Group to create
393
394   This function initializes a new Group.
395   With it you should be able to create Models with more than one SubModel inside
396*/
397bool Model::addGroup(const char* groupString)
398{
399  PRINTF(5)("Read Group: %s.\n", groupString);
400  if (this->groupCount != 0 && this->currentGroup->faceCount > 0)
401    {
402      //      finalizeGroup(currentGroup);
403      this->currentGroup = this->currentGroup->next = new ModelGroup;
404    }
405  // setting the group name if not default.
406  if (strcmp(groupString, "default"))
407    {
408      this->currentGroup->name = new char [strlen(groupString)+1];
409      strcpy(this->currentGroup->name, groupString);
410    }
411  ++this->groupCount;
412}
413
414/**
415   \brief parses a vertex-String
416   \param vertexString The String that will be parsed.
417
418   If a vertex line is found this function will inject it into the vertex-Array
419*/
420bool Model::addVertex (const char* vertexString)
421{
422  float subbuffer1;
423  float subbuffer2;
424  float subbuffer3;
425  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
426  PRINTF(5)("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
427  this->vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
428  this->vertexCount++;
429  return true;
430}
431
432/**
433   \brief parses a vertex-String
434   \param x the X-coordinate of the Vertex to add.
435   \param y the Y-coordinate of the Vertex to add.
436   \param z the Z-coordinate of the Vertex to add.
437   
438*/
439bool Model::addVertex(float x, float y, float z)
440{
441  PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
442  this->vertices->addEntry(x*scaleFactor, y*scaleFactor, z*scaleFactor);
443  this->vertexCount++;
444  return true;
445}
446
447/**
448   \brief parses a vertexNormal-String
449   \param normalString The String that will be parsed.
450
451   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
452*/
453bool Model::addVertexNormal (const char* normalString)
454{
455  float subbuffer1;
456  float subbuffer2;
457  float subbuffer3;
458  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
459  PRINTF(5)("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
460  this->normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
461  this->normalCount++;
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  this->normalCount++;
478  return true;
479}
480
481/**
482   \brief parses a vertexTextureCoordinate-String
483   \param vTextureString The String that will be parsed.
484
485   If a vertexTextureCoordinate line is found,
486   this function will inject it into the vertexTexture-Array
487*/
488bool Model::addVertexTexture (const char* vTextureString)
489{
490  float subbuffer1;
491  float subbuffer2;
492  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
493  PRINTF(5)("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
494  this->vTexture->addEntry(subbuffer1);
495  this->vTexture->addEntry(subbuffer2);
496  this->texCoordCount++;
497  return true;
498}
499
500/**
501   \brief adds a Texture Coordinate
502   \param u The u coordinate of the TextureCoordinate.
503   \param v The y coordinate of the TextureCoordinate.
504
505   If a TextureCoordinate line is found this function will inject it into the TextureCoordinate-Array
506*/
507bool Model::addVertexTexture(float u, float v)
508{
509  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
510  this->vTexture->addEntry(u);
511  this->vTexture->addEntry(v);
512  this->texCoordCount++;
513  return true;
514}
515
516/**
517   \brief parses a face-string
518   \param faceString The String that will be parsed.
519
520   If a face line is found this function will add it to the glList.
521*/
522bool Model::addFace (const char* faceString)
523{
524  if (this->currentGroup->faceCount >0)
525    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
526
527  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
528  tmpElem->next = NULL;
529  while(strcmp (faceString, "\0"))
530    {
531      if (this->currentGroup->currentFace->vertexCount>0)
532          tmpElem = tmpElem->next = new ModelFaceElement;
533      tmpElem->next = NULL;
534
535      char tmpValue [50];
536      int tmpLen;
537      char* vertex = NULL;
538      char* texture = NULL;
539      char* normal = NULL;
540
541      sscanf (faceString, "%s", tmpValue);
542      tmpLen = strlen(tmpValue);
543      vertex = tmpValue;
544
545      if ((texture = strstr (vertex, "/")) != NULL)
546        {
547          texture[0] = '\0';
548          texture ++;
549         
550          if ((normal = strstr (texture, "/")) !=NULL)
551            {
552              normal[0] = '\0';
553              normal ++;
554            }     
555        }
556      if (vertex)
557        tmpElem->vertexNumber = atoi(vertex)-1;
558      else
559        tmpElem->vertexNumber = -1;
560      if (texture)
561        tmpElem->texCoordNumber = atoi(texture)-1;
562      else
563        tmpElem->texCoordNumber = -1;
564      if (normal)
565        tmpElem->normalNumber = atoi(normal)-1;
566      else
567        tmpElem->normalNumber = -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 0: vertex only, 1: vertex and normal, 2: vertex and Texture, 3 vertex, normal and texture
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) -1;
599      if (type & TEXCOORD)
600        tmpElem->texCoordNumber = va_arg (itemlist, int) -1;
601      if (type & NORMAL)
602        tmpElem->normalNumber = va_arg(itemlist, int) -1;
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  /* normaleLess-testingMode
929  this->addFace ("1 2 4 3");
930  this->addFace ("3 4 6 5");
931  this->addFace ("5 6 8 7");
932  this->addFace ("7 8 2 1");
933  this->addFace ("2 8 6 4");
934  this->addFace ("7 1 3 5");
935  */
936
937  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,1, 2,2,2, 4,4,3, 3,3,4);
938  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 3,3,5, 4,4,6, 6,6,7, 5,5,8);
939  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 5,5,9, 6,6,10, 8,8,11, 7,7,12);
940  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,7,13, 8,8,14, 2,10,15, 1,9,16);
941  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,17, 8,11,18, 6,12,19, 4,4,20);
942  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,13,21, 1,1,22, 3,3,23, 5,14,24);
943
944}
Note: See TracBrowser for help on using the repository browser.