Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/importer: cleaned up the includes, while watching some Monty Python

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