Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4061 was 4038, checked in by bensch, 20 years ago

orxonox/trunk: seg-fault-prevention, and cleanup of model.cc

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