Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/importer: added cylinderModel to importer

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