Index: orxonox/branches/openAL/src/lib/graphics/importer/model.cc
===================================================================
--- orxonox/branches/openAL/src/lib/graphics/importer/model.cc	(revision 3920)
+++ orxonox/branches/openAL/src/lib/graphics/importer/model.cc	(revision 4194)
@@ -27,9 +27,109 @@
 using namespace std;
 
-//////////////////
-// DE-CONSTRUCT //
-//////////////////
-/**
-   \brief Creates a 3D-Model. and assigns it a Name.
+
+////////////////////
+/// SUB-Elements ///
+////////////////////
+/**
+   \brief creates a new ModelFaceElement
+*/
+ModelFaceElement::ModelFaceElement()
+{
+  this->vertexNumber = -1;
+  this->normalNumber = -1;
+  this->texCoordNumber = -1;    
+
+  this->next = NULL;
+}
+
+/**
+   \brief destroys a ModelFaceElement
+*/
+ModelFaceElement::~ModelFaceElement()
+{
+  if (this->next)
+    delete this->next;
+}
+
+/**
+   \brief creates a new ModelFace
+*/
+ModelFace::ModelFace()
+{
+  this->vertexCount = 0;
+
+  this->firstElem = NULL;
+  
+  this->material = NULL;
+  
+  this->next = NULL;
+
+}
+
+/**
+   \brief deletes a ModelFace
+*/
+ModelFace::~ModelFace()
+{
+  PRINTF(5)("Cleaning up Face\n");
+
+  if (this->firstElem != NULL)
+    delete this->firstElem;
+  
+  if (this->next != NULL)
+    delete this->next;
+}
+
+/**
+   \brief Creates a new ModelGroup
+*/
+ModelGroup::ModelGroup()
+{
+  PRINTF(4)("Adding new Group\n");
+  this->name = "";
+  this->faceMode = -1;
+  this->faceCount = 0;  
+  this->next = NULL;
+  
+  this->firstFace = new ModelFace;
+  this->currentFace = this->firstFace;
+}
+
+/**
+   \brief deletes a ModelGroup
+*/
+ModelGroup::~ModelGroup()
+{
+  PRINTF(5)("Cleaning up group\n");
+  if (this->firstFace != NULL)
+    delete this->firstFace;
+
+  if (this->next !=NULL)
+    delete this->next;
+}
+
+/**
+   \brief cleans up a ModelGroup
+
+   actually does the same as the delete Operator, but does not delete the predecessing group
+*/
+void ModelGroup::cleanup(void)
+{
+  PRINTF(5)("Cleaning up group\n");
+  if (this->firstFace)
+    delete this->firstFace;
+  this->firstFace = NULL;
+  if (this->next)
+    this->next->cleanup();
+}
+
+
+/////////////
+/// MODEL ///
+/////////////
+/**
+   \brief Creates a 3D-Model.
+
+   assigns it a Name and a Type
 */
 Model::Model(const char* modelName, MODEL_TYPE type)
@@ -42,9 +142,10 @@
   this->finalized = false;
   // setting the start group;
-  this->firstGroup = new Group;
-  this->currentGroup = this->firstGroup;
+  this->currentGroup = this->firstGroup = new ModelGroup;
   this->groupCount = 0;
-  
-  this->initGroup (this->currentGroup);
+  this->vertexCount = 0;
+  this->normalCount = 0;
+  this->texCoordCount = 0;
+  
   this->scaleFactor = 1;
 
@@ -76,12 +177,5 @@
 
   PRINTF(5)("Deleting display Lists.\n");
-  Group* walker = this->firstGroup;
-  while (walker != NULL)
-    {
-      glDeleteLists (walker->listNumber, 1);
-      Group* delWalker = walker;
-      walker = walker->next;
-      delete delWalker;
-    }
+  delete this->firstGroup;
 
   // deleting Arrays
