Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: materialList is now a property of model not material, makes more sense

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