Index: /trunk/src/lib/graphics/importer/abstract_model.h
===================================================================
--- /trunk/src/lib/graphics/importer/abstract_model.h	(revision 6007)
+++ /trunk/src/lib/graphics/importer/abstract_model.h	(revision 6008)
@@ -113,5 +113,5 @@
   unsigned int     numTriangles;         //!< number of triangles in the Model
   unsigned int     numNormals;           //!< how many Normals in the Model
-  unsigned int     numTexCoor;
+  unsigned int     numTexCoor;           //!< how many Texture Coordinates in the Model
 
   const float*     pVertices;            //!< array of the Vertives
@@ -131,9 +131,28 @@
     virtual ~AbstractModel() { }
 
-    inline const modelInfo* getModelInfo() const { return this->pModelInfo; }
+    inline const modelInfo* getModelInfo() const { return &this->pModelInfo; }
 
+    /** @returns a Pointer to the Vertex-Array, if it was deleted it returns NULL */
+    inline const float* getVertexArray() const { return this->pModelInfo.pVertices; };
+    /** @returns the VertexCount of this Model */
+    inline unsigned int getVertexCount() const { return this->pModelInfo.numVertices; };
+
+    /** @returns a Pointer to the Normals-Array, if it was deleted it returns NULL */
+    inline const float* getNormalsArray() const { return this->pModelInfo.pNormals; };
+    /** @returns the NormalsCount of this Model */
+    inline unsigned int getNormalsCount() const { return this->pModelInfo.numNormals; };
+
+    /** @returns a Pointer to the TexCoord-Array, if it was deleted it returns NULL */
+    inline const float* getTexCoordArray() const { return this->pModelInfo.pTexCoor; };
+    /** @returns the TexCoord-Count of this Model */
+    inline unsigned int getTexCoordCount() const { return this->pModelInfo.numTexCoor; };
+
+    /** @returns the Array of triangles */
+    inline sTriangleExt* getTriangles() const { return this->pModelInfo.pTriangles; };
+    /** @returns the Count of Faces of this Model */
+    inline unsigned int getFaceCount() const { return this->pModelInfo.numTriangles; };
 
   protected:
-    modelInfo*     pModelInfo;      //!< Reference to the modelInfo
+    modelInfo      pModelInfo;      //!< Reference to the modelInfo
 };
 
Index: /trunk/src/lib/graphics/importer/model.cc
===================================================================
--- /trunk/src/lib/graphics/importer/model.cc	(revision 6007)
+++ /trunk/src/lib/graphics/importer/model.cc	(revision 6008)
@@ -158,5 +158,4 @@
   this->triangleCount = 0;
   this->triangles = NULL;
-  this->pModelInfo = NULL;
 
   this->scaleFactor = 1;
@@ -205,5 +204,4 @@
     delete (*modMat);
   }
-  delete this->pModelInfo;
 }
 
@@ -223,13 +221,12 @@
 
   /* load the ModelInfo */
-  this->pModelInfo = new modelInfo;
-  this->pModelInfo->numVertices = this->vertexCount;
-  this->pModelInfo->pVertices = this->vertices->getArray();
-  this->pModelInfo->numTriangles = this->triangleCount;
-  this->pModelInfo->pTriangles = this->triangles;
-  this->pModelInfo->numNormals = this->normalCount;
-  this->pModelInfo->pNormals = this->normals->getArray();
-  this->pModelInfo->numTexCoor = this->vTexture->getCount();
-  this->pModelInfo->pTexCoor = this->vTexture->getArray();
+  this->pModelInfo.numVertices = this->vertexCount;
+  this->pModelInfo.pVertices = this->vertices->getArray();
+  this->pModelInfo.numTriangles = this->triangleCount;
+  this->pModelInfo.pTriangles = this->triangles;
+  this->pModelInfo.numNormals = this->normalCount;
+  this->pModelInfo.pNormals = this->normals->getArray();
+  this->pModelInfo.numTexCoor = this->vTexture->getCount();
+  this->pModelInfo.pTexCoor = this->vTexture->getArray();
 
   this->finalized = true;
