Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4791 was 4791, checked in by patrick, 19 years ago

orxonox/trunk: prepearing the objModel for triangles export support a la Patrick. @Bensch: I hope you will agree with my approach

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