Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3758 was 3750, checked in by patrick, 20 years ago

orxonox/trunk: made some sattelite object just for fun and to show on the convention tomarrow

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