Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/images/importer/object.cc @ 3122

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

orxonox/branches/images: little stupid-error-fix. see for yourself

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