Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: model: sphere-model is now working

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