Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/images: seg-fault shouldn't occure anymore from strings

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   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  fileName[0]='\0';
373  if (objFileName != NULL && !strcmp(objFileName, ""))
374    return false;
375  strcat(fileName, objPath);
376  strcat(fileName, objFileName);
377
378  ifstream* OBJ_FILE = new ifstream(fileName);
379  if (OBJ_FILE->fail())
380    {
381      if (verbose >=1)
382        printf ("unable to open .OBJ file: %s\n Loading Box Object instead.\n", fileName);
383      exit(0);
384      BoxObject();
385      return false;
386    }
387  if (verbose >=2)
388    printf ("Reading from opened file %s\n", fileName);
389  char Buffer[10000];
390  while(!OBJ_FILE->eof())
391    {
392      OBJ_FILE->getline(Buffer, 10000);
393      if (verbose >=4)
394        printf ("Read input line: %s\n",Buffer);
395     
396
397      // case vertice
398      if (!strncmp(Buffer, "v ", 2))
399        {
400          readVertex(Buffer+2);
401        }
402
403      // case face
404      else if (!strncmp(Buffer, "f ", 2))
405        {
406          readFace (Buffer+2);
407        }
408     
409      else if (!strncmp(Buffer, "mtllib ", 7))
410        {
411          readMtlLib (Buffer+7);
412        }
413
414      else if (!strncmp(Buffer, "usemtl ", 7))
415        {
416          readUseMtl (Buffer+7);
417        }
418
419      // case VertexNormal
420      else if (!strncmp(Buffer, "vn ", 3))
421      {
422        readVertexNormal(Buffer+3);
423      }
424
425      // case VertexTextureCoordinate
426      else if (!strncmp(Buffer, "vt ", 3))
427      {
428        readVertexTexture(Buffer+3);
429      }
430      // case group
431      else if (!strncmp(Buffer, "g ", 2))
432        {
433          readGroup (Buffer+2);
434        }
435      else if (!strncmp(Buffer, "s ", 2))
436        {
437          if (verbose >= 2)
438            printf("smoothing groups not supportet yet. line: %s\n", Buffer);
439        }
440    }
441  OBJ_FILE->close();
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  // setting the group name if not default.
455  if (strcmp(currentGroup->name, "default"))
456    {
457      currentGroup->name = new char [strlen(groupString)+1];
458      strcpy(currentGroup->name, groupString);
459    }
460  if (groupCount != 0 && currentGroup->faceCount>0)
461    {
462      //      finalizeGroup(currentGroup);
463      currentGroup = currentGroup->next = new Group;
464      initGroup(currentGroup);
465    }
466
467  ++groupCount;
468
469}
470
471/**
472   \brief parses a vertex-String
473   If a vertex line is found this function will inject it into the vertex-Array
474   \param vertexString The String that will be parsed.
475*/
476bool Object::readVertex (char* vertexString)
477{
478  float subbuffer1;
479  float subbuffer2;
480  float subbuffer3;
481  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
482  if (verbose >= 3)
483    printf ("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
484  vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
485  return true;
486}
487
488/**
489   \brief parses a face-string
490   If a face line is found this function will add it to the glList.
491   The function makes a difference between QUADS and TRIANGLES, and will if changed re-open, set and re-close the gl-processe.
492   \param faceString The String that will be parsed.
493*/
494bool Object::readFace (char* faceString)
495{
496  if (currentGroup->faceCount >0)
497    currentGroup->currentFace = currentGroup->currentFace->next = new Face;
498  initFace (currentGroup->currentFace);
499
500  FaceElement* tmpElem = currentGroup->currentFace->firstElem = new FaceElement;
501  tmpElem->next = NULL;
502  while(strcmp (faceString, "\0"))
503    {
504      if (currentGroup->currentFace->vertexCount>0)
505          tmpElem = tmpElem->next = new FaceElement;
506      tmpElem->next = NULL;
507
508      char tmpValue [50];
509      int tmpLen;
510      char* vertex = NULL;
511      char* texture = NULL;
512      char* normal = NULL;
513
514      sscanf (faceString, "%s", tmpValue);
515      tmpLen = strlen(tmpValue);
516      vertex = tmpValue;
517
518      if ((texture = strstr (vertex, "/")) != NULL)
519        {
520          texture[0] = '\0';
521          texture ++;
522         
523          if ((normal = strstr (texture, "/")) !=NULL)
524            {
525              normal[0] = '\0';
526              normal ++;
527            }     
528        }
529      if (vertex)
530        tmpElem->vertexNumber = atoi(vertex)-1;
531      else
532        tmpElem->vertexNumber = -1;
533      if (texture)
534        tmpElem->texCoordNumber = atoi(texture)-1;
535      else
536        tmpElem->texCoordNumber = -1;
537      if (normal)
538        tmpElem->normalNumber = atoi(normal)-1;
539      else
540        tmpElem->normalNumber = -1;
541
542      faceString += tmpLen;
543      if (strcmp (faceString, "\0"))
544        faceString++;
545      currentGroup->currentFace->vertexCount++;
546    }
547
548  currentGroup->faceCount += currentGroup->currentFace->vertexCount -2;
549}
550
551/**
552   \brief parses a vertexNormal-String
553   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
554   \param normalString The String that will be parsed.
555*/
556bool Object::readVertexNormal (char* normalString)
557{
558  float subbuffer1;
559  float subbuffer2;
560  float subbuffer3;
561  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
562  if (verbose >=3 )
563    printf("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
564  normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
565  return true;
566}
567
568/**
569   \brief parses a vertexTextureCoordinate-String
570   If a vertexTextureCoordinate line is found this function will inject it into the vertexTexture-Array
571   \param vTextureString The String that will be parsed.
572*/
573bool Object::readVertexTexture (char* vTextureString)
574{
575  float subbuffer1;
576  float subbuffer2;
577  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
578  if (verbose >=3 )
579    printf("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
580  vTexture->addEntry(subbuffer1);
581  vTexture->addEntry(subbuffer2);
582  return true;
583}
584
585/**
586    \brief Function to read in a mtl File.
587    this Function parses all Lines of an mtl File
588    \param mtlFile The .mtl file to read
589*/
590bool Object::readMtlLib (char* mtlFile)
591{
592  mtlFileName = new char [strlen(mtlFile)+1];
593  strcpy(mtlFileName, mtlFile);
594  char* fileName = new char [strlen(objPath) + strlen(mtlFileName)+1];
595  fileName[0] = '\0';
596  strcat(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      return false;
609    }
610  char Buffer[500];
611  Material* tmpMat = material;
612  while(!MTL_FILE->eof())
613    {
614      MTL_FILE->getline(Buffer, 500);
615      if (verbose >= 4)
616        printf("found line in mtlFile: %s\n", Buffer);
617     
618
619      // create new Material
620      if (!strncmp(Buffer, "newmtl ", 7))
621        {
622          tmpMat = tmpMat->addMaterial(Buffer+7);
623          //      printf ("%s, %p\n", tmpMat->getName(), tmpMat);
624        }
625      // setting a illumMode
626      else if (!strncmp(Buffer, "illum ", 6))
627        {
628          tmpMat->setIllum(Buffer+6);
629
630        }
631      // setting Diffuse Color
632      else if (!strncmp(Buffer, "Kd ", 3))
633        {
634          tmpMat->setDiffuse(Buffer+3);
635        }
636      // setting Ambient Color
637      else if (!strncmp(Buffer, "Ka ", 3))
638        {
639          tmpMat->setAmbient(Buffer+3);
640        }
641      // setting Specular Color
642      else if (!strncmp(Buffer, "Ks ", 3))
643        {
644          tmpMat->setSpecular(Buffer+3);
645        }
646      // setting The Specular Shininess
647      else if (!strncmp(Buffer, "Ns ", 3))
648        {
649          tmpMat->setShininess(Buffer+3);
650        }
651      // setting up transparency
652      else if (!strncmp(Buffer, "d ", 2))
653        {
654          tmpMat->setTransparency(Buffer+2);
655        }
656      else if (!strncmp(Buffer, "Tf ", 3))
657        {
658          tmpMat->setTransparency(Buffer+3);
659        }
660     
661      else if (!strncmp(Buffer, "map_Kd ", 7))
662        {
663          tmpMat->setDiffuseMap(Buffer+7);
664        }
665      else if (!strncmp(Buffer, "map_Ka ", 7))
666        {
667          tmpMat->setAmbientMap(Buffer+7);
668        }
669      else if (!strncmp(Buffer, "map_Ks ", 7))
670        {
671          tmpMat->setSpecularMap(Buffer+7);
672        }
673      else if (!strncmp(Buffer, "bump ", 5))
674        {
675          tmpMat->setBump(Buffer+7);
676        }
677     
678
679    }
680  return true;
681}
682
683/**
684   \brief Function that selects a material, if changed in the obj file.
685   \param matString the Material that will be set.
686*/
687bool Object::readUseMtl (char* matString)
688{
689  if (!strcmp (mtlFileName, ""))
690    {
691      if (verbose >= 1)
692        printf ("Not using new defined material, because no mtlFile found yet\n");
693      return false;
694    }
695     
696  if (currentGroup->faceCount >0)
697    currentGroup->currentFace = currentGroup->currentFace->next = new Face;
698  initFace (currentGroup->currentFace);
699 
700  currentGroup->currentFace->materialString = new char[strlen(matString)+1];
701  strcpy (currentGroup->currentFace->materialString, matString);
702 
703  if (currentGroup->faceCount == 0)
704    currentGroup->faceCount ++;
705
706}
707
708/**
709   \brief reads and includes the Faces/Materials into the openGL state Machine
710*/
711bool Object::importToGL (void)
712{
713
714  // finalize the Arrays
715  vertices->finalizeArray();
716  vTexture->finalizeArray();
717  if (normals->getCount() == 0) // vertices-Array must be uilt for this
718    buildVertexNormals();
719  normals->finalizeArray();
720
721  currentGroup = firstGroup;
722
723  while (currentGroup != NULL)
724    {
725
726      // creating a glList for the Group
727      if ((currentGroup->listNumber = glGenLists(1)) == 0)
728        {
729          printf ("list could not be created for this Object\n");
730          return false;
731        }
732      glNewList (currentGroup->listNumber, GL_COMPILE);
733
734      // Putting Faces to GL
735      Face* tmpFace = currentGroup->firstFace;
736      while (tmpFace != NULL)
737        {
738          if (tmpFace->vertexCount == 0 && tmpFace->materialString != NULL)
739            {
740              if (currentGroup->faceMode != -1)
741                glEnd();
742              currentGroup->faceMode = 0;
743              if (verbose >= 2)
744                printf ("using material %s for coming Faces.\n", tmpFace->materialString);
745              Material* tmpMat;
746              if ((tmpMat = material->search(tmpFace->materialString)) != NULL)
747                tmpMat->select();
748
749            }
750
751          else if (tmpFace->vertexCount == 3)
752            {
753              if (currentGroup->faceMode != 3)
754                {
755                  if (currentGroup->faceMode != -1)
756                    glEnd();
757                  glBegin(GL_TRIANGLES);
758                }
759             
760              currentGroup->faceMode = 3;
761              if (verbose >=3)
762                printf ("found triag.\n");
763            }
764         
765          else if (tmpFace->vertexCount == 4)
766            {
767              if (currentGroup->faceMode != 4)
768                {
769                  if (currentGroup->faceMode != -1)
770                    glEnd();
771                  glBegin(GL_QUADS);
772                }
773              currentGroup->faceMode = 4;
774              if (verbose >=3 )
775                printf ("found quad.\n");
776            }
777         
778          else if (tmpFace->vertexCount > 4)
779            {
780              if (currentGroup->faceMode != -1)
781                glEnd();
782              glBegin(GL_POLYGON);
783              if (verbose >=3)
784                printf ("Polygon with %i faces found.", tmpFace->vertexCount);
785              currentGroup->faceMode = tmpFace->vertexCount;
786            }
787         
788          FaceElement* tmpElem = tmpFace->firstElem;
789          while (tmpElem != NULL)
790            {
791              //      printf ("%s\n", tmpElem->value);
792              addGLElement(tmpElem);
793              tmpElem = tmpElem->next;
794            }
795          tmpFace = tmpFace->next;
796        }
797      glEnd();
798      glEndList();
799      currentGroup = currentGroup->next;
800    } 
801}
802
803/**
804   \brief Adds a Face-element (one vertex of a face) with all its information.
805   It does this by searching:
806   1. The Vertex itself
807   2. The VertexNormale
808   3. The VertexTextureCoordinate
809   merging this information, the face will be drawn.
810
811*/
812bool Object::addGLElement (FaceElement* elem)
813{
814  if (verbose >=3)
815    printf ("importing grafical Element to openGL.\n");
816
817  if (elem->texCoordNumber != -1)
818    glTexCoord2fv(vTexture->getArray() + elem->texCoordNumber * 2);
819  if (elem->normalNumber != -1)
820    glNormal3fv(normals->getArray() + elem->normalNumber * 3);
821  if (elem->vertexNumber != -1)
822    glVertex3fv(vertices->getArray() + elem->vertexNumber * 3);
823
824}
825
826/**
827   \brief A routine that is able to create normals.
828   The algorithm does the following:
829   1. It calculates creates Vectors for each normale, and sets them to zero.
830   2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
831   3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
832   4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
833*/
834bool Object::buildVertexNormals ()
835{
836 
837  if (verbose >=2)
838    printf("Normals are being calculated.\n");
839
840  Vector* normArray = new Vector [vertices->getCount()/3];
841  for (int i=0; i<vertices->getCount()/3;i++)
842    normArray[i] = Vector(.0,.0,.0);
843 
844  int firstTouch;
845  int secondTouch;
846  Vector prevV;
847  Vector nextV;
848  Vector curV;
849
850  Group* tmpGroup = firstGroup;
851  while (tmpGroup)
852    {
853      Face* tmpFace = tmpGroup->firstFace;
854      while (tmpFace)
855        {
856          if (tmpFace->firstElem)
857            {
858              FaceElement* firstElem = tmpFace->firstElem;
859              FaceElement* prevElem;
860              FaceElement* curElem = firstElem;
861              FaceElement* nextElem;
862              FaceElement* lastElem;
863              // 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.
864              while (curElem)
865                {
866                  prevElem = curElem;
867                  curElem = curElem->next;
868                }
869              lastElem = prevElem;
870             
871              curElem = firstElem;
872              for (int j=0; j<tmpFace->vertexCount; j++)
873                {
874                  if (!(nextElem = curElem->next))
875                    nextElem = firstElem;
876                  curElem->normalNumber = curElem->vertexNumber;
877                 
878                  curV = Vector (vertices->getArray()[curElem->vertexNumber*3], vertices->getArray()[curElem->vertexNumber*3+1], vertices->getArray()[curElem->vertexNumber*3+2]);
879                  prevV = Vector (vertices->getArray()[prevElem->vertexNumber*3], vertices->getArray()[prevElem->vertexNumber*3+1], vertices->getArray()[prevElem->vertexNumber*3+2]) - curV;
880                  nextV = Vector (vertices->getArray()[nextElem->vertexNumber*3], vertices->getArray()[nextElem->vertexNumber*3+1], vertices->getArray()[nextElem->vertexNumber*3+2]) - curV;
881                  normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
882
883                  prevElem = curElem;
884                  curElem = curElem->next;
885                }
886            }
887          tmpFace = tmpFace->next;
888        }
889      tmpGroup = tmpGroup->next;
890    }
891
892  for (int i=0; i<vertices->getCount()/3;i++)
893    {
894      normArray[i].normalize();
895      if (verbose >=3)
896        printf ("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
897
898      normals->addEntry(normArray[i].x, normArray[i].y, normArray[i].z);
899
900    }
901  delete []normArray; 
902 
903}
904
905
906/**
907   \brief Includes a default object
908   This will inject a Cube, because this is the most basic object.
909*/
910void Object::BoxObject(void)
911{
912  readVertex ("-0.500000 -0.500000 0.500000");
913  readVertex ("0.500000 -0.500000 0.500000");
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
921  readVertexTexture ("0.000000 0.000000");
922  readVertexTexture ("1.000000 0.000000");
923  readVertexTexture ("0.000000 1.000000");
924  readVertexTexture ("1.000000 1.000000");
925  readVertexTexture ("0.000000 2.000000");
926  readVertexTexture ("1.000000 2.000000");
927  readVertexTexture ("0.000000 3.000000");
928  readVertexTexture ("1.000000 3.000000");
929  readVertexTexture ("0.000000 4.000000");
930  readVertexTexture ("1.000000 4.000000");
931  readVertexTexture ("2.000000 0.000000");
932  readVertexTexture ("2.000000 1.000000");
933  readVertexTexture ("-1.000000 0.000000");
934  readVertexTexture ("-1.000000 1.000000");
935
936  readVertexNormal ("0.000000 0.000000 1.000000");
937  readVertexNormal ("0.000000 0.000000 1.000000");
938  readVertexNormal ("0.000000 0.000000 1.000000");
939  readVertexNormal ("0.000000 0.000000 1.000000");
940  readVertexNormal ("0.000000 1.000000 0.000000");
941  readVertexNormal ("0.000000 1.000000 0.000000");
942  readVertexNormal ("0.000000 1.000000 0.000000");
943  readVertexNormal ("0.000000 1.000000 0.000000");
944  readVertexNormal ("0.000000 0.000000 -1.000000");
945  readVertexNormal ("0.000000 0.000000 -1.000000");
946  readVertexNormal ("0.000000 0.000000 -1.000000");
947  readVertexNormal ("0.000000 0.000000 -1.000000");
948  readVertexNormal ("0.000000 -1.000000 0.000000");
949  readVertexNormal ("0.000000 -1.000000 0.000000");
950  readVertexNormal ("0.000000 -1.000000 0.000000");
951  readVertexNormal ("0.000000 -1.000000 0.000000");
952  readVertexNormal ("1.000000 0.000000 0.000000");
953  readVertexNormal ("1.000000 0.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
961  /* normaleLess-testingMode
962  readFace ("1 2 4 3");
963  readFace ("3 4 6 5");
964  readFace ("5 6 8 7");
965  readFace ("7 8 2 1");
966  readFace ("2 8 6 4");
967  readFace ("7 1 3 5");
968  */
969
970  readFace ("1/1/1 2/2/2 4/4/3 3/3/4");
971  readFace ("3/3/5 4/4/6 6/6/7 5/5/8");
972  readFace ("5/5/9 6/6/10 8/8/11 7/7/12");
973  readFace ("7/7/13 8/8/14 2/10/15 1/9/16");
974  readFace ("2/2/17 8/11/18 6/12/19 4/4/20");
975  readFace ("7/13/21 1/1/22 3/3/23 5/14/24");
976
977}
Note: See TracBrowser for help on using the repository browser.