Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: some more

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