@@ -92,4 +186,6 @@
   tIterator<Material>* tmpIt = this->materialList->getIterator();
   Material* material = tmpIt->nextElement();
+
+  //! \todo do we really have to delete this material??
   while(material)
     {
@@ -128,10 +224,10 @@
 {
   PRINTF(4)("drawing the 3D-Models\n"); 
-  Group* walker = this->firstGroup;
-  while (walker != NULL)
-    {
-      PRINTF(5)("Drawing model %s\n", walker->name);
-      glCallList (walker->listNumber);
-      walker = walker->next;
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+    {
+      PRINTF(5)("Drawing model %s\n", tmpGroup->name);
+      glCallList (tmpGroup->listNumber);
+      tmpGroup = tmpGroup->next;
     }
 }
@@ -151,16 +247,16 @@
     }
   PRINTF(4)("drawing the requested 3D-Models if found.\n"); 
-  Group* walker = this->firstGroup;
+  ModelGroup* tmpGroup = this->firstGroup;
   int counter = 0;
-  while (walker != NULL)
+  while (tmpGroup != NULL)
     {
       if (counter == groupNumber)
 	{
-	  PRINTF(4)("Drawing model number %i named %s\n", counter, walker->name);
-	  glCallList (walker->listNumber);
+	  PRINTF(4)("Drawing model number %i named %s\n", counter, tmpGroup->name);
+	  glCallList (tmpGroup->listNumber);
 	  return;
 	}
       ++counter;
-      walker = walker->next;
+      tmpGroup = tmpGroup->next;
     }
   PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->name);
