Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: prepare for VertexArrays

File size: 24.4 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// DE-CONSTRUCT //
31//////////////////
32/**
33   \brief Creates a 3D-Model. and assigns it a Name.
34*/
35Model::Model(const char* modelName, MODEL_TYPE type)
36{
37  PRINTF(4)("new 3D-Model is being created\n"); 
38  this->name = NULL;
39  this->setName(modelName);
40  this->type = type;
41
42  this->finalized = false;
43  // setting the start group;
44  this->firstGroup = new Group;
45  this->currentGroup = this->firstGroup;
46  this->groupCount = 0;
47 
48  this->initGroup (this->currentGroup);
49  this->scaleFactor = 1;
50
51  this->vertices = new Array();
52  this->vTexture = new Array();
53  this->normals = new Array();
54
55  this->materialList = new tList<Material>;
56}
57
58/**
59   \brief deletes an Model.
60
61   Looks if any from model allocated space is still in use, and if so deleted it.
62*/
63Model::~Model(void)
64{
65  PRINTF(4)("Deleting Model ");
66  if (this->name)
67    {
68      PRINT(4)("%s\n", this->name);
69      delete []this->name;
70    }
71  else
72      PRINT(4)("\n");
73
74  PRINTF(5)("Deleting display Lists.\n");
75  Group* walker = this->firstGroup;
76  while (walker != NULL)
77    {
78      glDeleteLists (walker->listNumber, 1);
79      Group* delWalker = walker;
80      walker = walker->next;
81      delete delWalker;
82    }
83
84  // deleting Arrays
85  this->deleteArrays();
86
87  // deleting the MaterialList
88  PRINTF(5)("Deleting Materials.\n");
89  tIterator<Material>* tmpIt = this->materialList->getIterator();
90  Material* material = tmpIt->nextElement();
91  while(material)
92    {
93      delete material;
94      material = tmpIt->nextElement();
95    }
96  delete tmpIt;
97  delete materialList;
98}
99
100/**
101   \brief Finalizes an Object. This can be done outside of the Class.
102*/
103void Model::finalize(void)
104{
105  // this creates the display List.
106  this->importToDisplayList();
107 
108
109  // deletes everything we allocated.
110  if (this->type == MODEL_DISPLAY_LIST)
111    this->deleteArrays();
112  this->cleanup();
113
114  this->finalized = true;
115}
116
117//////////
118// DRAW //
119//////////
120/**
121   \brief Draws the Models of all Groups.
122   It does this by just calling the Lists that must have been created earlier.
123*/
124void Model::draw (void) const
125{
126  PRINTF(4)("drawing the 3D-Models\n"); 
127  Group* walker = this->firstGroup;
128  while (walker != NULL)
129    {
130      PRINTF(5)("Drawing model %s\n", walker->name);
131      glCallList (walker->listNumber);
132      walker = walker->next;
133    }
134}
135
136/**
137   \brief Draws the Model number groupNumber
138   \param groupNumber The number of the group that will be displayed.
139
140   It does this by just calling the List that must have been created earlier.
141*/
142void Model::draw (int groupNumber) const 
143{
144  if (groupNumber >= this->groupCount)
145    {
146      PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount);
147      return;
148    }
149  PRINTF(4)("drawing the requested 3D-Models if found.\n"); 
150  Group* walker = this->firstGroup;
151  int counter = 0;
152  while (walker != NULL)
153    {
154      if (counter == groupNumber)
155        {
156          PRINTF(4)("Drawing model number %i named %s\n", counter, walker->name);
157          glCallList (walker->listNumber);
158          return;
159        }
160      ++counter;
161      walker = walker->next;
162    }
163  PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->name);
164  return;
165
166}
167
168/**
169   \brief Draws the Model with a specific groupName
170   \param groupName The name of the group that will be displayed.
171
172   It does this by just calling the List that must have been created earlier.
173*/
174void Model::draw (char* groupName) const
175{
176  PRINTF(4)("drawing the requested 3D-Models if found.\n"); 
177  Group* walker = this->firstGroup;
178  while (walker != NULL)
179    {
180      if (!strcmp(walker->name, groupName))
181        {
182          PRINTF(4)("Drawing model %s\n", walker->name);
183          glCallList (walker->listNumber);
184          return;
185        }
186      walker = walker->next;
187    }
188  PRINTF(2)("Model Named %s in %s not Found.\n", groupName, this->name);
189  return;
190}
191
192/**
193   \returns Count of the Models in this File
194*/
195int Model::getGroupCount (void) const
196{
197  return this->groupCount;
198}
199
200//////////
201// INIT //
202//////////
203/**
204   \brief sets a name to the Model
205   \param name The name to set to this Model
206*/
207void Model::setName(const char* name)
208{
209  if (this->name) 
210    delete this->name;
211  if (name)
212    {
213      this->name = new char[strlen(name)+1];
214      strcpy(this->name, name);
215    }
216  else 
217    this->name = NULL;
218}
219
220/**
221   \brief initializes a new Group model
222   \param group the group that should be initialized.
223   \todo Maybe Group should be a Class, because it does a lot of stuff
224   
225*/
226bool Model::initGroup(Group* group)
227{
228  PRINTF(4)("Adding new Group\n");
229  group->name = "";
230  group->faceMode = -1;
231  group->faceCount = 0; 
232  group->next = NULL;
233
234  group->firstFace = new Face;
235  this->initFace (group->firstFace);
236  group->currentFace = group->firstFace;
237}
238
239/**
240   \brief initializes a new Face. (sets default Values)
241   \param face The face to initialize
242*/
243bool Model::initFace (Face* face)
244{
245  face->vertexCount = 0;
246
247  face->firstElem = NULL;
248 
249  face->material = NULL;
250 
251  face->next = NULL;
252
253  return true;
254}
255
256/**
257   \brief deletes all the arrays
258*/
259bool Model::deleteArrays(void)
260{
261  if (this->vertices)
262    delete this->vertices;
263  if (this->vTexture)
264    delete this->vTexture;
265  if (this->normals)
266    delete this->normals;
267  this->vertices = NULL;
268  this->vTexture = NULL;
269  this->normals = NULL;
270}
271
272/**
273   \brief finalizes an Model.
274   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.
275*/
276bool Model::cleanup(void)
277{
278  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
279  this->cleanupGroup(this->firstGroup);
280  return true; 
281}
282
283/**
284   \brief Cleans up all groups starting from group.
285   \param group the first Group to clean
286*/
287bool Model::cleanupGroup (Group* group)
288{
289  PRINTF(5)("Cleaning up group\n");
290  if (group->firstFace != NULL)
291    {
292      cleanupFace (group->firstFace);
293      delete group->firstFace;
294    }
295
296  if (group->next !=NULL)
297    cleanupGroup (group->next);
298  return true;
299}
300
301/**
302   \brief Cleans up all Faces starting from face until NULL is reached.
303   \param face the first face to clean.
304*/
305bool Model::cleanupFace (Face* face)
306{
307  PRINTF(5)("Cleaning up Face\n");
308
309  if (face->firstElem != NULL)
310    {
311      this->cleanupFaceElement(face->firstElem);
312      delete face->firstElem;
313    }
314     
315  if (face->next != NULL)
316    {
317      this->cleanupFace (face->next);
318      delete face->next;
319    }
320}
321
322/**
323   \brief Cleans up all FaceElements starting from faceElem.
324   \param faceElem the first FaceElement to clean.
325*/
326bool Model::cleanupFaceElement(FaceElement* faceElem)
327{
328  if (faceElem->next != NULL)
329    {
330      this->cleanupFaceElement (faceElem->next);
331      delete faceElem->next;
332    }
333}
334
335//////////
336// MESH //
337//////////
338/**
339   \brief adds a new Material to the Material List
340   \param material the Material to add
341   \returns the added material
342
343   !! beware the Material will be deleted when the Model gets deleted
344*/
345Material* Model::addMaterial(Material* material)
346{
347  this->materialList->add(material);
348  return material;
349}
350
351/**
352   \brief adds a new Material to the Material List
353   \param material the name of the Material to add
354   \returns the added material
355*/
356Material* Model::addMaterial(const char* materialName)
357{
358 
359  Material* newMat = new Material();
360  newMat->setName(materialName);
361
362  // adding material to the List of materials
363  this->materialList->add(newMat); 
364  return newMat;
365}
366
367/**
368   \brief finds a Material by its name and returns it
369   \param materialName the Name of the material to search for.
370   \returns the Material if found, NULL otherwise
371*/
372Material* Model::findMaterialByName(const char* materialName)
373{
374  tIterator<Material>* tmpIt = this->materialList->getIterator();
375  Material* material = tmpIt->nextElement();
376  while(material)
377    {
378      if (!strcmp(material->getName(), materialName))
379        {
380          delete tmpIt;
381          return material;
382        }
383      material = tmpIt->nextElement();
384    }
385  delete tmpIt;
386  return NULL;
387}
388
389/**
390   \brief parses a group String
391   \param groupString the new Group to create
392
393   This function initializes a new Group.
394   With it you should be able to import .obj-files with more than one Models inside.
395*/
396bool Model::addGroup (const char* groupString)
397{
398  PRINTF(5)("Read Group: %s.\n", groupString);
399  if (this->groupCount != 0 && this->currentGroup->faceCount>0)
400    {
401      //      finalizeGroup(currentGroup);
402      this->currentGroup = this->currentGroup->next = new Group;
403      this->initGroup(this->currentGroup);
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  return true;
429}
430
431/**
432   \brief parses a vertex-String
433   \param x the X-coordinate of the Vertex to add.
434   \param y the Y-coordinate of the Vertex to add.
435   \param z the Z-coordinate of the Vertex to add.
436   
437*/
438bool Model::addVertex(float x, float y, float z)
439{
440  PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
441  this->vertices->addEntry(x*scaleFactor, y*scaleFactor, z*scaleFactor);
442  return true;
443}
444
445/**
446   \brief parses a vertexNormal-String
447   \param normalString The String that will be parsed.
448
449   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
450*/
451bool Model::addVertexNormal (const char* normalString)
452{
453  float subbuffer1;
454  float subbuffer2;
455  float subbuffer3;
456  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
457  PRINTF(5)("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
458  this->normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
459  return true;
460}
461
462/**
463   \brief adds a VertexNormal.
464   \param x The x coordinate of the Normal.
465   \param y The y coordinate of the Normal.
466   \param z The z coordinate of the Normal.
467
468   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
469*/
470bool Model::addVertexNormal(float x, float y, float z)
471{
472  PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
473  this->normals->addEntry(x, y, z);
474}
475
476/**
477   \brief parses a vertexTextureCoordinate-String
478   \param vTextureString The String that will be parsed.
479
480   If a vertexTextureCoordinate line is found,
481   this function will inject it into the vertexTexture-Array
482*/
483bool Model::addVertexTexture (const char* vTextureString)
484{
485  float subbuffer1;
486  float subbuffer2;
487  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
488  PRINTF(5)("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
489  this->vTexture->addEntry(subbuffer1);
490  this->vTexture->addEntry(subbuffer2);
491  return true;
492}
493
494/**
495   \brief adds a Texture Coordinate
496   \param u The u coordinate of the TextureCoordinate.
497   \param v The y coordinate of the TextureCoordinate.
498
499   If a TextureCoordinate line is found this function will inject it into the TextureCoordinate-Array
500*/
501bool Model::addVertexTexture(float u, float v)
502{
503  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
504  this->vTexture->addEntry(u);
505  this->vTexture->addEntry(v);
506}
507
508/**
509   \brief parses a face-string
510   \param faceString The String that will be parsed.
511
512   If a face line is found this function will add it to the glList.
513*/
514bool Model::addFace (const char* faceString)
515{
516  if (this->currentGroup->faceCount >0)
517    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
518  this->initFace (this->currentGroup->currentFace);
519
520  FaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new FaceElement;
521  tmpElem->next = NULL;
522  while(strcmp (faceString, "\0"))
523    {
524      if (this->currentGroup->currentFace->vertexCount>0)
525          tmpElem = tmpElem->next = new FaceElement;
526      tmpElem->next = NULL;
527
528      char tmpValue [50];
529      int tmpLen;
530      char* vertex = NULL;
531      char* texture = NULL;
532      char* normal = NULL;
533
534      sscanf (faceString, "%s", tmpValue);
535      tmpLen = strlen(tmpValue);
536      vertex = tmpValue;
537
538      if ((texture = strstr (vertex, "/")) != NULL)
539        {
540          texture[0] = '\0';
541          texture ++;
542         
543          if ((normal = strstr (texture, "/")) !=NULL)
544            {
545              normal[0] = '\0';
546              normal ++;
547            }     
548        }
549      if (vertex)
550        tmpElem->vertexNumber = atoi(vertex)-1;
551      else
552        tmpElem->vertexNumber = -1;
553      if (texture)
554        tmpElem->texCoordNumber = atoi(texture)-1;
555      else
556        tmpElem->texCoordNumber = -1;
557      if (normal)
558        tmpElem->normalNumber = atoi(normal)-1;
559      else
560        tmpElem->normalNumber = -1;
561
562      faceString += tmpLen;
563      if (strcmp (faceString, "\0"))
564        faceString++;
565      this->currentGroup->currentFace->vertexCount++;
566    }
567
568  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
569}
570
571/**
572   \brief adds a new Face
573   \param faceElemCount the number of Vertices to add to the Face.
574   \param type 0: vertex only, 1: vertex and normal, 2: vertex and Texture, 3 vertex, normal and texture
575*/
576bool Model::addFace(int faceElemCount, VERTEX_FORMAT type, ...)
577{
578   if (this->currentGroup->faceCount > 0)
579    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
580  this->initFace (this->currentGroup->currentFace);
581
582  FaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new FaceElement;
583  tmpElem->next = NULL;
584 
585  va_list itemlist;
586  va_start (itemlist, type);
587
588  for (int i = 0; i < faceElemCount; i++)
589    {
590      if (this->currentGroup->currentFace->vertexCount>0)
591          tmpElem = tmpElem->next = new FaceElement;
592      tmpElem->next = NULL;
593
594      tmpElem->vertexNumber = va_arg (itemlist, int) -1;
595      if (type & TEXCOORD)
596        tmpElem->texCoordNumber = va_arg (itemlist, int) -1;
597      if (type & NORMAL)
598        tmpElem->normalNumber = va_arg(itemlist, int) -1;
599      this->currentGroup->currentFace->vertexCount++;
600    }
601  va_end(itemlist);
602
603  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2;
604}
605
606/**
607   \brief Function that selects a material, if changed in the obj file.
608   \param matString the Material that will be set.
609*/
610bool Model::setMaterial(const char* matString)
611{
612  if (this->currentGroup->faceCount > 0)
613    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
614  this->initFace (this->currentGroup->currentFace);
615 
616  this->currentGroup->currentFace->material = this->findMaterialByName(matString);
617
618  if (this->currentGroup->faceCount == 0)
619    this->currentGroup->faceCount ++;
620}
621
622/**
623   \brief Function that selects a material, if changed in the obj file.
624   \param mtl the Material that will be set.
625*/
626bool Model::setMaterial(Material* mtl)
627{
628  if (this->currentGroup->faceCount > 0)
629    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
630  this->initFace (this->currentGroup->currentFace);
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  Group* tmpGroup = firstGroup;
662  while (tmpGroup)
663    {
664      Face* tmpFace = tmpGroup->firstFace;
665      while (tmpFace)
666        {
667          if (tmpFace->firstElem)
668            {
669              FaceElement* firstElem = tmpFace->firstElem;
670              FaceElement* prevElem;
671              FaceElement* curElem = firstElem;
672              FaceElement* nextElem;
673              FaceElement* 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->normals->addEntry(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      Face* 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          FaceElement* 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
823
824}
825
826
827
828/**
829   \brief Adds a Face-element (one vertex of a face) with all its information.
830   \param elem The FaceElement to add to the OpenGL-environment.
831
832   It does this by searching:
833   1. The Vertex itself
834   2. The VertexNormale
835   3. The VertexTextureCoordinate
836   merging this information, the face will be drawn.
837*/
838bool Model::addGLElement (FaceElement* elem)
839{
840  PRINTF(5)("importing grafical Element to openGL.\n");
841
842  if (elem->texCoordNumber != -1)
843    glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
844  if (elem->normalNumber != -1)
845    glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
846  if (elem->vertexNumber != -1)
847    glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
848
849}
850
851/**
852   \brief Includes a default model
853
854   This will inject a Cube, because this is the most basic model.
855*/
856void Model::cubeModel(void)
857{
858  this->addVertex (-0.5, -0.5, 0.5);
859  this->addVertex (0.5, -0.5, 0.5);
860  this->addVertex (-0.5, 0.5, 0.5);
861  this->addVertex (0.5, 0.5, 0.5);
862  this->addVertex (-0.5, 0.5, -0.5);
863  this->addVertex (0.5, 0.5, -0.5);
864  this->addVertex (-0.5, -0.5, -0.5);
865  this->addVertex (0.5, -0.5, -0.5);
866
867  this->addVertexTexture (0.0, 0.0);
868  this->addVertexTexture (1.0, 0.0);
869  this->addVertexTexture (0.0, 1.0);
870  this->addVertexTexture (1.0, 1.0);
871  this->addVertexTexture (0.0, 2.0);
872  this->addVertexTexture (1.0, 2.0);
873  this->addVertexTexture (0.0, 3.0);
874  this->addVertexTexture (1.0, 3.0);
875  this->addVertexTexture (0.0, 4.0);
876  this->addVertexTexture (1.0, 4.0);
877  this->addVertexTexture (2.0, 0.0);
878  this->addVertexTexture (2.0, 1.0);
879  this->addVertexTexture (-1.0, 0.0);
880  this->addVertexTexture (-1.0, 1.0);
881
882  this->addVertexNormal (0.0, 0.0, 1.0);
883  this->addVertexNormal (0.0, 0.0, 1.0);
884  this->addVertexNormal (0.0, 0.0, 1.0);
885  this->addVertexNormal (0.0, 0.0, 1.0);
886  this->addVertexNormal (0.0, 1.0, 0.0);
887  this->addVertexNormal (0.0, 1.0, 0.0);
888  this->addVertexNormal (0.0, 1.0, 0.0);
889  this->addVertexNormal (0.0, 1.0, 0.0);
890  this->addVertexNormal (0.0, 0.0, -1.0);
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, -1.0, 0.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 (1.0, 0.0, 0.0);
899  this->addVertexNormal (1.0, 0.0, 0.0);
900  this->addVertexNormal (1.0, 0.0, 0.0);
901  this->addVertexNormal (1.0, 0.0, 0.0);
902  this->addVertexNormal (-1.0, 0.0, 0.0);
903  this->addVertexNormal (-1.0, 0.0, 0.0);
904  this->addVertexNormal (-1.0, 0.0, 0.0);
905  this->addVertexNormal (-1.0, 0.0, 0.0);
906
907  /* normaleLess-testingMode
908  this->addFace ("1 2 4 3");
909  this->addFace ("3 4 6 5");
910  this->addFace ("5 6 8 7");
911  this->addFace ("7 8 2 1");
912  this->addFace ("2 8 6 4");
913  this->addFace ("7 1 3 5");
914  */
915
916  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,1, 2,2,2, 4,4,3, 3,3,4);
917  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 3,3,5, 4,4,6, 6,6,7, 5,5,8);
918  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 5,5,9, 6,6,10, 8,8,11, 7,7,12);
919  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,7,13, 8,8,14, 2,10,15, 1,9,16);
920  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,17, 8,11,18, 6,12,19, 4,4,20);
921  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,13,21, 1,1,22, 3,3,23, 5,14,24);
922
923}
Note: See TracBrowser for help on using the repository browser.