Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4438 was 4357, checked in by bensch, 20 years ago

orxonox/trunk: now Textures are maped as they should
before this textures where switched upside-down, now this is done in the corresponding model's textureCoordinate

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
492   !! WARNING THIS IS DIFFERNT FROM addVervexTexture(float, float); because it changes the second entry to 1-v !!
493*/
494bool Model::addVertexTexture (const char* vTextureString)
495{
496  float subbuffer1;
497  float subbuffer2;
498  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
499  PRINTF(5)("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
500  this->vTexture->addEntry(subbuffer1);
501  this->vTexture->addEntry(1 - subbuffer2);
502  this->texCoordCount++;
503  return true;
504}
505
506/**
507   \brief adds a Texture Coordinate
508   \param u The u coordinate of the TextureCoordinate.
509   \param v The y coordinate of the TextureCoordinate.
510
511   If a TextureCoordinate line is found this function will inject it into the TextureCoordinate-Array
512*/
513bool Model::addVertexTexture(float u, float v)
514{
515  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
516  this->vTexture->addEntry(u);
517  this->vTexture->addEntry(v);
518  this->texCoordCount++;
519  return true;
520}
521
522/**
523   \brief parses a face-string
524   \param faceString The String that will be parsed.
525
526   If a face line is found this function will add it to the glList.
527
528   String is different from the argument addFace, in this that the first Vertex/Normal/Texcoord is 1 instead of 0
529*/
530bool Model::addFace (const char* faceString)
531{
532  if (this->currentGroup->faceCount >0)
533    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
534
535  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
536  tmpElem->next = NULL;
537  while(strcmp (faceString, "\0"))
538    {
539      if (this->currentGroup->currentFace->vertexCount>0)
540          tmpElem = tmpElem->next = new ModelFaceElement;
541      tmpElem->next = NULL;
542
543      char tmpValue [50];
544      int tmpLen;
545      char* vertex = NULL;
546      char* texture = NULL;
547      char* normal = NULL;
548
549      sscanf (faceString, "%s", tmpValue);
550      tmpLen = strlen(tmpValue);
551      vertex = tmpValue;
552
553      if ((texture = strstr (vertex, "/")) != NULL)
554        {
555          texture[0] = '\0';
556          texture ++;
557         
558          if ((normal = strstr (texture, "/")) !=NULL)
559            {
560              normal[0] = '\0';
561              normal ++;
562            }     
563        }
564      if (vertex)
565        tmpElem->vertexNumber = atoi(vertex)-1;
566      if (texture)
567        tmpElem->texCoordNumber = atoi(texture)-1;
568      if (normal)
569        tmpElem->normalNumber = atoi(normal)-1;
570
571      faceString += tmpLen;
572      if (strcmp (faceString, "\0"))
573        faceString++;
574      this->currentGroup->currentFace->vertexCount++;
575    }
576
577  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
578}
579
580/**
581   \brief adds a new Face
582   \param faceElemCount the number of Vertices to add to the Face.
583   \param type The information Passed with each Vertex
584*/
585bool Model::addFace(int faceElemCount, VERTEX_FORMAT type, ...)
586{
587  if (this->currentGroup->faceCount > 0)
588    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
589 
590  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
591 
592  va_list itemlist;
593  va_start (itemlist, type);
594
595  for (int i = 0; i < faceElemCount; i++)
596    {
597      if (this->currentGroup->currentFace->vertexCount > 0)
598        tmpElem = tmpElem->next = new ModelFaceElement;
599
600      tmpElem->vertexNumber = va_arg (itemlist, int);
601      if (type & TEXCOORD)
602        tmpElem->texCoordNumber = va_arg (itemlist, int);
603      if (type & NORMAL)
604        tmpElem->normalNumber = va_arg(itemlist, int);
605      this->currentGroup->currentFace->vertexCount++;
606    }
607  va_end(itemlist);
608
609  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2;
610}
611
612/**
613   \brief Function that selects a material, if changed in the obj file.
614   \param matString the Material that will be set.
615*/
616bool Model::setMaterial(const char* matString)
617{
618  if (this->currentGroup->faceCount > 0)
619    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
620 
621  this->currentGroup->currentFace->material = this->findMaterialByName(matString);
622
623  if (this->currentGroup->faceCount == 0)
624    this->currentGroup->faceCount ++;
625}
626
627/**
628   \brief Function that selects a material, if changed in the obj file.
629   \param mtl the Material that will be set.
630*/
631bool Model::setMaterial(Material* mtl)
632{
633  if (this->currentGroup->faceCount > 0)
634    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
635 
636  this->currentGroup->currentFace->material = mtl;
637
638  if (this->currentGroup->faceCount == 0)
639    this->currentGroup->faceCount ++;
640}
641
642/**
643   \brief A routine that is able to create normals.
644
645   The algorithm does the following:
646   1. It calculates creates Vectors for each normale, and sets them to zero.
647   2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
648   3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
649   4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
650*/
651bool Model::buildVertexNormals ()
652{ 
653  PRINTF(4)("Normals are being calculated.\n");
654
655  Vector* normArray = new Vector [vertices->getCount()/3];
656  for (int i=0; i<vertices->getCount()/3;i++)
657    normArray[i] = Vector(.0,.0,.0);
658 
659  int firstTouch;
660  int secondTouch;
661  Vector prevV;
662  Vector nextV;
663  Vector curV;
664
665  ModelGroup* tmpGroup = firstGroup;
666  while (tmpGroup)
667    {
668      ModelFace* tmpFace = tmpGroup->firstFace;
669      while (tmpFace)
670        {
671          if (tmpFace->firstElem)
672            {
673              ModelFaceElement* firstElem = tmpFace->firstElem;
674              ModelFaceElement* prevElem;
675              ModelFaceElement* curElem = firstElem;
676              ModelFaceElement* nextElem;
677              ModelFaceElement* lastElem;
678              // 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.
679              while (curElem)
680                {
681                  prevElem = curElem;
682                  curElem = curElem->next;
683                }
684              lastElem = prevElem;
685             
686              curElem = firstElem;
687              for (int j=0; j<tmpFace->vertexCount; j++)
688                {
689                  if (!(nextElem = curElem->next))
690                    nextElem = firstElem;
691                  curElem->normalNumber = curElem->vertexNumber;
692                 
693                  curV = Vector (vertices->getArray()[curElem->vertexNumber*3], vertices->getArray()[curElem->vertexNumber*3+1], vertices->getArray()[curElem->vertexNumber*3+2]);
694                  prevV = Vector (vertices->getArray()[prevElem->vertexNumber*3], vertices->getArray()[prevElem->vertexNumber*3+1], vertices->getArray()[prevElem->vertexNumber*3+2]) - curV;
695                  nextV = Vector (vertices->getArray()[nextElem->vertexNumber*3], vertices->getArray()[nextElem->vertexNumber*3+1], vertices->getArray()[nextElem->vertexNumber*3+2]) - curV;
696                  normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
697
698                  prevElem = curElem;
699                  curElem = curElem->next;
700                }
701            }
702          tmpFace = tmpFace->next;
703        }
704      tmpGroup = tmpGroup->next;
705    }
706
707  for (int i=0; i < vertices->getCount()/3;i++)
708    {
709      normArray[i].normalize();
710      PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
711     
712      this->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z);
713
714    }
715  delete []normArray; 
716}
717
718////////////
719// openGL //
720////////////
721/**
722   \brief reads and includes the Faces/Materials into the openGL state Machine
723*/
724bool Model::importToDisplayList(void)
725{
726  // finalize the Arrays
727  this->vertices->finalizeArray();
728  this->vTexture->finalizeArray();
729  if (normals->getCount() == 0) // vertices-Array must be built for this
730    this->buildVertexNormals();
731  this->normals->finalizeArray();
732
733  this->currentGroup = this->firstGroup;
734
735  while (this->currentGroup != NULL)
736    {
737
738      // creating a glList for the Group
739      if ((this->currentGroup->listNumber = glGenLists(1)) == 0)
740        {
741          PRINTF(2)("glList could not be created for this Model\n");
742          return false;
743        }
744      glNewList (this->currentGroup->listNumber, GL_COMPILE);
745
746      // Putting Faces to GL
747      ModelFace* tmpFace = this->currentGroup->firstFace;
748      while (tmpFace != NULL)
749        {
750          if (tmpFace->vertexCount == 0 && tmpFace->material != NULL)
751            {
752              if (this->currentGroup->faceMode != -1)
753                glEnd();
754              this->currentGroup->faceMode = 0;
755              Material* tmpMat;
756              if (tmpFace->material != NULL)
757                {
758                  tmpFace->material->select();
759                  PRINTF(5)("using material %s for coming Faces.\n", tmpFace->material->getName());
760                }
761            }
762
763          else if (tmpFace->vertexCount == 3)
764            {
765              if (this->currentGroup->faceMode != 3)
766                {
767                  if (this->currentGroup->faceMode != -1)
768                    glEnd();
769                  glBegin(GL_TRIANGLES);
770                }
771             
772              this->currentGroup->faceMode = 3;
773              PRINTF(5)("found triag.\n");
774            }
775         
776          else if (tmpFace->vertexCount == 4)
777            {
778              if (this->currentGroup->faceMode != 4)
779                {
780                  if (this->currentGroup->faceMode != -1)
781                    glEnd();
782                  glBegin(GL_QUADS);
783                }
784              this->currentGroup->faceMode = 4;
785              PRINTF(5)("found quad.\n");
786            }
787         
788          else if (tmpFace->vertexCount > 4)
789            {
790              if (this->currentGroup->faceMode != -1)
791                glEnd();
792              glBegin(GL_POLYGON);
793              PRINTF(5)("Polygon with %i faces found.", tmpFace->vertexCount);
794              this->currentGroup->faceMode = tmpFace->vertexCount;
795            }
796         
797          ModelFaceElement* tmpElem = tmpFace->firstElem;
798          while (tmpElem != NULL)
799            {
800              //      PRINTF(2)("%s\n", tmpElem->value);
801              this->addGLElement(tmpElem);
802              tmpElem = tmpElem->next;
803            }
804          tmpFace = tmpFace->next;
805        }
806      glEnd();
807      glEndList();
808
809      this->currentGroup = this->currentGroup->next;
810    } 
811}
812
813/**
814   \brief reads and includes the Faces/Materials into the openGL state Machine
815*/
816bool Model::importToVertexArray(void)
817{
818  // finalize the Arrays
819  this->vertices->finalizeArray();
820  this->vTexture->finalizeArray();
821  if (normals->getCount() == 0) // vertices-Array must be built for this
822    this->buildVertexNormals();
823  this->normals->finalizeArray();
824
825  this->currentGroup = this->firstGroup;
826  glVertexPointer(3, GL_FLOAT, 0, this->vertices->getArray());
827  glNormalPointer(3, 0, this->normals->getArray());
828  glTexCoordPointer(2, GL_FLOAT, 0, this->vTexture->getArray());
829}
830
831
832
833/**
834   \brief Adds a Face-element (one vertex of a face) with all its information.
835   \param elem The FaceElement to add to the OpenGL-environment.
836
837   It does this by searching:
838   1. The Vertex itself
839   2. The VertexNormale
840   3. The VertexTextureCoordinate
841   merging this information, the face will be drawn.
842*/
843bool Model::addGLElement (ModelFaceElement* elem)
844{
845  PRINTF(5)("importing grafical Element to openGL.\n");
846
847  if (elem->texCoordNumber != -1)
848    {
849      if (likely(elem->texCoordNumber < this->texCoordCount))
850        glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
851      else
852        PRINTF(2)("TextureCoordinate %d is not in the List (max: %d)\nThe Model might be incomplete\n",
853                  elem->texCoordNumber, this->texCoordCount);
854    }
855  if (elem->normalNumber != -1)
856    {
857    if (likely(elem->normalNumber < this->normalCount))
858      glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
859    else
860        PRINTF(2)("Normal %d is not in the List (max: %d)\nThe Model might be incomplete",
861                  elem->normalNumber, this->normalCount);     
862    }
863  if (elem->vertexNumber != -1)
864    {
865      if (likely(elem->vertexNumber < this->vertexCount))
866          glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
867      else
868        PRINTF(2)("Vertex %d is not in the List (max: %d)\nThe Model might be incomplete",
869                  elem->vertexNumber, this->vertexCount);     
870    }   
871
872}
873
874/**
875   \brief Includes a default model
876
877   This will inject a Cube, because this is the most basic model.
878*/
879void Model::cubeModel(void)
880{
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  this->addVertex (-0.5, 0.5, -0.5);
886  this->addVertex (0.5, 0.5, -0.5);
887  this->addVertex (-0.5, -0.5, -0.5);
888  this->addVertex (0.5, -0.5, -0.5);
889
890  this->addVertexTexture (0.0, 0.0);
891  this->addVertexTexture (1.0, 0.0);
892  this->addVertexTexture (0.0, 1.0);
893  this->addVertexTexture (1.0, 1.0);
894  this->addVertexTexture (0.0, 2.0);
895  this->addVertexTexture (1.0, 2.0);
896  this->addVertexTexture (0.0, 3.0);
897  this->addVertexTexture (1.0, 3.0);
898  this->addVertexTexture (0.0, 4.0);
899  this->addVertexTexture (1.0, 4.0);
900  this->addVertexTexture (2.0, 0.0);
901  this->addVertexTexture (2.0, 1.0);
902  this->addVertexTexture (-1.0, 0.0);
903  this->addVertexTexture (-1.0, 1.0);
904
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 (0.0, 0.0, -1.0);
914  this->addVertexNormal (0.0, 0.0, -1.0);
915  this->addVertexNormal (0.0, 0.0, -1.0);
916  this->addVertexNormal (0.0, 0.0, -1.0);
917  this->addVertexNormal (0.0, -1.0, 0.0);
918  this->addVertexNormal (0.0, -1.0, 0.0);
919  this->addVertexNormal (0.0, -1.0, 0.0);
920  this->addVertexNormal (0.0, -1.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  this->addVertexNormal (-1.0, 0.0, 0.0);
926  this->addVertexNormal (-1.0, 0.0, 0.0);
927  this->addVertexNormal (-1.0, 0.0, 0.0);
928  this->addVertexNormal (-1.0, 0.0, 0.0);
929
930  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 0,0,0, 1,1,1, 3,3,2, 2,2,3);
931  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,4, 3,3,5, 5,5,6, 4,4,7);
932  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 4,4,8, 5,5,9, 7,7,10, 6,6,11);
933  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,6,12, 7,7,13, 1,9,14, 0,8,15);
934  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,16, 7,10,17, 5,11,18, 3,3,19);
935  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,12,20, 0,0,21, 2,2,22, 4,13,23);
936
937}
Note: See TracBrowser for help on using the repository browser.