@@ -178,25 +274,17 @@
 {
   PRINTF(4)("drawing the requested 3D-Models if found.\n"); 
-  Group* walker = this->firstGroup;
-  while (walker != NULL)
-    {
-      if (!strcmp(walker->name, groupName))
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+    {
+      if (!strcmp(tmpGroup->name, groupName))
 	{
-	  PRINTF(4)("Drawing model %s\n", walker->name);
-	  glCallList (walker->listNumber);
+	  PRINTF(4)("Drawing model %s\n", tmpGroup->name);
+	  glCallList (tmpGroup->listNumber);
 	  return;
 	}
-      walker = walker->next;
+      tmpGroup = tmpGroup->next;
     }
   PRINTF(2)("Model Named %s in %s not Found.\n", groupName, this->name);
   return;
-}
-
-/**
-   \returns Count of the Models in this File
-*/
-int Model::getGroupCount (void) const
-{
-  return this->groupCount;
 }
 
@@ -210,6 +298,6 @@
 void Model::setName(const char* name)
 {
-  if (this->name) 
-    delete this->name;
+  if (this->name)
+    delete []this->name;
   if (name)
     {
@@ -219,40 +307,4 @@
   else 
     this->name = NULL;
-}
-
-/**
-   \brief initializes a new Group model
-   \param group the group that should be initialized.
-   \todo Maybe Group should be a Class, because it does a lot of stuff
-   
-*/
-bool Model::initGroup(Group* group)
-{
-  PRINTF(4)("Adding new Group\n");
-  group->name = "";
-  group->faceMode = -1;
-  group->faceCount = 0;  
-  group->next = NULL;
-
-  group->firstFace = new Face;
-  this->initFace (group->firstFace);
-  group->currentFace = group->firstFace;
-}
-
-/**
-   \brief initializes a new Face. (sets default Values)
-   \param face The face to initialize
-*/
-bool Model::initFace (Face* face)
-{
-  face->vertexCount = 0;
-
-  face->firstElem = NULL;
-  
-  face->material = NULL;
-  
-  face->next = NULL;
-
-  return true;
 }
 
@@ -268,4 +320,5 @@
   if (this->normals)
     delete this->normals;
+
   this->vertices = NULL;
   this->vTexture = NULL;
@@ -280,59 +333,9 @@
 {
   PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
-  this->cleanupGroup(this->firstGroup);
+  this->firstGroup->cleanup();
   return true; 
 }
 
-/**
-   \brief Cleans up all groups starting from group.
-   \param group the first Group to clean
-*/
-bool Model::cleanupGroup (Group* group)
-{
-  PRINTF(5)("Cleaning up group\n");
-  if (group->firstFace != NULL)
-    {
-      cleanupFace (group->firstFace);
-      delete group->firstFace;
-    }
-
-  if (group->next !=NULL)
-    cleanupGroup (group->next);
-  return true;
-}
-
-/**
-   \brief Cleans up all Faces starting from face until NULL is reached.
-   \param face the first face to clean.
-*/
-bool Model::cleanupFace (Face* face)
-{
-  PRINTF(5)("Cleaning up Face\n");
-
-  if (face->firstElem != NULL)
-    {
-      this->cleanupFaceElement(face->firstElem);
-      delete face->firstElem;
-    }
-      
-  if (face->next != NULL)
-    {
-      this->cleanupFace (face->next);
-      delete face->next;
-    }
-}
-
-/**
-   \brief Cleans up all FaceElements starting from faceElem.
-   \param faceElem the first FaceElement to clean.
-*/
-bool Model::cleanupFaceElement(FaceElement* faceElem)
-{
-  if (faceElem->next != NULL)
-    {
-      this->cleanupFaceElement (faceElem->next);
-      delete faceElem->next;
-    }
-}
+
 
 //////////
@@ -354,10 +357,9 @@
 /**
    \brief adds a new Material to the Material List
-   \param material the name of the Material to add
+   \param materialName the name of the Material to add
    \returns the added material
 */
 Material* Model::addMaterial(const char* materialName)
 {
-  
   Material* newMat = new Material();
   newMat->setName(materialName);
@@ -395,14 +397,13 @@
 
    This function initializes a new Group. 
-   With it you should be able to import .obj-files with more than one Models inside. 
-*/
-bool Model::addGroup (const char* groupString)
+   With it you should be able to create Models with more than one SubModel inside
+*/
+bool Model::addGroup(const char* groupString)
 {
   PRINTF(5)("Read Group: %s.\n", groupString);
-  if (this->groupCount != 0 && this->currentGroup->faceCount>0)
+  if (this->groupCount != 0 && this->currentGroup->faceCount > 0)
     {
       //      finalizeGroup(currentGroup);
-      this->currentGroup = this->currentGroup->next = new Group;
-      this->initGroup(this->currentGroup);
+      this->currentGroup = this->currentGroup->next = new ModelGroup;
     }
   // setting the group name if not default.
@@ -429,4 +430,5 @@
   PRINTF(5)("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
   this->vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
+  this->vertexCount++;
   return true;
 }
@@ -443,4 +445,5 @@
   PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
   this->vertices->addEntry(x*scaleFactor, y*scaleFactor, z*scaleFactor);
+  this->vertexCount++;
   return true;
 }
@@ -460,4 +463,5 @@
   PRINTF(5)("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
   this->normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
+  this->normalCount++;
   return true;
 }
@@ -475,4 +479,6 @@
   PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
   this->normals->addEntry(x, y, z);
+  this->normalCount++;
+  return true;
 }
 
@@ -492,4 +498,5 @@
   this->vTexture->addEntry(subbuffer1);
   this->vTexture->addEntry(subbuffer2);
+  this->texCoordCount++;
   return true;
 }
@@ -507,4 +514,6 @@
   this->vTexture->addEntry(u);
   this->vTexture->addEntry(v);
+  this->texCoordCount++;
+  return true;
 }
 
@@ -514,17 +523,18 @@
 
    If a face line is found this function will add it to the glList.
