Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: array is now also a template

File size: 25.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 "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(void)
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
148  this->scaleFactor = 1;
149
150  this->vertices = new Array<GLfloat>();
151  this->vTexture = new Array<GLfloat>();
152  this->normals = new Array<GLfloat>();
153
154  this->materialList = new tList<Material>;
155
156  if (this->type == MODEL_VERTEX_ARRAY)
157    glEnableClientState(GL_VERTEX_ARRAY | GL_NORMAL_ARRAY | GL_TEXTURE_COORD_ARRAY);
158}
159
160/**
161   \brief deletes an Model.
162
163   Looks if any from model allocated space is still in use, and if so deleted it.
164*/
165Model::~Model(void)
166{
167  PRINTF(4)("Deleting Model ");
168  if (this->getName())
169    {
170      PRINT(4)("%s\n", this->getName());
171    }
172  else
173      PRINT(4)("\n");
174
175  PRINTF(5)("Deleting display Lists.\n");
176  delete this->firstGroup;
177
178  // deleting Arrays
179  this->deleteArrays();
180
181  // deleting the MaterialList
182  PRINTF(5)("Deleting Materials.\n");
183  tIterator<Material>* tmpIt = this->materialList->getIterator();
184  Material* material = tmpIt->nextElement();
185
186  //! \todo do we really have to delete this material??
187  while(material)
188    {
189      delete material;
190      material = tmpIt->nextElement();
191    }
192  delete tmpIt;
193  delete materialList;
194}
195
196/**
197   \brief Finalizes an Object. This can be done outside of the Class.
198*/
199void Model::finalize(void)
200{
201  // this creates the display List.
202  this->importToDisplayList();
203
204  // deletes everything we allocated.
205  if (this->type == MODEL_DISPLAY_LIST)
206    this->deleteArrays();
207  this->cleanup();
208
209  this->finalized = true;
210}
211
212//////////
213// DRAW //
214//////////
215/**
216   \brief Draws the Models of all Groups.
217   It does this by just calling the Lists that must have been created earlier.
218*/
219void Model::draw (void) const
220{
221  PRINTF(4)("drawing the 3D-Models\n");
222  ModelGroup* tmpGroup = this->firstGroup;
223  while (tmpGroup != NULL)
224    {
225      PRINTF(5)("Drawing model %s\n", tmpGroup->name);
226      glCallList (tmpGroup->listNumber);
227      tmpGroup = tmpGroup->next;
228    }
229}
230
231/**
232   \brief Draws the Model number groupNumber
233   \param groupNumber The number of the group that will be displayed.
234
235   It does this by just calling the List that must have been created earlier.
236*/
237void Model::draw (int groupNumber) const
238{
239  if (groupNumber >= this->groupCount)
240    {
241      PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount);
242      return;
243    }
244  PRINTF(4)("drawing the requested 3D-Models if found.\n");
245  ModelGroup* tmpGroup = this->firstGroup;
246  int counter = 0;
247  while (tmpGroup != NULL)
248    {
249      if (counter == groupNumber)
250        {
251          PRINTF(4)("Drawing model number %i named %s\n", counter, tmpGroup->name);
252          glCallList (tmpGroup->listNumber);
253          return;
254        }
255      ++counter;
256      tmpGroup = tmpGroup->next;
257    }
258  PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->getName());
259  return;
260
261}
262
263/**
264   \brief Draws the Model with a specific groupName
265   \param groupName The name of the group that will be displayed.
266
267   It does this by just calling the List that must have been created earlier.
268*/
269void Model::draw (char* groupName) const
270{
271  PRINTF(4)("drawing the requested 3D-Models if found.\n");
272  ModelGroup* tmpGroup = this->firstGroup;
273  while (tmpGroup != NULL)
274    {
275      if (!strcmp(tmpGroup->name, groupName))
276        {
277          PRINTF(4)("Drawing model %s\n", tmpGroup->name);
278          glCallList (tmpGroup->listNumber);
279          return;
280        }
281      tmpGroup = tmpGroup->next;
282    }
283  PRINTF(2)("Model Named %s in %s not Found.\n", groupName, this->getName());
284  return;
285}
286
287//////////
288// INIT //
289//////////
290/**
291   \brief deletes all the arrays
292*/
293bool Model::deleteArrays(void)
294{
295  if (this->vertices)
296    delete this->vertices;
297  if (this->vTexture)
298    delete this->vTexture;
299  if (this->normals)
300    delete this->normals;
301
302  this->vertices = NULL;
303  this->vTexture = NULL;
304  this->normals = NULL;
305}
306
307/**
308   \brief finalizes an Model.
309   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.
310*/
311bool Model::cleanup(void)
312{
313  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
314  this->firstGroup->cleanup();
315  return true;
316}
317
318//////////
319// MESH //
320//////////
321/**
322   \brief adds a new Material to the Material List
323   \param material the Material to add
324   \returns the added material
325
326   !! beware the Material will be deleted when the Model gets deleted
327*/
328Material* Model::addMaterial(Material* material)
329{
330  this->materialList->add(material);
331  return material;
332}
333
334/**
335   \brief adds a new Material to the Material List
336   \param materialName the name of the Material to add
337   \returns the added material
338*/
339Material* Model::addMaterial(const char* materialName)
340{
341  Material* newMat = new Material();
342  newMat->setName(materialName);
343
344  // adding material to the List of materials
345  this->materialList->add(newMat);
346  return newMat;
347}
348
349/**
350   \brief finds a Material by its name and returns it
351   \param materialName the Name of the material to search for.
352   \returns the Material if found, NULL otherwise
353*/
354Material* Model::findMaterialByName(const char* materialName)
355{
356  tIterator<Material>* tmpIt = this->materialList->getIterator();
357  Material* material = tmpIt->nextElement();
358  while(material)
359    {
360      if (!strcmp(material->getName(), materialName))
361        {
362          delete tmpIt;
363          return material;
364        }
365      material = tmpIt->nextElement();
366    }
367  delete tmpIt;
368  return NULL;
369}
370
371/**
372   \brief parses a group String
373   \param groupString the new Group to create
374
375   This function initializes a new Group.
376   With it you should be able to create Models with more than one SubModel inside
377*/
378bool Model::addGroup(const char* groupString)
379{
380  PRINTF(5)("Read Group: %s.\n", groupString);
381  if (this->groupCount != 0 && this->currentGroup->faceCount > 0)
382    {
383      //      finalizeGroup(currentGroup);
384      this->currentGroup = this->currentGroup->next = new ModelGroup;
385    }
386  // setting the group name if not default.
387  if (strcmp(groupString, "default"))
388    {
389      this->currentGroup->name = new char [strlen(groupString)+1];
390      strcpy(this->currentGroup->name, groupString);
391    }
392  ++this->groupCount;
393}
394
395/**
396   \brief parses a vertex-String
397   \param vertexString The String that will be parsed.
398
399   If a vertex line is found this function will inject it into the vertex-Array
400*/
401bool Model::addVertex (const char* vertexString)
402{
403  float subbuffer1;
404  float subbuffer2;
405  float subbuffer3;
406  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
407  PRINTF(5)("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
408  this->vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
409  this->vertexCount++;
410  return true;
411}
412
413/**
414   \brief parses a vertex-String
415   \param x the X-coordinate of the Vertex to add.
416   \param y the Y-coordinate of the Vertex to add.
417   \param z the Z-coordinate of the Vertex to add.
418
419*/
420bool Model::addVertex(float x, float y, float z)
421{
422  PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
423  this->vertices->addEntry(x*scaleFactor, y*scaleFactor, z*scaleFactor);
424  this->vertexCount++;
425  return true;
426}
427
428/**
429   \brief parses a vertexNormal-String
430   \param normalString The String that will be parsed.
431
432   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
433*/
434bool Model::addVertexNormal (const char* normalString)
435{
436  float subbuffer1;
437  float subbuffer2;
438  float subbuffer3;
439  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
440  PRINTF(5)("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
441  this->normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
442  this->normalCount++;
443  return true;
444}
445
446/**
447   \brief adds a VertexNormal.
448   \param x The x coordinate of the Normal.
449   \param y The y coordinate of the Normal.
450   \param z The z coordinate of the Normal.
451
452   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
453*/
454bool Model::addVertexNormal(float x, float y, float z)
455{
456  PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
457  this->normals->addEntry(x, y, z);
458  this->normalCount++;
459  return true;
460}
461
462/**
463   \brief parses a vertexTextureCoordinate-String
464   \param vTextureString The String that will be parsed.
465
466   If a vertexTextureCoordinate line is found,
467   this function will inject it into the vertexTexture-Array
468
469   !! WARNING THIS IS DIFFERNT FROM addVervexTexture(float, float); because it changes the second entry to 1-v !!
470*/
471bool Model::addVertexTexture (const char* vTextureString)
472{
473  float subbuffer1;
474  float subbuffer2;
475  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
476  PRINTF(5)("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
477  this->vTexture->addEntry(subbuffer1);
478  this->vTexture->addEntry(1 - subbuffer2);
479  this->texCoordCount++;
480  return true;
481}
482
483/**
484   \brief adds a Texture Coordinate
485   \param u The u coordinate of the TextureCoordinate.
486   \param v The y coordinate of the TextureCoordinate.
487
488   If a TextureCoordinate line is found this function will inject it into the TextureCoordinate-Array
489*/
490bool Model::addVertexTexture(float u, float v)
491{
492  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
493  this->vTexture->addEntry(u);
494  this->vTexture->addEntry(v);
495  this->texCoordCount++;
496  return true;
497}
498
499/**
500   \brief parses a face-string
501   \param faceString The String that will be parsed.
502
503   If a face line is found this function will add it to the glList.
504
505   String is different from the argument addFace, in this that the first Vertex/Normal/Texcoord is 1 instead of 0
506*/
507bool Model::addFace (const char* faceString)
508{
509  if (this->currentGroup->faceCount >0)
510    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
511
512  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
513  tmpElem->next = NULL;
514  while(strcmp (faceString, "\0"))
515    {
516      if (this->currentGroup->currentFace->vertexCount>0)
517          tmpElem = tmpElem->next = new ModelFaceElement;
518      tmpElem->next = NULL;
519
520      char tmpValue [50];
521      int tmpLen;
522      char* vertex = NULL;
523      char* texture = NULL;
524      char* normal = NULL;
525
526      sscanf (faceString, "%s", tmpValue);
527      tmpLen = strlen(tmpValue);
528      vertex = tmpValue;
529
530      if ((texture = strstr (vertex, "/")) != NULL)
531        {
532          texture[0] = '\0';
533          texture ++;
534
535          if ((normal = strstr (texture, "/")) !=NULL)
536            {
537              normal[0] = '\0';
538              normal ++;
539            }
540        }
541      if (vertex)
542        tmpElem->vertexNumber = atoi(vertex)-1;
543      if (texture)
544        tmpElem->texCoordNumber = atoi(texture)-1;
545      if (normal)
546        tmpElem->normalNumber = atoi(normal)-1;
547
548      faceString += tmpLen;
549      if (strcmp (faceString, "\0"))
550        faceString++;
551      this->currentGroup->currentFace->vertexCount++;
552    }
553
554  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
555}
556
557/**
558   \brief adds a new Face
559   \param faceElemCount the number of Vertices to add to the Face.
560   \param type The information Passed with each Vertex
561*/
562bool Model::addFace(int faceElemCount, VERTEX_FORMAT type, ...)
563{
564  if (this->currentGroup->faceCount > 0)
565    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
566
567  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
568
569  va_list itemlist;
570  va_start (itemlist, type);
571
572  for (int i = 0; i < faceElemCount; i++)
573    {
574      if (this->currentGroup->currentFace->vertexCount > 0)
575        tmpElem = tmpElem->next = new ModelFaceElement;
576
577      tmpElem->vertexNumber = va_arg (itemlist, int);
578      if (type & TEXCOORD)
579        tmpElem->texCoordNumber = va_arg (itemlist, int);
580      if (type & NORMAL)
581        tmpElem->normalNumber = va_arg(itemlist, int);
582      this->currentGroup->currentFace->vertexCount++;
583    }
584  va_end(itemlist);
585
586  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2;
587}
588
589/**
590   \brief Function that selects a material, if changed in the obj file.
591   \param matString the Material that will be set.
592*/
593bool Model::setMaterial(const char* matString)
594{
595  if (this->currentGroup->faceCount > 0)
596    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
597
598  this->currentGroup->currentFace->material = this->findMaterialByName(matString);
599
600  if (this->currentGroup->faceCount == 0)
601    this->currentGroup->faceCount ++;
602}
603
604/**
605   \brief Function that selects a material, if changed in the obj file.
606   \param mtl the Material that will be set.
607*/
608bool Model::setMaterial(Material* mtl)
609{
610  if (this->currentGroup->faceCount > 0)
611    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
612
613  this->currentGroup->currentFace->material = mtl;
614
615  if (this->currentGroup->faceCount == 0)
616    this->currentGroup->faceCount ++;
617}
618
619/**
620   \brief A routine that is able to create normals.
621
622   The algorithm does the following:
623   1. It calculates creates Vectors for each normale, and sets them to zero.
624   2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
625   3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
626   4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
627*/
628bool Model::buildVertexNormals ()
629{
630  PRINTF(4)("Normals are being calculated.\n");
631
632  Vector* normArray = new Vector [vertices->getCount()/3];
633  for (int i=0; i<vertices->getCount()/3;i++)
634    normArray[i] = Vector(.0,.0,.0);
635
636  int firstTouch;
637  int secondTouch;
638  Vector prevV;
639  Vector nextV;
640  Vector curV;
641
642  ModelGroup* tmpGroup = firstGroup;
643  while (tmpGroup)
644    {
645      ModelFace* tmpFace = tmpGroup->firstFace;
646      while (tmpFace)
647        {
648          if (tmpFace->firstElem)
649            {
650              ModelFaceElement* firstElem = tmpFace->firstElem;
651              ModelFaceElement* prevElem;
652              ModelFaceElement* curElem = firstElem;
653              ModelFaceElement* nextElem;
654              ModelFaceElement* lastElem;
655              // 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.
656              while (curElem)
657                {
658                  prevElem = curElem;
659                  curElem = curElem->next;
660                }
661              lastElem = prevElem;
662
663              curElem = firstElem;
664              for (int j=0; j<tmpFace->vertexCount; j++)
665                {
666                  if (!(nextElem = curElem->next))
667                    nextElem = firstElem;
668                  curElem->normalNumber = curElem->vertexNumber;
669
670                  curV = Vector (vertices->getArray()[curElem->vertexNumber*3], vertices->getArray()[curElem->vertexNumber*3+1], vertices->getArray()[curElem->vertexNumber*3+2]);
671                  prevV = Vector (vertices->getArray()[prevElem->vertexNumber*3], vertices->getArray()[prevElem->vertexNumber*3+1], vertices->getArray()[prevElem->vertexNumber*3+2]) - curV;
672                  nextV = Vector (vertices->getArray()[nextElem->vertexNumber*3], vertices->getArray()[nextElem->vertexNumber*3+1], vertices->getArray()[nextElem->vertexNumber*3+2]) - curV;
673                  normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
674
675                  prevElem = curElem;
676                  curElem = curElem->next;
677                }
678            }
679          tmpFace = tmpFace->next;
680        }
681      tmpGroup = tmpGroup->next;
682    }
683
684  for (int i=0; i < vertices->getCount()/3;i++)
685    {
686      normArray[i].normalize();
687      PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
688
689      this->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z);
690
691    }
692  delete []normArray;
693}
694
695////////////
696// openGL //
697////////////
698/**
699   \brief reads and includes the Faces/Materials into the openGL state Machine
700*/
701bool Model::importToDisplayList(void)
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      ModelFace* 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          ModelFaceElement* 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 reads and includes the Faces/Materials into the openGL state Machine
792*/
793bool Model::importToVertexArray(void)
794{
795  // finalize the Arrays
796  this->vertices->finalizeArray();
797  this->vTexture->finalizeArray();
798  if (normals->getCount() == 0) // vertices-Array must be built for this
799    this->buildVertexNormals();
800  this->normals->finalizeArray();
801
802  this->currentGroup = this->firstGroup;
803  glVertexPointer(3, GL_FLOAT, 0, this->vertices->getArray());
804  glNormalPointer(3, 0, this->normals->getArray());
805  glTexCoordPointer(2, GL_FLOAT, 0, this->vTexture->getArray());
806}
807
808
809
810/**
811   \brief Adds a Face-element (one vertex of a face) with all its information.
812   \param elem The FaceElement to add to the OpenGL-environment.
813
814   It does this by searching:
815   1. The Vertex itself
816   2. The VertexNormale
817   3. The VertexTextureCoordinate
818   merging this information, the face will be drawn.
819*/
820bool Model::addGLElement (ModelFaceElement* elem)
821{
822  PRINTF(5)("importing grafical Element to openGL.\n");
823
824  if (elem->texCoordNumber != -1)
825    {
826      if (likely(elem->texCoordNumber < this->texCoordCount))
827        glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
828      else
829        PRINTF(2)("TextureCoordinate %d is not in the List (max: %d)\nThe Model might be incomplete\n",
830                  elem->texCoordNumber, this->texCoordCount);
831    }
832  if (elem->normalNumber != -1)
833    {
834    if (likely(elem->normalNumber < this->normalCount))
835      glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
836    else
837        PRINTF(2)("Normal %d is not in the List (max: %d)\nThe Model might be incomplete",
838                  elem->normalNumber, this->normalCount);
839    }
840  if (elem->vertexNumber != -1)
841    {
842      if (likely(elem->vertexNumber < this->vertexCount))
843          glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
844      else
845        PRINTF(2)("Vertex %d is not in the List (max: %d)\nThe Model might be incomplete",
846                  elem->vertexNumber, this->vertexCount);
847    }
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  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 0,0,0, 1,1,1, 3,3,2, 2,2,3);
908  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,4, 3,3,5, 5,5,6, 4,4,7);
909  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 4,4,8, 5,5,9, 7,7,10, 6,6,11);
910  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,6,12, 7,7,13, 1,9,14, 0,8,15);
911  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,16, 7,10,17, 5,11,18, 3,3,19);
912  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,12,20, 0,0,21, 2,2,22, 4,13,23);
913
914}
Note: See TracBrowser for help on using the repository browser.