Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Model-Class is now more dynamic (all subelements are now classes too, i hope, that atilla was right about classes being as fast as structs

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