+
+   String is different from the argument addFace, in this that the first Vertex/Normal/Texcoord is 1 instead of 0
 */
 bool Model::addFace (const char* faceString)
 {
   if (this->currentGroup->faceCount >0)
-    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
-  this->initFace (this->currentGroup->currentFace);
-
-  FaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new FaceElement;
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
   tmpElem->next = NULL;
   while(strcmp (faceString, "\0"))
     {
       if (this->currentGroup->currentFace->vertexCount>0)
-	  tmpElem = tmpElem->next = new FaceElement;
+	  tmpElem = tmpElem->next = new ModelFaceElement;
       tmpElem->next = NULL;
 
@@ -552,14 +562,8 @@
       if (vertex)
 	tmpElem->vertexNumber = atoi(vertex)-1;
-      else
-	tmpElem->vertexNumber = -1;
       if (texture)
 	tmpElem->texCoordNumber = atoi(texture)-1;
-      else
-	tmpElem->texCoordNumber = -1;
       if (normal)
 	tmpElem->normalNumber = atoi(normal)-1;
-      else
-	tmpElem->normalNumber = -1;
 
       faceString += tmpLen;
@@ -575,14 +579,12 @@
    \brief adds a new Face
    \param faceElemCount the number of Vertices to add to the Face.
-   \param type 0: vertex only, 1: vertex and normal, 2: vertex and Texture, 3 vertex, normal and texture
+   \param type The information Passed with each Vertex
 */
 bool Model::addFace(int faceElemCount, VERTEX_FORMAT type, ...)
 {
-   if (this->currentGroup->faceCount > 0)
-    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
-  this->initFace (this->currentGroup->currentFace);
-
-  FaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new FaceElement;
-  tmpElem->next = NULL;
+  if (this->currentGroup->faceCount > 0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+  
+  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
   
   va_list itemlist;
@@ -591,13 +593,12 @@
   for (int i = 0; i < faceElemCount; i++)
     {
-      if (this->currentGroup->currentFace->vertexCount>0)
-	  tmpElem = tmpElem->next = new FaceElement;
-      tmpElem->next = NULL;
-
-      tmpElem->vertexNumber = va_arg (itemlist, int) -1;
+      if (this->currentGroup->currentFace->vertexCount > 0)
+	tmpElem = tmpElem->next = new ModelFaceElement;
+
+      tmpElem->vertexNumber = va_arg (itemlist, int);
       if (type & TEXCOORD)
-	tmpElem->texCoordNumber = va_arg (itemlist, int) -1;
+	tmpElem->texCoordNumber = va_arg (itemlist, int);
       if (type & NORMAL)
- 	tmpElem->normalNumber = va_arg(itemlist, int) -1;
+ 	tmpElem->normalNumber = va_arg(itemlist, int);
       this->currentGroup->currentFace->vertexCount++;
     }
@@ -614,6 +615,5 @@
 {
   if (this->currentGroup->faceCount > 0)
-    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
-  this->initFace (this->currentGroup->currentFace);
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
   
   this->currentGroup->currentFace->material = this->findMaterialByName(matString);
@@ -630,6 +630,5 @@
 {
   if (this->currentGroup->faceCount > 0)
-    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
-  this->initFace (this->currentGroup->currentFace);
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
   
   this->currentGroup->currentFace->material = mtl;
@@ -662,17 +661,17 @@
   Vector curV;
 
-  Group* tmpGroup = firstGroup;
+  ModelGroup* tmpGroup = firstGroup;
   while (tmpGroup)
     {
-      Face* tmpFace = tmpGroup->firstFace;
+      ModelFace* tmpFace = tmpGroup->firstFace;
       while (tmpFace)
 	{
 	  if (tmpFace->firstElem)
 	    {
-	      FaceElement* firstElem = tmpFace->firstElem;
-	      FaceElement* prevElem;
-	      FaceElement* curElem = firstElem;
-	      FaceElement* nextElem;
-	      FaceElement* lastElem;
+	      ModelFaceElement* firstElem = tmpFace->firstElem;
+	      ModelFaceElement* prevElem;
+	      ModelFaceElement* curElem = firstElem;
+	      ModelFaceElement* nextElem;
+	      ModelFaceElement* lastElem;
 	      // 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.
 	      while (curElem)
@@ -704,10 +703,10 @@
     }
 
-  for (int i=0; i<vertices->getCount()/3;i++)
+  for (int i=0; i < vertices->getCount()/3;i++)
     {
       normArray[i].normalize();
       PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
       
-      this->normals->addEntry(normArray[i].x, normArray[i].y, normArray[i].z);
+      this->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z);
 
     }
@@ -744,5 +743,5 @@
 
       // Putting Faces to GL
-      Face* tmpFace = this->currentGroup->firstFace;
+      ModelFace* tmpFace = this->currentGroup->firstFace;
       while (tmpFace != NULL)
 	{
@@ -794,5 +793,5 @@
 	    }
 	  
-	  FaceElement* tmpElem = tmpFace->firstElem;
+	  ModelFaceElement* tmpElem = tmpFace->firstElem;
 	  while (tmpElem != NULL)
 	    {
@@ -826,5 +825,4 @@
   glNormalPointer(3, 0, this->normals->getArray());
   glTexCoordPointer(2, GL_FLOAT, 0, this->vTexture->getArray());
-
 }
 
@@ -841,14 +839,32 @@
    merging this information, the face will be drawn.
 */
-bool Model::addGLElement (FaceElement* elem)
+bool Model::addGLElement (ModelFaceElement* elem)
 {
   PRINTF(5)("importing grafical Element to openGL.\n");
 
   if (elem->texCoordNumber != -1)
-    glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
+    {
+      if (likely(elem->texCoordNumber < this->texCoordCount))
+	glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
+      else
+	PRINTF(2)("TextureCoordinate %d is not in the List (max: %d)\nThe Model might be incomplete\n",
+		  elem->texCoordNumber, this->texCoordCount);
+    }
   if (elem->normalNumber != -1)
-    glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
+    {
+    if (likely(elem->normalNumber < this->normalCount))
+      glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
+    else
+	PRINTF(2)("Normal %d is not in the List (max: %d)\nThe Model might be incomplete",
+		  elem->normalNumber, this->normalCount);      
+    }
   if (elem->vertexNumber != -1)
-    glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
+    {
+      if (likely(elem->vertexNumber < this->vertexCount))
+	  glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
+      else
+	PRINTF(2)("Vertex %d is not in the List (max: %d)\nThe Model might be incomplete",
+		  elem->vertexNumber, this->vertexCount);      
+    }	
 
 }
@@ -910,19 +926,10 @@
   this->addVertexNormal (-1.0, 0.0, 0.0);
 
-  /* normaleLess-testingMode
-  this->addFace ("1 2 4 3");
-  this->addFace ("3 4 6 5");
-  this->addFace ("5 6 8 7");
-  this->addFace ("7 8 2 1");
-  this->addFace ("2 8 6 4");
-  this->addFace ("7 1 3 5");
-  */
-
-  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,1, 2,2,2, 4,4,3, 3,3,4);
-  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 3,3,5, 4,4,6, 6,6,7, 5,5,8);
-  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 5,5,9, 6,6,10, 8,8,11, 7,7,12);
-  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,7,13, 8,8,14, 2,10,15, 1,9,16);
-  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,17, 8,11,18, 6,12,19, 4,4,20);
-  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 7,13,21, 1,1,22, 3,3,23, 5,14,24);
-
-}
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 0,0,0, 1,1,1, 3,3,2, 2,2,3);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,4, 3,3,5, 5,5,6, 4,4,7);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 4,4,8, 5,5,9, 7,7,10, 6,6,11);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,6,12, 7,7,13, 1,9,14, 0,8,15);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,16, 7,10,17, 5,11,18, 3,3,19);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,12,20, 0,0,21, 2,2,22, 4,13,23);
+
+}
