Index: branches/new_class_id/src/lib/graphics/importer/Makefile.am
===================================================================
--- branches/new_class_id/src/lib/graphics/importer/Makefile.am	(revision 9828)
+++ branches/new_class_id/src/lib/graphics/importer/Makefile.am	(revision 9829)
@@ -11,4 +11,5 @@
 		grid.cc \
 		static_model.cc \
+		static_model_data.cc \
 		objModel.cc \
 		primitive_model.cc \
@@ -57,4 +58,5 @@
 		grid.h \
 		static_model.h \
+		static_model_data.h \
 		objModel.h \
 		primitive_model.h \
Index: branches/new_class_id/src/lib/graphics/importer/static_model_data.cc
===================================================================
--- branches/new_class_id/src/lib/graphics/importer/static_model_data.cc	(revision 9829)
+++ branches/new_class_id/src/lib/graphics/importer/static_model_data.cc	(revision 9829)
@@ -0,0 +1,1016 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   2005-07-06: (Patrick) added new function buildTriangleList()
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "static_model_data.h"
+
+#include "debug.h"
+#include <stdarg.h>
+
+
+
+
+////////////////////
+/// 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;
+}
+
+/**
+ *  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->listNumber = 0;
+  this->indices = 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;
+
+  // deleting the glList
+  if (this->listNumber != 0)
+    glDeleteLists(this->listNumber, 1);
+
+  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()
+{
+  PRINTF(5)("Cleaning up group\n");
+  if (this->firstFace)
+    delete this->firstFace;
+  this->firstFace = NULL;
+  if (this->next)
+    this->next->cleanup();
+}
+
+
+
+
+/////////////
+/// MODEL ///
+/////////////
+ObjectListDefinition(StaticModelData);
+
+/**
+ * @brief Creates a 3D-Model.
+ *
+ * assigns it a Name and a Type
+ */
+StaticModelData::StaticModelData(const std::string& modelName)
+{
+  this->registerObject(this, StaticModelData::_objectList);
+  PRINTF(4)("new 3D-Model is being created\n");
+  this->setName(modelName);
+
+  this->finalized = false;
+
+  // setting the start group;
+  this->currentGroup = this->firstGroup = new ModelGroup;
+  this->groupCount = 0;
+  this->faceCount = 0;
+
+  this->scaleFactor = 1.0f;
+}
+
+/**
+ * @brief deletes an Model.
+ *
+ * Looks if any from model allocated space is still in use, and if so deleted it.
+ */
+StaticModelData::~StaticModelData()
+{
+  PRINTF(4)("Deleting Model ");
+  if (!this->getName().empty())
+  {
+    PRINT(4)("%s\n", this->getCName());
+  }
+  else
+  {
+    PRINT(4)("\n");
+  }
+  this->cleanup();
+
+  PRINTF(5)("Deleting display Lists.\n");
+  delete this->firstGroup;
+
+  // deleting the MaterialList
+  PRINTF(5)("Deleting Materials.\n");
+
+  //! @todo do we really have to delete this material??
+  std::list<ModelMaterial*>::iterator modMat;
+  for(modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++)
+  {
+    if (!(*modMat)->external)
+      delete (*modMat)->material;
+    delete (*modMat);
+  }
+}
+
+/**
+ * @brief Finalizes an Object. This can be done outside of the Class.
+ */
+void StaticModelData::finalize()
+{
+  // this creates the display List.
+  this->importToDisplayList();
+  this->buildTriangleList();
+
+  this->finalized = true;
+}
+
+/**
+ * @brief rebuild the Model from the Information we got.
+ */
+void StaticModelData::rebuild()
+{
+  PRINTF(3)("Rebuilding Model '%s'\n", this->getCName());
+  this->finalize();
+}
+
+//////////
+// DRAW //
+//////////
+/**
+ * @brief Draws the Models of all Groups.
+ *
+ * It does this by just calling the Lists that must have been created earlier.
+ */
+void StaticModelData::draw () const
+{
+  PRINTF(4)("drawing the 3D-Models\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+  {
+    PRINTF(5)("Drawing model %s\n", tmpGroup->name.c_str());
+    glCallList (tmpGroup->listNumber);
+    tmpGroup = tmpGroup->next;
+  }
+}
+
+
+/**
+ * @brief Draws the Model number groupNumber
+ * @param groupNumber The number of the group that will be displayed.
+ *
+ * It does this by just calling the List that must have been created earlier.
+ */
+void StaticModelData::draw (int groupNumber) const
+{
+  if (unlikely(groupNumber >= this->groupCount))
+  {
+    PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount);
+    return;
+  }
+  PRINTF(4)("drawing the requested 3D-Models if found.\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  int counter = 0;
+  while (tmpGroup != NULL)
+  {
+    if (counter == groupNumber)
+    {
+      PRINTF(4)("Drawing model number %i named %s\n", counter, tmpGroup->name.c_str());
+      glCallList (tmpGroup->listNumber);
+      return;
+    }
+    ++counter;
+    tmpGroup = tmpGroup->next;
+  }
+  PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->getCName());
+  return;
+}
+
+
+/**
+ * @brief Draws the Model with a specific groupName
+ * @param groupName The name of the group that will be displayed.
+ *
+ * It does this by just calling the List that must have been created earlier.
+ */
+void StaticModelData::draw (const std::string& groupName) const
+{
+  PRINTF(4)("drawing the requested 3D-Models if found.\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+  {
+    if (tmpGroup->name == groupName)
+    {
+      PRINTF(4)("Drawing model %s\n", tmpGroup->name.c_str());
+      glCallList (tmpGroup->listNumber);
+      return;
+    }
+    tmpGroup = tmpGroup->next;
+  }
+  PRINTF(2)("Model Named %s in %s not Found.\n", groupName.c_str(), this->getCName());
+  return;
+}
+
+//////////
+// INIT //
+//////////
+
+/**
+ * @brief finalizes an Model.
+ *
+ * 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.
+*/
+bool StaticModelData::cleanup()
+{
+  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
+  this->firstGroup->cleanup();
+  return true;
+}
+
+//////////
+// MESH //
+//////////
+/**
+ * @brief adds a new Material to the Material List
+ * @param material the Material to add
+ * @returns the added material
+ *
+ * this also tells this Model, that all the Materials are handled externally
+ * with this option set the Materials will not be deleted with the Model.
+ */
+Material* StaticModelData::addMaterial(Material* material)
+{
+  if (material == NULL)
+    return NULL;
+  ModelMaterial* modMat = new ModelMaterial;
+  modMat->external = true;
+  modMat->material = material;
+  this->materialList.push_back(modMat);
+  return modMat->material;
+}
+
+/**
+ * @brief adds a new Material to the Material List
+ * @param materialName the name of the Material to add
+ * @returns the added material
+ */
+Material* StaticModelData::addMaterial(const std::string& materialName)
+{
+  ModelMaterial* modMat = new ModelMaterial;
+  modMat->external = false;
+  modMat->material = new Material(materialName);
+
+  // adding material to the List of materials
+  this->materialList.push_back(modMat);
+  return modMat->material;
+}
+
+/**
+ * @brief finds a Material by its name and returns it
+ * @param materialName the Name of the material to search for.
+ * @returns the Material if found, NULL otherwise
+ */
+Material* StaticModelData::findMaterialByName(const std::string& materialName)
+{
+  std::list<ModelMaterial*>::iterator modMat;
+  for  (modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++)
+    if (materialName == (*modMat)->material->getName())
+      return (*modMat)->material;
+  return NULL;
+}
+
+/**
+ * @brief parses a group String
+ * @param groupString the new Group to create
+ *
+ * This function initializes a new Group.
+ * With it you should be able to create Models with more than one SubModel inside
+ */
+bool StaticModelData::addGroup(const std::string& groupString)
+{
+  PRINTF(5)("Read Group: %s.\n", groupString.c_str());
+  if (this->groupCount != 0 && this->currentGroup->faceCount > 0)
+  {
+    // finalizeGroup(currentGroup);
+    this->currentGroup = this->currentGroup->next = new ModelGroup;
+  }
+  // setting the group name if not default.
+  if (groupString == "default")
+  {
+    this->currentGroup->name = groupString;
+  }
+  ++this->groupCount;
+  return true;
+}
+
+/**
+ * @brief parses a vertex-String
+ * @param vertexString The String that will be parsed.
+ *
+ *  If a vertex line is found this function will inject it into the vertex-Array
+ */
+bool StaticModelData::addVertex (const std::string& vertexString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (vertexString.c_str(), "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  this->vertices.push_back(subbuffer1*scaleFactor);
+  this->vertices.push_back(subbuffer2*scaleFactor);
+  this->vertices.push_back(subbuffer3*scaleFactor);
+  return true;
+}
+
+/**
+ * @brief parses a vertex-String
+ * @param x the X-coordinate of the Vertex to add.
+ * @param y the Y-coordinate of the Vertex to add.
+ * @param z the Z-coordinate of the Vertex to add.
+ */
+bool StaticModelData::addVertex(float x, float y, float z)
+{
+  PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
+  this->vertices.push_back(x*scaleFactor);
+  this->vertices.push_back(y*scaleFactor);
+  this->vertices.push_back(z*scaleFactor);
+  return true;
+}
+
+/**
+ * @brief parses a vertexNormal-String
+ * @param normalString The String that will be parsed.
+ *
+ * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+ */
+bool StaticModelData::addVertexNormal (const std::string& normalString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (normalString.c_str(), "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  this->normals.push_back(subbuffer1);
+  this->normals.push_back(subbuffer2);
+  this->normals.push_back(subbuffer3);
+  return true;
+}
+
+/**
+ * @brief adds a VertexNormal.
+ * @param x The x coordinate of the Normal.
+ * @param y The y coordinate of the Normal.
+ * @param z The z coordinate of the Normal.
+ *
+ * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+ */
+bool StaticModelData::addVertexNormal(float x, float y, float z)
+{
+  PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
+  this->normals.push_back(x);
+  this->normals.push_back(y);
+  this->normals.push_back(z);
+  return true;
+}
+
+/**
+ * @brief parses a vertexTextureCoordinate-String
+ * @param vTextureString The String that will be parsed.
+ *
+ * If a vertexTextureCoordinate line is found,
+ * this function will inject it into the vertexTexture-Array
+ *
+ * !! WARNING THIS IS DIFFERNT FROM addVervexTexture(float, float); because it changes the second entry to 1-v !!
+ */
+bool StaticModelData::addVertexTexture (const std::string& vTextureString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  sscanf (vTextureString.c_str(), "%f %f", &subbuffer1, &subbuffer2);
+  this->vTexture.push_back(subbuffer1);
+  this->vTexture.push_back(1 - subbuffer2);
+  return true;
+}
+
+/**
+ * @brief adds a Texture Coordinate
+ * @param u The u coordinate of the TextureCoordinate.
+ * @param v The y coordinate of the TextureCoordinate.
+ *
+ * If a TextureCoordinate line is found this function will
+ *  inject it into the TextureCoordinate-Array
+ */
+bool StaticModelData::addVertexTexture(float u, float v)
+{
+  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
+  this->vTexture.push_back(u);
+  this->vTexture.push_back(v);
+  return true;
+}
+
+/**
+ * @brief parses a face-string
+ * @param faceString The String that will be parsed.
+ *
+ * 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
+ *
+ * @TODO make it std::string conform
+ */
+bool StaticModelData::addFace (const std::string& faceStringInput)
+{
+  const char* faceString = faceStringInput.c_str();
+  if (this->currentGroup->faceCount >0)
+    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 ModelFaceElement;
+    tmpElem->next = NULL;
+
+    char tmpValue [50];
+    int tmpLen;
+    char* vertex = NULL;
+    char* texture = NULL;
+    char* normal = NULL;
+
+    sscanf (faceString, "%s", tmpValue);
+    tmpLen = strlen(tmpValue);
+    vertex = tmpValue;
+
+    if ((texture = strstr (vertex, "/")) != NULL)
+    {
+      texture[0] = '\0';
+      texture ++;
+
+      if ((normal = strstr (texture, "/")) !=NULL)
+      {
+        normal[0] = '\0';
+        normal ++;
+      }
+    }
+    if (vertex)
+      tmpElem->vertexNumber = atoi(vertex)-1;
+    if (texture)
+      tmpElem->texCoordNumber = atoi(texture)-1;
+    if (normal)
+      tmpElem->normalNumber = atoi(normal)-1;
+
+    faceString += tmpLen;
+    if (strcmp (faceString, "\0"))
+      faceString++;
+    this->currentGroup->currentFace->vertexCount++;
+  }
+
+  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
+  this->faceCount += this->currentGroup->currentFace->vertexCount -2;
+  return true;
+}
+
+/**
+ * @brief adds a new Face
+ * @param faceElemCount the number of Vertices to add to the Face.
+ * @param type The information Passed with each Vertex
+*/
+bool StaticModelData::addFace(int faceElemCount, VERTEX_FORMAT type, ...)
+{
+  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;
+  va_start (itemlist, type);
+
+  for (int i = 0; i < faceElemCount; i++)
+  {
+    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);
+    if (type & NORMAL)
+      tmpElem->normalNumber = va_arg(itemlist, int);
+    this->currentGroup->currentFace->vertexCount++;
+  }
+  va_end(itemlist);
+
+  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2;
+  this->faceCount += this->currentGroup->currentFace->vertexCount -2;
+  return true;
+}
+
+/**
+ * Function that selects a material, if changed in the obj file.
+ * @param matString the Material that will be set.
+*/
+bool StaticModelData::setMaterial(const std::string& matString)
+{
+  if (this->currentGroup->faceCount > 0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  this->currentGroup->currentFace->material = this->findMaterialByName(matString);
+
+  if (this->currentGroup->faceCount == 0)
+    this->currentGroup->faceCount++;
+  return true;
+}
+
+/**
+ * Function that selects a material, if changed in the obj file.
+ * @param mtl the Material that will be set.
+*/
+bool StaticModelData::setMaterial(Material* mtl)
+{
+  if (this->currentGroup->faceCount > 0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  this->currentGroup->currentFace->material = mtl;
+
+  if (this->currentGroup->faceCount == 0)
+    this->currentGroup->faceCount++;
+  return true;
+}
+
+/**
+ * @brief A routine that is able to create normals.
+ *
+ * The algorithm does the following:
+ * 1. It calculates creates Vectors for each normale, and sets them to zero.
+ * 2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
+ * 3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
+ * 4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
+ */
+bool StaticModelData::buildVertexNormals ()
+{
+  PRINTF(4)("Normals are being calculated.\n");
+
+  Vector* normArray = new Vector [vertices.size()/3];
+  for (unsigned int i=0; i<vertices.size()/3;i++)
+    normArray[i] = Vector(.0,.0,.0);
+
+  Vector prevV;
+  Vector nextV;
+  Vector curV;
+
+  ModelGroup* tmpGroup = firstGroup;
+  while (tmpGroup != NULL)
+  {
+    ModelFace* tmpFace = tmpGroup->firstFace;
+    while (tmpFace != NULL)
+    {
+      if (tmpFace->firstElem != NULL)
+      {
+        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 != NULL)
+        {
+          prevElem = curElem;
+          curElem = curElem->next;
+        }
+        lastElem = prevElem;
+
+        curElem = firstElem;
+        for (unsigned int j = 0; j < tmpFace->vertexCount; j++)
+        {
+          if (!(nextElem = curElem->next))
+            nextElem = firstElem;
+          curElem->normalNumber = curElem->vertexNumber;
+
+          curV = Vector (this->vertices[curElem->vertexNumber*3],
+                         this->vertices[curElem->vertexNumber*3+1],
+                         this->vertices[curElem->vertexNumber*3+2]);
+
+          prevV = Vector (this->vertices[prevElem->vertexNumber*3],
+                          this->vertices[prevElem->vertexNumber*3+1],
+                          this->vertices[prevElem->vertexNumber*3+2]) - curV;
+
+          nextV = Vector (this->vertices[nextElem->vertexNumber*3],
+                          this->vertices[nextElem->vertexNumber*3+1],
+                          this->vertices[nextElem->vertexNumber*3+2]) - curV;
+          normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
+
+          prevElem = curElem;
+          curElem = curElem->next;
+        }
+      }
+      tmpFace = tmpFace->next;
+    }
+    tmpGroup = tmpGroup->next;
+  }
+
+  for (unsigned int i=0; i < this->vertices.size()/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->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z);
+
+  }
+  delete[] normArray;
+  return true;
+}
+
+////////////
+// openGL //
+////////////
+/**
+ *  reads and includes the Faces/Materials into the openGL state Machine
+*/
+bool StaticModelData::importToDisplayList()
+{
+  // finalize the Arrays
+  if (normals.size() == 0) // vertices-Array must be built for this
+    this->buildVertexNormals();
+
+  this->currentGroup = this->firstGroup;
+
+  while (this->currentGroup != NULL)
+  {
+
+    // creating a glList for the Group
+    if ((this->currentGroup->listNumber = glGenLists(1)) == 0)
+    {
+      PRINTF(2)("glList could not be created for this Model\n");
+      return false;
+    }
+    glNewList (this->currentGroup->listNumber, GL_COMPILE);
+
+    // Putting Faces to GL
+    ModelFace* tmpFace = this->currentGroup->firstFace;
+    while (tmpFace != NULL)
+    {
+      if (tmpFace->vertexCount == 0 && tmpFace->material != NULL)
+      {
+        if (this->currentGroup->faceMode != -1)
+          glEnd();
+        this->currentGroup->faceMode = 0;
+        if (tmpFace->material != NULL)
+        {
+          tmpFace->material->select();
+          PRINTF(5)("using material %s for coming Faces.\n", tmpFace->material->getCName());
+        }
+      }
+
+      else if (tmpFace->vertexCount == 3)
+      {
+        if (this->currentGroup->faceMode != 3)
+        {
+          if (this->currentGroup->faceMode != -1)
+            glEnd();
+          glBegin(GL_TRIANGLES);
+        }
+
+        this->currentGroup->faceMode = 3;
+        PRINTF(5)("found triag.\n");
+      }
+
+      else if (tmpFace->vertexCount == 4)
+      {
+        if (this->currentGroup->faceMode != 4)
+        {
+          if (this->currentGroup->faceMode != -1)
+            glEnd();
+          glBegin(GL_QUADS);
+        }
+        this->currentGroup->faceMode = 4;
+        PRINTF(5)("found quad.\n");
+      }
+
+      else if (tmpFace->vertexCount > 4)
+      {
+        if (this->currentGroup->faceMode != -1)
+          glEnd();
+        glBegin(GL_POLYGON);
+        PRINTF(5)("Polygon with %i faces found.", tmpFace->vertexCount);
+        this->currentGroup->faceMode = tmpFace->vertexCount;
+      }
+
+      ModelFaceElement* tmpElem = tmpFace->firstElem;
+      while (tmpElem != NULL)
+      {
+        //      PRINTF(2)("%s\n", tmpElem->value);
+        this->addGLElement(tmpElem);
+        tmpElem = tmpElem->next;
+      }
+      tmpFace = tmpFace->next;
+    }
+    glEnd();
+    glEndList();
+
+    this->currentGroup = this->currentGroup->next;
+  }
+  return true;
+}
+
+
+/**
+ *  builds an array of triangles, that can later on be used for obb separation and octree separation
+ */
+bool StaticModelData::buildTriangleList()
+{
+  if( unlikely(!this->triangles.empty()))
+    return true;
+  /* make sure, that all the arrays are finalized */
+  if( normals.size() == 0) // vertices-Array must be built for this
+    this->buildVertexNormals();
+
+  int                index = 0;                   //!< the counter for the triangle array
+  ModelFaceElement*  tmpElem;       //!< the temporary faceelement reference
+  ModelFace*         tmpFace;              //!< the temporary face referece
+
+  unsigned int numTriangles = 0;
+  bool warned = false;
+
+  /* count the number of triangles */
+  /* now iterate through all groups and build up the triangle list */
+  this->currentGroup = this->firstGroup;
+  while( this->currentGroup != NULL)
+  {
+    tmpFace = this->currentGroup->firstFace;
+    while( tmpFace != NULL)
+    {
+      /* if its a triangle just add it to the list */
+      if( tmpFace->vertexCount == 3)
+      {
+        ++numTriangles;
+      } /* if the polygon is a quad */
+      else if( tmpFace->vertexCount == 4)
+      {
+        numTriangles += 2;
+      }
+      else if( tmpFace->vertexCount > 4)
+      {
+        if (!warned)
+        {
+          PRINTF(2)("This model (%s) got over 4 vertices per face <=> conflicts in the CD engine!\n", this->getCName());
+          warned = true;
+        }
+      }
+      tmpFace = tmpFace->next;
+    }
+    this->currentGroup = this->currentGroup->next;
+  }
+
+  PRINTF(3)("got %i triangles, %i vertices\n", numTriangles, this->vertices.size());
+
+
+  /* write MODELINFO structure */
+
+  /* allocate memory for the new triangle structures */
+  this->triangles.reserve(numTriangles);
+
+  /* now iterate through all groups and build up the triangle list */
+  this->currentGroup = this->firstGroup;
+  while( this->currentGroup != NULL)
+  {
+    tmpFace = this->currentGroup->firstFace;
+    while( tmpFace != NULL)
+    {
+      tmpElem = tmpFace->firstElem;
+
+      /* if its a triangle just add it to the list */
+      if( tmpFace->vertexCount == 3)
+      {
+        for( int j = 0; j < 3; ++j)
+        {
+          this->triangles[index].indexToVertices[j] = (unsigned int)tmpElem->vertexNumber * 3 ;
+          this->triangles[index].indexToNormals[j] = (unsigned int)tmpElem->normalNumber * 3 ;
+          this->triangles[index].indexToTexCoor[j] = (unsigned int)tmpElem->texCoordNumber * 3 ;
+          tmpElem = tmpElem->next;
+
+        }
+        ++index;
+      } /* if the polygon is a quad */
+      else if( tmpFace->vertexCount == 4)
+      {
+
+        this->triangles[index].indexToVertices[0] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index].indexToNormals[0] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index].indexToTexCoor[0] = (unsigned int)tmpElem->texCoordNumber * 3;
+
+        this->triangles[index + 1].indexToVertices[0] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index + 1].indexToNormals[0] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index + 1].indexToTexCoor[0] = (unsigned int)tmpElem->texCoordNumber * 3;
+        tmpElem = tmpElem->next;
+
+        this->triangles[index].indexToVertices[1] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index].indexToNormals[1] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index].indexToTexCoor[1] = (unsigned int)tmpElem->texCoordNumber * 3;
+        tmpElem = tmpElem->next;
+
+        this->triangles[index].indexToVertices[2] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index].indexToNormals[2] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index].indexToTexCoor[2] = (unsigned int)tmpElem->texCoordNumber * 3;
+
+        this->triangles[index + 1].indexToVertices[2] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index + 1].indexToNormals[2] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index + 1].indexToTexCoor[2] = (unsigned int)tmpElem->texCoordNumber * 3;
+        tmpElem = tmpElem->next;
+
+        this->triangles[index + 1].indexToVertices[1] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index + 1].indexToNormals[1] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index + 1].indexToTexCoor[1] = (unsigned int)tmpElem->texCoordNumber * 3;
+
+        index += 2;
+      }
+      tmpFace = tmpFace->next;
+    }
+    this->currentGroup = this->currentGroup->next;
+  }
+  return true;
+}
+
+
+/**
+ *  Adds a Face-element (one vertex of a face) with all its information.
+ * @param elem The FaceElement to add to the OpenGL-environment.
+
+   It does this by searching:
+   1. The Vertex itself
+   2. The VertexNormale
+   3. The VertexTextureCoordinate
+   merging this information, the face will be drawn.
+*/
+bool StaticModelData::addGLElement (ModelFaceElement* elem)
+{
+  PRINTF(5)("importing grafical Element to openGL.\n");
+
+  if (elem->texCoordNumber > -1)
+  {
+    if (likely((unsigned int)elem->texCoordNumber < this->vTexture.size()))
+      glTexCoord2fv(&this->vTexture[0] + elem->texCoordNumber * 2);
+    else
+      PRINTF(2)("TextureCoordinate %d is not in the List (max: %d)\nThe Model might be incomplete\n",
+                elem->texCoordNumber, this->vTexture.size());
+  }
+  if (elem->normalNumber > -1)
+  {
+    if (likely((unsigned int)elem->normalNumber < this->normals.size()))
+      glNormal3fv(&this->normals[0] + elem->normalNumber * 3);
+    else
+      PRINTF(2)("Normal %d is not in the List (max: %d)\nThe Model might be incomplete",
+                elem->normalNumber, this->normals.size());
+  }
+  if (elem->vertexNumber > -1)
+  {
+    if (likely((unsigned int)elem->vertexNumber < this->vertices.size()))
+      glVertex3fv(&this->vertices[0]+ elem->vertexNumber * 3);
+    else
+      PRINTF(2)("Vertex %d is not in the List (max: %d)\nThe Model might be incomplete",
+                elem->vertexNumber, this->vertices.size());
+  }
+
+  return true;
+}
+
+/**
+ *  Includes a default model
+
+   This will inject a Cube, because this is the most basic model.
+*/
+void StaticModelData::cubeModel()
+{
+  this->addVertex (-0.5, -0.5, 0.5);
+  this->addVertex (0.5, -0.5, 0.5);
+  this->addVertex (-0.5, 0.5, 0.5);
+  this->addVertex (0.5, 0.5, 0.5);
+  this->addVertex (-0.5, 0.5, -0.5);
+  this->addVertex (0.5, 0.5, -0.5);
+  this->addVertex (-0.5, -0.5, -0.5);
+  this->addVertex (0.5, -0.5, -0.5);
+
+  this->addVertexTexture (0.0, 0.0);
+  this->addVertexTexture (1.0, 0.0);
+  this->addVertexTexture (0.0, 1.0);
+  this->addVertexTexture (1.0, 1.0);
+  this->addVertexTexture (0.0, 2.0);
+  this->addVertexTexture (1.0, 2.0);
+  this->addVertexTexture (0.0, 3.0);
+  this->addVertexTexture (1.0, 3.0);
+  this->addVertexTexture (0.0, 4.0);
+  this->addVertexTexture (1.0, 4.0);
+  this->addVertexTexture (2.0, 0.0);
+  this->addVertexTexture (2.0, 1.0);
+  this->addVertexTexture (-1.0, 0.0);
+  this->addVertexTexture (-1.0, 1.0);
+
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+
+  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);
+}
Index: branches/new_class_id/src/lib/graphics/importer/static_model_data.h
===================================================================
--- branches/new_class_id/src/lib/graphics/importer/static_model_data.h	(revision 9829)
+++ branches/new_class_id/src/lib/graphics/importer/static_model_data.h	(revision 9829)
@@ -0,0 +1,164 @@
+/*!
+ * @file static_model.h
+ * @brief Contains the Model Class that handles Static 3D-Models rendered with glList's
+ */
+
+#ifndef _STATIC_MODEL_H
+#define _STATIC_MODEL_H
+
+#include "model.h"
+
+#include "material.h"
+#include <vector>
+
+// definition of different modes for setting up Faces
+#define VERTEX 0       //!< If Faces are created WITH Vertex-Coordinate
+#define NORMAL 1       //!< If Faces are created WITH Normals (otherwise autocalculate)
+#define TEXCOORD 2     //!< If Faces are created WITH TextureCoordinate
+
+//! an enumerator for VERTEX_FORMAT
+typedef enum VERTEX_FORMAT {
+  VERTEX_ONLY = VERTEX,
+  VERTEX_NORMAL = NORMAL,
+  VERTEX_TEXCOORD = TEXCOORD,
+  VERTEX_TEXCOORD_NORMAL = NORMAL | TEXCOORD
+};
+
+////////////////////
+/// SUB-ELEMENTS ///
+////////////////////
+//! This is the placeholder of one Vertex beloning to a Face.
+class ModelFaceElement
+{
+ public:
+  ModelFaceElement();
+  ~ModelFaceElement();
+
+  int                 vertexNumber;         //!< The number of the Vertex out of the Array* vertices, this vertex points to.
+  int                 normalNumber;         //!< The number of the Normal out of the Array* normals, this vertex points to.
+  int                 texCoordNumber;       //!< The number of the textureCoordinate out of the Array* vTexture, this vertex points to.
+
+  ModelFaceElement*   next;                 //!< Point to the next FaceElement in this List.
+};
+
+//! This is the placeholder of a Face belonging to a Group of Faces.
+class ModelFace
+{
+ public:
+  ModelFace();
+  ~ModelFace();
+
+  unsigned int        vertexCount;     //!< The Count of vertices this Face has.
+  ModelFaceElement*   firstElem;       //!< Points to the first Vertex (FaceElement) of this Face.
+  Material*           material;        //!< The Material to use.
+
+  ModelFace*          next;            //!< Pointer to the next Face.
+};
+
+//! Group to handle multiple Models per obj-file.
+class ModelGroup
+{
+ public:
+  ModelGroup();
+  ~ModelGroup();
+
+  void cleanup();
+
+  std::string  name;           //!< the Name of the Group. this is an identifier, that can be accessed via the draw (std::string name) function.
+  GLubyte*     indices;        //!< The indices of the Groups. Needed for vertex-arrays
+  GLuint       listNumber;     //!< The number of the GL-List this Group gets.
+  ModelFace*   firstFace;      //!< The first Face in this group.
+  ModelFace*   currentFace;    //!< The current Face in this Group (the one we are currently working with.)
+  int          faceMode;       //!< The Mode the Face is in: initially -1, 0 for FaceList opened, 1 for Material,  3 for triangle, 4 for Quad, 5+ for Poly @todo ENUM...
+  int          faceCount;      //!< The Number of Faces this Group holds.
+
+  ModelGroup*  next;           //!< Pointer to the next Group.
+};
+
+struct ModelMaterial
+{
+  Material* material;
+  bool external;
+};
+
+/////////////
+/// MODEL ///
+/////////////
+//! Class that handles static 3D-Models.
+/**
+ * it can also read them in and display them.
+ * All the objects are rendered with glLists
+ */
+class StaticModelData : public BaseObject
+{
+  ObjectListDeclaration(StaticModelData);
+  public:
+  StaticModelData(const std::string& modelName = "");
+  virtual ~StaticModelData();
+
+  virtual void draw() const;
+  void draw(int groupNumber) const;
+  void draw(const std::string& groupName) const;
+
+  void rebuild();
+
+  Material* addMaterial(Material* material);
+  Material* addMaterial(const std::string& materialName);
+
+  bool addGroup(const std::string& groupString);
+
+  bool addVertex(const std::string& vertexString);
+  bool addVertex(float x, float y, float z);
+
+  bool addFace(const std::string& faceString);
+  bool addFace(int faceElemCount, VERTEX_FORMAT type, ...);
+
+  bool addVertexNormal(const std::string& normalString);
+  bool addVertexNormal(float x, float y, float z);
+
+  bool addVertexTexture(const std::string& vTextureString);
+  bool addVertexTexture(float u, float v);
+
+  bool setMaterial(const std::string& mtlString);
+  bool setMaterial(Material* mtl);
+
+  void finalize();
+
+
+ protected:
+  void cubeModel();
+
+  Material* findMaterialByName(const std::string& materialName);
+
+ protected:
+  float            scaleFactor;     //!< The Factor with which the Model should be scaled. @todo maybe one wants to scale the Model after Initialisation
+
+ private:
+  bool buildVertexNormals();
+
+  bool importToDisplayList();
+  bool buildTriangleList();
+
+  bool addGLElement(ModelFaceElement* elem);
+
+  bool cleanup();
+
+ private:
+  bool                       finalized;       //!< Sets the Object to be finalized.
+
+  unsigned int               faceCount;       //!< A modelwide Counter for the faces
+
+  std::vector<GLfloat>       vertices;        //!< The Array that handles the Vertices.
+  std::vector<GLfloat>       normals;         //!< The Array that handles the Normals.
+  std::vector<GLfloat>       vTexture;        //!< The Array that handles the VertexTextureCoordinates.
+
+  std::vector<sTriangleExt>  triangles;       //!< The Triangles if built.
+
+  ModelGroup*                firstGroup;      //!< The first of all groups.
+  ModelGroup*                currentGroup;    //!< The currentGroup. this is the one we will work with.
+  int                        groupCount;      //!< The Count of Groups.
+
+  std::list<ModelMaterial*>  materialList;    //!< A list for all the Materials in this Model
+};
+
+#endif
