Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: doxygen tags

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