Index: orxonox/trunk/src/object.cc
===================================================================
--- orxonox/trunk/src/object.cc	(revision 2835)
+++ orxonox/trunk/src/object.cc	(revision 2853)
@@ -18,4 +18,8 @@
 #include "object.h"
 
+/**
+   \brief Creates a 3D-Object, but does not load any 3D-models
+   pretty useless
+*/
 Object::Object ()
 {
@@ -23,9 +27,13 @@
   initialize();
 
-  importFile ("reaphigh.obj");
+  BoxObject();
 
   finalize();
 }
 
+/**
+   \brief Crates a 3D-Object and loads in a File
+   \param fileName file to parse and load (must be a .obj file)
+*/
 Object::Object(char* fileName)
 {
@@ -36,4 +44,10 @@
   finalize();
 }
+
+/**
+   \brief Crates a 3D-Object, loads in a File and scales it.
+   \param fileName file to parse and load (must be a .obj file)
+   \param scaling The factor that the object will be scaled with.
+*/
 
 Object::Object(char* fileName, float scaling)
@@ -47,29 +61,52 @@
 }
 
+/**
+   \brief deletes an Object
+*/
+Object::~Object()
+{
+  if (verbose >= 2)
+    printf ("Deleting display List.\n");
+  Group* walker = firstGroup;
+  while (walker != NULL)
+    {
+      glDeleteLists (walker->listNumber, 1);
+      Group* lastWalker = walker;
+      walker = walker->nextGroup;
+      delete lastWalker;
+    } 
+}
+
+/** 
+    \brief initializes the Object
+    This Function initializes all the needed arrays, Lists and clientStates
+*/
 bool Object::initialize (void)
 {
   if (verbose >=3)
     printf("new 3D-Object is being created\n"); 
-  faceMode = -1;
-  if ( (listNumber = glGenLists(1)) == 0 )
-    {
-      printf ("list could not be created for this Object\n");
-      return false;
-    }
-
+
+  // setting the start group;
+  firstGroup = new Group;
+  currentGroup = firstGroup;
+  groupCount = 0;
+  
+  initGroup (currentGroup);
   mtlFileName = "";
   scaleFactor = 1;
-  vertices = new Array();
-  normals = new Array();
-  vTexture = new Array();
-
-  glNewList (listNumber, GL_COMPILE);
+  material = new Material();
+
   glEnableClientState (GL_VERTEX_ARRAY);
-  glEnableClientState (GL_NORMAL_ARRAY);
+  //  glEnableClientState (GL_NORMAL_ARRAY);
   //  glEnableClientState (GL_TEXTURE_COORD_ARRAY);
 
+
   return true;
 }
 
+/**
+   \brief Imports a obj file and handles the the relative location
+   \param fileName The file to import
+*/
 bool Object::importFile (char* fileName)
 {
@@ -81,22 +118,157 @@
 }
 
