Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/importer/object.cc @ 3104

Last change on this file since 3104 was 3083, checked in by bensch, 20 years ago

orxonox/trunk/importer: nicer Cube

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