Index: /trunk/src/lib/graphics/importer/vertex_list_model.cc
===================================================================
--- /trunk/src/lib/graphics/importer/vertex_list_model.cc	(revision 6008)
+++ /trunk/src/lib/graphics/importer/vertex_list_model.cc	(revision 6008)
@@ -0,0 +1,1015 @@
+/*
+   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 "vertex_list_model.h"
+
+#include "stdlibincl.h"
+#include <stdarg.h>
+
+#include "vector.h"
+
+using namespace std;
+
+/**
+ *  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 ///
+/////////////
+/**
+ *  Creates a 3D-Model.
+
+   assigns it a Name and a Type
+*/
+Model::Model(const char* modelName, MODEL_TYPE type)
+{
+  this->setClassID(CL_MODEL, "Model");
+  PRINTF(4)("new 3D-Model is being created\n");
+  this->setName(modelName);
+  this->type = type;
+
+  this->finalized = false;
+  // setting the start group;
+  this->currentGroup = this->firstGroup = new ModelGroup;
+  this->groupCount = 0;
+  this->vertexCount = 0;
+  this->normalCount = 0;
+  this->texCoordCount = 0;
+  this->faceCount = 0;
+  this->triangleCount = 0;
+  this->triangles = NULL;
+  this->pModelInfo = NULL;
+
+  this->scaleFactor = 1;
+
+  this->vertices = new tArray<GLfloat>();
+  this->vTexture = new tArray<GLfloat>();
+  this->normals = new tArray<GLfloat>();
+
+  if (this->type == MODEL_VERTEX_ARRAY)
+    glEnableClientState(GL_VERTEX_ARRAY | GL_NORMAL_ARRAY | GL_TEXTURE_COORD_ARRAY);
+}
+
+/**
+ *  deletes an Model.
+
+   Looks if any from model allocated space is still in use, and if so deleted it.
+*/
+Model::~Model()
+{
+  PRINTF(4)("Deleting Model ");
+  if (this->getName())
+  {
+    PRINT(4)("%s\n", this->getName());
+  }
+  else
+  {
+    PRINT(4)("\n");
+  }
+  this->cleanup();
+
+  PRINTF(5)("Deleting display Lists.\n");
+  delete this->firstGroup;
+
+  // deleting Arrays (if not allready done by finalize)
+  this->deleteArrays();
+
+  // deleting the MaterialList
+  PRINTF(5)("Deleting Materials.\n");
+
+  //! @todo do we really have to delete this material??
+  list<ModelMaterial*>::iterator modMat;
+  for(modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++)
+  {
+    if (!(*modMat)->external)
+      delete (*modMat)->material;
+    delete (*modMat);
+  }
+  delete this->pModelInfo;
+}
+
+/**
+ *  Finalizes an Object. This can be done outside of the Class.
+*/
+void Model::finalize()
+{
+  // this creates the display List.
+  this->importToDisplayList();
+  this->buildTriangleList();
+
+  // deletes everything we allocated.
+  //if (this->type == MODEL_DISPLAY_LIST)
+    //this->deleteArrays();
+  //  this->cleanup();
+
+  /* load the ModelInfo */
+  this->pModelInfo = new modelInfo;
+  this->pModelInfo->numVertices = this->vertexCount;
+  this->pModelInfo->pVertices = this->vertices->getArray();
+  this->pModelInfo->numTriangles = this->triangleCount;
+  this->pModelInfo->pTriangles = this->triangles;
+  this->pModelInfo->numNormals = this->normalCount;
+  this->pModelInfo->pNormals = this->normals->getArray();
+  this->pModelInfo->numTexCoor = this->vTexture->getCount();
+  this->pModelInfo->pTexCoor = this->vTexture->getArray();
+
+  this->finalized = true;
+}
+
+/**
+ * rebuild the Model from the Information we got.
+ */
+void Model::rebuild()
+{
+  PRINTF(3)("Rebuilding Model '%s'\n", this->getName());
+  this->finalize();
+
+}
+
+//////////
+// DRAW //
+//////////
+/**
+ *  Draws the Models of all Groups.
+   It does this by just calling the Lists that must have been created earlier.
+*/
+void Model::draw () const
+{
+
+  PRINTF(4)("drawing the 3D-Models\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+    {
+      PRINTF(5)("Drawing model %s\n", tmpGroup->name);
+      glCallList (tmpGroup->listNumber);
+      tmpGroup = tmpGroup->next;
+    }
+
+
+/*  const GLfloat* pVertices = NULL;
+  const GLfloat* pNorm = NULL;
+
+  glBegin(GL_TRIANGLES);
+  for( int i = 0; i < this->triangleCount; ++i)
+  {
+    //printf("int i = %i\n", i);
+    pNorm = &this->normals->getArray()[this->triangles[i].indexToNormals[0]];
+    pVertices = &this->vertices->getArray()[this->triangles[i].indexToVertices[0]];
+    glNormal3f(pNorm[0], pNorm[1], pNorm[2]);
+    glVertex3f(pVertices[0], pVertices[1], pVertices[2]);
+
+    pNorm = &this->normals->getArray()[this->triangles[i].indexToNormals[1]];
+    pVertices = &this->vertices->getArray()[this->triangles[i].indexToVertices[1]];
+    glNormal3f(pNorm[0], pNorm[1], pNorm[2]);
+    glVertex3f(pVertices[0], pVertices[1], pVertices[2]);
+
+    pNorm = &this->normals->getArray()[this->triangles[i].indexToNormals[2]];
+    pVertices = &this->vertices->getArray()[this->triangles[i].indexToVertices[2]];
+    glNormal3f(pNorm[0], pNorm[1], pNorm[2]);
+    glVertex3f(pVertices[0], pVertices[1], pVertices[2]);
+
+  }
+  glEnd();*/
+}
+
+/**
+ *  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 Model::draw (int groupNumber) const
+{
+  if (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);
+          glCallList (tmpGroup->listNumber);
+          return;
+        }
+      ++counter;
+      tmpGroup = tmpGroup->next;
+    }
+  PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->getName());
+  return;
+
+}
+
+/**
+ *  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 Model::draw (char* groupName) const
+{
+  PRINTF(4)("drawing the requested 3D-Models if found.\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+    {
+      if (!strcmp(tmpGroup->name, groupName))
+        {
+          PRINTF(4)("Drawing model %s\n", tmpGroup->name);
+          glCallList (tmpGroup->listNumber);
+          return;
+        }
+      tmpGroup = tmpGroup->next;
+    }
+  PRINTF(2)("Model Named %s in %s not Found.\n", groupName, this->getName());
+  return;
+}
+
+//////////
+// INIT //
+//////////
+/**
+ *  deletes all the arrays
+*/
+bool Model::deleteArrays()
+{
+  if (this->vertices)
+    delete this->vertices;
+  if (this->vTexture)
+    delete this->vTexture;
+  if (this->normals)
+    delete this->normals;
+  if (this->triangles)
+    delete[] this->triangles;
+
+  this->vertices = NULL;
+  this->vTexture = NULL;
+  this->normals = NULL;
+  this->triangles = NULL;
+  this->triangleCount = 0;
+}
+
+/**
+ *  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 Model::cleanup()
+{
+  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
+  this->firstGroup->cleanup();
+  return true;
+}
+
+//////////
+// MESH //
+//////////
+/**
+ * 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* Model::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;
+}
+
+/**
+ *  adds a new Material to the Material List
+ * @param materialName the name of the Material to add
+ * @returns the added material
+*/
+Material* Model::addMaterial(const char* 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;
+}
+
+/**
+ *  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* Model::findMaterialByName(const char* materialName)
+{
+  list<ModelMaterial*>::iterator modMat;
+  for  (modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++)
+    if (!strcmp((*modMat)->material->getName(), materialName))
+      return (*modMat)->material;
+  return NULL;
+}
+
+/**
+ *  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 Model::addGroup(const char* groupString)
+{
+  PRINTF(5)("Read Group: %s.\n", groupString);
+  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 (strcmp(groupString, "default"))
+    {
+      this->currentGroup->name = new char [strlen(groupString)+1];
+      strcpy(this->currentGroup->name, groupString);
+    }
+  ++this->groupCount;
+}
+
+/**
+ *  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 Model::addVertex (const char* vertexString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  this->vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
+  this->vertexCount++;
+  return true;
+}
+
+/**
+ *  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 Model::addVertex(float x, float y, float z)
+{
+  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;
+}
+
+/**
+ *  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 Model::addVertexNormal (const char* normalString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  this->normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
+  this->normalCount++;
+  return true;
+}
+
+/**
+ *  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 Model::addVertexNormal(float x, float y, float z)
+{
+  PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
+  this->normals->addEntry(x, y, z);
+  this->normalCount++;
+  return true;
+}
+
+/**
+ *  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 Model::addVertexTexture (const char* vTextureString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
+  this->vTexture->addEntry(subbuffer1);
+  this->vTexture->addEntry(1 - subbuffer2);
+  this->texCoordCount++;
+  return true;
+}
+
+/**
+ *  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 Model::addVertexTexture(float u, float v)
+{
+  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
+  this->vTexture->addEntry(u);
+  this->vTexture->addEntry(v);
+  this->texCoordCount++;
+  return true;
+}
+
+/**
+ *  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
+*/
+bool Model::addFace (const char* faceString)
+{
+  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;
+}
+
+/**
+ *  adds a new Face
+ * @param faceElemCount the number of Vertices to add to the Face.
+ * @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 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;
+}
+
+/**
+ * Function that selects a material, if changed in the obj file.
+ * @param matString the Material that will be set.
+*/
+bool Model::setMaterial(const char* 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 ++;
+}
+
+/**
+ * Function that selects a material, if changed in the obj file.
+ * @param mtl the Material that will be set.
+*/
+bool Model::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 ++;
+}
+
+/**
+ *  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 Model::buildVertexNormals ()
+{
+  PRINTF(4)("Normals are being calculated.\n");
+
+  Vector* normArray = new Vector [vertices->getCount()/3];
+  for (int i=0; i<vertices->getCount()/3;i++)
+    normArray[i] = Vector(.0,.0,.0);
+
+  int firstTouch;
+  int secondTouch;
+  Vector prevV;
+  Vector nextV;
+  Vector curV;
+
+  ModelGroup* tmpGroup = firstGroup;
+  while (tmpGroup)
+    {
+      ModelFace* tmpFace = tmpGroup->firstFace;
+      while (tmpFace)
+        {
+          if (tmpFace->firstElem)
+            {
+              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)
+                {
+                  prevElem = curElem;
+                  curElem = curElem->next;
+                }
+              lastElem = prevElem;
+
+              curElem = firstElem;
+              for (int j=0; j<tmpFace->vertexCount; j++)
+                {
+                  if (!(nextElem = curElem->next))
+                    nextElem = firstElem;
+                  curElem->normalNumber = curElem->vertexNumber;
+
+                  curV = Vector (vertices->getArray()[curElem->vertexNumber*3], vertices->getArray()[curElem->vertexNumber*3+1], vertices->getArray()[curElem->vertexNumber*3+2]);
+                  prevV = Vector (vertices->getArray()[prevElem->vertexNumber*3], vertices->getArray()[prevElem->vertexNumber*3+1], vertices->getArray()[prevElem->vertexNumber*3+2]) - curV;
+                  nextV = Vector (vertices->getArray()[nextElem->vertexNumber*3], vertices->getArray()[nextElem->vertexNumber*3+1], vertices->getArray()[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 (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->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z);
+
+    }
+  delete []normArray;
+}
+
+////////////
+// openGL //
+////////////
+/**
+ *  reads and includes the Faces/Materials into the openGL state Machine
+*/
+bool Model::importToDisplayList()
+{
+  // finalize the Arrays
+  this->vertices->finalizeArray();
+  this->vTexture->finalizeArray();
+  if (normals->getCount() == 0) // vertices-Array must be built for this
+    this->buildVertexNormals();
+  this->normals->finalizeArray();
+
+  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;
+              Material* tmpMat;
+              if (tmpFace->material != NULL)
+                {
+                  tmpFace->material->select();
+                  PRINTF(5)("using material %s for coming Faces.\n", tmpFace->material->getName());
+                }
+            }
+
+          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;
+    }
+}
+
+/**
+ *  reads and includes the Faces/Materials into the openGL state Machine
+*/
+bool Model::importToVertexArray()
+{
+  // finalize the Arrays
+  this->vertices->finalizeArray();
+  this->vTexture->finalizeArray();
+  if (normals->getCount() == 0) // vertices-Array must be built for this
+    this->buildVertexNormals();
+  this->normals->finalizeArray();
+
+  this->currentGroup = this->firstGroup;
+  glVertexPointer(3, GL_FLOAT, 0, this->vertices->getArray());
+  glNormalPointer(3, 0, this->normals->getArray());
+  glTexCoordPointer(2, GL_FLOAT, 0, this->vTexture->getArray());
+}
+
+
+
+/**
+ *  builds an array of triangles, that can later on be used for obb separation and octree separation
+ */
+bool Model::buildTriangleList()
+{
+  if( unlikely(this->triangles != NULL))
+    return true;
+  /* make sure, that all the arrays are finalized */
+  if( unlikely(!this->vertices->isFinalized()))
+    this->vertices->finalizeArray();
+  if( unlikely(!this->vTexture->isFinalized()))
+    this->vTexture->finalizeArray();
+  if( normals->getCount() == 0) // vertices-Array must be built for this
+    this->buildVertexNormals();
+  if( unlikely(!this->normals->isFinalized()))
+    this->normals->finalizeArray();
+
+
+  int index = 0;                   //!< the counter for the triangle array
+  ModelFaceElement* tmpElem;       //!< the temporary faceelement reference
+  ModelFace* tmpFace;              //!< the temporary face referece
+
+  /* count the number of triangles */
+  /* now iterate through all groups and build up the triangle list */
+  this->triangleCount = 0;
+  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)
+      {
+        ++this->triangleCount;
+      } /* if the polygon is a quad */
+      else if( tmpFace->vertexCount == 4)
+      {
+        this->triangleCount += 2;
+      }
+      else if( tmpFace->vertexCount > 4)
+      {
+        PRINTF(1)("This model (%s) got over 4 vertices per face <=> conflicts in the CD engine!\n", this->getName());
+      //exit(0);
+      }
+      tmpFace = tmpFace->next;
+    }
+    this->currentGroup = this->currentGroup->next;
+  }
+
+  PRINTF(3)("got %i triangles, %i vertices\n", this->triangleCount, this->vertexCount);
+
+
+  /* write MODELINFO structure */
+
+  /* allocate memory for the new triangle structures */
+  if( (this->triangles = new sTriangleExt[this->triangleCount]) == NULL)
+  {
+    PRINTF(1)("Could not allocate memory for triangle list\n");
+    return false;
+  }
+
+  /* now iterate through all groups and build up the triangle list */
+  this->currentGroup = this->firstGroup;
+  while( this->currentGroup != NULL)
+  {
+      // Putting Faces to GL
+    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 Model::addGLElement (ModelFaceElement* elem)
+{
+  PRINTF(5)("importing grafical Element to openGL.\n");
+
+  if (elem->texCoordNumber != -1)
+    {
+      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)
+    {
+    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)
+    {
+      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);
+    }
+
+}
+
+/**
+ *  Includes a default model
+
+   This will inject a Cube, because this is the most basic model.
+*/
+void Model::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: /trunk/src/lib/graphics/importer/vertex_list_model.h
===================================================================
--- /trunk/src/lib/graphics/importer/vertex_list_model.h	(revision 6008)
+++ /trunk/src/lib/graphics/importer/vertex_list_model.h	(revision 6008)
@@ -0,0 +1,91 @@
+/*!
+  \file model.h
+  \brief Contains the Model Class that handles 3D-Models
+*/
+
+#ifndef _MODEL_H
+#define _MODEL_H
+
+#include "abstract_model.h"
+
+#include "material.h"
+#include "glincl.h"
+#include "array.h"
+#include <list>
+
+// FORWARD DECLARATION //
+template<class T> class tArray;
+
+/////////////
+/// MODEL ///
+/////////////
+//! Class that handles 3D-Models. it can also read them in and display them.
+class Model : public AbstractModel
+{
+ public:
+  Model(const char* modelName = NULL, MODEL_TYPE type = MODEL_DISPLAY_LIST);
+  virtual ~Model();
+
+  void draw() const;
+
+  /** @returns a Pointer to the Vertex-Array, if it was deleted it returns NULL */
+  inline const GLfloat* getVertexArray() const { return this->vertices->getArray(); };
+  /** @returns the VertexCount of this Model */
+  inline unsigned int getVertexCount() const { return this->vertexCount; };
+
+  /** @returns a Pointer to the Normals-Array, if it was deleted it returns NULL */
+  inline const GLfloat* getNormalsArray() const { return this->normals->getArray(); };
+  /** @returns the NormalsCount of this Model */
+  inline unsigned int getNormalsCount() const { return this->normalCount; };
+
+  /** @returns a Pointer to the TexCoord-Array, if it was deleted it returns NULL */
+  inline const GLfloat* getTexCoordArray() const { return this->vTexture->getArray(); };
+  /** @returns the TexCoord-Count of this Model */
+  inline unsigned int getTexCoordCount() const { return this->texCoordCount; };
+
+  /** @returns the Count of Faces of this Model */
+  inline unsigned int getFaceCount() const { return this->faceCount; };
+
+
+  Material* addMaterial(Material* material);
+  Material* addMaterial(const char* materialName);
+
+
+  bool addVertex(float x, float y, float z);
+
+  bool addVertexNormal(float x, float y, float z);
+
+  bool addVertexTexture(float u, float v);
+
+  bool addFace(int faceElemCount, VERTEX_FORMAT type, ...);
+
+  bool addGroup(const char* groupString);
+
+  bool setMaterial(Material* mtl);
+
+  void finalize();
+
+
+ private:
+  bool buildTriangleList();
+
+  bool addGLElement(ModelFaceElement* elem);
+
+  bool importToVertexArray();
+
+  bool deleteArrays();
+  bool cleanup();
+
+ private:
+  bool                       finalized;       //!< Sets the Object to be finalized.
+
+  tArray<GLfloat>            vertices;        //!< The Array that handles the Vertices.
+  tArray<GLfloat>            normals;         //!< The Array that handles the Normals.
+  tArray<GLfloat>            textures;        //!< The Array that handles the VertexTextureCoordinates.
+
+  tArray<GLfloat>            indices;         //!< The Array that tells us what Vertex is connected to which other one.
+
+  std::list<ModelMaterial*>  materialList;    //!< A list for all the Materials in this Model
+};
+
+#endif