+/**
+   \brief finalizes an Object.
+   This funcion is needed, to close the glList and all the other lists.
+*/
 bool Object::finalize(void)
 {
-  if (verbose >=3)
+  //  if (verbose >=3)
     printf("finalizing the 3D-Object\n"); 
-  OBJ_FILE->close();
+  finalizeGroup (currentGroup);
+  if (material != NULL)
+    delete material;
+  return true;
+}
+
+/**
+   \brief Draws the Objects of all Groups.
+   It does this by just calling the Lists that must have been created earlier.
+*/
+void Object::draw (void)
+{
+  if (verbose >=2)
+    printf("drawing the 3D-Objects\n"); 
+  Group* walker = firstGroup;
+  while (walker != NULL)
+    {
+      if (verbose >= 3)
+	printf ("Drawing object %s\n", walker->name);
+      glCallList (walker->listNumber);
+      walker = walker->nextGroup;
+    }
+}
+
+/**
+   \brief Draws the Object number groupNumber
+   It does this by just calling the List that must have been created earlier.
+   \param groupNumber The number of the group that will be displayed.
+*/
+void Object::draw (int groupNumber)
+{
+  if (groupNumber >= groupCount)
+    {
+      if (verbose>=2)
+	printf ("You requested object number %i, but this File only contains of %i Objects.\n", groupNumber-1, groupCount);
+      return;
+    }
+  if (verbose >=2)
+    printf("drawing the requested 3D-Objects if found.\n"); 
+  Group* walker = firstGroup;
+  int counter = 0;
+  while (walker != NULL)
+    {
+      if (counter == groupNumber)
+	{
+	  if (verbose >= 2)
+	    printf ("Drawing object number %s named %s\n", counter, walker->name);
+	  glCallList (walker->listNumber);
+	  return;
+	}
+      ++counter;
+      walker = walker->nextGroup;
+    }
+  if (verbose >= 2)
+    printf("Object number %i in %s not Found.\n", groupNumber, objFileName);
+  return;
+
+}
+
+/**
+   \brief Draws the Object with a specific groupname
+   It does this by just calling the List that must have been created earlier.
+   \param groupName The name of the group that will be displayed.
+*/
+void Object::draw (char* groupName)
+{
+  if (verbose >=2)
+    printf("drawing the requested 3D-Objects if found.\n"); 
+  Group* walker = firstGroup;
+  while (walker != NULL)
+    {
+      if (!strcmp(walker->name, groupName))
+	{
+	  if (verbose >= 2)
+	    printf ("Drawing object %s\n", walker->name);
+	  glCallList (walker->listNumber);
+	  return;
+	}
+      walker = walker->nextGroup;
+    }
+  if (verbose >= 2)
+    printf("Object Named %s in %s not Found.\n", groupName, objFileName);
+  return;
+}
+
+/**
+   \returns Count of the Objects in this File
+*/
+int Object::getGroupCount (void)
+{
+  return groupCount;
+}
+
+/**
+   \brief initializes a new Group object
+*/
+bool Object::initGroup(Group* group)
+{
+  if (verbose >= 2)
+    printf("Adding new Group\n");
+  group->faceMode = -1;
+  group->name = "";
+  if ((group->listNumber = glGenLists(1)) == 0 )
+    {
+      printf ("list could not be created for this Object\n");
+      return false;
+    }
+  
+  if (groupCount == 0)
+    {
+      group->firstVertex = 0;
+      group->firstNormal = 0;
+      group->firstNormal = 0;
+    }
+  else
+    {
+      group->firstVertex = currentGroup->firstVertex + currentGroup->vertices->getCount()/3;
+      group->firstNormal = currentGroup->firstNormal + currentGroup->normals->getCount()/3;
+      group->firstVertexTexture = currentGroup->firstVertexTexture + currentGroup->vTexture->getCount()/2;
+    }
+
+  group->vertices = new Array();
+  group->normals = new Array();
+  group->vTexture = new Array();
+
+  glNewList (group->listNumber, GL_COMPILE);
+}
+
+/**
+   \brief finalizes a Group.
+*/
+bool Object::finalizeGroup(Group* group)
+{
   glEnd();
   glEndList();
-  return true;
-}
-
-void Object::draw (void)
-{
-  if (verbose >=3)
-    printf("drawing the 3D-Object\n"); 
-  glCallList (listNumber);
-}
-
-
+  
+  delete group->vertices;
+  delete group->normals;
+  delete group->vTexture;
+}
+/**
+   \brief Reads in the .obj File and sets all the Values.
+   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
+   \param fileName the File that will be parsed (.obj-file)
+*/
 bool Object::readFromObjFile (char* fileName)
 {
@@ -146,22 +318,27 @@
       }
 
-      // case vt
+      // case VertexTextureCoordinate
       else if (!strncmp(Buffer, "vt ", 2))
       {
 	readVertexTexture(Buffer+3);
       }
-	  
-
-    }
-  
-
-  
-  
-}
-
-
+      // case group
+      else if (!strncmp(Buffer, "g", 1))
+	{
+	  readGroup (Buffer+2);
+	}
+    }
+  OBJ_FILE->close();
+
+}
+
+/**
+   \brief parses a vertex-String
+   If a vertex line is found this function will inject it into the vertex-Array
+   \param vertexString The String that will be parsed.
+*/
 bool Object::readVertex (char* vertexString)
 {
-  readVertices = true;
+  readingVertices = true;
   char subbuffer1[20];
   char subbuffer2[20];
@@ -170,20 +347,27 @@
   if (verbose >= 3)
     printf ("reading in a vertex: %s %s %s\n", subbuffer1, subbuffer2, subbuffer3);
-  vertices->addEntry(atof(subbuffer1)*scaleFactor, atof(subbuffer2)*scaleFactor, atof(subbuffer3)*scaleFactor);
+  currentGroup->vertices->addEntry(atof(subbuffer1)*scaleFactor, atof(subbuffer2)*scaleFactor, atof(subbuffer3)*scaleFactor);
   return true;
 }
 
