Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: new Model Definitions, to make it more safe (better output)

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->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      if (unlikely(tmpElem->vertexNumber > this->vertexCount))
606        PRINTF(1)("VERTEX %d IS NOT IN THE LIST -> DANGER OF SEGFAULT (max is: %d)\n", tmpElem->vertexNumber, this->vertexCount);
607      if (unlikely(tmpElem->normalNumber > this->normalCount))
608        PRINTF(1)("VERTEX %d IS NOT IN THE LIST -> DANGER OF SEGFAULT (max is: %d)\n", tmpElem->normalNumber, this->normalCount);
609      if (unlikely(tmpElem->texCoordNumber > this->texCoordCount))
610        PRINTF(1)("VERTEX %d IS NOT IN THE LIST -> DANGER OF SEGFAULT (max is: %d)\n", tmpElem->texCoordNumber, this->texCoordCount);
611    }
612  va_end(itemlist);
613
614  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2;
615}
616
617/**
618   \brief Function that selects a material, if changed in the obj file.
619   \param matString the Material that will be set.
620*/
621bool Model::setMaterial(const char* matString)
622{
623  if (this->currentGroup->faceCount > 0)
624    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
625 
626  this->currentGroup->currentFace->material = this->findMaterialByName(matString);
627
628  if (this->currentGroup->faceCount == 0)
629    this->currentGroup->faceCount ++;
630}
631
632/**
633   \brief Function that selects a material, if changed in the obj file.
634   \param mtl the Material that will be set.
635*/
636bool Model::setMaterial(Material* mtl)
637{
638  if (this->currentGroup->faceCount > 0)
639    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
640 
641  this->currentGroup->currentFace->material = mtl;
642
643  if (this->currentGroup->faceCount == 0)
644    this->currentGroup->faceCount ++;
645}
646
647/**
648   \brief A routine that is able to create normals.
649
650   The algorithm does the following:
651   1. It calculates creates Vectors for each normale, and sets them to zero.
652   2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
653   3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
654   4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
655*/
656bool Model::buildVertexNormals ()
657{ 
658  PRINTF(4)("Normals are being calculated.\n");
659
660  Vector* normArray = new Vector [vertices->getCount()/3];
661  for (int i=0; i<vertices->getCount()/3;i++)
662    normArray[i] = Vector(.0,.0,.0);
663 
664  int firstTouch;
665  int secondTouch;
666  Vector prevV;
667  Vector nextV;
668  Vector curV;
669
670  ModelGroup* tmpGroup = firstGroup;
671  while (tmpGroup)
672    {
673      ModelFace* tmpFace = tmpGroup->firstFace;
674      while (tmpFace)
675        {
676          if (tmpFace->firstElem)
677            {
678              ModelFaceElement* firstElem = tmpFace->firstElem;
679              ModelFaceElement* prevElem;
680              ModelFaceElement* curElem = firstElem;
681              ModelFaceElement* nextElem;
682              ModelFaceElement* lastElem;
683              // 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.
684              while (curElem)
685                {
686                  prevElem = curElem;
687                  curElem = curElem->next;
688                }
689              lastElem = prevElem;
690             
691              curElem = firstElem;
692              for (int j=0; j<tmpFace->vertexCount; j++)
693                {
694                  if (!(nextElem = curElem->next))
695                    nextElem = firstElem;
696                  curElem->normalNumber = curElem->vertexNumber;
697                 
698                  curV = Vector (vertices->getArray()[curElem->vertexNumber*3], vertices->getArray()[curElem->vertexNumber*3+1], vertices->getArray()[curElem->vertexNumber*3+2]);
699                  prevV = Vector (vertices->getArray()[prevElem->vertexNumber*3], vertices->getArray()[prevElem->vertexNumber*3+1], vertices->getArray()[prevElem->vertexNumber*3+2]) - curV;
700                  nextV = Vector (vertices->getArray()[nextElem->vertexNumber*3], vertices->getArray()[nextElem->vertexNumber*3+1], vertices->getArray()[nextElem->vertexNumber*3+2]) - curV;
701                  normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
702
703                  prevElem = curElem;
704                  curElem = curElem->next;
705                }
706            }
707          tmpFace = tmpFace->next;
708        }
709      tmpGroup = tmpGroup->next;
710    }
711
712  for (int i=0; i<vertices->getCount()/3;i++)
713    {
714      normArray[i].normalize();
715      PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
716     
717      this->normals->addEntry(normArray[i].x, normArray[i].y, normArray[i].z);
718
719    }
720  delete []normArray; 
721}
722
723////////////
724// openGL //
725////////////
726/**
727   \brief reads and includes the Faces/Materials into the openGL state Machine
728*/
729bool Model::importToDisplayList(void)
730{
731  // finalize the Arrays
732  this->vertices->finalizeArray();
733  this->vTexture->finalizeArray();
734  if (normals->getCount() == 0) // vertices-Array must be built for this
735    this->buildVertexNormals();
736  this->normals->finalizeArray();
737
738  this->currentGroup = this->firstGroup;
739
740  while (this->currentGroup != NULL)
741    {
742
743      // creating a glList for the Group
744      if ((this->currentGroup->listNumber = glGenLists(1)) == 0)
745        {
746          PRINTF(2)("glList could not be created for this Model\n");
747          return false;
748        }
749      glNewList (this->currentGroup->listNumber, GL_COMPILE);
750
751      // Putting Faces to GL
752      ModelFace* tmpFace = this->currentGroup->firstFace;
753      while (tmpFace != NULL)
754        {
755          if (tmpFace->vertexCount == 0 && tmpFace->material != NULL)
756            {
757              if (this->currentGroup->faceMode != -1)
758                glEnd();
759              this->currentGroup->faceMode = 0;
760              Material* tmpMat;
761              if (tmpFace->material != NULL)
762                {
763                  tmpFace->material->select();
764                  PRINTF(5)("using material %s for coming Faces.\n", tmpFace->material->getName());
765                }
766            }
767
768          else if (tmpFace->vertexCount == 3)
769            {
770              if (this->currentGroup->faceMode != 3)
771                {
772                  if (this->currentGroup->faceMode != -1)
773                    glEnd();
774                  glBegin(GL_TRIANGLES);
775                }
776             
777              this->currentGroup->faceMode = 3;
778              PRINTF(5)("found triag.\n");
779            }
780         
781          else if (tmpFace->vertexCount == 4)
782            {
783              if (this->currentGroup->faceMode != 4)
784                {
785                  if (this->currentGroup->faceMode != -1)
786                    glEnd();
787                  glBegin(GL_QUADS);
788                }
789              this->currentGroup->faceMode = 4;
790              PRINTF(5)("found quad.\n");
791            }
792         
793          else if (tmpFace->vertexCount > 4)
794            {
795              if (this->currentGroup->faceMode != -1)
796                glEnd();
797              glBegin(GL_POLYGON);
798              PRINTF(5)("Polygon with %i faces found.", tmpFace->vertexCount);
799              this->currentGroup->faceMode = tmpFace->vertexCount;
800            }
801         
802          ModelFaceElement* tmpElem = tmpFace->firstElem;
803          while (tmpElem != NULL)
804            {
805              //      PRINTF(2)("%s\n", tmpElem->value);
806              this->addGLElement(tmpElem);
807              tmpElem = tmpElem->next;
808            }
809          tmpFace = tmpFace->next;
810        }
811      glEnd();
812      glEndList();
813
814      this->currentGroup = this->currentGroup->next;
815    } 
816}
817
818/**
819   \brief reads and includes the Faces/Materials into the openGL state Machine
820*/
821bool Model::importToVertexArray(void)
822{
823  // finalize the Arrays
824  this->vertices->finalizeArray();
825  this->vTexture->finalizeArray();
826  if (normals->getCount() == 0) // vertices-Array must be built for this
827    this->buildVertexNormals();
828  this->normals->finalizeArray();
829
830  this->currentGroup = this->firstGroup;
831  glVertexPointer(3, GL_FLOAT, 0, this->vertices->getArray());
832  glNormalPointer(3, 0, this->normals->getArray());
833  glTexCoordPointer(2, GL_FLOAT, 0, this->vTexture->getArray());
834}
835
836
837
838/**
839   \brief Adds a Face-element (one vertex of a face) with all its information.
840   \param elem The FaceElement to add to the OpenGL-environment.
841
842   It does this by searching:
843   1. The Vertex itself
844   2. The VertexNormale
845   3. The VertexTextureCoordinate
846   merging this information, the face will be drawn.
847*/
848bool Model::addGLElement (ModelFaceElement* elem)
849{
850  PRINTF(5)("importing grafical Element to openGL.\n");
851
852  if (elem->texCoordNumber != -1)
853    glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
854  if (elem->normalNumber != -1)
855    glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
856  if (elem->vertexNumber != -1)
857    glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
858}
859
860/**
861   \brief Includes a default model
862
863   This will inject a Cube, because this is the most basic model.
864*/
865void Model::cubeModel(void)
866{
867  this->addVertex (-0.5, -0.5, 0.5);
868  this->addVertex (0.5, -0.5, 0.5);
869  this->addVertex (-0.5, 0.5, 0.5);
870  this->addVertex (0.5, 0.5, 0.5);
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
876  this->addVertexTexture (0.0, 0.0);
877  this->addVertexTexture (1.0, 0.0);
878  this->addVertexTexture (0.0, 1.0);
879  this->addVertexTexture (1.0, 1.0);
880  this->addVertexTexture (0.0, 2.0);
881  this->addVertexTexture (1.0, 2.0);
882  this->addVertexTexture (0.0, 3.0);
883  this->addVertexTexture (1.0, 3.0);
884  this->addVertexTexture (0.0, 4.0);
885  this->addVertexTexture (1.0, 4.0);
886  this->addVertexTexture (2.0, 0.0);
887  this->addVertexTexture (2.0, 1.0);
888  this->addVertexTexture (-1.0, 0.0);
889  this->addVertexTexture (-1.0, 1.0);
890
891  this->addVertexNormal (0.0, 0.0, 1.0);
892  this->addVertexNormal (0.0, 0.0, 1.0);
893  this->addVertexNormal (0.0, 0.0, 1.0);
894  this->addVertexNormal (0.0, 0.0, 1.0);
895  this->addVertexNormal (0.0, 1.0, 0.0);
896  this->addVertexNormal (0.0, 1.0, 0.0);
897  this->addVertexNormal (0.0, 1.0, 0.0);
898  this->addVertexNormal (0.0, 1.0, 0.0);
899  this->addVertexNormal (0.0, 0.0, -1.0);
900  this->addVertexNormal (0.0, 0.0, -1.0);
901  this->addVertexNormal (0.0, 0.0, -1.0);
902  this->addVertexNormal (0.0, 0.0, -1.0);
903  this->addVertexNormal (0.0, -1.0, 0.0);
904  this->addVertexNormal (0.0, -1.0, 0.0);
905  this->addVertexNormal (0.0, -1.0, 0.0);
906  this->addVertexNormal (0.0, -1.0, 0.0);
907  this->addVertexNormal (1.0, 0.0, 0.0);
908  this->addVertexNormal (1.0, 0.0, 0.0);
909  this->addVertexNormal (1.0, 0.0, 0.0);
910  this->addVertexNormal (1.0, 0.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
916  /* normaleLess-testingMode
917  this->addFace ("1 2 4 3");
918  this->addFace ("3 4 6 5");
919  this->addFace ("5 6 8 7");
920  this->addFace ("7 8 2 1");
921  this->addFace ("2 8 6 4");
922  this->addFace ("7 1 3 5");
923  */
924
925  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,1, 2,2,2, 4,4,3, 3,3,4);
926  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 3,3,5, 4,4,6, 6,6,7, 5,5,8);
927  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 5,5,9, 6,6,10, 8,8,11, 7,7,12);
928  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,7,13, 8,8,14, 2,10,15, 1,9,16);
929  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,17, 8,11,18, 6,12,19, 4,4,20);
930  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,13,21, 1,1,22, 3,3,23, 5,14,24);
931
932}
Note: See TracBrowser for help on using the repository browser.