Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/importer/model.cc @ 3418

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

orxonox/trunk/importer: added primitive sphere, but it still has some errors on it

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