+/**
+   \brief parses a face-string
+   If a face line is found this function will add it to the glList.
+   The function makes a difference between QUADS and TRIANGLES, and will if changed re-open, set and re-close the gl-processe.
+   \param faceString The String that will be parsed.
+*/
 bool Object::readFace (char* faceString)
 {
-  if (readVertices == true)
-    {
-      vertices->finalizeArray();
-      glVertexPointer(3, GL_FLOAT, 0, vertices->getArray());
-      normals->finalizeArray();
-      glNormalPointer(GL_FLOAT, 0, normals->getArray());
-      vTexture->finalizeArray();
-    }
-
-  readVertices = false;
+  // finalize the Arrays;
+  if (readingVertices == true)
+    {
+      currentGroup->vertices->finalizeArray();
+      glVertexPointer(3, GL_FLOAT, 0, currentGroup->vertices->getArray());
+      currentGroup->normals->finalizeArray();
+      glNormalPointer(GL_FLOAT, 0, currentGroup->normals->getArray());
+      currentGroup->vTexture->finalizeArray();
+    }
+
+  readingVertices = false;
   char subbuffer1[20];
   char subbuffer2[20];
@@ -193,12 +377,12 @@
   if (!strcmp(subbuffer4, ""))
     {
-      if (faceMode != 3)
-	{
-	  if (faceMode != -1)
+      if (currentGroup->faceMode != 3)
+	{
+	  if (currentGroup->faceMode != -1)
 	    glEnd();
 	  glBegin(GL_TRIANGLES);
 	}
       
-      faceMode = 3;
+      currentGroup->faceMode = 3;
       if (verbose >=3)
 	printf ("found triag: %s, %s, %s\n", subbuffer1, subbuffer2, subbuffer3);
@@ -210,11 +394,11 @@
   else
     {
-      if (faceMode != 4)
-	{
-	  if (faceMode != -1)
+      if (currentGroup->faceMode != 4)
+	{
+	  if (currentGroup->faceMode != -1)
 	    glEnd();
 	  glBegin(GL_QUADS);
 	}
-      faceMode = 4;
+      currentGroup->faceMode = 4;
       if (verbose >=3 )
 	printf ("found quad: %s, %s, %s, %s\n", subbuffer1, subbuffer2, subbuffer3, subbuffer4);
@@ -227,4 +411,13 @@
 }
 
+/**
+   \brief Adds a Face-element (one vertex of a face) with all its information. 
+   It does this by searching:
+   1. The Vertex itself
+   2. The VertexNormale
+   3. The VertexTextureCoordinate
+   merging this information, the face will be drawn.
+
+*/
 bool Object::addGLElement (char* elementString)
 {
@@ -237,5 +430,5 @@
   texture[0] = '\0';
   texture ++;
-  glTexCoord2fv(vTexture->getArray()+(atoi(texture)-1)*2);
+  glTexCoord2fv(currentGroup->vTexture->getArray()+(atoi(texture)-1 - currentGroup->firstVertexTexture)*2);
 
   char* normal;
@@ -245,13 +438,18 @@
       normal ++;
       //glArrayElement(atoi(vertex)-1);
-      glNormal3fv(normals->getArray() +(atoi(normal)-1)*3);
-    }
-  glVertex3fv(vertices->getArray() +(atoi(vertex)-1)*3);
-
-}
-
+      glNormal3fv(currentGroup->normals->getArray() +(atoi(normal)-1 - currentGroup->firstNormal)*3);
+    }
+  glVertex3fv(currentGroup->vertices->getArray() +(atoi(vertex)-1 - currentGroup->firstVertex)*3);
+
+}
+
+/**
+   \brief parses a vertexNormal-String
+   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+   \param normalString The String that will be parsed.
+*/
 bool Object::readVertexNormal (char* normalString)
 {
-  readVertices = true;
+  readingVertices = true;
   char subbuffer1[20];
   char subbuffer2[20];
@@ -260,11 +458,16 @@
   if (verbose >=3 )
     printf("found vertex-Normal %s, %s, %s\n", subbuffer1,subbuffer2,subbuffer3);
-  normals->addEntry(atof(subbuffer1), atof(subbuffer2), atof(subbuffer3));
+  currentGroup->normals->addEntry(atof(subbuffer1), atof(subbuffer2), atof(subbuffer3));
   return true;
 }
 
+/**
+   \brief parses a vertexTextureCoordinate-String
+   If a vertexTextureCoordinate line is found this function will inject it into the vertexTexture-Array
+   \param vTextureString The String that will be parsed.
+*/
 bool Object::readVertexTexture (char* vTextureString)
 {
-  readVertices = true;
+  readingVertices = true;
   char subbuffer1[20];
   char subbuffer2[20];
@@ -272,10 +475,43 @@
   if (verbose >=3 )
     printf("found vertex-Texture %s, %s\n", subbuffer1,subbuffer2);
-  vTexture->addEntry(atof(subbuffer1));
-  vTexture->addEntry(atof(subbuffer2));
+  currentGroup->vTexture->addEntry(atof(subbuffer1));
+  currentGroup->vTexture->addEntry(atof(subbuffer2));
   return true;
 }
 
-
+/**
+   \brief parses a group String
+   This function initializes a new Group. 
+   With it you should be able to import .obj-files with more than one Objects inside. 
+   \param groupString the new Group to create
+*/
+bool Object::readGroup (char* groupString)
+{
+  //  printf ("test\n");
+  if (!strcmp(groupString, "default"))
+    {
+      if (groupCount != 0)
+	{
+	  Group* newGroup = new Group;
+	  finalizeGroup(currentGroup);
+	  currentGroup->nextGroup = newGroup;
+	  initGroup(newGroup);
+	  currentGroup = newGroup; // must be after init see initGroup for more info
+	}
+      ++groupCount;
+    }
+  else
+    {
+      
+      currentGroup->name = new char [strlen(groupString)];      
+      strcpy(currentGroup->name, groupString);
+    }
+}
+
+/** 
+    \brief Function to read in a mtl File.
+    this Function parses all Lines of an mtl File
+    \param mtlFile The .mtl file to read
+*/
 bool Object::readMtlLib (char* mtlFile)
 {
@@ -291,6 +527,4 @@
     printf ("Opening mtlFile: %s\n", mtlFileName);
   char Buffer[500];
-  vertices = new Array();
-  material = new Material();
   Material* tmpMat = material;
   while(!MTL_FILE->eof())
@@ -328,7 +562,27 @@
 	  tmpMat->setSpecular(Buffer+3);
 	}
+      // setting The Specular Shininess
+      else if (!strncmp(Buffer, "Ns", 2))
+	{
+	  tmpMat->setShininess(Buffer+3);
+	}
+      // setting up transparency
+      else if (!strncmp(Buffer, "d", 1))
+	{
+	  tmpMat->setTransparency(Buffer+2);
+	}
+      else if (!strncpy(Buffer, "Tf", 2))
+	{
+	  tmpMat->setTransparency(Buffer+3);
+	}
+
     }
   return true;
 }
+
+/**
+   \brief Function that selects a material, if changed in the obj file.
+   \param matString the Material that will be set.
+*/
 
 bool Object::readUseMtl (char* matString)
@@ -341,7 +595,7 @@
     }
       
-  if (faceMode != -1)
+  if (currentGroup->faceMode != -1)
     glEnd();
-  faceMode = 0;
+  currentGroup->faceMode = 0;
   if (verbose >= 2)
     printf ("using material %s for coming Faces.\n", matString);
@@ -349,5 +603,8 @@
 }
 
-
+/**
+   \brief Includes a default object
+   This will inject a Cube, because this is the most basic object.
+*/
 void Object::BoxObject(void)
 {
