Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/heightMap/src/lib/graphics/importer/model.cc @ 4111

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

orxonox/trunk: merged the Trunk/importer back here.
merged with command:
svn merge -r 3918:HEAD ../../trunk/src/lib/graphics/importer/ src/lib/graphics/importer/

this fixed the issue with the segfault. It really was an error in the Model-class
@nico:

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