Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/images: ability to read-in from a folder of your desire

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  objFileName[strlen(name)] = '\0';
362  this->readFromObjFile ();
363  return true;
364}
365
366/**
367   \brief Reads in the .obj File and sets all the Values.
368   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
369*/
370bool Object::readFromObjFile (void)
371{
372  char* fileName = new char [strlen(objPath)+strlen(objFileName)+2];
373  fileName[0]='\0';
374  if (objFileName != NULL && !strcmp(objFileName, ""))
375    return false;
376  strcat(fileName, objPath);
377  strcat(fileName, objFileName);
378  printf ("%s. %d\n", fileName, strlen(fileName));
379
380  ifstream* OBJ_FILE = new ifstream(fileName);
381  if (OBJ_FILE->fail())
382    {
383      if (verbose >=1)
384        printf ("unable to open .OBJ file: %s\n Loading Box Object instead.\n", fileName);
385      exit(0);
386      BoxObject();
387      return false;
388    }
389  if (verbose >=2)
390    printf ("Reading from opened file %s\n", fileName);
391  char Buffer[10000];
392  while(!OBJ_FILE->eof())
393    {
394      OBJ_FILE->getline(Buffer, 10000);
395      if (verbose >=4)
396        printf ("Read input line: %s\n",Buffer);
397     
398
399      // case vertice
400      if (!strncmp(Buffer, "v ", 2))
401        {
402          readVertex(Buffer+2);
403        }
404
405      // case face
406      else if (!strncmp(Buffer, "f ", 2))
407        {
408          readFace (Buffer+2);
409        }
410     
411      else if (!strncmp(Buffer, "mtllib ", 7))
412        {
413          readMtlLib (Buffer+7);
414        }
415
416      else if (!strncmp(Buffer, "usemtl ", 7))
417        {
418          readUseMtl (Buffer+7);
419        }
420
421      // case VertexNormal
422      else if (!strncmp(Buffer, "vn ", 3))
423      {
424        readVertexNormal(Buffer+3);
425      }
426
427      // case VertexTextureCoordinate
428      else if (!strncmp(Buffer, "vt ", 3))
429      {
430        readVertexTexture(Buffer+3);
431      }
432      // case group
433      else if (!strncmp(Buffer, "g ", 2))
434        {
435          readGroup (Buffer+2);
436        }
437      else if (!strncmp(Buffer, "s ", 2))
438        {
439          if (verbose >= 2)
440            printf("smoothing groups not supportet yet. line: %s\n", Buffer);
441        }
442    }
443  OBJ_FILE->close();
444  return true;
445
446}
447
448/**
449   \brief parses a group String
450   This function initializes a new Group.
451   With it you should be able to import .obj-files with more than one Objects inside.
452   \param groupString the new Group to create
453*/
454bool Object::readGroup (char* groupString)
455{
456  // setting the group name if not default.
457  if (strcmp(currentGroup->name, "default"))
458    {
459      currentGroup->name = new char [strlen(groupString)];
460      strcpy(currentGroup->name, groupString);
461    }
462  if (groupCount != 0 && currentGroup->faceCount>0)
463    {
464      //      finalizeGroup(currentGroup);
465      currentGroup = currentGroup->next = new Group;
466      initGroup(currentGroup);
467    }
468
469  ++groupCount;
470
471}
472
473/**
474   \brief parses a vertex-String
475   If a vertex line is found this function will inject it into the vertex-Array
476   \param vertexString The String that will be parsed.
477*/
478bool Object::readVertex (char* vertexString)
479{
480  float subbuffer1;
481  float subbuffer2;
482  float subbuffer3;
483  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
484  if (verbose >= 3)
485    printf ("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
486  vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
487  return true;
488}
489
490/**
491   \brief parses a face-string
492   If a face line is found this function will add it to the glList.
493   The function makes a difference between QUADS and TRIANGLES, and will if changed re-open, set and re-close the gl-processe.
494   \param faceString The String that will be parsed.
495*/
496bool Object::readFace (char* faceString)
497{
498  if (currentGroup->faceCount >0)
499    currentGroup->currentFace = currentGroup->currentFace->next = new Face;
500  initFace (currentGroup->currentFace);
501
502  FaceElement* tmpElem = currentGroup->currentFace->firstElem = new FaceElement;
503  tmpElem->next = NULL;
504  while(strcmp (faceString, "\0"))
505    {
506      if (currentGroup->currentFace->vertexCount>0)
507          tmpElem = tmpElem->next = new FaceElement;
508      tmpElem->next = NULL;
509
510      char tmpValue [50];
511      int tmpLen;
512      char* vertex = NULL;
513      char* texture = NULL;
514      char* normal = NULL;
515
516      sscanf (faceString, "%s", tmpValue);
517      tmpLen = strlen(tmpValue);
518      vertex = tmpValue;
519
520      if ((texture = strstr (vertex, "/")) != NULL)
521        {
522          texture[0] = '\0';
523          texture ++;
524         
525          if ((normal = strstr (texture, "/")) !=NULL)
526            {
527              normal[0] = '\0';
528              normal ++;
529            }     
530        }
531      if (vertex)
532        tmpElem->vertexNumber = atoi(vertex)-1;
533      else
534        tmpElem->vertexNumber = -1;
535      if (texture)
536        tmpElem->texCoordNumber = atoi(texture)-1;
537      else
538        tmpElem->texCoordNumber = -1;
539      if (normal)
540        tmpElem->normalNumber = atoi(normal)-1;
541      else
542        tmpElem->normalNumber = -1;
543
544      faceString += tmpLen;
545      if (strcmp (faceString, "\0"))
546        faceString++;
547      currentGroup->currentFace->vertexCount++;
548    }
549
550  currentGroup->faceCount += currentGroup->currentFace->vertexCount -2;
551}
552
553/**
554   \brief parses a vertexNormal-String
555   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
556   \param normalString The String that will be parsed.
557*/
558bool Object::readVertexNormal (char* normalString)
559{
560  float subbuffer1;
561  float subbuffer2;
562  float subbuffer3;
563  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
564  if (verbose >=3 )
565    printf("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
566  normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
567  return true;
568}
569
570/**
571   \brief parses a vertexTextureCoordinate-String
572   If a vertexTextureCoordinate line is found this function will inject it into the vertexTexture-Array
573   \param vTextureString The String that will be parsed.
574*/
575bool Object::readVertexTexture (char* vTextureString)
576{
577  float subbuffer1;
578  float subbuffer2;
579  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
580  if (verbose >=3 )
581    printf("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
582  vTexture->addEntry(subbuffer1);
583  vTexture->addEntry(subbuffer2);
584  return true;
585}
586
587/**
588    \brief Function to read in a mtl File.
589    this Function parses all Lines of an mtl File
590    \param mtlFile The .mtl file to read
591*/
592bool Object::readMtlLib (char* mtlFile)
593{
594  mtlFileName = new char [strlen(mtlFile)+1];
595  strcpy(mtlFileName, mtlFile);
596  char* fileName = new char [strlen(objPath) + strlen(mtlFileName)];
597  fileName[0] = '\0';
598  strcat(fileName, objPath);
599  strcat(fileName, mtlFileName);
600 
601
602  if (verbose >=2)
603    printf ("Opening mtlFile: %s\n", fileName);
604
605  ifstream* MTL_FILE = new ifstream (fileName);
606  if (MTL_FILE->fail())
607    {
608      if (verbose >= 1)
609        printf ("unable to open file: %s\n", fileName);
610      return false;
611    }
612  char Buffer[500];
613  Material* tmpMat = material;
614  while(!MTL_FILE->eof())
615    {
616      MTL_FILE->getline(Buffer, 500);
617      if (verbose >= 4)
618        printf("found line in mtlFile: %s\n", Buffer);
619     
620
621      // create new Material
622      if (!strncmp(Buffer, "newmtl ", 7))
623        {
624          tmpMat = tmpMat->addMaterial(Buffer+7);
625          //      printf ("%s, %p\n", tmpMat->getName(), tmpMat);
626        }
627      // setting a illumMode
628      else if (!strncmp(Buffer, "illum ", 6))
629        {
630          tmpMat->setIllum(Buffer+6);
631
632        }
633      // setting Diffuse Color
634      else if (!strncmp(Buffer, "Kd ", 3))
635        {
636          tmpMat->setDiffuse(Buffer+3);
637        }
638      // setting Ambient Color
639      else if (!strncmp(Buffer, "Ka ", 3))
640        {
641          tmpMat->setAmbient(Buffer+3);
642        }
643      // setting Specular Color
644      else if (!strncmp(Buffer, "Ks ", 3))
645        {
646          tmpMat->setSpecular(Buffer+3);
647        }
648      // setting The Specular Shininess
649      else if (!strncmp(Buffer, "Ns ", 3))
650        {
651          tmpMat->setShininess(Buffer+3);
652        }
653      // setting up transparency
654      else if (!strncmp(Buffer, "d ", 2))
655        {
656          tmpMat->setTransparency(Buffer+2);
657        }
658      else if (!strncmp(Buffer, "Tf ", 3))
659        {
660          tmpMat->setTransparency(Buffer+3);
661        }
662     
663      else if (!strncmp(Buffer, "map_Kd ", 7))
664        {
665          tmpMat->setDiffuseMap(Buffer+7);
666        }
667      else if (!strncmp(Buffer, "map_Ka ", 7))
668        {
669          tmpMat->setAmbientMap(Buffer+7);
670        }
671      else if (!strncmp(Buffer, "map_Ks ", 7))
672        {
673          tmpMat->setSpecularMap(Buffer+7);
674        }
675      else if (!strncmp(Buffer, "bump ", 5))
676        {
677          tmpMat->setBump(Buffer+7);
678        }
679     
680
681    }
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 (!strcmp (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)];
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.