Index: orxonox/trunk/configure
===================================================================
--- orxonox/trunk/configure	(revision 3364)
+++ orxonox/trunk/configure	(revision 3365)
@@ -1,5 +1,5 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for orxonox 2.0.1-pre-alpha.
+# Generated by GNU Autoconf 2.59 for orxonox 0.2.1-pre-alpha.
 #
 # Report bugs to <orxonox-dev at mail.datacore.ch>.
@@ -270,6 +270,6 @@
 PACKAGE_NAME='orxonox'
 PACKAGE_TARNAME='orxonox'
-PACKAGE_VERSION='2.0.1-pre-alpha'
-PACKAGE_STRING='orxonox 2.0.1-pre-alpha'
+PACKAGE_VERSION='0.2.1-pre-alpha'
+PACKAGE_STRING='orxonox 0.2.1-pre-alpha'
 PACKAGE_BUGREPORT='orxonox-dev at mail.datacore.ch'
 
@@ -789,5 +789,5 @@
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures orxonox 2.0.1-pre-alpha to adapt to many kinds of systems.
+\`configure' configures orxonox 0.2.1-pre-alpha to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -856,5 +856,5 @@
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of orxonox 2.0.1-pre-alpha:";;
+     short | recursive ) echo "Configuration of orxonox 0.2.1-pre-alpha:";;
    esac
   cat <<\_ACEOF
@@ -984,5 +984,5 @@
 if $ac_init_version; then
   cat <<\_ACEOF
-orxonox configure 2.0.1-pre-alpha
+orxonox configure 0.2.1-pre-alpha
 generated by GNU Autoconf 2.59
 
@@ -998,5 +998,5 @@
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by orxonox $as_me 2.0.1-pre-alpha, which was
+It was created by orxonox $as_me 0.2.1-pre-alpha, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
@@ -1719,5 +1719,5 @@
 # Define the identity of the package.
  PACKAGE='orxonox'
- VERSION='2.0.1-pre-alpha'
+ VERSION='0.2.1-pre-alpha'
 
 
@@ -7946,5 +7946,5 @@
 cat >&5 <<_CSEOF
 
-This file was extended by orxonox $as_me 2.0.1-pre-alpha, which was
+This file was extended by orxonox $as_me 0.2.1-pre-alpha, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
@@ -8009,5 +8009,5 @@
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-orxonox config.status 2.0.1-pre-alpha
+orxonox config.status 0.2.1-pre-alpha
 configured by $0, generated by GNU Autoconf 2.59,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
Index: orxonox/trunk/doc/orxodox.src
===================================================================
--- orxonox/trunk/doc/orxodox.src	(revision 3364)
+++ orxonox/trunk/doc/orxodox.src	(revision 3365)
@@ -7,5 +7,5 @@
 PROJECT_NAME           = Orxonox
 PROJECT_NUMBER         = 1
-OUTPUT_DIRECTORY       = doc/doxygen/
+OUTPUT_DIRECTORY       = doxygen/
 CREATE_SUBDIRS         = YES
 OUTPUT_LANGUAGE        = English
@@ -34,6 +34,6 @@
 #---------------------------------------------------------------------------
 EXTRACT_ALL            = NO
-EXTRACT_PRIVATE        = NO
-EXTRACT_STATIC         = NO
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
 EXTRACT_LOCAL_CLASSES  = YES
 EXTRACT_LOCAL_METHODS  = NO
@@ -69,7 +69,7 @@
 # configuration options related to the input files
 #---------------------------------------------------------------------------
-INPUT                  = src/
+INPUT                  = .
 FILE_PATTERNS          = 
-RECURSIVE              = YES
+RECURSIVE              = NO
 EXCLUDE                = 
 EXCLUDE_SYMLINKS       = NO
Index: orxonox/trunk/src/Makefile.am
===================================================================
--- orxonox/trunk/src/Makefile.am	(revision 3364)
+++ orxonox/trunk/src/Makefile.am	(revision 3365)
@@ -24,9 +24,18 @@
 		 story_entity.cc \
 		 environment.cc \
-		 importer/object.cc \
+		 importer/model.cc \
 		 importer/array.cc \
 		 importer/material.cc \
+		 importer/texture.cc \
 		 list.cc \
-		 p_node.cc
+		 p_node.cc \
+		 null_parent.cc \
+		 base_object.cc \
+		 helper_parent.cc \
+		 track_manager.cc \
+		 matrix.cc \
+		 curve.cc \
+		 glmenu_imagescreen.cc
+
 
 noinst_HEADERS = ability.h \
@@ -54,5 +63,4 @@
 		 shoot_laser.h \
 		 world_entity.h \
-		 coordinates.h \
 		 message_structures.h \
 		 shoot_rocket.h \
@@ -62,5 +70,13 @@
 		 game_loader.h \
 		 campaign.h \
-		 p_node.h
+		 p_node.h \
+		 null_parent.h \
+		 base_object.h \
+		 helper_parent.h \
+		 track_manager.h \
+		 matrix.h \
+		 curve.h \
+		 glmenu_imagescreen.h
+
 
 ## orxonox.conf will be used from home-dir instead.
Index: orxonox/trunk/src/Makefile.in
===================================================================
--- orxonox/trunk/src/Makefile.in	(revision 3364)
+++ orxonox/trunk/src/Makefile.in	(revision 3365)
@@ -59,6 +59,9 @@
 	track.$(OBJEXT) base_entity.$(OBJEXT) game_loader.$(OBJEXT) \
 	campaign.$(OBJEXT) story_entity.$(OBJEXT) \
-	environment.$(OBJEXT) object.$(OBJEXT) array.$(OBJEXT) \
-	material.$(OBJEXT) list.$(OBJEXT) p_node.$(OBJEXT)
+	environment.$(OBJEXT) model.$(OBJEXT) array.$(OBJEXT) \
+	material.$(OBJEXT) texture.$(OBJEXT) list.$(OBJEXT) \
+	p_node.$(OBJEXT) null_parent.$(OBJEXT) base_object.$(OBJEXT) \
+	helper_parent.$(OBJEXT) track_manager.$(OBJEXT) \
+	matrix.$(OBJEXT) curve.$(OBJEXT) glmenu_imagescreen.$(OBJEXT)
 orxonox_OBJECTS = $(am_orxonox_OBJECTS)
 orxonox_LDADD = $(LDADD)
@@ -67,15 +70,20 @@
 am__depfiles_maybe = depfiles
 @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/array.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/base_entity.Po ./$(DEPDIR)/camera.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/base_entity.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/base_object.Po ./$(DEPDIR)/camera.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/campaign.Po ./$(DEPDIR)/collision.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/command_node.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/command_node.Po ./$(DEPDIR)/curve.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/data_tank.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/environment.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/game_loader.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/glmenu_imagescreen.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/helper_parent.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/ini_parser.Po ./$(DEPDIR)/keynames.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/list.Po ./$(DEPDIR)/material.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/object.Po ./$(DEPDIR)/orxonox.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/matrix.Po ./$(DEPDIR)/model.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/null_parent.Po ./$(DEPDIR)/orxonox.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/p_node.Po ./$(DEPDIR)/player.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/story_entity.Po ./$(DEPDIR)/track.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/story_entity.Po ./$(DEPDIR)/texture.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/track.Po ./$(DEPDIR)/track_manager.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/vector.Po ./$(DEPDIR)/world.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/world_entity.Po
@@ -214,9 +222,17 @@
 		 story_entity.cc \
 		 environment.cc \
-		 importer/object.cc \
+		 importer/model.cc \
 		 importer/array.cc \
 		 importer/material.cc \
+		 importer/texture.cc \
 		 list.cc \
-		 p_node.cc
+		 p_node.cc \
+		 null_parent.cc \
+		 base_object.cc \
+		 helper_parent.cc \
+		 track_manager.cc \
+		 matrix.cc \
+		 curve.cc \
+		 glmenu_imagescreen.cc
 
 noinst_HEADERS = ability.h \
@@ -244,5 +260,4 @@
 		 shoot_laser.h \
 		 world_entity.h \
-		 coordinates.h \
 		 message_structures.h \
 		 shoot_rocket.h \
@@ -252,5 +267,12 @@
 		 game_loader.h \
 		 campaign.h \
-		 p_node.h
+		 p_node.h \
+		 null_parent.h \
+		 base_object.h \
+		 helper_parent.h \
+		 track_manager.h \
+		 matrix.h \
+		 curve.h \
+		 glmenu_imagescreen.h
 
 EXTRA_DIST = orxonox.conf
@@ -332,21 +354,29 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base_entity.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base_object.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camera.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/campaign.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command_node.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curve.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_tank.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/environment.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/game_loader.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glmenu_imagescreen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper_parent.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ini_parser.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keynames.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/material.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/model.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/null_parent.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orxonox.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p_node.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/player.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/story_entity.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texture.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/track.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/track_manager.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vector.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/world.Po@am__quote@
@@ -369,19 +399,19 @@
 @am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
-object.o: importer/object.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT object.o -MD -MP -MF "$(DEPDIR)/object.Tpo" -c -o object.o `test -f 'importer/object.cc' || echo '$(srcdir)/'`importer/object.cc; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/object.Tpo" "$(DEPDIR)/object.Po"; else rm -f "$(DEPDIR)/object.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='importer/object.cc' object='object.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/object.Po' tmpdepfile='$(DEPDIR)/object.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o object.o `test -f 'importer/object.cc' || echo '$(srcdir)/'`importer/object.cc
-
-object.obj: importer/object.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT object.obj -MD -MP -MF "$(DEPDIR)/object.Tpo" -c -o object.obj `if test -f 'importer/object.cc'; then $(CYGPATH_W) 'importer/object.cc'; else $(CYGPATH_W) '$(srcdir)/importer/object.cc'; fi`; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/object.Tpo" "$(DEPDIR)/object.Po"; else rm -f "$(DEPDIR)/object.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='importer/object.cc' object='object.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/object.Po' tmpdepfile='$(DEPDIR)/object.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o object.obj `if test -f 'importer/object.cc'; then $(CYGPATH_W) 'importer/object.cc'; else $(CYGPATH_W) '$(srcdir)/importer/object.cc'; fi`
+model.o: importer/model.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT model.o -MD -MP -MF "$(DEPDIR)/model.Tpo" -c -o model.o `test -f 'importer/model.cc' || echo '$(srcdir)/'`importer/model.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/model.Tpo" "$(DEPDIR)/model.Po"; else rm -f "$(DEPDIR)/model.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='importer/model.cc' object='model.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/model.Po' tmpdepfile='$(DEPDIR)/model.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o model.o `test -f 'importer/model.cc' || echo '$(srcdir)/'`importer/model.cc
+
+model.obj: importer/model.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT model.obj -MD -MP -MF "$(DEPDIR)/model.Tpo" -c -o model.obj `if test -f 'importer/model.cc'; then $(CYGPATH_W) 'importer/model.cc'; else $(CYGPATH_W) '$(srcdir)/importer/model.cc'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/model.Tpo" "$(DEPDIR)/model.Po"; else rm -f "$(DEPDIR)/model.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='importer/model.cc' object='model.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/model.Po' tmpdepfile='$(DEPDIR)/model.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o model.obj `if test -f 'importer/model.cc'; then $(CYGPATH_W) 'importer/model.cc'; else $(CYGPATH_W) '$(srcdir)/importer/model.cc'; fi`
 
 array.o: importer/array.cc
@@ -416,4 +446,20 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o material.obj `if test -f 'importer/material.cc'; then $(CYGPATH_W) 'importer/material.cc'; else $(CYGPATH_W) '$(srcdir)/importer/material.cc'; fi`
+
+texture.o: importer/texture.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT texture.o -MD -MP -MF "$(DEPDIR)/texture.Tpo" -c -o texture.o `test -f 'importer/texture.cc' || echo '$(srcdir)/'`importer/texture.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/texture.Tpo" "$(DEPDIR)/texture.Po"; else rm -f "$(DEPDIR)/texture.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='importer/texture.cc' object='texture.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/texture.Po' tmpdepfile='$(DEPDIR)/texture.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o texture.o `test -f 'importer/texture.cc' || echo '$(srcdir)/'`importer/texture.cc
+
+texture.obj: importer/texture.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT texture.obj -MD -MP -MF "$(DEPDIR)/texture.Tpo" -c -o texture.obj `if test -f 'importer/texture.cc'; then $(CYGPATH_W) 'importer/texture.cc'; else $(CYGPATH_W) '$(srcdir)/importer/texture.cc'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/texture.Tpo" "$(DEPDIR)/texture.Po"; else rm -f "$(DEPDIR)/texture.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='importer/texture.cc' object='texture.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/texture.Po' tmpdepfile='$(DEPDIR)/texture.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o texture.obj `if test -f 'importer/texture.cc'; then $(CYGPATH_W) 'importer/texture.cc'; else $(CYGPATH_W) '$(srcdir)/importer/texture.cc'; fi`
 uninstall-info-am:
 
Index: orxonox/trunk/src/base_object.cc
===================================================================
--- orxonox/trunk/src/base_object.cc	(revision 3365)
+++ orxonox/trunk/src/base_object.cc	(revision 3365)
@@ -0,0 +1,48 @@
+
+
+/* 
+   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: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "base_object.h"
+
+
+using namespace std;
+
+
+/**
+   \brief standard constructor
+*/
+BaseObject::BaseObject () {}
+
+
+/**
+   \brief standard deconstructor
+*/
+BaseObject::~BaseObject () {}
+
+
+void BaseObject::setClassName (char* className)
+{
+  this->className = className;
+}
+
+
+bool BaseObject::isA (char* className)
+{
+  if( this->className == className)
+    return false;
+  return true;
+}
Index: orxonox/trunk/src/base_object.h
===================================================================
--- orxonox/trunk/src/base_object.h	(revision 3365)
+++ orxonox/trunk/src/base_object.h	(revision 3365)
@@ -0,0 +1,27 @@
+/*! 
+    \file proto_class.h
+    \brief Definition of the proto class template, used quickly start work
+*/
+
+
+#ifndef _BASE_OBJECT_H
+#define _BASE_OBJECT_H
+
+#include "stdincl.h"
+
+
+class BaseObject {
+
+ public:
+  BaseObject ();
+  ~BaseObject ();
+
+  void setClassName (char* className);
+  bool isA (char* className);
+
+ private:
+  char* className;
+
+};
+
+#endif /* _BASE_OBJECT_H */
Index: orxonox/trunk/src/camera.cc
===================================================================
--- orxonox/trunk/src/camera.cc	(revision 3364)
+++ orxonox/trunk/src/camera.cc	(revision 3365)
@@ -42,7 +42,6 @@
   this->t = 0.0;
 
-  this->actualPlace.r.x = 0.0;
-  this->actualPlace.r.y = 10.0;
-  this->actualPlace.r.z = -5.0;
+
+  this->setDrawable (false);
 }
 
@@ -67,5 +66,5 @@
   //printf("time is: t=%f\n", t );
   updateDesiredPlace();
-  jump(NULL);
+  //jump(NULL);
 }
 
@@ -83,4 +82,5 @@
     case ELLIPTICAL:
       {
+	/*
 	//r = actual_place.r 
 	Orxonox *orx = Orxonox::getInstance();
@@ -95,5 +95,4 @@
 	      {
 		Vector *start = new Vector(0.0, 1.0, 0.0);
-		//r = /*actual_place.r*/ *start - plFocus.r;
 		r = *(new Vector(0.0, 5.0, 0.0));
 
@@ -120,37 +119,24 @@
 	    //printf("vector r = %f, %f, %f\n",r.x, r.y, r.z );
 	    rAbs = r.len();
-	    if(t < 30.0) /* FIXME!!*/
+	    if(t < 30)
 	      {
 		ka = rAbs / deltaTime*deltaTime;
 	      }
-	    /* this is the new length of the vector */
-	    //float len = ka * powf((deltaTime - t), 2);
-	    
-	    /* calc the rotation */
-	    /*
-	    Vector axis(0.0, 0.0, 1.0);
-	    if(t < 30.0)
-	      a0 = PI/4 - atanf(fabs(r.x) / fabs(r.y));
-	    printf("a0 = %f\n", a0);
-	    float angle = a0/deltaTime * (deltaTime - t);
-	    printf("angle is: %f\n", angle);
-	    Quaternion q(angle, axis);
-	    */
-	    //r = q.apply(r);
-	    //r = r * (len/r.len());
-	    
-	    //res->quatSlerp(from, to, t/deltaTime, res);
+
 	    res->quatSlerp(to, from, t/deltaTime, res);
 
 	    Vector ursp(0.0, 0.0, 0.0);
-	    desiredPlace.r = /*plFocus.r -*/ ursp - res->apply(r); 
+	    desiredPlace.r =  ursp - res->apply(r); 
 
 	    printf("desired place is: %f, %f, %f\n", desiredPlace.r.x, desiredPlace.r.y, desiredPlace.r.z);
 	    //plLastBPlace = *bound->get_placement();
+	    
 	  } 
+      */
       }
       break;
     case SMOTH_FOLLOW:
       {
+	/*
 	Placement *plBound = bound->getPlacement();
 	Location lcBound;
@@ -160,6 +146,7 @@
 	    Vector vDirection(0.0, 0.0, 1.0);
 	    vDirection = plBound->w.apply(vDirection);
-	    desiredPlace.r = (vDirection * ((lcBound.dist-10.0)/* / l*/)) + Vector(0,0,5.0);
+	    desiredPlace.r = (vDirection * ((lcBound.dist-10.0))) + Vector(0,0,5.0);
 	  }
+	*/
 	break;
       }
@@ -167,4 +154,5 @@
     case STICKY:
       {
+	/*
 	if(bound != null)
 	  {
@@ -175,18 +163,21 @@
 	    desiredPlace.r = plBound->r - vDirection*10 + eclipticOffset;
 	  }
+	*/
 	break;
       }
       /* the camera is handled like an entity and rolls on the track */
     case NORMAL:
-      Location lookat;  
       if( bound != NULL && world != NULL )
 	{
-	  bound->getLookat (&lookat);
-	  world->calcCameraPos (&lookat, &desiredPlace);
+	  //FIXME: camera should be made via relative coordinates
+	  Vector* cameraOffset = new Vector (-10, 5, 0);
+	  this->setRelCoor (cameraOffset);
 	} 
       else
 	{
+	  /*
 	  desiredPlace.r = Vector (0,0,0);
 	  desiredPlace.w = Quaternion (); 
+	  */
 	}
       break;
@@ -237,17 +228,18 @@
   // rotation
   float matrix[4][4];
-  actualPlace.w.conjugate().matrix (matrix);
+  //this->absDirection.conjugate().matrix (matrix);
   /* orientation and */
-  glMultMatrixf ((float*)matrix);
+  //glMultMatrixf ((float*)matrix);
+
   /*  translation */
-  glTranslatef (-actualPlace.r.x, -actualPlace.r.y,- actualPlace.r.z);
-//Placement *plBound = bound->get_placement();
+  //glTranslatef (this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z );
+
 
   // ===== second camera control calculation option
-  /*
-   gluLookAt(actual_place.r.x, actual_place.r.y, actual_place.r.z, 
-              plBound->r.x, plBound->r.y, plBound->r.z,
-              0.0, 0.0, 1.0);
-  */
+  
+  gluLookAt(this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z, 
+	    this->parent->getAbsCoor ().x, this->parent->getAbsCoor ().y, this->parent->getAbsCoor ().z,
+	    0.0, 1.0, 0.0);
+  
 
   glMatrixMode (GL_MODELVIEW);
@@ -255,23 +247,5 @@
 }
 
-/**
-  \brief set the camera position
-  \param plc: The Placement to set the camera to 
-	
-	This will set the actual and desired placement of the camera to plc
-*/
-void Camera::jump (Placement* plc = NULL)
-{
-  if( plc == NULL)
-    {
-      actualPlace = desiredPlace;
-      //printf("Camera|jump: camer@ %f, %f, %f\n\n", actual_place.r.x, actual_place.r.y, actual_place.r.z);
-    }
-  else
-    {
-      desiredPlace = *plc;
-      actualPlace = *plc;
-    }
-}
+
 
 /**
Index: orxonox/trunk/src/camera.h
===================================================================
--- orxonox/trunk/src/camera.h	(revision 3364)
+++ orxonox/trunk/src/camera.h	(revision 3365)
@@ -8,6 +8,7 @@
 
 #include "stdincl.h"
+#include "world_entity.h"
 
-class WorldEntity;
+
 class World;
 
@@ -23,9 +24,7 @@
 enum CAMERA_MODE {NORMAL, SMOTH_FOLLOW, STICKY, ELLIPTICAL};
 
-class Camera {
+class Camera : public WorldEntity {
  private:
   WorldEntity* bound;		//!< the WorldEntity the Camera is bound to
-  Placement actualPlace;	        //!< the Camera's current position
-  Placement desiredPlace;        //!< where the Camera should be according to calculations
   World* world;
   
@@ -37,5 +36,4 @@
   
   /* elliptical camera mode variables */
-  Placement plLastBPlace;
   float cameraOffset;
   float cameraOffsetZ;
@@ -63,5 +61,4 @@
   void apply ();
   void bind (WorldEntity* entity);
-  void jump (Placement* plc);
   void destroy();
 
Index: orxonox/trunk/src/curve.cc
===================================================================
--- orxonox/trunk/src/curve.cc	(revision 3364)
+++ orxonox/trunk/src/curve.cc	(revision 3365)
@@ -11,9 +11,11 @@
    ### File Specific:
    main-programmer: Benjamin Grauer
-   co-programmer: ...
+   co-programmer: Patrick Boenzli
+
+   ADD: Patrick Boenzli           B-Spline 
+
 
    TODO: 
      local-Time implementation
-     closed Bezier Curve
      NURBS
      
@@ -21,6 +23,9 @@
 
 #include "curve.h"
-
-
+#include "matrix.h"
+#include "debug.h"
+
+#include <math.h>
+#include <stdio.h>
 
 /**
@@ -37,7 +42,26 @@
   currentNode->next = 0; // not sure if this really points to NULL!!
   currentNode->number = (++nodeCount);
+  this->rebuild();
   return;
 }
 
+/**
+   \brief Finds a Node by its Number, and returns its Position
+   \param nodeToFind the n'th node in the List of nodes
+   \returns A Vector to the Position of the Node.
+*/
+Vector Curve::getNode(unsigned int nodeToFind)
+{
+  if (nodeToFind > this->nodeCount)
+    return Vector(0,0,0);
+  PathNode* tmpNode = this->firstNode;
+  for (int i = 1; i < nodeToFind; i++)
+    tmpNode = tmpNode->next;
+  return tmpNode->position;
+}
+
+///////////////////////////////////
+/// Bezier Curve //////////////////
+///////////////////////////////////
 
 /**
@@ -45,4 +69,43 @@
 */
 BezierCurve::BezierCurve (void)
+{
+  this->derivation = 0;
+  dirCurve = new BezierCurve(1);
+  this->init();
+}
+
+/**
+   \brief Creates a new BezierCurve-Derivation-Curve
+*/
+BezierCurve::BezierCurve (int derivation)
+{
+  this->derivation = derivation;
+  dirCurve=NULL;
+  this->init();
+}
+
+/**
+   \brief Deletes a BezierCurve.
+
+   It does this by freeing all the space taken over from the nodes
+*/
+BezierCurve::~BezierCurve(void)
+{
+  PathNode* tmpNode;
+  currentNode = firstNode;
+  while (tmpNode != 0)
+    {
+      tmpNode = currentNode;
+      currentNode = currentNode->next;
+      delete tmpNode;
+    }
+  if (dirCurve)
+    delete dirCurve;
+}
+
+/**
+   \brief Initializes a BezierCurve
+*/
+void BezierCurve::init(void)
 {
   nodeCount = 0;
@@ -58,9 +121,135 @@
 
 /**
-   \brief Deletes a BezierCurve.
+   \brief Rebuilds a Curve
+*/
+void BezierCurve::rebuild(void)
+{
+  PathNode* tmpNode = firstNode;
+
+  // rebuilding the Curve itself
+  float k=0;
+  float n = nodeCount -1;
+  float binCoef = 1;
+  while(tmpNode)
+    {
+      tmpNode->factor = binCoef;
+      if (tmpNode =tmpNode->next)
+	{
+	  binCoef *=(n-k)/(k+1);
+	  ++k;
+	}
+    }
+
+  // rebuilding the Derivation curve
+  if(this->derivation == 0)
+    {
+      tmpNode = firstNode;
+      delete dirCurve;
+      dirCurve = new BezierCurve(1);
+      while(tmpNode->next)
+	{
+	  Vector tmpVector = (tmpNode->next->position)- (tmpNode->position);
+	  tmpVector.x*=(float)nodeCount;
+	  tmpVector.y*=(float)nodeCount;
+	  tmpVector.z*=(float)nodeCount;
+	  tmpVector.normalize();
+	  this->dirCurve->addNode(tmpVector);
+	  tmpNode = tmpNode->next;
+	}
+    }
+}
+
+/**
+   \brief calculates the Position on the curve
+   \param t The position on the Curve (0<=t<=1)
+   \return the Position on the Path
+*/
+Vector BezierCurve::calcPos(float t) 
+{
+  Vector ret = Vector(0.0,0.0,0.0);
+  if (this->nodeCount >= 3)
+    {
+      PathNode* tmpNode = this->firstNode;
+      double factor = pow(1.0-t,nodeCount-1);
+      while(tmpNode)
+	{
+	  ret.x += tmpNode->factor * factor * tmpNode->position.x;
+	  ret.y += tmpNode->factor * factor * tmpNode->position.y;
+	  ret.z += tmpNode->factor * factor * tmpNode->position.z;
+	  factor *= t/(1.0-t); // same as pow but much faster.
+	  
+	  tmpNode = tmpNode->next;
+	}
+    }
+  else if (nodeCount == 2)
+    {
+      ret = this->firstNode->position *(1.0-t);
+      ret = ret + this->firstNode->next->position * t;
+    }
+  else if (nodeCount == 1)
+    ret = this->firstNode->position;
+  return ret;
+}
+
+/**
+   \brief Calulates the direction of the Curve at time t.
+   \param The time at which to evaluate the curve.
+   \returns The vvaluated Vector.
+*/
+Vector BezierCurve::calcDir (float t)
+{
+  return dirCurve->calcPos(t);
+}
+
+/**
+   \brief Calculates the Quaternion needed for our rotations
+   \param t The time at which to evaluate the cuve.
+   \returns The evaluated Quaternion.
+*/
+Quaternion BezierCurve::calcQuat (float t)
+{
+  return Quaternion (calcDir(t), Vector(0,0,1));
+}
+
+
+/**
+  \brief returns the Position of the point calculated on the Curve
+  \return a Vector to the calculated position
+*/
+Vector BezierCurve::getPos(void) const
+{
+  return curvePoint;
+}
+
+
+
+///////////////////////////////////
+//// Uniform Point curve  /////////
+///////////////////////////////////
+/**
+   \brief Creates a new UPointCurve
+*/
+UPointCurve::UPointCurve (void)
+{
+  this->derivation = 0;
+  this->init();
+}
+
+/**
+   \brief Creates a new UPointCurve-Derivation-Curve of deriavation'th degree
+*/
+UPointCurve::UPointCurve (int derivation)
+{
+  this->derivation = derivation;
+  dirCurve=NULL;
+  this->init();
+}
+
+/**
+   \brief Deletes a UPointCurve.
 
    It does this by freeing all the space taken over from the nodes
 */
-BezierCurve::~BezierCurve (void)
+UPointCurve::~UPointCurve(void)
 {
   PathNode* tmpNode;
@@ -72,4 +261,69 @@
       delete tmpNode;
     }
+  if (dirCurve)
+    delete dirCurve;
+}
+
+/**
+   \brief Initializes a UPointCurve
+*/
+void UPointCurve::init(void)
+{
+  nodeCount = 0;
+  firstNode = new PathNode;
+  currentNode = firstNode;
+
+  firstNode->position = Vector (.0, .0, .0);
+  firstNode->number = 0;
+  firstNode->next = 0; // not sure if this really points to NULL!!
+
+  return;
+}
+
+/**
+   \brief Rebuilds a UPointCurve
+   
+   \todo very bad algorithm
+*/
+void UPointCurve::rebuild(void)
+{
+  // rebuilding the Curve itself
+  PathNode* tmpNode = this->firstNode;
+  int i=0;
+  Matrix xTmpMat = Matrix(this->nodeCount, this->nodeCount);
+  Matrix yTmpMat = Matrix(this->nodeCount, this->nodeCount);
+  Matrix zTmpMat = Matrix(this->nodeCount, this->nodeCount);
+  Matrix xValMat = Matrix(this->nodeCount, 3);
+  Matrix yValMat = Matrix(this->nodeCount, 3);
+  Matrix zValMat = Matrix(this->nodeCount, 3);
+  while(tmpNode)
+    {
+      Vector fac = Vector(1,1,1);
+      for (int j = 0; j < this->nodeCount; j++)
+	{
+	  xTmpMat(i,j) = fac.x; fac.x *= (float)i/(float)this->nodeCount;//tmpNode->position.x;
+	  yTmpMat(i,j) = fac.y; fac.y *= (float)i/(float)this->nodeCount;//tmpNode->position.y;
+	  zTmpMat(i,j) = fac.z; fac.z *= (float)i/(float)this->nodeCount;//tmpNode->position.z;
+	}
+      xValMat(i,0) = tmpNode->position.x;
+      yValMat(i,0) = tmpNode->position.y;
+      zValMat(i,0) = tmpNode->position.z;
+      ++i;
+      tmpNode = tmpNode->next;
+    }
+  tmpNode = this->firstNode;
+  xValMat = xTmpMat.Inv() *= xValMat;
+  yValMat = yTmpMat.Inv() *= yValMat;
+  zValMat = zTmpMat.Inv() *= zValMat;
+  i = 0;
+  while(tmpNode)
+    {
+      tmpNode->vFactor.x = xValMat(i,0);
+      tmpNode->vFactor.y = yValMat(i,0);
+      tmpNode->vFactor.z = zValMat(i,0);
+
+      i++;
+      tmpNode = tmpNode->next;
+    }
 }
 
@@ -79,32 +333,17 @@
    \return the Position on the Path
 */
-Vector BezierCurve::calcPos(float t) 
-{
-  if (nodeCount <=4)
-    {
-      //      if (verbose >= 1)
-      //      printf ("Please define at least 4 nodes, until now you have only defined %i.\n", nodeCount);
-      return Vector(0,0,0);
-    }
+Vector UPointCurve::calcPos(float t) 
+{
   PathNode* tmpNode = firstNode;
-    
   Vector ret = Vector(0.0,0.0,0.0);
-  double factor;
-  int k=0;
-  while(tmpNode!=0)
-    {
-      k++;
-      factor = ncr (nodeCount, k);
-      
-      for (int j=0; j<nodeCount-k; j++)
-	factor*=(1-t);
-      for (int j=0; j<k; j++)
-	factor*=t;
-      ret.x += factor * tmpNode->position.x;
-      ret.y += factor * tmpNode->position.y;
-      ret.z += factor * tmpNode->position.z;
-      
+  float factor = 1.0;
+  while(tmpNode)
+    {
+      ret.x += tmpNode->vFactor.x * factor;
+      ret.y += tmpNode->vFactor.y * factor;
+      ret.z += tmpNode->vFactor.z * factor;
+      factor *= t;
+
       tmpNode = tmpNode->next;
-
     }
   return ret;
@@ -116,24 +355,20 @@
    \returns The vvaluated Vector.
 */
-Vector BezierCurve::calcDir (float t)
+Vector UPointCurve::calcDir (float t)
 {
   PathNode* tmpNode = firstNode;
-  BezierCurve* tmpCurve = new BezierCurve();
-  Vector ret;
-  Vector tmpVector;
-
-  while (tmpNode->next != 0)
-    {
-      tmpVector = (tmpNode->next->position)- (tmpNode->position);
-      tmpVector.x*=(float)nodeCount;
-      tmpVector.y*=(float)nodeCount;
-      tmpVector.z*=(float)nodeCount;
-
-      tmpCurve->addNode(tmpVector);
+  Vector ret = Vector(0.0,0.0,0.0);
+  float factor = 1.0/t;
+  int k=0;
+  while(tmpNode)
+    {
+      ret.x += tmpNode->vFactor.x * factor *k;
+      ret.y += tmpNode->vFactor.y * factor *k;
+      ret.z += tmpNode->vFactor.z * factor *k;
+      factor *= t;
+      k++;
       tmpNode = tmpNode->next;
     }
-  ret = tmpCurve->calcPos(t);
   ret.normalize();
-
   return ret;
 }
@@ -144,5 +379,5 @@
    \returns The evaluated Quaternion.
 */
-Quaternion BezierCurve::calcQuat (float t)
+Quaternion UPointCurve::calcQuat (float t)
 {
   return Quaternion (calcDir(t), Vector(0,0,1));
@@ -154,24 +389,6 @@
   \return a Vector to the calculated position
 */
-Vector BezierCurve::getPos() const
+Vector UPointCurve::getPos(void) const
 {
   return curvePoint;
 }
-
-/**
-   \brief ncr-calculator, did not find an other method
-   \todo a c++ variante to do this
-*/
-int ncr(int n, int i)
-{
-  int ret = 1;
-  for (int k=1; k<=n; k++)
-    ret*=k;
-  for (int k=1; k<=i; k++)
-    ret/=k;
-  for (int k=1; k<=n-i; k++)
-    ret/=k;
-
-  return ret;
-}
-
Index: orxonox/trunk/src/curve.h
===================================================================
--- orxonox/trunk/src/curve.h	(revision 3364)
+++ orxonox/trunk/src/curve.h	(revision 3365)
@@ -1,2 +1,3 @@
+
 /*! 
     \file curve.h
@@ -11,6 +12,9 @@
 #include "vector.h"
 
+//! An Enumerator that defines what sort of Curves are availible
+enum CurveType {BEZIERCURVE, UPOINTCURVE};
 
-//! An abstract class to handle curves.
+
+//! An abstract class to handle curves. Needed for the Tracking system in orxonox.
 class Curve
 {
@@ -19,4 +23,6 @@
   Vector curvePoint;     //!< The point on the Cureve at a local Time.
   float localTime;       //!< If the time of one point is asked more than once the programm will not calculate it again.
+  Curve* dirCurve;       //!< The derivation-curve of this Curve.
+  int derivation;        //!< Which derivation of a Curve is this.
 
   //! Handles the curve-points (dynamic List)
@@ -24,4 +30,6 @@
   {
     int number;          //!< The N-th node of this curve.
+    float factor;        //!< Curve specific multiplier factor.
+    Vector vFactor;      //!< A Vector-factor for multipliing.
     Vector position;     //!< Vector Pointung to this curve-point.
     PathNode* next;      //!< Pointer to the next Node.
@@ -31,32 +39,74 @@
   PathNode* currentNode; //!< The node we are working with (the Last node).
 
+ private:
+  virtual void rebuild(void) = 0;
  public:
-  void addNode (const Vector& newNode);
+  void addNode(const Vector& newNode);
+  Vector getNode(unsigned int nodeToFind);
+  inline int getNodeCount(void) { return this->nodeCount;}
 
+  virtual Vector calcPos(float t) = 0;
+  virtual Vector calcDir(float t) = 0;
+  virtual Quaternion calcQuat(float t) = 0;
+ 
 };
 
-//! Bezier Curve
+//!    Class to handle bezier curves in 3-dimesnsional space
 /**
-   Class to handle bezier curves in 3-dimesnsional space
-   
-   needed for  the Tracking system in OrxOnoX.
+   This Curve is good, for Fast Interaction. If you want to change it during the game, go on.
+   !!be aware!! BezierCurves only flow through their first and last Node. Their Tangents at those Points a directed to the second and second-last Point.
 */
 class BezierCurve : public Curve
 {
  private:
-  // all from Curve-Class
+  void rebuild(void);
  public:
-  BezierCurve (void);
-  ~BezierCurve (void);
-  Vector calcPos (float t);
-  Vector calcDir (float t);
-  Quaternion calcQuat (float t);
+  BezierCurve(void);
+  BezierCurve(int derivation);
+  ~BezierCurve(void);
+  void init(void);
+
+  Vector calcPos(float t);
+  Vector calcDir(float t);
+  Quaternion calcQuat(float t);
   
   
-  Vector getPos () const;
+  Vector getPos(void) const;
 };
 
-int ncr(int n, int i);
+
+//! B-Spline
+/**
+   class to handle b-spline in 3d space
+*/
+class BSplieCurve : public Curve
+{
 
 
+};
+
+//! Uniform Point Curve-class
+/**
+   A UPoint Curve is a A Curve, that flows through all the nodes given it.
+   The Algorithm to buid the curve is rather slow, but Painting and tracing along the curve has high speed, so do not change this curve during the Game.
+
+   This Curve is very erattic, so i do not recommend to use it.
+*/
+class UPointCurve : public Curve
+{
+ private:
+  void rebuild(void);
+ public:
+  UPointCurve(void);
+  UPointCurve(int derivation);
+  ~UPointCurve(void);
+  void init(void);
+
+  Vector calcPos(float t);
+  Vector calcDir(float t);
+  Quaternion calcQuat(float t);
+  
+  Vector getPos(void) const;
+};
+
 #endif /* _CURVE_H */
Index: orxonox/trunk/src/data_tank.cc
===================================================================
--- orxonox/trunk/src/data_tank.cc	(revision 3364)
+++ orxonox/trunk/src/data_tank.cc	(revision 3365)
@@ -19,4 +19,6 @@
 using namespace std;
 
+long DataTank::timeStamp = 0;
+
 DataTank::DataTank () {}
 DataTank::~DataTank () {}
Index: orxonox/trunk/src/data_tank.h
===================================================================
--- orxonox/trunk/src/data_tank.h	(revision 3364)
+++ orxonox/trunk/src/data_tank.h	(revision 3365)
@@ -10,4 +10,6 @@
   ~DataTank ();
 
+  static long timeStamp;
+
 };
 
Index: orxonox/trunk/src/debug.h
===================================================================
--- orxonox/trunk/src/debug.h	(revision 3364)
+++ orxonox/trunk/src/debug.h	(revision 3365)
@@ -8,4 +8,5 @@
 
 #ifdef  DEBUG
+extern int verbose;
 #define PRINTF(x) \
            PRINTF ## x
Index: orxonox/trunk/src/environment.cc
===================================================================
--- orxonox/trunk/src/environment.cc	(revision 3364)
+++ orxonox/trunk/src/environment.cc	(revision 3365)
@@ -21,39 +21,21 @@
 #include "world_entity.h"
 #include "vector.h"
+#include "importer/model.h"
 
 using namespace std;
 
 
-//Sorry Bensch
-#define LEVEL_LENGTH 500
 
 Environment::Environment () : WorldEntity()
 {
-
-  /*
-  //Sorry Bensch: x,y = 10
-  for (int x = 0; x < 50; x++)
-    {
-      for (int y = 0; y < 50; y++)
-	{
-	  mountainTest[x][y] =0;
-	                                         
-	}
-    }
-  //Sorry Bensch: x,y = 9
-  for (int x = 1; x < LEVEL_LENGTH; x++)
-    {
-      for (int y = 1; y < LEVEL_LENGTH; y++)
-	{
-	  //mountainTest[x][y] = (float)random() / 900000000;
-	  mountainTest[x][y] = (float)(random() % 4);                                       
-	}
-    }
-  */
+  this->model = new Model("reaplow.obj");
 }
 
 
 
-Environment::~Environment () {}
+Environment::~Environment () 
+{
+  delete this->model;
+}
 
 void Environment::tick (float time) {}
@@ -71,70 +53,11 @@
   float matrix[4][4];
   
-  glTranslatef(getPlacement()->r.x,getPlacement()->r.y,getPlacement()->r.z);
-  getPlacement()->w.matrix (matrix);
-  glMultMatrixf ((float*)matrix);
-
-  glBegin(GL_TRIANGLES);
-  glColor3f(1,0,1);
-  glVertex3f(0,0,0.5);
-  glVertex3f(-0.5,0,-1);
-  glVertex3f(0.5,0,-1);
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  //rotate
+  this->getAbsDir ().matrix (matrix);
+  glMultMatrixf((float*)matrix);
   
-  glVertex3f(0,0,0.5);
-  glVertex3f(0,0.5,-1);
-  glVertex3f(0,-0.5,-1);
-  glEnd();
-    
-  glBegin(GL_QUADS);
-  glColor3f(1,0,1);
-  glVertex3f(0.5,0.5,-1);
-  glVertex3f(0.5,-0.5,-1);
-  glVertex3f(-0.5,-0.5,-1);
-  glVertex3f(-0.5,0.5,-1);
-  glEnd();
+  glMatrixMode(GL_MODELVIEW);
+  this->model->draw();
 }
 
-/*
-void Environment::paint()
-{
-  
-  glPushMatrix();
-  //glScalef(0.5, 0.5, 1.0);
-  //glTranslatef(xCor, yCor, zCor);
-  glTranslatef( -16.0, -2.0, 0.0);
-  
-  glColor3f(0.0, 1.0, 0.0);
-  
-  glBegin(GL_LINES);
-  for (int x = 0; x < LEVEL_LENGTH; x += 1)
-    {
-      for (int y = 0; y < 190; y += 1)
-	{
-	  glVertex3f((float)(2*x), (float)(2*y), mountainTest[x][y]);
-	  glVertex3f((float)(2*x), (float)(2*(y+1)), mountainTest[x][y+1]);
-	}
-    }
-  glEnd();
-  
-  
-  glBegin(GL_LINES);
-  for (int y = 0; y < LEVEL_LENGTH; y += 1)
-    {
-      for (int x = 0; x < 90; x += 1)
-	{
-	  glVertex3f((float)(2*x), (float)(2*y), mountainTest[x][y]);
-	  glVertex3f((float)(2*(x+1)), (float)(2*y), mountainTest[x+1][y]);
-	}
-    }
-  glEnd();
-  
-  glPopMatrix();
-  
-}
-
-void Environment::drawEnvironment() 
-{
-
-}
-
-*/
Index: orxonox/trunk/src/glmenu_imagescreen.cc
===================================================================
--- orxonox/trunk/src/glmenu_imagescreen.cc	(revision 3365)
+++ orxonox/trunk/src/glmenu_imagescreen.cc	(revision 3365)
@@ -0,0 +1,258 @@
+
+
+/* 
+   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: Patrick Boenzli
+   co-programmer: 
+*/
+
+
+#include "glmenu_imagescreen.h"
+#include "importer/texture.h"
+
+using namespace std;
+
+
+/**
+   \brief standard constructor
+
+   \todo this constructor is not jet implemented - do it
+*/
+GLMenuImageScreen::GLMenuImageScreen () 
+{
+   this->setClassName ("GLMenuImageScreen");
+}
+
+
+/**
+   \brief standard deconstructor
+
+   \todo this deconstructor is not jet implemented - do it
+*/
+GLMenuImageScreen::~GLMenuImageScreen () {}
+
+
+/**
+   \brief function to init the screen
+*/
+void GLMenuImageScreen::init ()
+{
+  /*
+  int w = 680;
+  int h = 480;
+
+  glViewport(0,0,w,h);
+  
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity(); 
+  gluPerspective(45.0f,(GLfloat)w/(GLfloat)h, .5f ,150.0f);
+  glMatrixMode(GL_MODELVIEW); 
+
+  this->backTex = new Texture();
+  this->backTex->loadImage("orx_tex.bmp");
+
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  glLoadIdentity();
+  gluLookAt(0, 0, 6,     0, 0, 0,     0, 1, 0);
+
+  // Bind the texture stored at the zero index of g_Texture[]
+  //glBindTexture(GL_TEXTURE_2D, g_Texture[0]);
+  */
+
+  
+  // Select Our VU Meter Background Texture
+  this->backTex = new Texture();
+  this->backTex->loadImage("load_screen.jpg");
+
+  // End of Background image code.
+}
+
+
+/**
+   \brief function to innit screen with all attributes set
+   \param name of the background-image file
+   \param height of the ImageScreen
+   \param width of the Image Screen
+   \param x offset from (0, 0)
+   \param y offset from (0, 0)
+
+   GLMenu uses its own coordinating system: upper left corner is (0, 0). x-axis is down=height, 
+   right axis is right direction (=width)
+*/
+void GLMenuImageScreen::init (char* backImageName, float height, float width, 
+			      float offsetX, float offsetY)
+{}
+
+
+/**
+   \brief draws the ImageScreen to the screenbuffer
+*/
+void GLMenuImageScreen::draw ()
+{
+  /*
+  // Display a quad texture to the screen
+  glEnable(GL_TEXTURE_2D);
+  glBegin(GL_QUADS);
+  
+  // Display the top left vertice
+  glTexCoord2f(0.0f, 1.0f);
+  glVertex3f(-2.5, 2.5, 0);
+  
+  // Display the bottom left vertice
+  glTexCoord2f(0.0f, 0.0f);
+  glVertex3f(-2.5, -2.5, 0);
+  
+  // Display the bottom right vertice
+  glTexCoord2f(1.0f, 0.0f);
+  glVertex3f(2.5, -2.5, 0);
+  
+  // Display the top right vertice
+  glTexCoord2f(1.0f, 1.0f);
+  glVertex3f(2.5, 2.5, 0);
+
+  glEnd();
+  glEnable(GL_TEXTURE_2D);  
+  */
+
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+  // Screen Size.
+  int screenWidth = 640;
+  int screenHeight = 480;
+  
+  // Set Image Size.
+  int imageWidth = 640;
+  int imageHeight = 480;
+  
+  // Start pos of image.
+  int offsetX = (screenWidth - imageWidth)/2;
+  int offsetY = (screenHeight - imageHeight)/2;
+  
+  glEnable(GL_BLEND);
+  glEnable(GL_TEXTURE_2D);
+
+  glPushAttrib(GL_LIGHTING_BIT | GL_TRANSFORM_BIT);
+  
+  glDisable(GL_LIGHTING);
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity();
+  /* set up an ortho screen */
+  glOrtho(0, screenWidth, 0, screenHeight, -1, 1); 
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  glPushMatrix();
+  glEnable(GL_BLEND);
+
+  glBegin(GL_QUADS);
+  glTexCoord2i(0, 0); glVertex2i(offsetX, offsetY);
+  glTexCoord2i(1, 0 ); glVertex2i(offsetX + imageWidth, offsetY);
+  glTexCoord2i( 1, 1 ); glVertex2i(offsetX + imageWidth, offsetY + imageHeight);
+  glTexCoord2i( 0, 1 ); glVertex2i(offsetX, offsetY + imageHeight);
+  glEnd();
+
+  glDisable(GL_TEXTURE_2D);
+
+  glBegin(GL_QUADS);
+  glColor3f(1.0, 0.0, 0.0);
+  glVertex2i(100, 100);
+  glVertex2i(200, 100);
+  glVertex2i(200, 150);
+  glVertex2i(100, 150);
+  glEnd();
+
+
+  glDisable(GL_BLEND);
+  glPopMatrix();
+  glMatrixMode(GL_PROJECTION);
+  glPopMatrix();
+  glPopAttrib();
+
+  SDL_GL_SwapBuffers();                    
+  SDL_Delay(1000);
+}
+ 
+
+/** 
+    \brief sets the background image name
+    \param file name of the backgroun-image
+ */
+void GLMenuImageScreen::setBackImageName (char* backImageName)
+{}
+
+
+/**
+   \brief sets position of the ImageScreen
+   \param x offset from (0, 0)
+   \param y offset from (0, 0)
+*/
+void GLMenuImageScreen::setPosition(float offsetX, float offsetY)
+{}
+
+
+/*
+  \brief sets size of the ImageScreen
+  \param height of the ImageScreen
+  \param width of the Image Screen
+*/
+void GLMenuImageScreen::setSize(float height, float width)
+{}
+
+
+/**
+   \brief set the maximum of countable steps
+   \param maximum of steps
+*/
+void GLMenuImageScreen::setMaximum(int maxStep)
+{
+  this->maxStep = maxStep;
+}
+
+
+/**
+   \brief gets the maximum of countable steps
+*/
+int GLMenuImageScreen::getMaximum()
+{
+  return this->maxStep;
+}
+
+
+/**
+   \brief set current value
+   \param current value
+*/
+void GLMenuImageScreen::setValue(int currentValue)
+{
+  this->currentValue = currentValue;
+  this->draw();
+}
+
+
+/**
+   \brief get the current value
+ */
+int GLMenuImageScreen::getValue()
+{
+  return this->currentValue;
+}
+
+
+/** 
+    \brief call this to trigger a progress event
+    
+    this has to redraw the progress bar and the whole image
+ */
+void GLMenuImageScreen::step ()
+{
+  this->currentValue++;
+}
Index: orxonox/trunk/src/glmenu_imagescreen.h
===================================================================
--- orxonox/trunk/src/glmenu_imagescreen.h	(revision 3365)
+++ orxonox/trunk/src/glmenu_imagescreen.h	(revision 3365)
@@ -0,0 +1,46 @@
+/*! 
+    \file glmenu_imagescreen
+    \brief class to display a image
+*/
+
+
+#ifndef _GLMENU_IMAGESCREEN_H
+#define _GLMENU_IMAGESCREEN_H
+
+#include "stdincl.h"
+
+class Texture;
+
+class GLMenuImageScreen : public BaseObject {
+
+ public:
+  GLMenuImageScreen ();
+  ~GLMenuImageScreen ();
+
+  void init ();
+  void init (char* backImageName, float height, float width, 
+	     float offsetX, float offsetY);
+
+  void draw ();
+  
+  void setBackImageName (char* backImageName);
+  void setPosition (float offsetX, float offsetY);
+  void setSize (float height, float width);
+  
+  void setMaximum (int maxStep);
+  int getMaximum ();
+  void setValue (int currentValue);
+  int getValue ();
+  void step ();
+
+ private:
+  char* backImageName;       //! the name of the file of the background image
+  float height, width;       //! hight and width of the image
+  float offsetX, offsetY;    //! offset of the image from left and up
+  Texture* backTex;          //! background texture
+  int currentValue;          //! the current count of step() calls fired yet
+  int maxStep;               //! total count of steps
+
+};
+
+#endif /* _GLMENU_IMAGESCREEN_H */
Index: orxonox/trunk/src/helper_parent.cc
===================================================================
--- orxonox/trunk/src/helper_parent.cc	(revision 3365)
+++ orxonox/trunk/src/helper_parent.cc	(revision 3365)
@@ -0,0 +1,42 @@
+
+
+/* 
+   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: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "helper_parent.h"
+
+
+using namespace std;
+
+
+/**
+   \brief standard constructor
+
+   \todo this constructor is not jet implemented - do it
+*/
+HelperParent::HelperParent () 
+{
+   this->setClassName ("HelperParent");
+}
+
+
+/**
+   \brief standard deconstructor
+
+   \todo this deconstructor is not jet implemented - do it
+*/
+HelperParent::~HelperParent () {}
+
Index: orxonox/trunk/src/helper_parent.h
===================================================================
--- orxonox/trunk/src/helper_parent.h	(revision 3365)
+++ orxonox/trunk/src/helper_parent.h	(revision 3365)
@@ -0,0 +1,24 @@
+/*! 
+    \file helper_parent.h
+    \brief this is a parent class, that isn't visible in the real world itself
+*/
+
+
+#ifndef _HELPER_PARENT_H
+#define _HELPER_PARENT_H
+
+#include "stdincl.h"
+#include "p_node.h"
+
+
+
+class HelperParent : public PNode {
+
+ public:
+  HelperParent ();
+  ~HelperParent ();
+
+
+};
+
+#endif /* _HELPER_PARENT_H */
Index: orxonox/trunk/src/importer/Makefile.am
===================================================================
--- orxonox/trunk/src/importer/Makefile.am	(revision 3364)
+++ orxonox/trunk/src/importer/Makefile.am	(revision 3365)
@@ -8,14 +8,16 @@
 importer_SOURCES= framework.cc \
 	          windowHandler.cc \
-	  	  object.cc \
+	  	  model.cc \
 	  	  array.cc \
 	  	  material.cc \
+		  texture.cc \
 	  	  vector.cc 
 
 noinst_HEADERS= framework.h \
 	  	windowHandler.h \
-	  	object.h \
+	  	model.h \
 	  	array.h \
-		material.h 
+		material.h \
+		texture.h
 
 
Index: orxonox/trunk/src/importer/Makefile.in
===================================================================
--- orxonox/trunk/src/importer/Makefile.in	(revision 3364)
+++ orxonox/trunk/src/importer/Makefile.in	(revision 3365)
@@ -54,6 +54,6 @@
 PROGRAMS = $(bin_PROGRAMS)
 am_importer_OBJECTS = framework.$(OBJEXT) windowHandler.$(OBJEXT) \
-	object.$(OBJEXT) array.$(OBJEXT) material.$(OBJEXT) \
-	vector.$(OBJEXT)
+	model.$(OBJEXT) array.$(OBJEXT) material.$(OBJEXT) \
+	texture.$(OBJEXT) vector.$(OBJEXT)
 importer_OBJECTS = $(am_importer_OBJECTS)
 importer_LDADD = $(LDADD)
@@ -62,6 +62,7 @@
 am__depfiles_maybe = depfiles
 @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/array.Po ./$(DEPDIR)/framework.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/material.Po ./$(DEPDIR)/object.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/vector.Po ./$(DEPDIR)/windowHandler.Po
+@AMDEP_TRUE@	./$(DEPDIR)/material.Po ./$(DEPDIR)/model.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/texture.Po ./$(DEPDIR)/vector.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/windowHandler.Po
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -176,14 +177,16 @@
 importer_SOURCES = framework.cc \
 	          windowHandler.cc \
-	  	  object.cc \
+	  	  model.cc \
 	  	  array.cc \
 	  	  material.cc \
+		  texture.cc \
 	  	  vector.cc 
 
 noinst_HEADERS = framework.h \
 	  	windowHandler.h \
-	  	object.h \
+	  	model.h \
 	  	array.h \
-		material.h 
+		material.h \
+		texture.h
 
 all: all-am
@@ -256,5 +259,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/framework.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/material.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/model.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texture.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vector.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windowHandler.Po@am__quote@
Index: orxonox/trunk/src/importer/framework.cc
===================================================================
--- orxonox/trunk/src/importer/framework.cc	(revision 3364)
+++ orxonox/trunk/src/importer/framework.cc	(revision 3365)
@@ -52,5 +52,5 @@
 int main(int argc, char *argv[])
 {
-  int verbose = 3;
+  verbose = 2;
 
   PRINTF(2)("This is The big verbose-Test %i, %s\n", 1, "cool");
@@ -71,9 +71,9 @@
   PRINTF(2)("screensize: %i, %i\n", wHandler.screen->w, wHandler.screen->h);
   if (argc>=3)
-    obj = new Object (argv[1], atof(argv[2]));
+    obj = new Model (argv[1], atof(argv[2]));
   else if (argc>=2)
-    obj = new Object(argv[1]);
+    obj = new Model(argv[1]);
   else 
-    obj = new Object();
+    obj = new Model();
   
   M = Vector(wHandler.screen->w/2, wHandler.screen->h/2, 0); 
@@ -215,5 +215,5 @@
 	  case SDLK_c:
 	    if (!obj)
-	      obj = new Object(argv[1]);
+	      obj = new Model(argv[1]);
 	    break;
 	  }
Index: orxonox/trunk/src/importer/framework.h
===================================================================
--- orxonox/trunk/src/importer/framework.h	(revision 3364)
+++ orxonox/trunk/src/importer/framework.h	(revision 3365)
@@ -3,5 +3,5 @@
  
 #include "windowHandler.h" // Include the Whandler Basecode
-#include "object.h"
+#include "model.h"
 #include "vector.h"
 
@@ -33,5 +33,5 @@
 
 WindowHandler wHandler;  // Create an instance of the whandler basecode class
-Object* obj;
+Model* obj;
 
 
Index: orxonox/trunk/src/importer/material.cc
===================================================================
--- orxonox/trunk/src/importer/material.cc	(revision 3364)
+++ orxonox/trunk/src/importer/material.cc	(revision 3365)
@@ -13,93 +13,10 @@
    co-programmer: ...
 
-   TGA-code: borrowed from nehe-Tutorials
-
 */
 
 #include "material.h"
 
-// headers only for PathList
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <fstream>
-
 using namespace std;
 
-/**
-   \brief creates a ned PathList.
-   
-   It is a good idea to use this as an initial List,
-   because if you give on a name the Path will not be checked for its existence.
-*/
-PathList::PathList()
-{
-  this->pathName = NULL;
-  this->next = NULL;
-}
-
-/**
-   \brief Creates a new PathList with a Name.
-   \param pName the Name of The Path.
-
-   This function just adds the Path without checking if it exists.
-*/
-PathList::PathList(char* pName)
-{
-  this->pathName = new char [strlen(pName)+1];
-  strcpy (this->pathName, pName);
-  this->next = NULL;
-}
-
-/**
-   \brief destroys a PathList
-
-   It does this by deleting the Name and then delete its preceding PathList.
-*/
-PathList::~PathList()
-{
-  if (this->pathName)
-    delete []this->pathName;
-  if (this->next)
-    delete this->next;
-}
-
-/**
-   \brief Adds a new Pathlist Element.
-   \param pName
-   
-   Adding a Path automatically checks if the Path exists,
-   and if it does not it will not add it to the List.
-*/
-void PathList::addPath (char* pName)
-{
-  if (pName[0] == '\0')
-    {
-      PRINTF(3)("not Adding empty Path to the List.\n");
-      return;
-    }
-  char* tmpPName = new char[strlen(pName)];
-  strncpy(tmpPName, pName, strlen(pName)-1);
-  tmpPName[strlen(pName)-1] = '\0';
-  if (access (tmpPName, F_OK) == 0)
-    {
-      struct stat status;
-      stat(tmpPName, &status);
-      if (status.st_mode & S_IFDIR)
-	{
-	  PRINTF(2)("Adding Path %s to the PathList.\n", pName);
-	  PathList* tmpPathList = this;
-	  while (tmpPathList->next)
-	    tmpPathList = tmpPathList->next;
-	  tmpPathList->next = new PathList(pName);
-	}
-      else
-	PRINTF(2)("You tried to add non-folder %s to a PathList.\n", tmpPName);
-    }
-  else
-      PRINTF(2)("You tried to add non-existing folder %s to a PathList.\n", tmpPName);
-  delete []tmpPName;
-}
 
 /**
@@ -133,6 +50,6 @@
   if (this->name)
     delete []this->name;
-  if (this->diffuseTextureSet)
-    glDeleteTextures (1, &this->diffuseTexture);
+  if (this->diffuseTexture)
+    this->diffuseTexture;
   if (this->nextMat)
     delete this->nextMat;
@@ -172,7 +89,8 @@
   this->setTransparency(0.0);
 
-  if (!this->pathList)
-    this->pathList = new PathList("");
-
+
+  this->diffuseTexture = NULL;
+  this->ambientTexture = NULL;
+  this->specularTexture = NULL;
 
   this->diffuseTextureSet = false;
@@ -182,6 +100,4 @@
   
 }
-
-PathList *Material::pathList = NULL;
 
 /**
@@ -233,5 +149,5 @@
 
   if (this->diffuseTextureSet)
-    glBindTexture(GL_TEXTURE_2D, this->diffuseTexture);
+    glBindTexture(GL_TEXTURE_2D, this->diffuseTexture->getTexture());
   else
     glBindTexture(GL_TEXTURE_2D, 0);
@@ -394,40 +310,6 @@
 void Material::addTexturePath(char* pathName)
 {
-  this->pathList->addPath (pathName);
-}
-
-/**
-   \brief Searches for a Texture inside one of the defined Paths
-   \param texName The name of the texture o search for.
-   \returns pathName+texName if texName was found in the pathList. NULL if the Texture is not found.
-*/
-char* Material::searchTextureInPaths(char* texName) const
-{
-  char* tmpName = NULL;
-  PathList* pList = pathList;
-  while (pList)
-    {
-      if (pList->pathName)
-	{
-	  tmpName = new char [strlen(pList->pathName)+strlen(texName)+1];
-	  strcpy(tmpName, pList->pathName);
-	}
-      else
-	{
-	  tmpName = new char [strlen(texName)+1];
-	  tmpName[0]='\0';
-	}
-      strcat(tmpName, texName);
-      if (access (tmpName, F_OK) == 0)
-	return tmpName;
-      
-      if (tmpName)
-	delete []tmpName;
-      tmpName = NULL;
-      pList = pList->next;
-    }
-  return NULL;
-}
-
+  PathList::getInstance()->addPath(pathName);
+}
 
 // MAPPING //
@@ -440,7 +322,6 @@
 {
   PRINTF(3)("setting Diffuse Map %s\n", dMap);
-
-  //  diffuseTextureSet = loadBMP(dMap, &diffuseTexture);
-  this->diffuseTextureSet = this->loadImage(dMap, &this->diffuseTexture);
+  diffuseTexture = new Texture();
+  this->diffuseTextureSet = diffuseTexture->loadImage(dMap);
 
 }
@@ -477,765 +358,2 @@
 
 }
-
-/**
-   \brief Loads a Texture to the openGL-environment.
-   \param pImage The Image to load to openGL
-   \param texture The Texture to apply it to.
-*/
-bool Material::loadTexToGL (Image* pImage, GLuint* texture)
-{
-  PRINTF(2)("Loading texture to OpenGL-Environment.\n");
-  glGenTextures(1, texture);
-  glBindTexture(GL_TEXTURE_2D, *texture);
-  /* not Working, and not needed. 
-  glTexImage2D( GL_TEXTURE_2D, 0, 3, width,
-		height, 0, GL_BGR,
-		GL_UNSIGNED_BYTE, map->pixels );
-  */ 
-  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->width, pImage->height, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
-  
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
-  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);	
-}
-
-
-#ifdef HAVE_SDL_SDL_IMAGE_H
-bool Material::loadImage(char* imageName, GLuint* texture)
-{
-  char* imgNameWithPath = searchTextureInPaths(imageName);
-  if (imgNameWithPath)
-    {
-      SDL_Surface* map;
-      Image* pImage = new Image;
-      map=IMG_Load(imgNameWithPath);
-      if(!map)
-	{
-	  PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
-	  return false;
-	}
-      pImage->height = map->h;
-      pImage->width  = map->w;
-      pImage->data   = (GLubyte*)map->pixels;
-      if( !IMG_isPNG(SDL_RWFromFile(imgNameWithPath, "rb")) && !IMG_isJPG(SDL_RWFromFile(imgNameWithPath, "rb")))
-	for (int i=0;i<map->h * map->w *3;i+=3)
-	  { 
-	    GLuint temp = pImage->data[i];
-	    pImage->data[i] = pImage->data[i+2];
-	    pImage->data[i+2] = temp;
-	  }
-      this->loadTexToGL (pImage, texture);
-    }
-  else
-    {
-      PRINTF(1)("Image not Found: %s\n", imgNameWithPath);
-      return false;
-    }
-}
-
-
-#else /* HAVE_SDL_SDL_IMAGE_H */
-/**
-   \brief Makes the Programm ready to Read-in a texture-File
-   1. Checks what type of Image should be imported
-   2. ToDO: Checks where to find the Image
-*/
-bool Material::loadImage(char* imageName, GLuint* texture)
-{
-  char* imgNameWithPath = searchTextureInPaths(imageName);
-  if (imgNameWithPath)
-    {
-      if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".bmp", 4))
-	{
-	  PRINTF(3)("Requested bmp-image. Trying to Import.\n");
-	  return this->loadBMP(imgNameWithPath, texture);
-	}
-      
-      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".jpg", 4) || !strncmp(imgNameWithPath+strlen(imgNameWithPath)-5, ".jpg", 5))
-	{
-	  PRINTF(3)("Requested jpeg-image. Trying to Import\n");
-	  return this->loadJPG(imgNameWithPath, texture);
-	}
-      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".tga", 4))
-	{
-	  PRINTF(3)("Requested tga-image. Trying to Import\n");
-	  return this->loadTGA(imgNameWithPath, texture);
-	}
-      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".png", 4))
-	{
-	  PRINTF(3)("Requested png-image. Trying to Import\n");
-	  return this->loadPNG(imgNameWithPath, texture);
-	}
-      else
-	{
-	  PRINTF(1)("Requested Image was not recognized in its type. (Maybe a type-Cast-error.)\n FileName: %s", imgNameWithPath);
-	  return false;
-	}
-    }
-  else
-    {
-      PRINTF(1)("Image not Found: %s\n", imgNameWithPath);
-      return false;
-    }
-}
-
-/**
-   \brief reads in a Windows BMP-file, and imports it to openGL.
-   \param bmpName The name of the Image to load.
-   \param texture A pointer to the Texture which should be read to.
-*/
-bool Material::loadBMP (char* bmpName, GLuint* texture)
-{
-  Image* pImage = new Image;
-  FILE *file;
-  unsigned long size;                 // size of the image in bytes.
-  unsigned long i;                    // standard counter.
-  unsigned short int planes;          // number of planes in image (must be 1) 
-  unsigned short int bpp;             // number of bits per pixel (must be 24)
-  GLuint temp;                          // temporary color storage for bgr-rgb conversion.
-
-  // make sure the file is there.
-  if ((file = fopen(bmpName, "rb"))==NULL)
-    {
-      PRINTF(1)("File Not Found : %s\n",bmpName);
-      return false;
-    }
-  // seek through the bmp header, up to the width/height:
-  fseek(file, 18, SEEK_CUR);
-  
-  // read the width
-  if ((i = fread(&pImage->width, 4, 1, file)) != 1) 
-    {
-      PRINTF(1)("Error reading width from %s.\n", bmpName);
-      return false;
-    }
-  // read the height 
-  if ((i = fread(&pImage->height, 4, 1, file)) != 1) 
-    {
-      PRINTF(1)("Error reading height from %s.\n", bmpName);
-      return false;
-    }
-  
-  // calculate the size (assuming 24 bits or 3 bytes per pixel).
-  size = pImage->width * pImage->height * 3;
-  
-  // read the planes
-  if ((fread(&planes, 2, 1, file)) != 1) 
-    {
-      PRINTF(1)("Error reading planes from %s.\n", bmpName);
-      return false;
-    }
-  if (planes != 1) 
-    {
-      PRINTF(1)("Planes from %s is not 1: %u\n", bmpName, planes);
-      return false;
-    }
-  
-  // read the bpp
-  if ((i = fread(&bpp, 2, 1, file)) != 1) 
-    {
-      PRINTF(1)("Error reading bpp from %s.\n", bmpName);
-      return false;
-    }
-  if (bpp != 24) 
-    {
-      PRINTF(1)("Bpp from %s is not 24: %u\n", bmpName, bpp);
-      return false;
-    }
-  
-  // seek past the rest of the bitmap header.
-  fseek(file, 24, SEEK_CUR);
-  
-  // read the data. 
-  pImage->data = (GLubyte *) malloc(size);
-  if (pImage->data == NULL) 
-    {
-      PRINTF(1)("Error allocating memory for color-corrected image data");
-      return false;	
-    }
-  
-  if ((i = fread(pImage->data, size, 1, file)) != 1) 
-    {
-      PRINTF(1)("Error reading image data from %s.\n", bmpName);
-      return false;
-    }
-  fclose(file);
-
-  // reverse all of the colors. (bgr -> rgb)
-  for (i=0;i<size;i+=3) 
-    { 
-      temp = pImage->data[i];
-      pImage->data[i] = pImage->data[i+2];
-      pImage->data[i+2] = temp;
-    }
-  this->loadTexToGL (pImage, texture);
-  
-
-  if (pImage)
-    {
-      if (pImage->data)
-	{
-	  free(pImage->data);
-	}
-      
-      free(pImage);
-    }
-  return true;
-
-}
-
-/**
-   \brief reads in a jpg-file
-   \param jpgName the Name of the Image to load
-   \param texture a reference to the Texture to write the image to
-*/
-bool Material::loadJPG (char* jpgName, GLuint* texture)
-{
-#ifdef HAVE_JPEGLIB_H
-  struct jpeg_decompress_struct cinfo;
-  Image *pImage = NULL;
-  FILE *pFile;
-  
-  // Open a file pointer to the jpeg file and check if it was found and opened 
-  if((pFile = fopen(jpgName, "rb")) == NULL) 
-    {
-      // Display an error message saying the file was not found, then return NULL
-      PRINTF(1)("Unable to load JPG File %s.\n", jpgName);
-      return false;
-    }
-  
-  // Create an error handler
-  jpeg_error_mgr jerr;
-  
-  // Have our compression info object point to the error handler address
-  cinfo.err = jpeg_std_error(&jerr);
-  
-  // Initialize the decompression object
-  jpeg_create_decompress(&cinfo);
-  
-  // Specify the data source (Our file pointer)	
-  jpeg_stdio_src(&cinfo, pFile);
-  
-  // Allocate the structure that will hold our eventual jpeg data (must free it!)
-  pImage = (Image*)malloc(sizeof(Image));
-  
-  // DECOFING
-  // Read in the header of the jpeg file
-  jpeg_read_header(&cinfo, TRUE);
-  
-  // Start to decompress the jpeg file with our compression info
-  jpeg_start_decompress(&cinfo);
-  
-  // Get the image dimensions and row span to read in the pixel data
-  pImage->rowSpan = cinfo.image_width * cinfo.num_components;
-  pImage->width   = cinfo.image_width;
-  pImage->height   = cinfo.image_height;
-  
-  // Allocate memory for the pixel buffer
-  pImage->data = new unsigned char[pImage->rowSpan * pImage->height];
-  
-  // Here we use the library's state variable cinfo.output_scanline as the
-  // loop counter, so that we don't have to keep track ourselves.
-  
-  // Create an array of row pointers
-  unsigned char** rowPtr = new unsigned char*[pImage->height];
-  for (int i = 0; i < pImage->height; i++)
-    rowPtr[i] = &(pImage->data[i*pImage->rowSpan]);
-  
-  // Now comes the juice of our work, here we extract all the pixel data
-  int rowsRead = 0;
-  while (cinfo.output_scanline < cinfo.output_height) 
-    {
-      // Read in the current row of pixels and increase the rowsRead count
-      rowsRead += jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead);
-    }
-  
-  // Delete the temporary row pointers
-  delete [] rowPtr;
-  
-  // Finish decompressing the data
-  jpeg_finish_decompress(&cinfo);//  decodeJPG(&cinfo, pImage);
-  
-  // This releases all the stored memory for reading and decoding the jpeg
-  jpeg_destroy_decompress(&cinfo);
-  
-  // Close the file pointer that opened the file
-  fclose(pFile);
-  
-
-  if(pImage == NULL)
-    exit(0);
-  
-  this->loadTexToGL (pImage, texture);
-  if (pImage)
-    {
-      if (pImage->data)
-	{
-	  free(pImage->data);
-	}
-      
-      free(pImage);
-    }
-  return true;
-#else /* HAVE_JPEGLIB_H */
-  PRINTF(1)("sorry, but you did not compile with jpeg-support.\nEither install SDL_image or jpeglib, and recompile to see the image\n");
-  return false;
-#endif /* HAVE_JPEGLIB_H */
-
-}
-
-/**
-   \brief reads in a tga-file
-   \param tgaName the Name of the Image to load
-   \param texture a reference to the Texture to write the image to
-*/
-bool Material::loadTGA(const char * tgaName, GLuint* texture)
-{
-  typedef struct
-  {
-    GLubyte Header[12];
-  } TGAHeader;
-  TGAHeader tgaHeader;			
-  
-  GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0};	// Uncompressed TGA Header 
-  GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0};	// Compressed TGA Header 
-  FILE * fTGA;
-  fTGA = fopen(tgaName, "rb");
-
-  if(fTGA == NULL)
-    {
-      PRINTF(1)("Error could not open texture file: %s\n", tgaName);
-      return false;
-    }
-  
-  if(fread(&tgaHeader, sizeof(TGAHeader), 1, fTGA) == 0)
-    {
-      PRINTF(1)("Error could not read file header of %s\n", tgaName);
-      if(fTGA != NULL)
-	{
-	  fclose(fTGA);
-	}
-      return false;
-    }
-  
-  if(memcmp(uTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
-    {
-      loadUncompressedTGA(tgaName, fTGA, texture);
-      if (fTGA)
-	fclose (fTGA);
-    }
-  else if(memcmp(cTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
-    {
-      loadCompressedTGA(tgaName, fTGA, texture);
-	if (fTGA)
-	  fclose (fTGA);
-    }
-  else
-    {
-      PRINTF(1)("Error TGA file be type 2 or type 10\n");
-      if (fTGA)
-	fclose(fTGA);
-      return false;
-    }
-  return true;
-}
-
-/**
-   \brief reads in an uncompressed tga-file
-   \param filename the Name of the Image to load
-   \param fTGA a Pointer to a File, that should be read
-   \param texture a reference to the Texture to write the image to
-*/
-bool Material::loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
-{
-  GLubyte header[6];      // First 6 Useful Bytes From The Header 
-  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File 
-  GLuint  imageSize;	  // Used To Store The Image Size When Setting Aside Ram 
-  GLuint  temp;		  // Temporary Variable
-  GLuint  type;
-  GLuint  Height;	  // Height of Image 
-  GLuint  Width;	  // Width of Image 
-  GLuint  Bpp;		  // Bits Per Pixel 
-
-  Image* pImage = new Image;
-  GLuint cswap;
-  if(fread(header, sizeof(header), 1, fTGA) == 0)
-    {
-      PRINTF(1)("Error could not read info header\n");
-      return false;
-    }
-  
-  Width = pImage->width  = header[1] * 256 + header[0];
-  Height =  pImage->height = header[3] * 256 + header[2];
-  Bpp = pImage->bpp = header[4];
-  // Make sure all information is valid
-  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
-    {
-      PRINTF(1)("Error invalid texture information\n");
-      return false;
-    }
-  
-  if(pImage->bpp == 24)	
-    {
-      pImage->type = GL_RGB;
-    }
-  else
-    {
-      pImage->type = GL_RGBA;
-    }
-  
-  bytesPerPixel	= (Bpp / 8);
-  imageSize = (bytesPerPixel * Width * Height);
-  pImage->data = (GLubyte*) malloc(imageSize);
-  
-  if(pImage->data == NULL)
-    {
-      PRINTF(1)("Error could not allocate memory for image\n");
-      return false;
-    }
-  
-  if(fread(pImage->data, 1, imageSize, fTGA) != imageSize)
-    {
-      PRINTF(1)("Error could not read image data\n");
-      if(pImage->data != NULL)
-	{
-	  free(pImage->data);
-	}
-      return false;
-    }
-  
-  for(cswap = 0; cswap < (int)imageSize; cswap += bytesPerPixel)
-    {
-      pImage->data[cswap] ^= pImage->data[cswap+2] ^=
-	pImage->data[cswap] ^= pImage->data[cswap+2];
-    }
-  
-  this->loadTexToGL (pImage, texture);
-
-  return true;
-}
-
-/**
-   \brief reads in a compressed tga-file
-   \param filename the Name of the Image to load
-   \param fTGA a Pointer to a File, that should be read
-   \param texture a reference to the Texture to write the image to
-*/
-bool Material::loadCompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
-{
-  GLubyte header[6];      // First 6 Useful Bytes From The Header 
-  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File 
-  GLuint  imageSize;	  // Used To Store The Image Size When Setting Aside Ram 
-  GLuint  temp;		  // Temporary Variable
-  GLuint  type;
-  GLuint  Height;	  // Height of Image 
-  GLuint  Width;	  // Width of Image 
-  GLuint  Bpp;		  // Bits Per Pixel 
-
-  Image* pImage = new Image;
-
-  
-  if(fread(header, sizeof(header), 1, fTGA) == 0)
-    {
-      PRINTF(1)("Error could not read info header\n");
-      return false;
-    }
-  
-  Width = pImage->width  = header[1] * 256 + header[0];
-  Height = pImage->height = header[3] * 256 + header[2];
-  Bpp = pImage->bpp	= header[4];
-
-  GLuint pixelcount	= Height * Width;
-  GLuint currentpixel	= 0;
-  GLuint currentbyte	= 0;
-  GLubyte * colorbuffer = (GLubyte *)malloc(bytesPerPixel);
-
-  //Make sure all pImage info is ok 
-  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
-    {
-      PRINTF(1)("Error Invalid pImage information\n");
-      return false;
-    }
-  
-  bytesPerPixel	= (Bpp / 8);
-  imageSize		= (bytesPerPixel * Width * Height);
-  pImage->data	= (GLubyte*) malloc(imageSize);
-  
-  if(pImage->data == NULL)
-    {
-      PRINTF(1)("Error could not allocate memory for image\n");
-      return false;
-    }
-  
-  do
-    {
-      GLubyte chunkheader = 0;
-      
-      if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)
-	{
-	  PRINTF(1)("Error could not read RLE header\n");
-	  if(pImage->data != NULL)
-	    {
-	      free(pImage->data);
-	    }
-	  return false;
-	}
-      // If the ehader is < 128, it means the that is the number of RAW color packets minus 1 
-      if(chunkheader < 128)
-	{
-	  short counter;
-	  chunkheader++;
-	  // Read RAW color values
-	  for(counter = 0; counter < chunkheader; counter++)
-	    { 
-	      // Try to read 1 pixel 
-	      if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel)
-		{
-		  PRINTF(1)("Error could not read image data\n");
-		  if(colorbuffer != NULL)
-		    {
-		      free(colorbuffer);
-		    }
-		  
-		  if(pImage->data != NULL)
-		    {
-		      free(pImage->data);
-		    }
-		  
-		  return false;	
-		}
-	      // write to memory 
-	      // Flip R and B vcolor values around in the process 
-	      pImage->data[currentbyte	  ] = colorbuffer[2];				    
-	      pImage->data[currentbyte + 1] = colorbuffer[1];
-	      pImage->data[currentbyte + 2] = colorbuffer[0];
-	      
-	      if(bytesPerPixel == 4) // if its a 32 bpp image 
-		{
-		  pImage->data[currentbyte + 3] = colorbuffer[3];// copy the 4th byte 
-		}
-	      
-	      currentbyte += bytesPerPixel;
-	      currentpixel++;
-
-	      // Make sure we haven't read too many pixels 
-	      if(currentpixel > pixelcount)	
-		{
-		  PRINTF(1)("Error too many pixels read\n");
-		  if(colorbuffer != NULL)
-		    {
-		      free(colorbuffer);
-		    }
-		  
-		  if(pImage->data != NULL)
-		    {
-		      free(pImage->data);
-		    }
-		  
-		  return false;
-		}
-	    }
-	}
-      // chunkheader > 128 RLE data, next color  reapeated chunkheader - 127 times
-      else
-	{
-	  short counter;
-	  chunkheader -= 127;	// Subteact 127 to get rid of the ID bit 
-	  if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel) // Attempt to read following color values 
-	    {
-	      PRINTF(1)("Error could not read from file");
-	      if(colorbuffer != NULL)
-		{
-		  free(colorbuffer);
-		}
-	      
-	      if(pImage->data != NULL)
-		{
-		  free(pImage->data);
-		}
-	      
-	      return false;
-	    }
-	  
-	  for(counter = 0; counter < chunkheader; counter++) //copy the color into the image data as many times as dictated
-	    {							
-	      // switch R and B bytes areound while copying
-	      pImage->data[currentbyte	  ] = colorbuffer[2];
-	      pImage->data[currentbyte + 1] = colorbuffer[1];
-	      pImage->data[currentbyte + 2] = colorbuffer[0];
-	      
-	      if(bytesPerPixel == 4)
-		{
-		  pImage->data[currentbyte + 3] = colorbuffer[3];
-		}
-	      
-	      currentbyte += bytesPerPixel;
-	      currentpixel++;
-	      
-	      if(currentpixel > pixelcount)
-		{
-		  PRINTF(1)("Error too many pixels read\n");
-		  if(colorbuffer != NULL)
-		    {
-		      free(colorbuffer);
-		    }
-		  
-		  if(pImage->data != NULL)
-		    {
-		      free(pImage->data);
-		    }
-		  
-		  return false;
-		}
-	    }
-	}
-    }
-  
-  while(currentpixel < pixelcount);	// Loop while there are still pixels left
-
-  this->loadTexToGL (pImage, texture);
-
-  return true;
-}
-
-
-/*
-static int ST_is_power_of_two(unsigned int number)
-{
-  return (number & (number - 1)) == 0;
-}
-*/
-
-/**
-   \brief reads in a png-file
-   \param pngName the Name of the Image to load
-   \param texture a reference to the Texture to write the image to
-*/
-bool Material::loadPNG(const char* pngName, GLuint* texture)
-{
-#ifdef HAVE_PNG_H
-  Image* pImage = new Image;
-
-  FILE *PNG_file = fopen(pngName, "rb");
-  if (PNG_file == NULL)
-    {
-      return 0;
-    }
-  
-  GLubyte PNG_header[8];
-  
-  fread(PNG_header, 1, 8, PNG_file);
-  if (png_sig_cmp(PNG_header, 0, 8) != 0)
-    {
-      PRINTF(2)("Not Recognized as a pngFile\n");
-      fclose (PNG_file);
-      return 0;
-    }
-  
-  png_structp PNG_reader = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-  if (PNG_reader == NULL)
-    {
-      fclose(PNG_file);
-      return 0;
-    }
-  
-  png_infop PNG_info = png_create_info_struct(PNG_reader);
-  if (PNG_info == NULL)
-    {
-      png_destroy_read_struct(&PNG_reader, NULL, NULL);
-      fclose(PNG_file);
-      return 0;
-    }
-  
-  png_infop PNG_end_info = png_create_info_struct(PNG_reader);
-  if (PNG_end_info == NULL)
-    {
-      png_destroy_read_struct(&PNG_reader, &PNG_info, NULL);
-      fclose(PNG_file);
-      return 0;
-    }
-  
-  if (setjmp(png_jmpbuf(PNG_reader)))
-    {
-      png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
-      fclose(PNG_file);
-      return (0);
-    }
-  
-  png_init_io(PNG_reader, PNG_file);
-  png_set_sig_bytes(PNG_reader, 8);
-  
-  png_read_info(PNG_reader, PNG_info);
-  
-  pImage->width = png_get_image_width(PNG_reader, PNG_info);
-  pImage->height = png_get_image_height(PNG_reader, PNG_info);
-  
-  png_uint_32 bit_depth, color_type;
-  bit_depth = png_get_bit_depth(PNG_reader, PNG_info);
-  color_type = png_get_color_type(PNG_reader, PNG_info);
-  
-  if (color_type == PNG_COLOR_TYPE_PALETTE)
-    {
-      png_set_palette_to_rgb(PNG_reader);
-    }
-  
-  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
-    {
-      png_set_gray_1_2_4_to_8(PNG_reader);
-    }
-  
-  if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-    {
-      png_set_gray_to_rgb(PNG_reader);
-    }
-  
-  if (png_get_valid(PNG_reader, PNG_info, PNG_INFO_tRNS))
-    {
-      png_set_tRNS_to_alpha(PNG_reader);
-    }
-  else
-    {
-      png_set_filler(PNG_reader, 0xff, PNG_FILLER_AFTER);
-    }
-  
-  if (bit_depth == 16)
-    {
-      png_set_strip_16(PNG_reader);
-    }
-  
-  png_read_update_info(PNG_reader, PNG_info);
-  
-  pImage->data = (png_byte*)malloc(4 * pImage->width * pImage->height);
-  png_byte** PNG_rows = (png_byte**)malloc(pImage->height * sizeof(png_byte*));
-  
-  unsigned int row;
-  for (row = 0; row < pImage->height; ++row)
-    {
-      PNG_rows[pImage->height - 1 - row] = pImage->data + (row * 4 * pImage->width);
-    }
-  
-  png_read_image(PNG_reader, PNG_rows);
-  
-  free(PNG_rows);
-  
-  png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
-  fclose(PNG_file);
-  
-  /*  if (!ST_is_power_of_two(pImage->width) || !ST_is_power_of_two(pImage->height))
-    {
-      free(pImage->data);
-      return 0;
-    }
-  */
-  this->loadTexToGL (pImage, texture);  
-  
-  free(pImage->data);
-  
-  return true;
-#else /* HAVE_PNG_H */
-  PRINTF(1)("sorry, but you did not compile with png-support.\nEither install SDL_image or libpng, and recompile to see the image\n");
-  return false;
-#endif /* HAVE_PNG_H */
-
-}
-
-#endif /* HAVE_SDL_SDL_IMAGE_H */
Index: orxonox/trunk/src/importer/material.h
===================================================================
--- orxonox/trunk/src/importer/material.h	(revision 3364)
+++ orxonox/trunk/src/importer/material.h	(revision 3365)
@@ -14,4 +14,5 @@
 
 #include "../stdincl.h"
+#include "texture.h"
 
 #if HAVE_CONFIG_H 
@@ -19,36 +20,5 @@
 #endif /* HAVE_CONFIG_H */
 
-#ifdef HAVE_SDL_SDL_IMAGE_H
-#include <SDL/SDL_image.h>
-#else
-// IMAGE LIBS //
-#ifdef HAVE_JPEGLIB_H
-extern "C"{         // This has to be done, because not a c++ lib
-#include <jpeglib.h>
-}
-#endif /* HAVE_JPEGLIB_H */
-#ifdef HAVE_PNG_H
-#include <png.h>
-#endif /* HAVE_PNG_H */
-#endif /* HAVE_SDL_SDL_IMAGE_H */
 
-//! Class to handle lists of paths.
-/**
-   \todo Ability to return Paths by itself.
-
-   It is simple to use, and good, for all PathList you want.
-   just create a new Pathlist, and add Paths.
-*/
-class PathList
-{
- public:
-  PathList();
-  PathList(char* pName);
-
-  ~PathList();
-  void addPath (char* pName);
-  char* pathName;          //!< The Name of the current Path.
-  PathList* next;          //!< Pointer to the next Pathlist.
-};
 
 
@@ -92,16 +62,4 @@
 
  private:
-  //! Struct to handle Infos about an Image
-  struct Image
-  {
-    int rowSpan;    //!< The count of the rows this Image has.
-    GLuint width;   //!< The width of the Image.
-    GLuint height;  //!< The height of the Image.
-    GLuint bpp;     //!< BitsPerPixel
-    GLuint type;    //!< Type of the Image.
-    GLubyte *data;  //!< The Image Data comes here! DANGER: uncompressed data.
-  };
-
-
   char* name;        //!< The Name of the Material.
   int illumModel;    //!< The IlluminationModel is either flat or smooth.
@@ -112,9 +70,7 @@
   float transparency;//!< The transperency of the Material.
 
-  static PathList* pathList; //!< A pointer to the first element of Pathlist. This is static, because pathlists are global \todo copy this to the Globals.h or DataTank for deletion at the end.
-  
-  GLuint diffuseTexture; //!< The diffuse texture of the Material.
-  GLuint ambientTexture; //!< The ambient texture of the Material.
-  GLuint specularTexture;//!< The specular texture of the Material.
+  Texture* diffuseTexture; //!< The diffuse texture of the Material.
+  Texture* ambientTexture; //!< The ambient texture of the Material.
+  Texture* specularTexture;//!< The specular texture of the Material.
   
   bool diffuseTextureSet; //!< Chekcs if the diffuse texture is Set.
@@ -124,22 +80,5 @@
   Material* nextMat; //!< pointer to the Next Material of the List. NULL if no next exists.
 
-  // TEXTURING
-  bool loadTexToGL (Image* pImage, GLuint* texture);
 
-  bool loadImage(char* imageName, GLuint* texture);
-#ifndef HAVE_SDL_SDL_IMAGE_H
-
-  bool loadBMP (char* bmpName, GLuint* texture);
-
-  bool loadJPG (char* jpgName, GLuint* texture);
-
-  /// TGA ///
-
-  bool loadTGA(const char * tgaName, GLuint* texture);
-  bool loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture);
-  bool loadCompressedTGA(const char * filename, FILE * fTGA, GLuint* texture);
-
-  bool loadPNG(const char* pngName, GLuint* texture);
-#endif
 };
 #endif
Index: orxonox/trunk/src/importer/model.cc
===================================================================
--- orxonox/trunk/src/importer/model.cc	(revision 3365)
+++ orxonox/trunk/src/importer/model.cc	(revision 3365)
@@ -0,0 +1,976 @@
+/* 
+   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: ...
+*/
+
+#include "model.h"
+int verbose = 1; //! \todo should be GLOBAL
+using namespace std;
+
+/**
+   \brief Creates a 3D-Model, but does not load any 3D-models.
+
+   This Constructor is pretty useless, because why load no model in an model-loader??
+*/
+Model::Model ()
+{
+
+  this->initialize();
+
+  this->BoxModel();
+
+  this->importToGL ();
+
+  this->cleanup();
+}
+
+/**
+   \brief Crates a 3D-Model and loads in a File.
+   \param fileName file to parse and load (must be a .obj file)
+*/
+Model::Model(char* fileName)
+{
+  this->initialize();
+
+  this->importFile (fileName);
+
+  this->importToGL ();
+
+  this->cleanup();
+}
+
+/**
+   \brief Crates a 3D-Model, loads in a File and scales it.
+   \param fileName file to parse and load (must be a .obj file)
+   \param scaling The factor that the model will be scaled with.
+*/
+Model::Model(char* fileName, float scaling)
+{
+  this->initialize();
+  this->scaleFactor = scaling;
+
+  this->importFile (fileName);
+
+  this->importToGL ();
+
+  this->cleanup();
+}
+
+/**
+   \brief deletes an Model.
+
+   Looks if any from model allocated space is still in use, and if so deleted it.
+*/
+Model::~Model()
+{
+  PRINTF(2)("Deleting display Lists.\n");
+  Group* walker = this->firstGroup;
+  while (walker != NULL)
+    {
+      glDeleteLists (walker->listNumber, 1);
+      Group* delWalker = walker;
+      walker = walker->next;
+      delete delWalker;
+    }
+
+  if (this->objPath)
+    delete []this->objPath;
+  if (this->objFileName)
+    delete []this->objFileName;
+  if (this->mtlFileName)
+    delete []this->mtlFileName;
+  PRINTF(2)("Deleting Materials.\n");
+  if (this->material)
+    delete this->material;
+}
+
+
+/**
+   \brief Draws the Models of all Groups.
+   It does this by just calling the Lists that must have been created earlier.
+*/
+void Model::draw (void) const
+{
+  PRINTF(2)("drawing the 3D-Models\n"); 
+  Group* walker = this->firstGroup;
+  while (walker != NULL)
+    {
+      PRINTF(3)("Drawing model %s\n", walker->name);
+      glCallList (walker->listNumber);
+      walker = walker->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 Model::draw (int groupNumber) const 
+{
+  if (groupNumber >= this->groupCount)
+    {
+      PRINTF(1)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount);
+      return;
+    }
+  PRINTF(2)("drawing the requested 3D-Models if found.\n"); 
+  Group* walker = this->firstGroup;
+  int counter = 0;
+  while (walker != NULL)
+    {
+      if (counter == groupNumber)
+	{
+	  PRINTF(2)("Drawing model number %i named %s\n", counter, walker->name);
+	  glCallList (walker->listNumber);
+	  return;
+	}
+      ++counter;
+      walker = walker->next;
+    }
+  PRINTF(1)("Model number %i in %s not Found.\n", groupNumber, this->objFileName);
+  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 Model::draw (char* groupName) const
+{
+  PRINTF(2)("drawing the requested 3D-Models if found.\n"); 
+  Group* walker = this->firstGroup;
+  while (walker != NULL)
+    {
+      if (!strcmp(walker->name, groupName))
+	{
+	  PRINTF(2)("Drawing model %s\n", walker->name);
+	  glCallList (walker->listNumber);
+	  return;
+	}
+      walker = walker->next;
+    }
+  PRINTF(1)("Model Named %s in %s not Found.\n", groupName, this->objFileName);
+  return;
+}
+
+/**
+   \returns Count of the Models in this File
+*/
+int Model::getGroupCount (void) const
+{
+  return this->groupCount;
+}
+
+/**
+    \brief initializes the Model.
+
+    This Function initializes all the needed arrays, Lists and clientStates.
+    It also defines default values.
+*/
+bool Model::initialize (void)
+{
+  PRINTF(2)("new 3D-Model is being created\n"); 
+
+  // setting the start group;
+  this->firstGroup = new Group;
+  this->currentGroup = this->firstGroup;
+  this->groupCount = 0;
+  
+  this->initGroup (this->currentGroup);
+  this->objPath = NULL;
+  this->objFileName = NULL;
+  this->mtlFileName = NULL;
+  this->scaleFactor = 1;
+  this->material = new Material();
+
+  this->vertices = new Array();
+  this->vTexture = new Array();
+  this->normals = new Array();
+
+  return true;
+}
+
+/**
+   \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(3)("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->materialString = NULL;
+  
+  face->next = NULL;
+
+  return true;
+}
+
+/**
+   \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 Model::cleanup(void)
+{
+  PRINTF(3)("cleaning up the 3D-Model to save Memory.\n");
+
+  if (this->vertices)
+    delete this->vertices;
+  if (this->vTexture)
+    delete this->vTexture;
+  if (this->normals)
+    delete this->normals;
+
+  this->cleanupGroup(this->firstGroup);
+  return true; 
+}
+
+/**
+   \brief Cleans up all groups starting from group.
+   \param group the first Group to clean
+*/
+bool Model::cleanupGroup (Group* group)
+{
+  PRINTF(3)("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(3)("Cleaning up Face\n");
+
+  if (face->materialString != NULL)
+      delete []face->materialString;
+  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;
+    }
+}
+
+/**
+   \brief Imports a obj file and handles the the relative location
+   \param fileName The file to import
+*/
+bool Model::importFile (char* fileName)
+{
+  PRINTF(3)("preparing to read in file: %s\n", fileName);
+
+
+#ifdef __WIN32__
+  // win32 path reading
+  char pathSplitter= '\\';
+#else /* __WIN32__ */
+  // unix path reading
+  char pathSplitter='/';
+#endif /* __WIN32__ */
+  char* tmpName = fileName;
+  if (tmpName[0] == pathSplitter)
+    tmpName++;
+  char* name = tmpName;
+  while (( tmpName = strchr (tmpName+1, pathSplitter)))
+    {
+      name = tmpName+1;
+    }
+  this->objPath = new char[name-fileName];
+  strncpy(this->objPath, fileName, name-fileName);
+  this->objPath[name-fileName] = '\0';
+  if (verbose >=2)
+    if (strlen(objPath)> 0)
+      PRINTF(0)("Resolved file %s to folder: %s.\n", name, objPath);
+    else
+      PRINTF(0)("Resolved file %s.\n", name);
+  
+  if (this->material)
+    this->material->addTexturePath(this->objPath);
+  this->objFileName = new char[strlen(name)+1];
+  strcpy (this->objFileName, name);
+  this->readFromObjFile ();
+  return true;
+}
+
+/**
+   \brief Reads in the .obj File and sets all the Values.
+   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
+*/
+bool Model::readFromObjFile (void)
+{
+  char* fileName = new char [strlen(objPath)+strlen(objFileName)+1];
+  if (this->objFileName != NULL && !strcmp(this->objFileName, ""))
+    return false;
+  strcpy(fileName, this->objPath);
+  strcat(fileName, this->objFileName);
+
+  ifstream* OBJ_FILE = new ifstream(fileName);
+  if (OBJ_FILE->fail())
+    {
+      PRINTF(1)("unable to open .OBJ file: %s\n Loading Box Model instead.\n", fileName);
+      BoxModel();
+      OBJ_FILE->close();
+      delete []fileName;
+      delete OBJ_FILE;
+      return false;
+    }
+  PRINTF(2)("Reading from opened file %s\n", fileName);
+  char Buffer[10000];
+  while(!OBJ_FILE->eof())
+    {
+      OBJ_FILE->getline(Buffer, 10000);
+      PRINTF(3)("Read input line: %s\n", Buffer);
+      
+
+      // case vertice
+      if (!strncmp(Buffer, "v ", 2))
+	{
+	  this->readVertex(Buffer+2);
+	}
+
+      // case face
+      else if (!strncmp(Buffer, "f ", 2))
+	{
+	  this->readFace (Buffer+2);
+	}
+      
+      else if (!strncmp(Buffer, "mtllib ", 7))
+	{
+	  this->readMtlLib (Buffer+7);
+	}
+
+      else if (!strncmp(Buffer, "usemtl ", 7))
+	{
+	  this->readUseMtl (Buffer+7);
+	}
+
+      // case VertexNormal
+      else if (!strncmp(Buffer, "vn ", 3))
+	{
+	  this->readVertexNormal(Buffer+3);
+	}
+      
+      // case VertexTextureCoordinate
+      else if (!strncmp(Buffer, "vt ", 3))
+	{
+	  this->readVertexTexture(Buffer+3);
+	}
+      // case group
+      else if (!strncmp(Buffer, "g ", 2))
+	{
+	  this->readGroup (Buffer+2);
+	}
+      else if (!strncmp(Buffer, "s ", 2)) //! \todo smoothing groups have to be implemented
+	{
+	  if (verbose >= 2)
+	    PRINTF(2)("smoothing groups not supportet yet. line: %s\n", Buffer);
+	}
+    }
+  OBJ_FILE->close();
+  delete OBJ_FILE;
+  delete []fileName;
+  return true;
+
+}
+
+/**
+   \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 import .obj-files with more than one Models inside. 
+*/
+bool Model::readGroup (char* groupString)
+{
+  PRINTF(3)("Read Group: %s.\n", groupString);
+  if (this->groupCount != 0 && this->currentGroup->faceCount>0)
+    {
+      //      finalizeGroup(currentGroup);
+      this->currentGroup = this->currentGroup->next = new Group;
+      this->initGroup(this->currentGroup);
+    }
+  // 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;
+
+}
+
+/**
+   \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 Model::readVertex (char* vertexString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  PRINTF(3)("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
+  this->vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
+  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.
+   The function makes a difference between QUADS and TRIANGLES, and will if changed re-open, set and re-close the gl-processe.
+*/
+bool Model::readFace (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;
+  tmpElem->next = NULL;
+  while(strcmp (faceString, "\0"))
+    {
+      if (this->currentGroup->currentFace->vertexCount>0)
+	  tmpElem = tmpElem->next = new FaceElement;
+      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;
+      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;
+      if (strcmp (faceString, "\0"))
+	faceString++;
+      this->currentGroup->currentFace->vertexCount++;
+    }
+
+  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
+}
+
+/**
+   \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 Model::readVertexNormal (char* normalString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  PRINTF(3)("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
+  this->normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
+  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
+*/
+bool Model::readVertexTexture (char* vTextureString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
+  PRINTF(3)("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
+  this->vTexture->addEntry(subbuffer1);
+  this->vTexture->addEntry(subbuffer2);
+  return true;
+}
+
+/** 
+    \brief Function to read in a mtl File.
+    \param mtlFile The .mtl file to read
+
+    This Function parses all Lines of an mtl File.
+    The reason for it not to be in the materials-class is,
+    that a material does not have to be able to read itself in from a File.
+
+*/
+bool Model::readMtlLib (char* mtlFile)
+{
+  this->mtlFileName = new char [strlen(mtlFile)+1];
+  strcpy(this->mtlFileName, mtlFile);
+  char* fileName = new char [strlen(objPath) + strlen(this->mtlFileName)+1];
+  strcpy(fileName, this->objPath);
+  strcat(fileName, this->mtlFileName);
+  
+
+  PRINTF(3)("Opening mtlFile: %s\n", fileName);
+
+  ifstream* MTL_FILE = new ifstream (fileName);
+  if (MTL_FILE->fail())
+    {
+      PRINTF(1)("unable to open file: %s\n", fileName);
+      MTL_FILE->close();
+      delete []fileName;
+      delete MTL_FILE;
+      return false;
+    }
+  char Buffer[500];
+  Material* tmpMat = material;
+  while(!MTL_FILE->eof())
+    {
+      MTL_FILE->getline(Buffer, 500);
+      PRINTF(4)("found line in mtlFile: %s\n", Buffer);
+      
+
+      // create new Material
+      if (!strncmp(Buffer, "newmtl ", 7))
+	{
+	  tmpMat = tmpMat->addMaterial(Buffer+7);
+	  //	  PRINTF(2)("%s, %p\n", tmpMat->getName(), tmpMat);
+	}
+      // setting a illumMode
+      else if (!strncmp(Buffer, "illum ", 6))
+	{
+	  tmpMat->setIllum(Buffer+6);
+
+	}
+      // setting Diffuse Color
+      else if (!strncmp(Buffer, "Kd ", 3))
+	{
+	  tmpMat->setDiffuse(Buffer+3);
+	}
+      // setting Ambient Color
+      else if (!strncmp(Buffer, "Ka ", 3))
+	{
+	  tmpMat->setAmbient(Buffer+3);
+	}
+      // setting Specular Color
+      else if (!strncmp(Buffer, "Ks ", 3))
+	{
+	  tmpMat->setSpecular(Buffer+3);
+	}
+      // setting The Specular Shininess
+      else if (!strncmp(Buffer, "Ns ", 3))
+	{
+	  tmpMat->setShininess(Buffer+3);
+	}
+      // setting up transparency
+      else if (!strncmp(Buffer, "d ", 2))
+	{
+	  tmpMat->setTransparency(Buffer+2);
+	}
+      else if (!strncmp(Buffer, "Tf ", 3))
+	{
+	  tmpMat->setTransparency(Buffer+3);
+	}
+      
+      else if (!strncmp(Buffer, "map_Kd ", 7))
+	{
+	  tmpMat->setDiffuseMap(Buffer+7);
+	}
+      else if (!strncmp(Buffer, "map_Ka ", 7))
+	{
+	  tmpMat->setAmbientMap(Buffer+7);
+	}
+      else if (!strncmp(Buffer, "map_Ks ", 7))
+	{
+	  tmpMat->setSpecularMap(Buffer+7);
+	}
+      else if (!strncmp(Buffer, "bump ", 5))
+	{
+	  tmpMat->setBump(Buffer+7);
+	}
+     
+
+    }
+  MTL_FILE->close();
+  delete []fileName;
+  delete MTL_FILE;
+  return true;
+}
+
+/**
+   \brief Function that selects a material, if changed in the obj file.
+   \param matString the Material that will be set.
+*/
+bool Model::readUseMtl (char* matString)
+{
+  if (!this->mtlFileName)
+    {
+      PRINTF(4)("Not using new defined material, because no mtlFile found yet\n");
+      return false;
+    }
+      
+  if (this->currentGroup->faceCount >0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
+  this->initFace (this->currentGroup->currentFace);
+  
+  this->currentGroup->currentFace->materialString = new char[strlen(matString)+1];
+  strcpy (this->currentGroup->currentFace->materialString, matString);
+  
+  if (this->currentGroup->faceCount == 0)
+    this->currentGroup->faceCount ++;
+
+}
+
+/**
+   \brief reads and includes the Faces/Materials into the openGL state Machine
+*/
+bool Model::importToGL (void)
+{
+
+  // finalize the Arrays
+  this->vertices->finalizeArray();
+  this->vTexture->finalizeArray();
+  if (normals->getCount() == 0) // vertices-Array must be uilt 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(1)("list could not be created for this Model\n");
+	  return false;
+	}
+      glNewList (this->currentGroup->listNumber, GL_COMPILE);
+
+      // Putting Faces to GL
+      Face* tmpFace = this->currentGroup->firstFace;
+      while (tmpFace != NULL)
+	{
+	  if (tmpFace->vertexCount == 0 && tmpFace->materialString != NULL)
+	    {
+	      if (this->currentGroup->faceMode != -1)
+		glEnd();
+	      this->currentGroup->faceMode = 0;
+	      PRINTF(2)("using material %s for coming Faces.\n", tmpFace->materialString);
+	      Material* tmpMat;
+	      if ((tmpMat = material->search(tmpFace->materialString)) != NULL)
+		tmpMat->select();
+
+	    }
+
+	  else if (tmpFace->vertexCount == 3)
+	    {
+	      if (this->currentGroup->faceMode != 3)
+		{
+		  if (this->currentGroup->faceMode != -1)
+		    glEnd();
+		  glBegin(GL_TRIANGLES);
+		}
+	      
+	      this->currentGroup->faceMode = 3;
+	      PRINTF(3)("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(3)("found quad.\n");
+	    }
+	  
+	  else if (tmpFace->vertexCount > 4)
+	    {
+	      if (this->currentGroup->faceMode != -1)
+		glEnd();
+	      glBegin(GL_POLYGON);
+	      PRINTF(3)("Polygon with %i faces found.", tmpFace->vertexCount);
+	      this->currentGroup->faceMode = tmpFace->vertexCount;
+	    }
+	  
+	  FaceElement* 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;
+    } 
+}
+
+/**
+   \brief 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 (FaceElement* elem)
+{
+  PRINTF(3)("importing grafical Element to openGL.\n");
+
+  if (elem->texCoordNumber != -1)
+    glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
+  if (elem->normalNumber != -1)
+    glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
+  if (elem->vertexNumber != -1)
+    glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
+
+}
+
+/**
+   \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 Model::buildVertexNormals ()
+{
+  
+  PRINTF(2)("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;
+
+  Group* tmpGroup = firstGroup;
+  while (tmpGroup)
+    {
+      Face* tmpFace = tmpGroup->firstFace;
+      while (tmpFace)
+	{
+	  if (tmpFace->firstElem)
+	    {
+	      FaceElement* firstElem = tmpFace->firstElem;
+	      FaceElement* prevElem;
+	      FaceElement* curElem = firstElem;
+	      FaceElement* nextElem;
+	      FaceElement* 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(3)("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);
+
+    }
+  delete []normArray; 
+  
+}
+
+
+/**
+   \brief Includes a default model
+
+   This will inject a Cube, because this is the most basic model.
+*/
+void Model::BoxModel(void)
+{
+  this->readVertex ("-0.5 -0.5 0.5");
+  this->readVertex ("0.5 -0.5 0.5");
+  this->readVertex ("-0.5 0.5 0.5");
+  this->readVertex ("0.5 0.5 0.5");
+  this->readVertex ("-0.5 0.5 -0.5");
+  this->readVertex ("0.5 0.5 -0.5");
+  this->readVertex ("-0.5 -0.5 -0.5");
+  this->readVertex ("0.5 -0.5 -0.5");
+
+  this->readVertexTexture ("0.0 0.0");
+  this->readVertexTexture ("1.0 0.0");
+  this->readVertexTexture ("0.0 1.0");
+  this->readVertexTexture ("1.0 1.0");
+  this->readVertexTexture ("0.0 2.0");
+  this->readVertexTexture ("1.0 2.0");
+  this->readVertexTexture ("0.0 3.0");
+  this->readVertexTexture ("1.0 3.0");
+  this->readVertexTexture ("0.0 4.0");
+  this->readVertexTexture ("1.0 4.0");
+  this->readVertexTexture ("2.0 0.0");
+  this->readVertexTexture ("2.0 1.0");
+  this->readVertexTexture ("-1.0 0.0");
+  this->readVertexTexture ("-1.0 1.0");
+
+  this->readVertexNormal ("0.0 0.0 1.0");
+  this->readVertexNormal ("0.0 0.0 1.0");
+  this->readVertexNormal ("0.0 0.0 1.0");
+  this->readVertexNormal ("0.0 0.0 1.0");
+  this->readVertexNormal ("0.0 1.0 0.0");
+  this->readVertexNormal ("0.0 1.0 0.0");
+  this->readVertexNormal ("0.0 1.0 0.0");
+  this->readVertexNormal ("0.0 1.0 0.0");
+  this->readVertexNormal ("0.0 0.0 -1.0");
+  this->readVertexNormal ("0.0 0.0 -1.0");
+  this->readVertexNormal ("0.0 0.0 -1.0");
+  this->readVertexNormal ("0.0 0.0 -1.0");
+  this->readVertexNormal ("0.0 -1.0 0.0");
+  this->readVertexNormal ("0.0 -1.0 0.0");
+  this->readVertexNormal ("0.0 -1.0 0.0");
+  this->readVertexNormal ("0.0 -1.0 0.0");
+  this->readVertexNormal ("1.0 0.0 0.0");
+  this->readVertexNormal ("1.0 0.0 0.0");
+  this->readVertexNormal ("1.0 0.0 0.0");
+  this->readVertexNormal ("1.0 0.0 0.0");
+  this->readVertexNormal ("-1.0 0.0 0.0");
+  this->readVertexNormal ("-1.0 0.0 0.0");
+  this->readVertexNormal ("-1.0 0.0 0.0");
+  this->readVertexNormal ("-1.0 0.0 0.0");
+
+  /* normaleLess-testingMode
+  this->readFace ("1 2 4 3");
+  this->readFace ("3 4 6 5");
+  this->readFace ("5 6 8 7");
+  this->readFace ("7 8 2 1");
+  this->readFace ("2 8 6 4");
+  this->readFace ("7 1 3 5");
+  */
+
+  this->readFace ("1/1/1 2/2/2 4/4/3 3/3/4");
+  this->readFace ("3/3/5 4/4/6 6/6/7 5/5/8");
+  this->readFace ("5/5/9 6/6/10 8/8/11 7/7/12");
+  this->readFace ("7/7/13 8/8/14 2/10/15 1/9/16");
+  this->readFace ("2/2/17 8/11/18 6/12/19 4/4/20");
+  this->readFace ("7/13/21 1/1/22 3/3/23 5/14/24");
+
+}
Index: orxonox/trunk/src/importer/model.h
===================================================================
--- orxonox/trunk/src/importer/model.h	(revision 3365)
+++ orxonox/trunk/src/importer/model.h	(revision 3365)
@@ -0,0 +1,122 @@
+/*!
+  \file model.h
+  \brief Contains the Model Class that handles 3D-Models
+*/
+
+#ifndef _MODEL_H
+#define _MODEL_H
+
+#include "../stdincl.h"
+
+#include "array.h"
+#include "material.h"
+#include "vector.h"
+#include <fstream>
+
+using namespace std;
+
+
+
+//! Class that handles 3D-Models. it can also read them in and display them.
+class Model
+{
+ public:
+  Model ();
+  Model (char* fileName);
+  Model(char* fileName, float scaling);
+  ~Model ();
+  
+  void draw (void) const;
+  void draw (int groupNumber) const;
+  void draw (char* groupName) const;
+  int getGroupCount() const;
+
+ private:
+  //! This is the placeholder of one Vertex beloning to a Face.
+  struct FaceElement 
+  {
+    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.
+    FaceElement* next;   //!< Point to the next FaceElement in this List.
+  };
+
+  //! This is the placeholder of a Face belonging to a Group of Faces.
+  /**
+     \todo take Material to a call for itself.
+
+     This can also be a Material-Change switch. 
+     That means if you want to change a Material inside of a group,
+     you can create an empty face and apply a material to it, and the Importer will cahnge Colors
+  */
+  struct Face 
+  {
+    int vertexCount;        //!< The Count of vertices this Face has.
+    FaceElement* firstElem; //!< Points to the first Vertex (FaceElement) of this Face.
+
+    char* materialString;   //!< The Name of the Material to which to Change.
+
+    Face* next;             //!< Pointer to the next Face.
+  }; 
+
+  //! Group to handle multiple Models per obj-file.
+  struct Group
+  {
+    char* name;         //!< the Name of the Group. this is an identifier, that can be accessed via the draw (char* name) function.
+
+    GLuint listNumber;  //!< The number of the GL-List this Group gets.
+    Face* firstFace;    //!< The first Face in this group.
+    Face* 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.
+
+    Group* next;        //!< Pointer to the next Group.
+  };
+
+
+  Array* vertices;      //!< The Array that handles the Vertices.
+  int verticesCount;    //!< A global Counter for vertices.
+  Array* normals;       //!< The Array that handles the Normals.
+  Array* vTexture;      //!< The Array that handles the VertexTextureCoordinates.
+
+  
+  Group* firstGroup;    //!< The first of all groups.
+  Group* currentGroup;  //!< The currentGroup. this is the one we will work with.
+  int groupCount;       //!< The Count of Groups.
+
+  Material* material;   //!< Initial pointer to the Material. This can hold many materials, because Material can be added with Material::addMaterial(..)
+  float scaleFactor;    //!< The Factor with which the Model should be scaled. \todo maybe one wants to scale the Model after Initialisation
+
+  char* objPath;        //!< The Path wher the obj and mtl-file are located.
+  char* objFileName;    //!< The Name of the obj-file.
+  char* mtlFileName;    //!< The Name of the mtl-file (parsed out of the obj-file)
+
+  bool initialize (void);
+  bool initGroup(Group* group);
+  bool initFace (Face* face);
+  bool cleanup(void);
+  bool cleanupGroup(Group* group);
+  bool cleanupFace(Face* face);
+  bool cleanupFaceElement(FaceElement* faceElem);
+
+  ///// readin ///
+  bool importFile (char* fileName);
+  bool readFromObjFile (void);
+  
+  bool readGroup (char* groupString);
+  bool readVertex (char* vertexString);
+  bool readFace (char* faceString);
+  bool readVertexNormal (char* normalString);
+  bool readVertexTexture (char* vTextureString);
+  bool readMtlLib (char* matFile);
+  bool readUseMtl (char* mtlString);
+
+  bool importToGL (void);
+  bool addGLElement (FaceElement* elem);
+
+  bool buildVertexNormals ();
+
+  void BoxModel (void);
+};
+
+#endif
Index: orxonox/trunk/src/importer/object.cc
===================================================================
--- orxonox/trunk/src/importer/object.cc	(revision 3364)
+++ 	(revision )
@@ -1,977 +1,0 @@
-/* 
-   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: ...
-*/
-
-#include "object.h"
-int verbose = 1; //! \todo should be GLOBAL
-using namespace std;
-
-/**
-   \brief Creates a 3D-Object, but does not load any 3D-models.
-
-   This Constructor is pretty useless, because why load no object in an object-loader??
-*/
-Object::Object ()
-{
-
-  this->initialize();
-
-  this->BoxObject();
-
-  this->importToGL ();
-
-  this->cleanup();
-}
-
-/**
-   \brief Crates a 3D-Object and loads in a File.
-   \param fileName file to parse and load (must be a .obj file)
-*/
-Object::Object(char* fileName)
-{
-  this->initialize();
-
-  this->importFile (fileName);
-
-  this->importToGL ();
-
-  this->cleanup();
-}
-
-/**
-   \brief Crates a 3D-Object, loads in a File and scales it.
-   \param fileName file to parse and load (must be a .obj file)
-   \param scaling The factor that the object will be scaled with.
-*/
-Object::Object(char* fileName, float scaling)
-{
-  this->initialize();
-  this->scaleFactor = scaling;
-
-  this->importFile (fileName);
-
-  this->importToGL ();
-
-  this->cleanup();
-}
-
-/**
-   \brief deletes an Object.
-
-   Looks if any from object allocated space is still in use, and if so deleted it.
-*/
-Object::~Object()
-{
-  PRINTF(2)("Deleting display Lists.\n");
-  Group* walker = this->firstGroup;
-  while (walker != NULL)
-    {
-      glDeleteLists (walker->listNumber, 1);
-      Group* delWalker = walker;
-      walker = walker->next;
-      delete delWalker;
-    }
-
-  if (this->objPath)
-    delete []this->objPath;
-  if (this->objFileName)
-    delete []this->objFileName;
-  if (this->mtlFileName)
-    delete []this->mtlFileName;
-  PRINTF(2)("Deleting Materials.\n");
-  if (this->material)
-    delete this->material;
-}
-
-
-/**
-   \brief Draws the Objects of all Groups.
-   It does this by just calling the Lists that must have been created earlier.
-*/
-void Object::draw (void) const
-{
-  PRINTF(2)("drawing the 3D-Objects\n"); 
-  Group* walker = this->firstGroup;
-  while (walker != NULL)
-    {
-      PRINTF(3)("Drawing object %s\n", walker->name);
-      glCallList (walker->listNumber);
-      walker = walker->next;
-    }
-}
-
-/**
-   \brief Draws the Object 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 Object::draw (int groupNumber) const 
-{
-  if (groupNumber >= this->groupCount)
-    {
-      PRINTF(1)("You requested object number %i, but this File only contains of %i Objects.\n", groupNumber-1, this->groupCount);
-      return;
-    }
-  PRINTF(2)("drawing the requested 3D-Objects if found.\n"); 
-  Group* walker = this->firstGroup;
-  int counter = 0;
-  while (walker != NULL)
-    {
-      if (counter == groupNumber)
-	{
-	  PRINTF(2)("Drawing object number %i named %s\n", counter, walker->name);
-	  glCallList (walker->listNumber);
-	  return;
-	}
-      ++counter;
-      walker = walker->next;
-    }
-  PRINTF(1)("Object number %i in %s not Found.\n", groupNumber, this->objFileName);
-  return;
-
-}
-
-/**
-   \brief Draws the Object 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 Object::draw (char* groupName) const
-{
-  PRINTF(2)("drawing the requested 3D-Objects if found.\n"); 
-  Group* walker = this->firstGroup;
-  while (walker != NULL)
-    {
-      if (!strcmp(walker->name, groupName))
-	{
-	  PRINTF(2)("Drawing object %s\n", walker->name);
-	  glCallList (walker->listNumber);
-	  return;
-	}
-      walker = walker->next;
-    }
-  PRINTF(1)("Object Named %s in %s not Found.\n", groupName, this->objFileName);
-  return;
-}
-
-/**
-   \returns Count of the Objects in this File
-*/
-int Object::getGroupCount (void) const
-{
-  return this->groupCount;
-}
-
-/**
-    \brief initializes the Object.
-
-    This Function initializes all the needed arrays, Lists and clientStates.
-    It also defines default values.
-*/
-bool Object::initialize (void)
-{
-  PRINTF(2)("new 3D-Object is being created\n"); 
-
-  // setting the start group;
-  this->firstGroup = new Group;
-  this->currentGroup = this->firstGroup;
-  this->groupCount = 0;
-  
-  this->initGroup (this->currentGroup);
-  this->objPath = NULL;
-  this->objFileName = NULL;
-  this->mtlFileName = NULL;
-  this->scaleFactor = 1;
-  this->material = new Material();
-
-  this->vertices = new Array();
-  this->vTexture = new Array();
-  this->normals = new Array();
-
-  return true;
-}
-
-/**
-   \brief initializes a new Group object
-   \param group the group that should be initialized.
-   \todo Maybe Group should be a Class, because it does a lot of stuff
-   
-*/
-bool Object::initGroup(Group* group)
-{
-  PRINTF(3)("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 Object::initFace (Face* face)
-{
-  face->vertexCount = 0;
-
-  face->firstElem = NULL;
-  
-  face->materialString = NULL;
-  
-  face->next = NULL;
-
-  return true;
-}
-
-/**
-   \brief finalizes an Object.
-   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 Object::cleanup(void)
-{
-  PRINTF(3)("cleaning up the 3D-Object to save Memory.\n");
-
-  if (this->vertices)
-    delete this->vertices;
-  if (this->vTexture)
-    delete this->vTexture;
-  if (this->normals)
-    delete this->normals;
-
-  this->cleanupGroup(this->firstGroup);
-  return true; 
-}
-
-/**
-   \brief Cleans up all groups starting from group.
-   \param group the first Group to clean
-*/
-bool Object::cleanupGroup (Group* group)
-{
-  PRINTF(3)("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 Object::cleanupFace (Face* face)
-{
-  PRINTF(3)("Cleaning up Face\n");
-
-  if (face->materialString != NULL)
-      delete []face->materialString;
-  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 Object::cleanupFaceElement(FaceElement* faceElem)
-{
-  if (faceElem->next != NULL)
-    {
-      this->cleanupFaceElement (faceElem->next);
-      delete faceElem->next;
-    }
-}
-
-/**
-   \brief Imports a obj file and handles the the relative location
-   \param fileName The file to import
-*/
-bool Object::importFile (char* fileName)
-{
-  PRINTF(3)("preparing to read in file: %s\n", fileName);
-
-
-#ifdef __WIN32__
-  // win32 path reading
-  char pathSplitter= '\\';
-#else /* __WIN32__ */
-  // unix path reading
-  char pathSplitter='/';
-#endif /* __WIN32__ */
-  char* tmpName = fileName;
-  if (tmpName[0] == pathSplitter)
-    tmpName++;
-  char* name = tmpName;
-  while (( tmpName = strchr (tmpName+1, pathSplitter)))
-    {
-      name = tmpName+1;
-    }
-  this->objPath = new char[name-fileName];
-  strncpy(this->objPath, fileName, name-fileName);
-  this->objPath[name-fileName] = '\0';
-  if (verbose >=2)
-    if (strlen(objPath)> 0)
-      PRINTF(0)("Resolved file %s to folder: %s.\n", name, objPath);
-    else
-      PRINTF(0)("Resolved file %s.\n", name);
-  
-  if (this->material)
-    this->material->addTexturePath(this->objPath);
-  this->objFileName = new char[strlen(name)+1];
-  strcpy (this->objFileName, name);
-  this->readFromObjFile ();
-  return true;
-}
-
-/**
-   \brief Reads in the .obj File and sets all the Values.
-   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
-*/
-bool Object::readFromObjFile (void)
-{
-  char* fileName = new char [strlen(objPath)+strlen(objFileName)+1];
-  if (this->objFileName != NULL && !strcmp(this->objFileName, ""))
-    return false;
-  strcpy(fileName, this->objPath);
-  strcat(fileName, this->objFileName);
-
-  ifstream* OBJ_FILE = new ifstream(fileName);
-  if (OBJ_FILE->fail())
-    {
-      PRINTF(1)("unable to open .OBJ file: %s\n Loading Box Object instead.\n", fileName);
-      BoxObject();
-      OBJ_FILE->close();
-      delete []fileName;
-      delete OBJ_FILE;
-      return false;
-    }
-  PRINTF(2)("Reading from opened file %s\n", fileName);
-  char Buffer[10000];
-  while(!OBJ_FILE->eof())
-    {
-      OBJ_FILE->getline(Buffer, 10000);
-      PRINTF(3)("Read input line: %s\n", Buffer);
-      
-
-      // case vertice
-      if (!strncmp(Buffer, "v ", 2))
-	{
-	  this->readVertex(Buffer+2);
-	}
-
-      // case face
-      else if (!strncmp(Buffer, "f ", 2))
-	{
-	  this->readFace (Buffer+2);
-	}
-      
-      else if (!strncmp(Buffer, "mtllib ", 7))
-	{
-	  this->readMtlLib (Buffer+7);
-	}
-
-      else if (!strncmp(Buffer, "usemtl ", 7))
-	{
-	  this->readUseMtl (Buffer+7);
-	}
-
-      // case VertexNormal
-      else if (!strncmp(Buffer, "vn ", 3))
-	{
-	  this->readVertexNormal(Buffer+3);
-	}
-      
-      // case VertexTextureCoordinate
-      else if (!strncmp(Buffer, "vt ", 3))
-	{
-	  this->readVertexTexture(Buffer+3);
-	}
-      // case group
-      else if (!strncmp(Buffer, "g ", 2))
-	{
-	  this->readGroup (Buffer+2);
-	}
-      else if (!strncmp(Buffer, "s ", 2)) //! \todo smoothing groups have to be implemented
-	{
-	  if (verbose >= 2)
-	    PRINTF(2)("smoothing groups not supportet yet. line: %s\n", Buffer);
-	}
-    }
-  OBJ_FILE->close();
-  delete OBJ_FILE;
-  delete []fileName;
-  return true;
-
-}
-
-/**
-   \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 import .obj-files with more than one Objects inside. 
-*/
-bool Object::readGroup (char* groupString)
-{
-  PRINTF(3)("Read Group: %s.\n", groupString);
-  if (this->groupCount != 0 && this->currentGroup->faceCount>0)
-    {
-      //      finalizeGroup(currentGroup);
-      this->currentGroup = this->currentGroup->next = new Group;
-      this->initGroup(this->currentGroup);
-    }
-  // 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;
-
-}
-
-/**
-   \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 Object::readVertex (char* vertexString)
-{
-  float subbuffer1;
-  float subbuffer2;
-  float subbuffer3;
-  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
-  PRINTF(3)("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
-  this->vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
-  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.
-   The function makes a difference between QUADS and TRIANGLES, and will if changed re-open, set and re-close the gl-processe.
-*/
-bool Object::readFace (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;
-  tmpElem->next = NULL;
-  while(strcmp (faceString, "\0"))
-    {
-      if (this->currentGroup->currentFace->vertexCount>0)
-	  tmpElem = tmpElem->next = new FaceElement;
-      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;
-      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;
-      if (strcmp (faceString, "\0"))
-	faceString++;
-      this->currentGroup->currentFace->vertexCount++;
-    }
-
-  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
-}
-
-/**
-   \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 Object::readVertexNormal (char* normalString)
-{
-  float subbuffer1;
-  float subbuffer2;
-  float subbuffer3;
-  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
-  PRINTF(3)("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
-  this->normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
-  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
-*/
-bool Object::readVertexTexture (char* vTextureString)
-{
-  float subbuffer1;
-  float subbuffer2;
-  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
-  PRINTF(3)("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
-  this->vTexture->addEntry(subbuffer1);
-  this->vTexture->addEntry(subbuffer2);
-  return true;
-}
-
-/** 
-    \brief Function to read in a mtl File.
-    \param mtlFile The .mtl file to read
-
-    This Function parses all Lines of an mtl File.
-    The reason for it not to be in the materials-class is,
-    that a material does not have to be able to read itself in from a File.
-
-*/
-bool Object::readMtlLib (char* mtlFile)
-{
-  this->mtlFileName = new char [strlen(mtlFile)+1];
-  strcpy(this->mtlFileName, mtlFile);
-  char* fileName = new char [strlen(objPath) + strlen(this->mtlFileName)+1];
-  strcpy(fileName, this->objPath);
-  strcat(fileName, this->mtlFileName);
-  
-
-  PRINTF(2)("Opening mtlFile: %s\n", fileName);
-
-  ifstream* MTL_FILE = new ifstream (fileName);
-  if (MTL_FILE->fail())
-    {
-      if (verbose >= 1)
-	PRINTF(2)("unable to open file: %s\n", fileName);
-      MTL_FILE->close();
-      delete []fileName;
-      delete MTL_FILE;
-      return false;
-    }
-  char Buffer[500];
-  Material* tmpMat = material;
-  while(!MTL_FILE->eof())
-    {
-      MTL_FILE->getline(Buffer, 500);
-      PRINTF(4)("found line in mtlFile: %s\n", Buffer);
-      
-
-      // create new Material
-      if (!strncmp(Buffer, "newmtl ", 7))
-	{
-	  tmpMat = tmpMat->addMaterial(Buffer+7);
-	  //	  PRINTF(2)("%s, %p\n", tmpMat->getName(), tmpMat);
-	}
-      // setting a illumMode
-      else if (!strncmp(Buffer, "illum ", 6))
-	{
-	  tmpMat->setIllum(Buffer+6);
-
-	}
-      // setting Diffuse Color
-      else if (!strncmp(Buffer, "Kd ", 3))
-	{
-	  tmpMat->setDiffuse(Buffer+3);
-	}
-      // setting Ambient Color
-      else if (!strncmp(Buffer, "Ka ", 3))
-	{
-	  tmpMat->setAmbient(Buffer+3);
-	}
-      // setting Specular Color
-      else if (!strncmp(Buffer, "Ks ", 3))
-	{
-	  tmpMat->setSpecular(Buffer+3);
-	}
-      // setting The Specular Shininess
-      else if (!strncmp(Buffer, "Ns ", 3))
-	{
-	  tmpMat->setShininess(Buffer+3);
-	}
-      // setting up transparency
-      else if (!strncmp(Buffer, "d ", 2))
-	{
-	  tmpMat->setTransparency(Buffer+2);
-	}
-      else if (!strncmp(Buffer, "Tf ", 3))
-	{
-	  tmpMat->setTransparency(Buffer+3);
-	}
-      
-      else if (!strncmp(Buffer, "map_Kd ", 7))
-	{
-	  tmpMat->setDiffuseMap(Buffer+7);
-	}
-      else if (!strncmp(Buffer, "map_Ka ", 7))
-	{
-	  tmpMat->setAmbientMap(Buffer+7);
-	}
-      else if (!strncmp(Buffer, "map_Ks ", 7))
-	{
-	  tmpMat->setSpecularMap(Buffer+7);
-	}
-      else if (!strncmp(Buffer, "bump ", 5))
-	{
-	  tmpMat->setBump(Buffer+7);
-	}
-     
-
-    }
-  MTL_FILE->close();
-  delete []fileName;
-  delete MTL_FILE;
-  return true;
-}
-
-/**
-   \brief Function that selects a material, if changed in the obj file.
-   \param matString the Material that will be set.
-*/
-bool Object::readUseMtl (char* matString)
-{
-  if (!this->mtlFileName)
-    {
-      PRINTF(4)("Not using new defined material, because no mtlFile found yet\n");
-      return false;
-    }
-      
-  if (this->currentGroup->faceCount >0)
-    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new Face;
-  this->initFace (this->currentGroup->currentFace);
-  
-  this->currentGroup->currentFace->materialString = new char[strlen(matString)+1];
-  strcpy (this->currentGroup->currentFace->materialString, matString);
-  
-  if (this->currentGroup->faceCount == 0)
-    this->currentGroup->faceCount ++;
-
-}
-
-/**
-   \brief reads and includes the Faces/Materials into the openGL state Machine
-*/
-bool Object::importToGL (void)
-{
-
-  // finalize the Arrays
-  this->vertices->finalizeArray();
-  this->vTexture->finalizeArray();
-  if (normals->getCount() == 0) // vertices-Array must be uilt 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(1)("list could not be created for this Object\n");
-	  return false;
-	}
-      glNewList (this->currentGroup->listNumber, GL_COMPILE);
-
-      // Putting Faces to GL
-      Face* tmpFace = this->currentGroup->firstFace;
-      while (tmpFace != NULL)
-	{
-	  if (tmpFace->vertexCount == 0 && tmpFace->materialString != NULL)
-	    {
-	      if (this->currentGroup->faceMode != -1)
-		glEnd();
-	      this->currentGroup->faceMode = 0;
-	      PRINTF(2)("using material %s for coming Faces.\n", tmpFace->materialString);
-	      Material* tmpMat;
-	      if ((tmpMat = material->search(tmpFace->materialString)) != NULL)
-		tmpMat->select();
-
-	    }
-
-	  else if (tmpFace->vertexCount == 3)
-	    {
-	      if (this->currentGroup->faceMode != 3)
-		{
-		  if (this->currentGroup->faceMode != -1)
-		    glEnd();
-		  glBegin(GL_TRIANGLES);
-		}
-	      
-	      this->currentGroup->faceMode = 3;
-	      PRINTF(3)("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(3)("found quad.\n");
-	    }
-	  
-	  else if (tmpFace->vertexCount > 4)
-	    {
-	      if (this->currentGroup->faceMode != -1)
-		glEnd();
-	      glBegin(GL_POLYGON);
-	      PRINTF(3)("Polygon with %i faces found.", tmpFace->vertexCount);
-	      this->currentGroup->faceMode = tmpFace->vertexCount;
-	    }
-	  
-	  FaceElement* 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;
-    } 
-}
-
-/**
-   \brief 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 Object::addGLElement (FaceElement* elem)
-{
-  PRINTF(3)("importing grafical Element to openGL.\n");
-
-  if (elem->texCoordNumber != -1)
-    glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
-  if (elem->normalNumber != -1)
-    glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
-  if (elem->vertexNumber != -1)
-    glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
-
-}
-
-/**
-   \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 Object::buildVertexNormals ()
-{
-  
-  PRINTF(2)("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;
-
-  Group* tmpGroup = firstGroup;
-  while (tmpGroup)
-    {
-      Face* tmpFace = tmpGroup->firstFace;
-      while (tmpFace)
-	{
-	  if (tmpFace->firstElem)
-	    {
-	      FaceElement* firstElem = tmpFace->firstElem;
-	      FaceElement* prevElem;
-	      FaceElement* curElem = firstElem;
-	      FaceElement* nextElem;
-	      FaceElement* 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(3)("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);
-
-    }
-  delete []normArray; 
-  
-}
-
-
-/**
-   \brief Includes a default object
-
-   This will inject a Cube, because this is the most basic object.
-*/
-void Object::BoxObject(void)
-{
-  this->readVertex ("-0.5 -0.5 0.5");
-  this->readVertex ("0.5 -0.5 0.5");
-  this->readVertex ("-0.5 0.5 0.5");
-  this->readVertex ("0.5 0.5 0.5");
-  this->readVertex ("-0.5 0.5 -0.5");
-  this->readVertex ("0.5 0.5 -0.5");
-  this->readVertex ("-0.5 -0.5 -0.5");
-  this->readVertex ("0.5 -0.5 -0.5");
-
-  this->readVertexTexture ("0.0 0.0");
-  this->readVertexTexture ("1.0 0.0");
-  this->readVertexTexture ("0.0 1.0");
-  this->readVertexTexture ("1.0 1.0");
-  this->readVertexTexture ("0.0 2.0");
-  this->readVertexTexture ("1.0 2.0");
-  this->readVertexTexture ("0.0 3.0");
-  this->readVertexTexture ("1.0 3.0");
-  this->readVertexTexture ("0.0 4.0");
-  this->readVertexTexture ("1.0 4.0");
-  this->readVertexTexture ("2.0 0.0");
-  this->readVertexTexture ("2.0 1.0");
-  this->readVertexTexture ("-1.0 0.0");
-  this->readVertexTexture ("-1.0 1.0");
-
-  this->readVertexNormal ("0.0 0.0 1.0");
-  this->readVertexNormal ("0.0 0.0 1.0");
-  this->readVertexNormal ("0.0 0.0 1.0");
-  this->readVertexNormal ("0.0 0.0 1.0");
-  this->readVertexNormal ("0.0 1.0 0.0");
-  this->readVertexNormal ("0.0 1.0 0.0");
-  this->readVertexNormal ("0.0 1.0 0.0");
-  this->readVertexNormal ("0.0 1.0 0.0");
-  this->readVertexNormal ("0.0 0.0 -1.0");
-  this->readVertexNormal ("0.0 0.0 -1.0");
-  this->readVertexNormal ("0.0 0.0 -1.0");
-  this->readVertexNormal ("0.0 0.0 -1.0");
-  this->readVertexNormal ("0.0 -1.0 0.0");
-  this->readVertexNormal ("0.0 -1.0 0.0");
-  this->readVertexNormal ("0.0 -1.0 0.0");
-  this->readVertexNormal ("0.0 -1.0 0.0");
-  this->readVertexNormal ("1.0 0.0 0.0");
-  this->readVertexNormal ("1.0 0.0 0.0");
-  this->readVertexNormal ("1.0 0.0 0.0");
-  this->readVertexNormal ("1.0 0.0 0.0");
-  this->readVertexNormal ("-1.0 0.0 0.0");
-  this->readVertexNormal ("-1.0 0.0 0.0");
-  this->readVertexNormal ("-1.0 0.0 0.0");
-  this->readVertexNormal ("-1.0 0.0 0.0");
-
-  /* normaleLess-testingMode
-  this->readFace ("1 2 4 3");
-  this->readFace ("3 4 6 5");
-  this->readFace ("5 6 8 7");
-  this->readFace ("7 8 2 1");
-  this->readFace ("2 8 6 4");
-  this->readFace ("7 1 3 5");
-  */
-
-  this->readFace ("1/1/1 2/2/2 4/4/3 3/3/4");
-  this->readFace ("3/3/5 4/4/6 6/6/7 5/5/8");
-  this->readFace ("5/5/9 6/6/10 8/8/11 7/7/12");
-  this->readFace ("7/7/13 8/8/14 2/10/15 1/9/16");
-  this->readFace ("2/2/17 8/11/18 6/12/19 4/4/20");
-  this->readFace ("7/13/21 1/1/22 3/3/23 5/14/24");
-
-}
Index: orxonox/trunk/src/importer/object.h
===================================================================
--- orxonox/trunk/src/importer/object.h	(revision 3364)
+++ 	(revision )
@@ -1,122 +1,0 @@
-/*!
-  \file object.h
-  \brief Contains the Object Class that handles 3D-Objects
-*/
-
-#ifndef _OBJECT_H
-#define _OBJECT_H
-
-#include "../stdincl.h"
-
-#include "array.h"
-#include "material.h"
-#include "vector.h"
-#include <fstream>
-
-using namespace std;
-
-
-
-//! Class that handles 3D-Objects. it can also read them in and display them.
-class Object
-{
- public:
-  Object ();
-  Object (char* fileName);
-  Object(char* fileName, float scaling);
-  ~Object ();
-  
-  void draw (void) const;
-  void draw (int groupNumber) const;
-  void draw (char* groupName) const;
-  int getGroupCount() const;
-
- private:
-  //! This is the placeholder of one Vertex beloning to a Face.
-  struct FaceElement 
-  {
-    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.
-    FaceElement* next;   //!< Point to the next FaceElement in this List.
-  };
-
-  //! This is the placeholder of a Face belonging to a Group of Faces.
-  /**
-     \todo take Material to a call for itself.
-
-     This can also be a Material-Change switch. 
-     That means if you want to change a Material inside of a group,
-     you can create an empty face and apply a material to it, and the Importer will cahnge Colors
-  */
-  struct Face 
-  {
-    int vertexCount;        //!< The Count of vertices this Face has.
-    FaceElement* firstElem; //!< Points to the first Vertex (FaceElement) of this Face.
-
-    char* materialString;   //!< The Name of the Material to which to Change.
-
-    Face* next;             //!< Pointer to the next Face.
-  }; 
-
-  //! Group to handle multiple Objects per obj-file.
-  struct Group
-  {
-    char* name;         //!< the Name of the Group. this is an identifier, that can be accessed via the draw (char* name) function.
-
-    GLuint listNumber;  //!< The number of the GL-List this Group gets.
-    Face* firstFace;    //!< The first Face in this group.
-    Face* 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.
-
-    Group* next;        //!< Pointer to the next Group.
-  };
-
-
-  Array* vertices;      //!< The Array that handles the Vertices.
-  int verticesCount;    //!< A global Counter for vertices.
-  Array* normals;       //!< The Array that handles the Normals.
-  Array* vTexture;      //!< The Array that handles the VertexTextureCoordinates.
-
-  
-  Group* firstGroup;    //!< The first of all groups.
-  Group* currentGroup;  //!< The currentGroup. this is the one we will work with.
-  int groupCount;       //!< The Count of Groups.
-
-  Material* material;   //!< Initial pointer to the Material. This can hold many materials, because Material can be added with Material::addMaterial(..)
-  float scaleFactor;    //!< The Factor with which the Object hould be scaled. \todo maybe one wants to scale the Object after Initialisation
-
-  char* objPath;        //!< The Path wher the obj and mtl-file are located.
-  char* objFileName;    //!< The Name of the obj-file.
-  char* mtlFileName;    //!< The Name of the mtl-file (parsed out of the obj-file)
-
-  bool initialize (void);
-  bool initGroup(Group* group);
-  bool initFace (Face* face);
-  bool cleanup(void);
-  bool cleanupGroup(Group* group);
-  bool cleanupFace(Face* face);
-  bool cleanupFaceElement(FaceElement* faceElem);
-
-  ///// readin ///
-  bool importFile (char* fileName);
-  bool readFromObjFile (void);
-  
-  bool readGroup (char* groupString);
-  bool readVertex (char* vertexString);
-  bool readFace (char* faceString);
-  bool readVertexNormal (char* normalString);
-  bool readVertexTexture (char* vTextureString);
-  bool readMtlLib (char* matFile);
-  bool readUseMtl (char* mtlString);
-
-  bool importToGL (void);
-  bool addGLElement (FaceElement* elem);
-
-  bool buildVertexNormals ();
-
-  void BoxObject (void);
-};
-
-#endif
Index: orxonox/trunk/src/importer/texture.cc
===================================================================
--- orxonox/trunk/src/importer/texture.cc	(revision 3365)
+++ orxonox/trunk/src/importer/texture.cc	(revision 3365)
@@ -0,0 +1,956 @@
+/* 
+   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: ...
+
+   TGA-code: borrowed from nehe-Tutorials
+
+*/
+
+
+#include "texture.h"
+
+// headers only for PathList
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <fstream>
+
+/**
+   \brief creates a ned PathList.
+   
+   It is a good idea to use this as an initial List,
+   because if you give on a name the Path will not be checked for its existence.
+*/
+PathList::PathList()
+{
+  this->pathName = NULL;
+  this->next = NULL;
+}
+
+/**
+   \brief Creates a new PathList with a Name.
+   \param pName the Name of The Path.
+
+   This function just adds the Path without checking if it exists.
+*/
+PathList::PathList(char* pName)
+{
+  this->pathName = new char [strlen(pName)+1];
+  strcpy (this->pathName, pName);
+  this->next = NULL;
+}
+
+/**
+   \brief destroys a PathList
+
+   It does this by deleting the Name and then delete its preceding PathList.
+*/
+PathList::~PathList()
+{
+  if (this->pathName)
+    delete []this->pathName;
+  if (this->next)
+    delete this->next;
+}
+
+PathList* PathList::firstPath = NULL;
+
+/**
+   \returns A Pointer to the first Path of the Pathlist
+*/
+PathList* PathList::getInstance(void)
+{
+  if (firstPath)
+    return firstPath;
+  firstPath = new PathList();
+}
+/**
+   \brief Adds a new Pathlist Element.
+   \param pName
+   
+   Adding a Path automatically checks if the Path exists,
+   and if it does not it will not add it to the List.
+*/
+void PathList::addPath (char* pName)
+{
+  if (pName[0] == '\0')
+    {
+      PRINTF(3)("not Adding empty Path to the List.\n");
+      return;
+    }
+  char* tmpPName = new char[strlen(pName)];
+  strncpy(tmpPName, pName, strlen(pName)-1);
+  tmpPName[strlen(pName)-1] = '\0';
+  if (access (tmpPName, F_OK) == 0)
+    {
+      struct stat status;
+      stat(tmpPName, &status);
+      if (status.st_mode & S_IFDIR)
+	{
+	  PRINTF(2)("Adding Path %s to the PathList.\n", pName);
+	  PathList* tmpPathList = this;
+	  while (tmpPathList->next)
+	    tmpPathList = tmpPathList->next;
+	  tmpPathList->next = new PathList(pName);
+	}
+      else
+	PRINTF(2)("You tried to add non-folder %s to a PathList.\n", tmpPName);
+    }
+  else
+      PRINTF(2)("You tried to add non-existing folder %s to a PathList.\n", tmpPName);
+  delete []tmpPName;
+}
+
+
+
+/**
+   \brief Constructor for a Texture
+*/
+Texture::Texture(void)
+{
+  this->pImage = new Image;
+  this->pImage->data = NULL;
+  this->map = NULL;
+  this->texture = 0;
+}
+
+/**
+   \brief Destructor of a Texture
+   
+   Frees Data, and deletes the textures from GL
+*/
+Texture::~Texture(void)
+{
+  if (this->pImage->data)
+    delete []this->pImage->data;
+  delete pImage;
+  if (this->texture)
+    glDeleteTextures(1, &this->texture);
+}
+
+/**
+   \brief Searches for a Texture inside one of the defined Paths
+   \param texName The name of the texture o search for.
+   \returns pathName+texName if texName was found in the pathList. NULL if the Texture is not found.
+*/
+char* Texture::searchTextureInPaths(char* texName) const
+{
+  char* tmpName = NULL;
+  PathList* pList = PathList::getInstance();
+  while (pList)
+    {
+      if (pList->pathName)
+	{
+	  tmpName = new char [strlen(pList->pathName)+strlen(texName)+1];
+	  strcpy(tmpName, pList->pathName);
+	}
+      else
+	{
+	  tmpName = new char [strlen(texName)+1];
+	  tmpName[0]='\0';
+	}
+      strcat(tmpName, texName);
+      if (access (tmpName, F_OK) == 0)
+	return tmpName;
+      
+      if (tmpName)
+	delete []tmpName;
+      tmpName = NULL;
+      pList = pList->next;
+    }
+  return NULL;
+}
+
+/**
+   \brief a Simple function that switches two char values
+   \param a The first value
+   \param b The second value
+*/
+inline void Texture::swap (unsigned char &a, unsigned char &b)
+{
+  unsigned char temp;
+  temp = a;
+  a    = b;
+  b    = temp;
+}
+
+
+/**
+   \brief Loads a Texture to the openGL-environment.
+   \param pImage The Image to load to openGL
+   \param texture The Texture to apply it to.
+*/
+bool Texture::loadTexToGL (Image* pImage)
+{
+  PRINTF(2)("Loading texture to OpenGL-Environment.\n");
+  glGenTextures(1, &this->texture);
+  glBindTexture(GL_TEXTURE_2D, this->texture);
+  /* not Working, and not needed. 
+  glTexImage2D( GL_TEXTURE_2D, 0, 3, width,
+		height, 0, GL_BGR,
+		GL_UNSIGNED_BYTE, map->pixels );
+  */ 
+  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->width, pImage->height, pImage->format, GL_UNSIGNED_BYTE, pImage->data);
+  
+  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);	
+}
+
+
+#ifdef HAVE_SDL_SDL_IMAGE_H
+bool Texture::loadImage(char* imageName)
+{
+  char* imgNameWithPath = searchTextureInPaths(imageName);
+  if (imgNameWithPath)
+    {
+      this->map=IMG_Load(imgNameWithPath);
+      if(!map)
+	{
+	  PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
+	  return false;
+	}
+      pImage->height = map->h;
+      pImage->width  = map->w;
+      pImage->data   = (GLubyte*)map->pixels;
+      pImage->bpp    = map->format->BytesPerPixel;
+      if (pImage->bpp == 3)
+	pImage->format = GL_RGB;
+      else if (pImage->bpp == 4)
+	pImage->format = GL_RGBA;
+	  
+      PRINTF(0)("Bits Per Pixel: %d\n", pImage->bpp);
+      if( !IMG_isPNG(SDL_RWFromFile(imgNameWithPath, "rb")) && !IMG_isJPG(SDL_RWFromFile(imgNameWithPath, "rb")))
+	for (int i=0;i<map->h * map->w *3;i+=3)
+	  { 
+	    GLuint temp = pImage->data[i];
+	    pImage->data[i] = pImage->data[i+2];
+	    pImage->data[i+2] = temp;
+	  }
+      /* this is the real swapping algorithm */
+      for( int i = 0 ; i < (pImage->height / 2) ; ++i )
+	for( int j = 0 ; j < pImage->width * pImage->bpp; j += pImage->bpp )
+	  for(int k = 0; k < pImage->bpp; ++k)
+	    swap( pImage->data[ (i * pImage->width * pImage->bpp) + j + k], pImage->data[ ( (pImage->height - i - 1) * pImage->width * pImage->bpp ) + j + k]);
+ 
+      this->loadTexToGL (this->pImage);
+      SDL_FreeSurface(map);
+      this->pImage->data = NULL;
+    }
+  else
+    {
+      PRINTF(1)("Image not Found: %s\n", imgNameWithPath);
+      return false;
+    }
+}
+
+
+#else /* HAVE_SDL_SDL_IMAGE_H */
+/**
+   \brief Makes the Programm ready to Read-in a texture-File
+   1. Checks what type of Image should be imported
+   2. ToDO: Checks where to find the Image
+*/
+bool Texture::loadImage(char* imageName)
+{
+  char* imgNameWithPath = searchTextureInPaths(imageName);
+  if (imgNameWithPath)
+    {
+      if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".bmp", 4))
+	{
+	  PRINTF(3)("Requested bmp-image. Trying to Import.\n");
+	  return this->loadBMP(imgNameWithPath);
+	}
+      
+      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".jpg", 4) || !strncmp(imgNameWithPath+strlen(imgNameWithPath)-5, ".jpg", 5))
+	{
+	  PRINTF(3)("Requested jpeg-image. Trying to Import\n");
+	  return this->loadJPG(imgNameWithPath);
+	}
+      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".tga", 4))
+	{
+	  PRINTF(3)("Requested tga-image. Trying to Import\n");
+	  return this->loadTGA(imgNameWithPath);
+	}
+      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".png", 4))
+	{
+	  PRINTF(3)("Requested png-image. Trying to Import\n");
+	  return this->loadPNG(imgNameWithPath);
+	}
+      else
+	{
+	  PRINTF(1)("Requested Image was not recognized in its type. (Maybe a type-Cast-error.)\n FileName: %s", imgNameWithPath);
+	  return false;
+	}
+    }
+  else
+    {
+      PRINTF(1)("Image not Found: %s\n", imgNameWithPath);
+      return false;
+    }
+}
+
+/**
+   \brief reads in a Windows BMP-file, and imports it to openGL.
+   \param bmpName The name of the Image to load.
+   \param texture A pointer to the Texture which should be read to.
+*/
+bool Texture::loadBMP (char* bmpName)
+{
+  FILE *file;
+  unsigned long size;                 // size of the image in bytes.
+  unsigned long i;                    // standard counter.
+  unsigned short int planes;          // number of planes in image (must be 1) 
+  unsigned short int bpp;             // number of bits per pixel (must be 24)
+  GLuint temp;                          // temporary color storage for bgr-rgb conversion.
+
+  // make sure the file is there.
+  if ((file = fopen(bmpName, "rb"))==NULL)
+    {
+      PRINTF(1)("File Not Found : %s\n",bmpName);
+      return false;
+    }
+  // seek through the bmp header, up to the width/height:
+  fseek(file, 18, SEEK_CUR);
+  
+  // read the width
+  if ((i = fread(&pImage->width, 4, 1, file)) != 1) 
+    {
+      PRINTF(1)("Error reading width from %s.\n", bmpName);
+      return false;
+    }
+  // read the height 
+  if ((i = fread(&pImage->height, 4, 1, file)) != 1) 
+    {
+      PRINTF(1)("Error reading height from %s.\n", bmpName);
+      return false;
+    }
+  
+  // calculate the size (assuming 24 bits or 3 bytes per pixel).
+  size = pImage->width * pImage->height * 3;
+  
+  // read the planes
+  if ((fread(&planes, 2, 1, file)) != 1) 
+    {
+      PRINTF(1)("Error reading planes from %s.\n", bmpName);
+      return false;
+    }
+  if (planes != 1) 
+    {
+      PRINTF(1)("Planes from %s is not 1: %u\n", bmpName, planes);
+      return false;
+    }
+  
+  // read the bpp
+  if ((i = fread(&bpp, 2, 1, file)) != 1) 
+    {
+      PRINTF(1)("Error reading bpp from %s.\n", bmpName);
+      return false;
+    }
+  if (bpp != 24) 
+    {
+      PRINTF(1)("Bpp from %s is not 24: %u\n", bmpName, bpp);
+      return false;
+    }
+  
+  // seek past the rest of the bitmap header.
+  fseek(file, 24, SEEK_CUR);
+  
+  // read the data. 
+  pImage->data = (GLubyte *) malloc(size);
+  if (pImage->data == NULL) 
+    {
+      PRINTF(1)("Error allocating memory for color-corrected image data");
+      return false;	
+    }
+  
+  if ((i = fread(pImage->data, size, 1, file)) != 1) 
+    {
+      PRINTF(1)("Error reading image data from %s.\n", bmpName);
+      return false;
+    }
+  fclose(file);
+
+  // reverse all of the colors. (bgr -> rgb)
+  for (i=0;i<size;i+=3) 
+    { 
+      temp = pImage->data[i];
+      pImage->data[i] = pImage->data[i+2];
+      pImage->data[i+2] = temp;
+    }
+  this->loadTexToGL (pImage);
+  
+
+  if (pImage)
+    {
+      if (pImage->data)
+	{
+	  free(pImage->data);
+	}
+      
+      free(pImage);
+    }
+  return true;
+
+}
+
+/**
+   \brief reads in a jpg-file
+   \param jpgName the Name of the Image to load
+   \param texture a reference to the Texture to write the image to
+*/
+bool Texture::loadJPG (char* jpgName)
+{
+#ifdef HAVE_JPEGLIB_H
+  struct jpeg_decompress_struct cinfo;
+  Image *pImage = NULL;
+  FILE *pFile;
+  
+  // Open a file pointer to the jpeg file and check if it was found and opened 
+  if((pFile = fopen(jpgName, "rb")) == NULL) 
+    {
+      // Display an error message saying the file was not found, then return NULL
+      PRINTF(1)("Unable to load JPG File %s.\n", jpgName);
+      return false;
+    }
+  
+  // Create an error handler
+  jpeg_error_mgr jerr;
+  
+  // Have our compression info object point to the error handler address
+  cinfo.err = jpeg_std_error(&jerr);
+  
+  // Initialize the decompression object
+  jpeg_create_decompress(&cinfo);
+  
+  // Specify the data source (Our file pointer)	
+  jpeg_stdio_src(&cinfo, pFile);
+  
+  // Allocate the structure that will hold our eventual jpeg data (must free it!)
+  pImage = (Image*)malloc(sizeof(Image));
+  
+  // DECOFING
+  // Read in the header of the jpeg file
+  jpeg_read_header(&cinfo, TRUE);
+  
+  // Start to decompress the jpeg file with our compression info
+  jpeg_start_decompress(&cinfo);
+  
+  // Get the image dimensions and row span to read in the pixel data
+  pImage->rowSpan = cinfo.image_width * cinfo.num_components;
+  pImage->width   = cinfo.image_width;
+  pImage->height   = cinfo.image_height;
+  
+  // Allocate memory for the pixel buffer
+  pImage->data = new unsigned char[pImage->rowSpan * pImage->height];
+  
+  // Here we use the library's state variable cinfo.output_scanline as the
+  // loop counter, so that we don't have to keep track ourselves.
+  
+  // Create an array of row pointers
+  unsigned char** rowPtr = new unsigned char*[pImage->height];
+  for (int i = 0; i < pImage->height; i++)
+    rowPtr[i] = &(pImage->data[i*pImage->rowSpan]);
+  
+  // Now comes the juice of our work, here we extract all the pixel data
+  int rowsRead = 0;
+  while (cinfo.output_scanline < cinfo.output_height) 
+    {
+      // Read in the current row of pixels and increase the rowsRead count
+      rowsRead += jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead);
+    }
+  
+  // Delete the temporary row pointers
+  delete [] rowPtr;
+  
+  // Finish decompressing the data
+  jpeg_finish_decompress(&cinfo);//  decodeJPG(&cinfo, pImage);
+  
+  // This releases all the stored memory for reading and decoding the jpeg
+  jpeg_destroy_decompress(&cinfo);
+  
+  // Close the file pointer that opened the file
+  fclose(pFile);
+  
+
+  if(pImage == NULL)
+    exit(0);
+  
+  this->loadTexToGL (pImage);
+  if (pImage)
+    {
+      if (pImage->data)
+	{
+	  free(pImage->data);
+	}
+      
+      free(pImage);
+    }
+  return true;
+#else /* HAVE_JPEGLIB_H */
+  PRINTF(1)("sorry, but you did not compile with jpeg-support.\nEither install SDL_image or jpeglib, and recompile to see the image\n");
+  return false;
+#endif /* HAVE_JPEGLIB_H */
+
+}
+
+/**
+   \brief reads in a tga-file
+   \param tgaName the Name of the Image to load
+   \param texture a reference to the Texture to write the image to
+*/
+bool Texture::loadTGA(const char * tgaName)
+{
+  typedef struct
+  {
+    GLubyte Header[12];
+  } TGAHeader;
+  TGAHeader tgaHeader;			
+  
+  GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0};	// Uncompressed TGA Header 
+  GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0};	// Compressed TGA Header 
+  FILE * fTGA;
+  fTGA = fopen(tgaName, "rb");
+
+  if(fTGA == NULL)
+    {
+      PRINTF(1)("Error could not open texture file: %s\n", tgaName);
+      return false;
+    }
+  
+  if(fread(&tgaHeader, sizeof(TGAHeader), 1, fTGA) == 0)
+    {
+      PRINTF(1)("Error could not read file header of %s\n", tgaName);
+      if(fTGA != NULL)
+	{
+	  fclose(fTGA);
+	}
+      return false;
+    }
+  
+  if(memcmp(uTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
+    {
+      loadUncompressedTGA(tgaName, fTGA);
+      if (fTGA)
+	fclose (fTGA);
+    }
+  else if(memcmp(cTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
+    {
+      loadCompressedTGA(tgaName, fTGA);
+	if (fTGA)
+	  fclose (fTGA);
+    }
+  else
+    {
+      PRINTF(1)("Error TGA file be type 2 or type 10\n");
+      if (fTGA)
+	fclose(fTGA);
+      return false;
+    }
+  return true;
+}
+
+/**
+   \brief reads in an uncompressed tga-file
+   \param filename the Name of the Image to load
+   \param fTGA a Pointer to a File, that should be read
+   \param texture a reference to the Texture to write the image to
+*/
+bool Texture::loadUncompressedTGA(const char * filename, FILE * fTGA)
+{
+  GLubyte header[6];      // First 6 Useful Bytes From The Header 
+  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File 
+  GLuint  imageSize;	  // Used To Store The Image Size When Setting Aside Ram 
+  GLuint  temp;		  // Temporary Variable
+  GLuint  type;
+  GLuint  Height;	  // Height of Image 
+  GLuint  Width;	  // Width of Image 
+  GLuint  Bpp;		  // Bits Per Pixel 
+
+  GLuint cswap;
+  if(fread(header, sizeof(header), 1, fTGA) == 0)
+    {
+      PRINTF(1)("Error could not read info header\n");
+      return false;
+    }
+  
+  Width = pImage->width  = header[1] * 256 + header[0];
+  Height =  pImage->height = header[3] * 256 + header[2];
+  Bpp = pImage->bpp = header[4];
+  // Make sure all information is valid
+  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
+    {
+      PRINTF(1)("Error invalid texture information\n");
+      return false;
+    }
+  
+  if(pImage->bpp == 24)	
+    {
+      pImage->type = GL_RGB;
+    }
+  else
+    {
+      pImage->type = GL_RGBA;
+    }
+  
+  bytesPerPixel	= (Bpp / 8);
+  imageSize = (bytesPerPixel * Width * Height);
+  pImage->data = (GLubyte*) malloc(imageSize);
+  
+  if(pImage->data == NULL)
+    {
+      PRINTF(1)("Error could not allocate memory for image\n");
+      return false;
+    }
+  
+  if(fread(pImage->data, 1, imageSize, fTGA) != imageSize)
+    {
+      PRINTF(1)("Error could not read image data\n");
+      if(pImage->data != NULL)
+	{
+	  free(pImage->data);
+	}
+      return false;
+    }
+  
+  for(cswap = 0; cswap < (int)imageSize; cswap += bytesPerPixel)
+    {
+      pImage->data[cswap] ^= pImage->data[cswap+2] ^=
+	pImage->data[cswap] ^= pImage->data[cswap+2];
+    }
+  
+  this->loadTexToGL (pImage);
+
+  return true;
+}
+
+/**
+   \brief reads in a compressed tga-file
+   \param filename the Name of the Image to load
+   \param fTGA a Pointer to a File, that should be read
+   \param texture a reference to the Texture to write the image to
+*/
+bool Texture::loadCompressedTGA(const char * filename, FILE * fTGA)
+{
+  GLubyte header[6];      // First 6 Useful Bytes From The Header 
+  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File 
+  GLuint  imageSize;	  // Used To Store The Image Size When Setting Aside Ram 
+  GLuint  temp;		  // Temporary Variable
+  GLuint  type;
+  GLuint  Height;	  // Height of Image 
+  GLuint  Width;	  // Width of Image 
+  GLuint  Bpp;		  // Bits Per Pixel 
+
+  if(fread(header, sizeof(header), 1, fTGA) == 0)
+    {
+      PRINTF(1)("Error could not read info header\n");
+      return false;
+    }
+  
+  Width = pImage->width  = header[1] * 256 + header[0];
+  Height = pImage->height = header[3] * 256 + header[2];
+  Bpp = pImage->bpp	= header[4];
+
+  GLuint pixelcount	= Height * Width;
+  GLuint currentpixel	= 0;
+  GLuint currentbyte	= 0;
+  GLubyte * colorbuffer = (GLubyte *)malloc(bytesPerPixel);
+
+  //Make sure all pImage info is ok 
+  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
+    {
+      PRINTF(1)("Error Invalid pImage information\n");
+      return false;
+    }
+  
+  bytesPerPixel	= (Bpp / 8);
+  imageSize		= (bytesPerPixel * Width * Height);
+  pImage->data	= (GLubyte*) malloc(imageSize);
+  
+  if(pImage->data == NULL)
+    {
+      PRINTF(1)("Error could not allocate memory for image\n");
+      return false;
+    }
+  
+  do
+    {
+      GLubyte chunkheader = 0;
+      
+      if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)
+	{
+	  PRINTF(1)("Error could not read RLE header\n");
+	  if(pImage->data != NULL)
+	    {
+	      free(pImage->data);
+	    }
+	  return false;
+	}
+      // If the ehader is < 128, it means the that is the number of RAW color packets minus 1 
+      if(chunkheader < 128)
+	{
+	  short counter;
+	  chunkheader++;
+	  // Read RAW color values
+	  for(counter = 0; counter < chunkheader; counter++)
+	    { 
+	      // Try to read 1 pixel 
+	      if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel)
+		{
+		  PRINTF(1)("Error could not read image data\n");
+		  if(colorbuffer != NULL)
+		    {
+		      free(colorbuffer);
+		    }
+		  
+		  if(pImage->data != NULL)
+		    {
+		      free(pImage->data);
+		    }
+		  
+		  return false;	
+		}
+	      // write to memory 
+	      // Flip R and B vcolor values around in the process 
+	      pImage->data[currentbyte	  ] = colorbuffer[2];				    
+	      pImage->data[currentbyte + 1] = colorbuffer[1];
+	      pImage->data[currentbyte + 2] = colorbuffer[0];
+	      
+	      if(bytesPerPixel == 4) // if its a 32 bpp image 
+		{
+		  pImage->data[currentbyte + 3] = colorbuffer[3];// copy the 4th byte 
+		}
+	      
+	      currentbyte += bytesPerPixel;
+	      currentpixel++;
+
+	      // Make sure we haven't read too many pixels 
+	      if(currentpixel > pixelcount)	
+		{
+		  PRINTF(1)("Error too many pixels read\n");
+		  if(colorbuffer != NULL)
+		    {
+		      free(colorbuffer);
+		    }
+		  
+		  if(pImage->data != NULL)
+		    {
+		      free(pImage->data);
+		    }
+		  
+		  return false;
+		}
+	    }
+	}
+      // chunkheader > 128 RLE data, next color  reapeated chunkheader - 127 times
+      else
+	{
+	  short counter;
+	  chunkheader -= 127;	// Subteact 127 to get rid of the ID bit 
+	  if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel) // Attempt to read following color values 
+	    {
+	      PRINTF(1)("Error could not read from file");
+	      if(colorbuffer != NULL)
+		{
+		  free(colorbuffer);
+		}
+	      
+	      if(pImage->data != NULL)
+		{
+		  free(pImage->data);
+		}
+	      
+	      return false;
+	    }
+	  
+	  for(counter = 0; counter < chunkheader; counter++) //copy the color into the image data as many times as dictated
+	    {							
+	      // switch R and B bytes areound while copying
+	      pImage->data[currentbyte	  ] = colorbuffer[2];
+	      pImage->data[currentbyte + 1] = colorbuffer[1];
+	      pImage->data[currentbyte + 2] = colorbuffer[0];
+	      
+	      if(bytesPerPixel == 4)
+		{
+		  pImage->data[currentbyte + 3] = colorbuffer[3];
+		}
+	      
+	      currentbyte += bytesPerPixel;
+	      currentpixel++;
+	      
+	      if(currentpixel > pixelcount)
+		{
+		  PRINTF(1)("Error too many pixels read\n");
+		  if(colorbuffer != NULL)
+		    {
+		      free(colorbuffer);
+		    }
+		  
+		  if(pImage->data != NULL)
+		    {
+		      free(pImage->data);
+		    }
+		  
+		  return false;
+		}
+	    }
+	}
+    }
+  
+  while(currentpixel < pixelcount);	// Loop while there are still pixels left
+
+  this->loadTexToGL (pImage);
+
+  return true;
+}
+
+
+/*
+static int ST_is_power_of_two(unsigned int number)
+{
+  return (number & (number - 1)) == 0;
+}
+*/
+
+/**
+   \brief reads in a png-file
+   \param pngName the Name of the Image to load
+   \param texture a reference to the Texture to write the image to
+*/
+bool Texture::loadPNG(const char* pngName)
+{
+#ifdef HAVE_PNG_H
+
+  FILE *PNG_file = fopen(pngName, "rb");
+  if (PNG_file == NULL)
+    {
+      return 0;
+    }
+  
+  GLubyte PNG_header[8];
+  
+  fread(PNG_header, 1, 8, PNG_file);
+  if (png_sig_cmp(PNG_header, 0, 8) != 0)
+    {
+      PRINTF(2)("Not Recognized as a pngFile\n");
+      fclose (PNG_file);
+      return 0;
+    }
+  
+  png_structp PNG_reader = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+  if (PNG_reader == NULL)
+    {
+      fclose(PNG_file);
+      return 0;
+    }
+  
+  png_infop PNG_info = png_create_info_struct(PNG_reader);
+  if (PNG_info == NULL)
+    {
+      png_destroy_read_struct(&PNG_reader, NULL, NULL);
+      fclose(PNG_file);
+      return 0;
+    }
+  
+  png_infop PNG_end_info = png_create_info_struct(PNG_reader);
+  if (PNG_end_info == NULL)
+    {
+      png_destroy_read_struct(&PNG_reader, &PNG_info, NULL);
+      fclose(PNG_file);
+      return 0;
+    }
+  
+  if (setjmp(png_jmpbuf(PNG_reader)))
+    {
+      png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
+      fclose(PNG_file);
+      return (0);
+    }
+  
+  png_init_io(PNG_reader, PNG_file);
+  png_set_sig_bytes(PNG_reader, 8);
+  
+  png_read_info(PNG_reader, PNG_info);
+  
+  pImage->width = png_get_image_width(PNG_reader, PNG_info);
+  pImage->height = png_get_image_height(PNG_reader, PNG_info);
+  
+  png_uint_32 bit_depth, color_type;
+  bit_depth = png_get_bit_depth(PNG_reader, PNG_info);
+  color_type = png_get_color_type(PNG_reader, PNG_info);
+  
+  if (color_type == PNG_COLOR_TYPE_PALETTE)
+    {
+      png_set_palette_to_rgb(PNG_reader);
+    }
+  
+  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
+    {
+      png_set_gray_1_2_4_to_8(PNG_reader);
+    }
+  
+  if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+    {
+      png_set_gray_to_rgb(PNG_reader);
+    }
+  
+  if (png_get_valid(PNG_reader, PNG_info, PNG_INFO_tRNS))
+    {
+      png_set_tRNS_to_alpha(PNG_reader);
+    }
+  else
+    {
+      png_set_filler(PNG_reader, 0xff, PNG_FILLER_AFTER);
+    }
+  
+  if (bit_depth == 16)
+    {
+      png_set_strip_16(PNG_reader);
+    }
+  
+  png_read_update_info(PNG_reader, PNG_info);
+  
+  pImage->data = (png_byte*)malloc(4 * pImage->width * pImage->height);
+  png_byte** PNG_rows = (png_byte**)malloc(pImage->height * sizeof(png_byte*));
+  
+  unsigned int row;
+  for (row = 0; row < pImage->height; ++row)
+    {
+      PNG_rows[pImage->height - 1 - row] = pImage->data + (row * 4 * pImage->width);
+    }
+  
+  png_read_image(PNG_reader, PNG_rows);
+  
+  free(PNG_rows);
+  
+  png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
+  fclose(PNG_file);
+  
+  /*  if (!ST_is_power_of_two(pImage->width) || !ST_is_power_of_two(pImage->height))
+    {
+      free(pImage->data);
+      return 0;
+    }
+  */
+  this->loadTexToGL (pImage);  
+  
+  free(pImage->data);
+  
+  return true;
+#else /* HAVE_PNG_H */
+  PRINTF(1)("sorry, but you did not compile with png-support.\nEither install SDL_image or libpng, and recompile to see the image\n");
+  return false;
+#endif /* HAVE_PNG_H */
+
+}
+#endif /* HAVE_SDL_SDL_IMAGE_H */
Index: orxonox/trunk/src/importer/texture.h
===================================================================
--- orxonox/trunk/src/importer/texture.h	(revision 3365)
+++ orxonox/trunk/src/importer/texture.h	(revision 3365)
@@ -0,0 +1,100 @@
+/*!
+  \file texture.h
+  \brief Contains the texture class, that handles the reading of Images into Texutre-files.
+
+  \todo free SDL-surface when deleting Material.
+  \todo delete imgNameWithPath after use creation.
+*/
+
+#ifndef _TEXTURE_H
+#define _TEXTURE_H
+
+#include "../stdincl.h"
+extern int verbose;
+#ifdef HAVE_SDL_SDL_IMAGE_H
+#include <SDL/SDL_image.h>
+#else
+// IMAGE LIBS //
+#ifdef HAVE_JPEGLIB_H
+extern "C"{         // This has to be done, because not a c++ lib
+#include <jpeglib.h>
+}
+#endif /* HAVE_JPEGLIB_H */
+#ifdef HAVE_PNG_H
+#include <png.h>
+#endif /* HAVE_PNG_H */
+#endif /* HAVE_SDL_SDL_IMAGE_H */
+
+
+
+//! Class to handle lists of paths.
+/**
+   \todo Ability to return Paths by itself.
+
+   It is simple to use, and good, for all PathList you want.
+   just create a new Pathlist, and add Paths.
+*/
+class PathList
+{
+ private:
+  PathList();
+  static PathList* firstPath; //!< A static Pointer to the first PathList in the List.
+ public:
+  PathList(char* pName);
+  ~PathList();
+  static PathList* getInstance(void);
+  
+  void addPath (char* pName);
+  char* pathName;              //!< The Name of the current Path.
+  PathList* next;              //!< Pointer to the next Pathlist.
+};
+
+//! A Class, that reads in Textures from different fileformats.
+class Texture
+{
+ private:
+  //! Struct to handle Infos about an Image
+  struct Image
+  {
+    int rowSpan;    //!< The count of the rows this Image has.
+    GLuint width;   //!< The width of the Image.
+    GLuint height;  //!< The height of the Image.
+    GLuint bpp;     //!< BytesPerPixel
+    GLenum format;  //!< The Format of the PixelData
+    GLuint type;    //!< Type of the Image.
+    GLubyte *data;  //!< The Image Data comes here! DANGER: uncompressed data.
+  };
+  Image* pImage;
+  GLuint texture;
+  SDL_Surface* map;
+  char* searchTextureInPaths(char* texName) const;
+  inline void swap(unsigned char &a, unsigned char &b);
+ public:
+  Texture(void);
+  ~Texture(void);
+
+  inline GLuint getTexture(void) {return this->texture;} //!< \returns The textureID of this texture.
+  bool loadTexToGL (Image* pImage);
+
+  bool loadImage(char* imageName);
+#ifndef HAVE_SDL_SDL_IMAGE_H
+
+  bool loadBMP (char* bmpName);
+
+  bool loadJPG (char* jpgName);
+
+  /// TGA ///
+
+  bool loadTGA(const char * tgaName);
+  bool loadUncompressedTGA(const char * filename, FILE * fTGA);
+  bool loadCompressedTGA(const char * filename, FILE * fTGA);
+
+  bool loadPNG(const char* pngName, GLuint* texture);
+#endif
+
+
+};
+
+
+
+#endif /* _TEXTURE_H */
Index: orxonox/trunk/src/list.h
===================================================================
--- orxonox/trunk/src/list.h	(revision 3364)
+++ orxonox/trunk/src/list.h	(revision 3365)
@@ -78,6 +78,6 @@
   
 
-  void add(WorldEntity* entity);
-  void remove(WorldEntity* entity);
+  void add(T* entity);
+  void remove(T* entity);
   void destroy();
   T* firstElement();
@@ -104,5 +104,5 @@
 
 template<class T>
-void tList<T>::add(WorldEntity* entity)
+void tList<T>::add(T* entity)
 {
   listElement* el = new listElement;
@@ -120,5 +120,5 @@
 
 template<class T>
-void tList<T>::remove(WorldEntity* entity)
+void tList<T>::remove(T* entity)
 {
   this->currentEl = this->first;
Index: orxonox/trunk/src/matrix.cc
===================================================================
--- orxonox/trunk/src/matrix.cc	(revision 3365)
+++ orxonox/trunk/src/matrix.cc	(revision 3365)
@@ -0,0 +1,746 @@
+
+/* 
+   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: ...
+
+   \todo Null-Parent => center of the coord system - singleton
+   \todo Smooth-Parent: delay, speed
+   \todo destroy the stuff again, delete...
+*/
+
+#include "matrix.h"
+
+Matrix::Matrix (size_t row, size_t col)
+{
+  _m = new base_mat( row, col, 0);
+}
+
+// copy constructor
+Matrix::Matrix (const Matrix& m)
+{
+    _m = m._m;
+    _m->Refcnt++;
+}
+
+// Internal copy constructor
+void Matrix::clone ()
+{
+    _m->Refcnt--;
+    _m = new base_mat( _m->Row, _m->Col, _m->Val);
+}
+
+// destructor
+Matrix::~Matrix ()
+{
+   if (--_m->Refcnt == 0) delete _m;
+}
+
+// assignment operator
+Matrix& Matrix::operator = (const Matrix& m) 
+{
+    m._m->Refcnt++;
+    if (--_m->Refcnt == 0) delete _m;
+    _m = m._m;
+    return *this;
+}
+
+//  reallocation method
+void Matrix::realloc (size_t row, size_t col)
+{
+   if (row == _m->RowSiz && col == _m->ColSiz)
+   {
+      _m->Row = _m->RowSiz;
+      _m->Col = _m->ColSiz;
+      return;
+   }
+
+   base_mat *m1 = new base_mat( row, col, NULL);
+   size_t colSize = min(_m->Col,col) * sizeof(float);
+   size_t minRow = min(_m->Row,row);
+
+   for (size_t i=0; i < minRow; i++)
+      memcpy( m1->Val[i], _m->Val[i], colSize);
+
+   if (--_m->Refcnt == 0) 
+       delete _m;
+   _m = m1;
+
+   return;
+}
+
+// public method for resizing Matrix
+void Matrix::SetSize (size_t row, size_t col) 
+{
+   size_t i,j;
+   size_t oldRow = _m->Row;
+   size_t oldCol = _m->Col;
+
+   if (row != _m->RowSiz || col != _m->ColSiz)
+      realloc( row, col);
+
+   for (i=oldRow; i < row; i++)
+      for (j=0; j < col; j++)
+	 _m->Val[i][j] = float(0);
+
+   for (i=0; i < row; i++)                      
+      for (j=oldCol; j < col; j++)
+	 _m->Val[i][j] = float(0);
+
+   return;
+}
+
+// subscript operator to get/set individual elements
+float& Matrix::operator () (size_t row, size_t col) 
+{
+   if (row >= _m->Row || col >= _m->Col)
+      printf( "Matrix::operator(): Index out of range!\n");
+   if (_m->Refcnt > 1) clone();
+   return _m->Val[row][col];
+}
+
+// subscript operator to get/set individual elements
+float Matrix::operator () (size_t row, size_t col) const 
+{
+   if (row >= _m->Row || col >= _m->Col)
+      printf( "Matrix::operator(): Index out of range!\n");
+   return _m->Val[row][col];
+}
+
+// input stream function
+istream& operator >> (istream& istrm, Matrix& m)
+{
+   for (size_t i=0; i < m.RowNo(); i++)
+      for (size_t j=0; j < m.ColNo(); j++)
+      {
+         float x;
+         istrm >> x;
+         m(i,j) = x;
+      }
+   return istrm;
+}
+
+// output stream function
+ostream& operator << (ostream& ostrm, const Matrix& m)
+{
+   for (size_t i=0; i < m.RowNo(); i++)
+   {
+      for (size_t j=0; j < m.ColNo(); j++)
+      {
+         float x = m(i,j);
+         ostrm << x << '\t';
+      }
+      ostrm << endl;
+   }
+   return ostrm;
+}
+
+
+// logical equal-to operator
+bool operator == (const Matrix& m1, const Matrix& m2) 
+{
+   if (m1.RowNo() != m2.RowNo() || m1.ColNo() != m2.ColNo())
+      return false;
+
+   for (size_t i=0; i < m1.RowNo(); i++)
+      for (size_t j=0; j < m1.ColNo(); j++)
+	      if (m1(i,j) != m2(i,j))
+	         return false;
+
+   return true;
+}
+
+// logical no-equal-to operator
+bool operator != (const Matrix& m1, const Matrix& m2) 
+{
+    return (m1 == m2) ? false : true;
+}
+
+// combined addition and assignment operator
+Matrix& Matrix::operator += (const Matrix& m) 
+{
+   if (_m->Row != m._m->Row || _m->Col != m._m->Col)
+     printf("Matrix::operator+= : Inconsistent Matrix sizes in addition!\n");
+   if (_m->Refcnt > 1) clone();
+   for (size_t i=0; i < m._m->Row; i++)
+      for (size_t j=0; j < m._m->Col; j++)
+	 _m->Val[i][j] += m._m->Val[i][j];
+   return *this;
+}
+
+// combined subtraction and assignment operator
+Matrix& Matrix::operator -= (const Matrix& m) 
+{
+   if (_m->Row != m._m->Row || _m->Col != m._m->Col)
+      printf( "Matrix::operator-= : Inconsistent Matrix sizes in subtraction!\n");
+   if (_m->Refcnt > 1) clone();
+   for (size_t i=0; i < m._m->Row; i++)
+      for (size_t j=0; j < m._m->Col; j++)
+	 _m->Val[i][j] -= m._m->Val[i][j];
+   return *this;
+}
+
+// combined scalar multiplication and assignment operator
+ Matrix&
+Matrix::operator *= (const float& c) 
+{
+    if (_m->Refcnt > 1) clone();
+    for (size_t i=0; i < _m->Row; i++)
+	for (size_t j=0; j < _m->Col; j++)
+	    _m->Val[i][j] *= c;
+    return *this;
+}
+
+// combined Matrix multiplication and assignment operator
+ Matrix&
+Matrix::operator *= (const Matrix& m) 
+{
+   if (_m->Col != m._m->Row)
+      printf( "Matrix::operator*= : Inconsistent Matrix sizes in multiplication!\n");
+
+   Matrix temp(_m->Row,m._m->Col);
+
+   for (size_t i=0; i < _m->Row; i++)
+      for (size_t j=0; j < m._m->Col; j++)
+      {
+         temp._m->Val[i][j] = float(0);
+         for (size_t k=0; k < _m->Col; k++)
+            temp._m->Val[i][j] += _m->Val[i][k] * m._m->Val[k][j];
+      }
+   *this = temp;
+
+   return *this;
+}
+
+// combined scalar division and assignment operator
+ Matrix&
+Matrix::operator /= (const float& c) 
+{
+    if (_m->Refcnt > 1) clone();
+    for (size_t i=0; i < _m->Row; i++)
+	for (size_t j=0; j < _m->Col; j++)
+	    _m->Val[i][j] /= c;
+
+    return *this;
+}
+
+// combined power and assignment operator
+ Matrix&
+Matrix::operator ^= (const size_t& pow) 
+{
+  Matrix temp(*this);
+
+  for (size_t i=2; i <= pow; i++)
+    *this *=  temp; // changed from *this = *this * temp;
+
+  return *this;
+}
+
+// unary negation operator
+ Matrix
+Matrix::operator - () 
+{
+   Matrix temp(_m->Row,_m->Col);
+
+   for (size_t i=0; i < _m->Row; i++)
+      for (size_t j=0; j < _m->Col; j++)
+	 temp._m->Val[i][j] = - _m->Val[i][j];
+
+   return temp;
+}
+
+// binary addition operator
+ Matrix
+operator + (const Matrix& m1, const Matrix& m2) 
+{
+   Matrix temp = m1;
+   temp += m2;
+   return temp;
+}
+
+// binary subtraction operator
+ Matrix
+operator - (const Matrix& m1, const Matrix& m2) 
+{
+   Matrix temp = m1;
+   temp -= m2;
+   return temp;
+}
+
+// binary scalar multiplication operator
+ Matrix
+operator * (const Matrix& m, const float& no) 
+{
+   Matrix temp = m;
+   temp *= no;
+   return temp;
+}
+
+
+// binary scalar multiplication operator
+ Matrix
+operator * (const float& no, const Matrix& m) 
+{
+   return (m * no);
+}
+
+// binary Matrix multiplication operator
+ Matrix
+operator * (const Matrix& m1, const Matrix& m2) 
+{
+   Matrix temp = m1;
+   temp *= m2;
+   return temp;
+}
+
+// binary scalar division operator
+ Matrix
+operator / (const Matrix& m, const float& no) 
+{
+    return (m * (float(1) / no));
+}
+
+
+// binary scalar division operator
+ Matrix
+operator / (const float& no, const Matrix& m) 
+{
+    return (!m * no);
+}
+
+// binary Matrix division operator
+ Matrix
+operator / (const Matrix& m1, const Matrix& m2) 
+{
+    return (m1 * !m2);
+}
+
+// binary power operator
+ Matrix
+operator ^ (const Matrix& m, const size_t& pow) 
+{
+   Matrix temp = m;
+   temp ^= pow;
+   return temp;
+}
+
+// unary transpose operator
+ Matrix
+operator ~ (const Matrix& m) 
+{
+   Matrix temp(m.ColNo(),m.RowNo());
+
+   for (size_t i=0; i < m.RowNo(); i++)
+      for (size_t j=0; j < m.ColNo(); j++)
+      {
+         float x = m(i,j);
+	      temp(j,i) = x;
+      }
+   return temp;
+}
+
+// unary inversion operator
+ Matrix
+operator ! (const Matrix m) 
+{
+   Matrix temp = m;
+   return temp.Inv();
+}
+
+// inversion function
+ Matrix
+Matrix::Inv () 
+{
+   size_t i,j,k;
+   float a1,a2,*rowptr;
+
+   if (_m->Row != _m->Col)
+      printf( "Matrix::operator!: Inversion of a non-square Matrix\n");
+
+   Matrix temp(_m->Row,_m->Col);
+   if (_m->Refcnt > 1) clone();
+
+
+   temp.Unit();
+   for (k=0; k < _m->Row; k++)
+   {
+      int indx = pivot(k);
+      if (indx == -1)
+	      printf( "Matrix::operator!: Inversion of a singular Matrix\n");
+
+      if (indx != 0)
+      {
+	      rowptr = temp._m->Val[k];
+	      temp._m->Val[k] = temp._m->Val[indx];
+	      temp._m->Val[indx] = rowptr;
+      }
+      a1 = _m->Val[k][k];
+      for (j=0; j < _m->Row; j++)
+      {
+	      _m->Val[k][j] /= a1;
+	      temp._m->Val[k][j] /= a1;
+      }
+      for (i=0; i < _m->Row; i++)
+	   if (i != k)
+	   {
+	      a2 = _m->Val[i][k];
+	      for (j=0; j < _m->Row; j++)
+	      {
+	         _m->Val[i][j] -= a2 * _m->Val[k][j];
+	         temp._m->Val[i][j] -= a2 * temp._m->Val[k][j];
+	      }
+	   }
+   }
+   return temp;
+}
+
+// solve simultaneous equation
+ Matrix
+Matrix::Solve (const Matrix& v) const 
+{
+   size_t i,j,k;
+   float a1;
+
+   if (!(_m->Row == _m->Col && _m->Col == v._m->Row))
+      printf( "Matrix::Solve():Inconsistent matrices!\n");
+
+   Matrix temp(_m->Row,_m->Col+v._m->Col);
+   for (i=0; i < _m->Row; i++)
+   {
+      for (j=0; j < _m->Col; j++)
+	 temp._m->Val[i][j] = _m->Val[i][j];
+      for (k=0; k < v._m->Col; k++)
+	 temp._m->Val[i][_m->Col+k] = v._m->Val[i][k];
+   }
+   for (k=0; k < _m->Row; k++)
+   {
+      int indx = temp.pivot(k);
+      if (indx == -1)
+	 printf( "Matrix::Solve(): Singular Matrix!\n");
+
+      a1 = temp._m->Val[k][k];
+      for (j=k; j < temp._m->Col; j++)
+	 temp._m->Val[k][j] /= a1;
+
+      for (i=k+1; i < _m->Row; i++)
+      {
+	 a1 = temp._m->Val[i][k];
+	 for (j=k; j < temp._m->Col; j++)
+	   temp._m->Val[i][j] -= a1 * temp._m->Val[k][j];
+      }
+   }
+   Matrix s(v._m->Row,v._m->Col);
+   for (k=0; k < v._m->Col; k++)
+      for (int m=int(_m->Row)-1; m >= 0; m--)
+      {
+	 s._m->Val[m][k] = temp._m->Val[m][_m->Col+k];
+	 for (j=m+1; j < _m->Col; j++)
+	    s._m->Val[m][k] -= temp._m->Val[m][j] * s._m->Val[j][k];
+      }
+   return s;
+}
+
+// set zero to all elements of this Matrix
+ void
+Matrix::Null (const size_t& row, const size_t& col) 
+{
+    if (row != _m->Row || col != _m->Col)
+	realloc( row,col);
+
+    if (_m->Refcnt > 1) 
+	clone();
+
+    for (size_t i=0; i < _m->Row; i++)
+	for (size_t j=0; j < _m->Col; j++)
+	    _m->Val[i][j] = float(0);
+    return;
+}
+
+// set zero to all elements of this Matrix
+ void
+Matrix::Null() 
+{
+    if (_m->Refcnt > 1) clone();   
+    for (size_t i=0; i < _m->Row; i++)
+	for (size_t j=0; j < _m->Col; j++)
+		_m->Val[i][j] = float(0);
+    return;
+}
+
+// set this Matrix to unity
+ void
+Matrix::Unit (const size_t& row) 
+{
+    if (row != _m->Row || row != _m->Col)
+	realloc( row, row);
+	
+    if (_m->Refcnt > 1) 
+	clone();
+
+    for (size_t i=0; i < _m->Row; i++)
+	for (size_t j=0; j < _m->Col; j++)
+	    _m->Val[i][j] = i == j ? float(1) : float(0);
+    return;
+}
+
+// set this Matrix to unity
+ void
+Matrix::Unit () 
+{
+    if (_m->Refcnt > 1) clone();   
+    size_t row = min(_m->Row,_m->Col);
+    _m->Row = _m->Col = row;
+
+    for (size_t i=0; i < _m->Row; i++)
+	for (size_t j=0; j < _m->Col; j++)
+	    _m->Val[i][j] = i == j ? float(1) : float(0);
+    return;
+}
+
+// private partial pivoting method
+ int
+Matrix::pivot (size_t row)
+{
+  int k = int(row);
+  double amax,temp;
+
+  amax = -1;
+  for (size_t i=row; i < _m->Row; i++)
+    if ( (temp = abs( _m->Val[i][row])) > amax && temp != 0.0)
+     {
+       amax = temp;
+       k = i;
+     }
+  if (_m->Val[k][row] == float(0))
+     return -1;
+  if (k != int(row))
+  {
+     float* rowptr = _m->Val[k];
+     _m->Val[k] = _m->Val[row];
+     _m->Val[row] = rowptr;
+     return k;
+  }
+  return 0;
+}
+
+// calculate the determinant of a Matrix
+ float
+Matrix::Det () const 
+{
+   size_t i,j,k;
+   float piv,detVal = float(1);
+
+   if (_m->Row != _m->Col)
+      printf( "Matrix::Det(): Determinant a non-squareMatrix!\n");
+   
+   Matrix temp(*this);
+   if (temp._m->Refcnt > 1) temp.clone();
+
+   for (k=0; k < _m->Row; k++)
+   {
+      int indx = temp.pivot(k);
+      if (indx == -1)
+	 return 0;
+      if (indx != 0)
+	 detVal = - detVal;
+      detVal = detVal * temp._m->Val[k][k];
+      for (i=k+1; i < _m->Row; i++)
+      {
+	 piv = temp._m->Val[i][k] / temp._m->Val[k][k];
+	 for (j=k+1; j < _m->Row; j++)
+	    temp._m->Val[i][j] -= piv * temp._m->Val[k][j];
+      }
+   }
+   return detVal;
+}
+
+// calculate the norm of a Matrix
+ float
+Matrix::Norm () 
+{
+   float retVal = float(0);
+
+   for (size_t i=0; i < _m->Row; i++)
+      for (size_t j=0; j < _m->Col; j++)
+	 retVal += _m->Val[i][j] * _m->Val[i][j];
+   retVal = sqrt( retVal);
+
+   return retVal;
+}
+
+// calculate the condition number of a Matrix
+ float
+Matrix::Cond () 
+{
+   Matrix inv = ! (*this);
+   return (Norm() * inv.Norm());
+}
+
+// calculate the cofactor of a Matrix for a given element
+ float
+Matrix::Cofact (size_t row, size_t col) 
+{
+   size_t i,i1,j,j1;
+
+   if (_m->Row != _m->Col)
+      printf( "Matrix::Cofact(): Cofactor of a non-square Matrix!\n");
+
+   if (row > _m->Row || col > _m->Col)
+      printf( "Matrix::Cofact(): Index out of range!\n");
+
+   Matrix temp (_m->Row-1,_m->Col-1);
+
+   for (i=i1=0; i < _m->Row; i++)
+   {
+      if (i == row)
+	continue;
+      for (j=j1=0; j < _m->Col; j++)
+      {
+	 if (j == col)
+	    continue;
+	 temp._m->Val[i1][j1] = _m->Val[i][j];
+	 j1++;
+      }
+      i1++;
+   }
+   float  cof = temp.Det();
+   if ((row+col)%2 == 1)
+      cof = -cof;
+
+   return cof;
+}
+
+
+// calculate adjoin of a Matrix
+ Matrix
+Matrix::Adj () 
+{
+   if (_m->Row != _m->Col)
+      printf( "Matrix::Adj(): Adjoin of a non-square Matrix.\n");
+
+   Matrix temp(_m->Row,_m->Col);
+
+   for (size_t i=0; i < _m->Row; i++)
+      for (size_t j=0; j < _m->Col; j++)
+	  temp._m->Val[j][i] = Cofact(i,j);
+   return temp;
+}
+
+// Determine if the Matrix is singular
+ bool
+Matrix::IsSingular () 
+{
+   if (_m->Row != _m->Col)
+      return false;
+   return (Det() == float(0));
+}
+
+// Determine if the Matrix is diagonal
+ bool
+Matrix::IsDiagonal () 
+{
+   if (_m->Row != _m->Col)
+      return false;
+   for (size_t i=0; i < _m->Row; i++)
+     for (size_t j=0; j < _m->Col; j++)
+	if (i != j && _m->Val[i][j] != float(0))
+	  return false;
+   return true;
+}
+
+// Determine if the Matrix is scalar
+ bool
+Matrix::IsScalar () 
+{
+   if (!IsDiagonal())
+     return false;
+   float v = _m->Val[0][0];
+   for (size_t i=1; i < _m->Row; i++)
+     if (_m->Val[i][i] != v)
+	return false;
+   return true;
+}
+
+// Determine if the Matrix is a unit Matrix
+ bool
+Matrix::IsUnit () 
+{
+   if (IsScalar() && _m->Val[0][0] == float(1))
+     return true;
+   return false;
+}
+
+// Determine if this is a null Matrix
+ bool
+Matrix::IsNull () 
+{
+   for (size_t i=0; i < _m->Row; i++)
+      for (size_t j=0; j < _m->Col; j++)
+	 if (_m->Val[i][j] != float(0))
+	    return false;
+   return true;
+}
+
+// Determine if the Matrix is symmetric
+ bool
+Matrix::IsSymmetric () 
+{
+   if (_m->Row != _m->Col)
+      return false;
+   for (size_t i=0; i < _m->Row; i++)
+      for (size_t j=0; j < _m->Col; j++)
+	 if (_m->Val[i][j] != _m->Val[j][i])
+	    return false;
+   return true;
+}
+	   
+// Determine if the Matrix is skew-symmetric
+ bool
+Matrix::IsSkewSymmetric () 
+{
+   if (_m->Row != _m->Col)
+      return false;
+   for (size_t i=0; i < _m->Row; i++)
+      for (size_t j=0; j < _m->Col; j++)
+	 if (_m->Val[i][j] != -_m->Val[j][i])
+	    return false;
+   return true;
+}
+   
+// Determine if the Matrix is upper triangular
+ bool
+Matrix::IsUpperTriangular () 
+{
+   if (_m->Row != _m->Col)
+      return false;
+   for (size_t i=1; i < _m->Row; i++)
+      for (size_t j=0; j < i-1; j++)
+	 if (_m->Val[i][j] != float(0))
+	    return false;
+   return true;
+}
+
+// Determine if the Matrix is lower triangular
+ bool
+Matrix::IsLowerTriangular () 
+{
+   if (_m->Row != _m->Col)
+      return false;
+
+   for (size_t j=1; j < _m->Col; j++)
+      for (size_t i=0; i < j-1; i++)
+	 if (_m->Val[i][j] != float(0))
+	    return false;
+
+   return true;
+}
+
Index: orxonox/trunk/src/matrix.h
===================================================================
--- orxonox/trunk/src/matrix.h	(revision 3365)
+++ orxonox/trunk/src/matrix.h	(revision 3365)
@@ -0,0 +1,110 @@
+#ifndef _MATRIX_H
+#define _MATRIX_H
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+
+using namespace std;
+
+class Matrix
+{
+public:
+  // Constructors
+  Matrix (const Matrix& m);
+  Matrix (size_t row, size_t col);
+  
+  // Destructor
+  ~Matrix ();
+  
+  // Assignment operators
+  Matrix& operator = (const Matrix& m) ;
+  
+  // Value extraction method
+  size_t RowNo () const { return _m->Row; }
+  size_t ColNo () const { return _m->Col; }
+  
+  // Subscript operator
+  float& operator () (size_t row, size_t col);
+   float  operator () (size_t row, size_t col) const;
+
+   // Unary operators
+   Matrix operator + ()  { return *this; }
+   Matrix operator - () ;
+
+   // Combined assignment - calculation operators
+   Matrix& operator += (const Matrix& m);
+   Matrix& operator -= (const Matrix& m);
+   Matrix& operator *= (const Matrix& m);
+   Matrix& operator *= (const float& c) ;
+   Matrix& operator /= (const float& c) ;
+   Matrix& operator ^= (const size_t& pow);
+
+   // Miscellaneous -methods
+   void Null (const size_t& row, const size_t& col) ;
+   void Null () ;
+   void Unit (const size_t& row) ;
+   void Unit () ;
+   void SetSize (size_t row, size_t col) ;
+
+   // Utility methods
+   Matrix Solve (const Matrix& v) const;
+   Matrix Adj ();
+   Matrix Inv ();
+   float Det () const;
+   float Norm () ;
+   float Cofact (size_t row, size_t col);
+   float Cond () ;
+
+   // Type of matrices
+   bool IsSquare ()  { return (_m->Row == _m->Col); } 
+   bool IsSingular ();
+   bool IsDiagonal ();
+   bool IsScalar ();
+   bool IsUnit ();
+   bool IsNull ();
+   bool IsSymmetric ();
+   bool IsSkewSymmetric ();
+   bool IsUpperTriangular ();
+   bool IsLowerTriangular ();
+
+private:
+   struct base_mat
+    {
+	float **Val;
+	size_t Row, Col, RowSiz, ColSiz;
+	int Refcnt;
+
+	base_mat (size_t row, size_t col, float** v)
+	{
+	    Row = row; RowSiz = row;
+	    Col = col; ColSiz = col;
+	    Refcnt = 1;
+
+	    Val = new float* [row];
+	    size_t rowlen = col * sizeof(float);
+
+	    for (size_t i=0; i < row; i++)
+	    {
+		Val[i] = new float [col];
+		if (v) memcpy( Val[i], v[i], rowlen);
+	    }
+	}
+	~base_mat ()
+	{
+	    for (size_t i=0; i < RowSiz; i++)
+		delete [] Val[i];
+	    delete [] Val;
+	}
+    };
+    base_mat *_m;
+
+    void clone ();
+    void realloc (size_t row, size_t col);
+    int pivot (size_t row);
+};
+
+Matrix operator ! (const Matrix m);
+
+#endif /*_MATRIX_H */
Index: orxonox/trunk/src/null_parent.cc
===================================================================
--- orxonox/trunk/src/null_parent.cc	(revision 3365)
+++ orxonox/trunk/src/null_parent.cc	(revision 3365)
@@ -0,0 +1,96 @@
+
+
+/* 
+   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: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "null_parent.h"
+
+
+using namespace std;
+
+NullParent* NullParent::singletonRef = 0;
+
+NullParent* NullParent::getInstance ()
+{
+  if( singletonRef == NULL)
+    singletonRef = new NullParent ();
+  return singletonRef;
+}
+
+/**
+   \brief standard constructor
+
+   \todo this constructor is not jet implemented - do it
+*/
+NullParent::NullParent () 
+{
+  this->parent = this;
+  this->mode = ALL;
+}
+
+
+NullParent::NullParent (Vector* absCoordinate)
+{
+  this->parent = this;
+  this->mode = ALL;
+  this->absCoordinate = *absCoordinate;
+}
+
+
+/**
+   \brief standard deconstructor
+
+   \todo this deconstructor is not jet implemented - do it
+*/
+NullParent::~NullParent () 
+{
+  delete singletonRef;
+  singletonRef = NULL;
+}
+
+
+
+
+/**
+   \brief updates the absCoordinate/absDirection
+
+   this is used to go through the parent-tree to update all the absolute coordinates
+   and directions. this update should be done by the engine, so you don't have to 
+   worry, normaly...
+*/
+void NullParent::update (float timeStamp)
+{
+  this->absCoordinate = this->relCoordinate;
+  this->absDirection = parent->getAbsDir () * this->relDirection;
+  
+  PNode* pn = this->children->enumerate ();
+  while( pn != NULL) 
+    { 
+      /* if this node has changed, make sure, that all children are updated also */
+      if( this->bRelCoorChanged || this->bAbsCoorChanged)
+	pn->parentCoorChanged ();
+      if( this->bRelDirChanged || this->bAbsDirChanged)
+	pn->parentDirChanged ();
+      pn->update (timeStamp);
+      pn = this->children->nextElement ();
+    }
+
+  this->timeStamp = timeStamp;
+  this->bRelCoorChanged = false;
+  this->bAbsCoorChanged = false;
+  this->bRelDirChanged = false;
+  this->bAbsDirChanged = false;
+}
Index: orxonox/trunk/src/null_parent.h
===================================================================
--- orxonox/trunk/src/null_parent.h	(revision 3365)
+++ orxonox/trunk/src/null_parent.h	(revision 3365)
@@ -0,0 +1,30 @@
+/*! 
+    \file proto_class.h
+    \brief Definition of the proto class template, used quickly start work
+*/
+
+
+#ifndef _NULL_PARENT_H
+#define _NULL_PARENT_H
+
+#include "stdincl.h"
+#include "p_node.h"
+
+
+class NullParent : public PNode {
+
+ public:
+  static NullParent* getInstance ();
+  ~NullParent ();
+  
+  static NullParent* singletonRef;
+
+  virtual void update (float timeStamp);
+
+ private:
+  NullParent ();
+  NullParent (Vector* absCoordinate);
+
+};
+
+#endif /* _NULL_PARENT_H */
Index: orxonox/trunk/src/orxonox.cc
===================================================================
--- orxonox/trunk/src/orxonox.cc	(revision 3364)
+++ orxonox/trunk/src/orxonox.cc	(revision 3365)
@@ -115,17 +115,48 @@
   // Set video mode
   // TO DO: parse arguments for settings
-  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
-  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
-  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
-  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
-  
+  //SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+  //SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
+  //SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+  //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+  
+
+  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );   
+  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);    
+  SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0);  
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
+
+
+
   int bpp = 16;
   int width = 640;
   int height = 480;
-  Uint32 flags = SDL_HWSURFACE | SDL_OPENGL | SDL_GL_DOUBLEBUFFER;
-  
-  if((screen = SDL_SetVideoMode (width, height, bpp, flags)) == NULL)
+  //Uint32 flags = SDL_HWSURFACE | SDL_OPENGL | SDL_GL_DOUBLEBUFFER; /* \todo: SDL_OPENGL doen't permit to load images*/
+  //Uint32 flags = SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER;
+
+  Uint32 videoFlags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE;
+
+  /* query SDL for information about our video hardware */
+  const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo ();
+  
+  if( videoInfo == NULL)
+    {
+      printf ("Orxonox::initVideo() - Failed getting Video Info :%s\n", SDL_GetError()); 
+      SDL_Quit ();
+    }
+  if( videoInfo->hw_available)
+    videoFlags |= SDL_HWSURFACE;
+  else 
+    videoFlags |= SDL_SWSURFACE;
+  /*
+  if(VideoInfo -> blit_hw)                            
+    VideoFlags |= SDL_HWACCEL;
+  */
+  
+  if((this->screen = SDL_SetVideoMode (width, height, bpp, videoFlags)) == NULL)
   {
-    printf("Could not SDL_SetVideoMode(%d, %d, %d, %d): %s\n", width, height, bpp, flags, SDL_GetError());
+    printf("Could not SDL_SetVideoMode(%d, %d, %d, %d): %s\n", width, height, bpp, videoFlags, SDL_GetError());
     SDL_Quit();
     return -1;
@@ -133,5 +164,5 @@
   
   // Set window labeling
-  SDL_WM_SetCaption("Orxonox " PACKAGE_VERSION, "Orxonox " PACKAGE_VERSION);
+  SDL_WM_SetCaption ("Orxonox " PACKAGE_VERSION, "Orxonox " PACKAGE_VERSION);
   
   // TO DO: Create a cool icon and use it here
@@ -139,7 +170,6 @@
 
   // OpenGL stuff
-  // (Is this all we initialize globally???)
-  glClearColor(0.0, 0.0, 0.0, 0.0);
-  glEnable(GL_DEPTH_TEST);
+  glClearColor (0.0, 0.0, 0.0, 0.0);
+  glEnable (GL_DEPTH_TEST);
  
   // LIGHTING
@@ -148,12 +178,13 @@
   GLfloat lightPosition[] = {10.0, 10, 19.0, 0.0};
 
-  glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteLight);
-  glLightfv(GL_LIGHT0, GL_SPECULAR, whiteLight);
-  glEnable(GL_LIGHTING);
-  glEnable(GL_LIGHT0);
-  glEnable(GL_DEPTH_TEST);
-  glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
-  glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteLight);
+  glLightfv (GL_LIGHT0, GL_DIFFUSE, whiteLight);
+  glLightfv (GL_LIGHT0, GL_SPECULAR, whiteLight);
+  glEnable (GL_LIGHTING);
+  glEnable (GL_LIGHT0);
+  glEnable (GL_DEPTH_TEST);
+  glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
+  glLightfv (GL_LIGHT0, GL_DIFFUSE, whiteLight);
    
+  //glEnable (GL_TEXTURE_2D); 
   //  glEnable(GL_COLOR);
   //  glShadeModel(GL_SMOOTH);
@@ -311,4 +342,8 @@
 
 
+SDL_Surface* Orxonox::getScreen ()
+{
+  return this->screen;
+}
 
 
Index: orxonox/trunk/src/orxonox.h
===================================================================
--- orxonox/trunk/src/orxonox.h	(revision 3364)
+++ orxonox/trunk/src/orxonox.h	(revision 3365)
@@ -68,4 +68,5 @@
   Camera* getCamera();
   World* getWorld();
+  SDL_Surface* getScreen ();
   
   //void mainLoop();
Index: orxonox/trunk/src/p_node.cc
===================================================================
--- orxonox/trunk/src/p_node.cc	(revision 3364)
+++ orxonox/trunk/src/p_node.cc	(revision 3365)
@@ -14,4 +14,8 @@
    main-programmer: Patrick Boenzli
    co-programmer: ...
+
+   \todo Null-Parent => center of the coord system - singleton
+   \todo Smooth-Parent: delay, speed
+   \todo destroy the stuff again, delete...
 */
 
@@ -28,5 +32,32 @@
    \todo this constructor is not jet implemented - do it
 */
-PNode::PNode () {}
+PNode::PNode () 
+{
+  this->children = new tList<PNode>();
+  this->bRelCoorChanged = true;
+  this->bAbsCoorChanged = false;
+  this->bRelDirChanged = true;
+  this->bAbsDirChanged = false;
+  this->parent = NULL;
+}
+
+
+/**
+   \brief constructor with coodinates
+*/
+PNode::PNode (Vector* absCoordinate, PNode* parent )
+{
+  this->absCoordinate = *absCoordinate;
+  this->relCoordinate = this->absCoordinate - parent->getAbsCoor ();
+  
+  this->children = new tList<PNode>();
+  this->bRelCoorChanged = true;
+  this->bAbsCoorChanged = false;
+  this->bRelDirChanged = true;
+  this->bAbsDirChanged = false;
+  this->parent = parent;
+
+  parent->addChild (this);
+}
 
 
@@ -36,4 +67,376 @@
    \todo this deconstructor is not jet implemented - do it
 */
-PNode::~PNode () {}
-
+PNode::~PNode () 
+{
+  /*
+  delete &this->children;
+  delete &this->relCoordinate;
+  delete &this->absCoordinate;
+  delete &this->relDirection;
+  delete &this->absDirection;
+  */
+  this->parent = NULL;
+  /* there is currently a problem with cleaning up - fix*/
+}
+
+
+/**
+   \brief deletes the hole pnode tree
+
+   cleans up all pnodes
+*/
+void PNode::destroy ()
+{
+  PNode* pn = this->children->enumerate();
+  while( pn != NULL) 
+    { 
+      pn->destroy ();
+      pn = this->children->nextElement();
+    } 
+  this->children->destroy ();
+}
+
+
+/**
+   \brief get relative coordinates
+   \returns relative coordinates to its parent
+*/
+Vector PNode::getRelCoor ()
+{
+  Vector r = this->relCoordinate; /* return a copy, so it can't be modified */
+  return r;
+}
+
+
+/**
+   \brief set relative coordinates
+   \param relative coordinates to its parent
+
+   it is very importand, that you use this function, if you want to update the
+   relCoordinates. If you don't use this, the PNode won't recognize, that something
+   has changed and won't update the children Nodes.
+*/
+void PNode::setRelCoor (Vector* relCoord)
+{
+  this->bRelCoorChanged = true;
+  this->relCoordinate = *relCoord;
+}
+
+
+/**
+   \brief get absolute coordinates
+   \returns absolute coordinates from (0,0,0)
+*/
+Vector PNode::getAbsCoor ()
+{
+  return this->absCoordinate;
+}
+
+
+/**
+   \brief get relative coordinates
+   \returns relative coordinates to its parent
+
+   it is very importand, that you use this function, if you want to update the
+   absCoordinates. If you don't use this, the PNode won't recognize, that something
+   has changed and won't update the children Nodes.
+*/
+void PNode::setAbsCoor (Vector* absCoord)
+{
+  this->bAbsCoorChanged = true;
+  this->absCoordinate = *absCoord;
+}
+
+
+/**
+   \brief shift coordinate (abs and rel)
+   \param shift vector
+
+   this function shifts the current coordinates about the vector shift. this is
+   usefull because from some place else you can:
+   PNode* someNode = ...;
+   Vector objectMovement = calculateShift();
+   someNode->shiftCoor(objectMovement);
+
+   elsewhere you would have to:
+   PNode* someNode = ...;
+   Vector objectMovement = calculateShift();
+   Vector currentCoor = someNode->getRelCoor();
+   Vector newCoor = currentCoor + objectMovement;
+   someNode->setRelCoor(newCoor);
+   
+   yea right... shorter...
+
+*/
+void PNode::shiftCoor (Vector* shift)
+{
+  if( this->bAbsCoorChanged)
+    {
+      this->absCoordinate = this->absCoordinate + *shift;
+    }
+  else 
+    {
+      this->relCoordinate = this->relCoordinate + *shift;
+      this->bRelCoorChanged = true;
+    }
+}
+
+
+
+/**
+   \brief get relative direction
+   \returns relative direction to its parent
+*/
+Quaternion PNode::getRelDir ()
+{
+  return this->relDirection;
+}
+
+
+/**
+   \brief set relative direction
+   \param relative direction to its parent
+
+   it is very importand, that you use this function, if you want to update the
+   relDirection. If you don't use this, the PNode won't recognize, that something
+   has changed and won't update the children Nodes.
+*/
+void PNode::setRelDir (Quaternion* relDir)
+{
+  this->bRelCoorChanged = true;
+  this->relDirection = *relDir;
+}
+
+
+/**
+   \brief gets the absolute direction (0,0,1)
+   \returns absolute coordinates
+*/
+Quaternion PNode::getAbsDir ()
+{}
+
+
+/**
+   \brief sets the absolute direction (0,0,1)
+   \param absolute coordinates
+
+   it is very importand, that you use this function, if you want to update the
+   absDirection. If you don't use this, the PNode won't recognize, that something
+   has changed and won't update the children Nodes.
+*/
+void PNode::setAbsDir (Quaternion* absDir)
+{}
+
+
+/**
+   \brief shift coordinate (abs and rel)
+   \param shift vector
+
+   this function shifts the current coordinates about the vector shift. this is
+   usefull because from some place else you can:
+   PNode* someNode = ...;
+   Quaternion objectMovement = calculateShift();
+   someNode->shiftCoor(objectMovement);
+
+   elsewhere you would have to:
+   PNode* someNode = ...;
+   Quaternion objectMovement = calculateShift();
+   Quaternion currentCoor = someNode->getRelCoor();
+   Quaternion newCoor = currentCoor + objectMovement;
+   someNode->setRelCoor(newCoor);
+   
+   yea right... shorter...
+
+*/
+void PNode::shiftDir (Quaternion* shift)
+{}
+
+
+
+/**
+   \brief adds a child and makes this node to a parent
+   \param child reference
+
+   use this to add a child to this node.
+*/
+void PNode::addChild (PNode* pNode)
+{
+  this->addChild(pNode, DEFAULT_MODE);
+}
+
+
+/**
+   \brief adds a child and makes this node to a parent
+   \param child reference
+   \param on which changes the child should also change ist state
+
+   use this to add a child to this node.
+*/
+void PNode::addChild (PNode* pNode, parentingMode mode)
+{
+  pNode->mode = mode;
+  pNode->parent = this;
+  this->children->add (pNode);
+}
+
+
+/**
+   /brief removes a child from the node
+*/
+void PNode::removeChild (PNode* pNode)
+{
+  this->children->remove (pNode);
+}
+
+
+/**
+   \brief sets the parent of this PNode
+*/
+void PNode::setParent (PNode* parent)
+{
+  this->parent = parent;
+}
+
+/**
+   \brief set the mode of this parent manualy
+*/
+void PNode::setMode (parentingMode mode)
+{
+  this->mode = mode;
+}
+
+/**
+   \brief has to be called, if the parent coordinate has changed
+   
+   normaly this will be done by the parent itself automaticaly. If you call this, you
+   will force an update of the coordinated of the node.
+*/
+void PNode::parentCoorChanged ()
+{
+  this->bRelCoorChanged = true;
+}
+
+
+/**
+   \brief has to be called, if the parent direction has changed
+   
+   normaly this will be done by the parent itself automaticaly. If you call this, you
+   will force an update of the direction of the node.
+*/
+void PNode::parentDirChanged ()
+{
+  this->bRelDirChanged = true;
+}
+
+
+/**
+   \brief updates the absCoordinate/absDirection
+
+   this is used to go through the parent-tree to update all the absolute coordinates
+   and directions. this update should be done by the engine, so you don't have to 
+   worry, normaly...
+*/
+void PNode::update (float timeStamp)
+{
+  printf ("PNode::update - %s - (%f, %f, %f)\n", this->objectName, this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
+
+      if( this->mode == MOVEMENT || this->mode == ALL)
+	{
+	  if( this->bAbsCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
+	    {
+	      printf("PNode::update () - this->bAbsCoorChanged = true\n");
+	      /* if you have set the absolute coordinates this overrides all other changes */
+	      this->relCoordinate = this->absCoordinate - parent->getAbsCoor ();
+	    }
+	  else if( this->bRelCoorChanged /*&& this->timeStamp != DataTank::timeStamp*/)
+	    {
+	      /*this is bad style... must be deleted later - just for testing*/
+	      if( this->parent == NULL)
+		{
+		this->absCoordinate = this->relCoordinate;
+		}
+	      else
+		this->absCoordinate = parent->getAbsCoor () + this->relCoordinate;	      /* update the current absCoordinate */
+	    }
+	}
+      
+      if( this->mode == ROTATION && this->mode == ALL)
+	{
+	  if( this->bAbsDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
+	    {
+	      /* if you have set the absolute coordinates this overrides all other changes */
+	      this->relDirection = this->absDirection - parent->getAbsDir ();
+	    }
+	  else if( this->bRelDirChanged /*&& this->timeStamp != DataTank::timeStamp*/)
+	    {
+	      /* update the current absDirection - remember * means rotation around sth.*/
+	      this->absDirection = parent->getAbsDir () * this->relDirection;
+	    }
+	}    
+      // }
+  PNode* pn = this->children->enumerate();
+  while( pn != NULL) 
+    { 
+      /* if this node has changed, make sure, that all children are updated also */
+      if( this->bRelCoorChanged || this->bAbsCoorChanged)
+	pn->parentCoorChanged ();
+      if( this->bRelDirChanged || this->bAbsDirChanged)
+	pn->parentDirChanged ();
+      pn->update(timeStamp);
+      pn = this->children->nextElement();
+    }
+
+  this->timeStamp = timeStamp;
+  this->bRelCoorChanged = false;
+  this->bAbsCoorChanged = false;
+  this->bRelDirChanged = false;
+  this->bAbsDirChanged = false;
+}
+
+
+/*
+  \brief tick
+*/
+void PNode::processTick (float dt)
+{
+  this->tick (dt);
+  PNode* pn = this->children->enumerate();
+  while( pn != NULL) 
+    { 
+      pn->processTick (dt);
+      pn = this->children->nextElement();
+    } 
+}
+
+
+void PNode::tick (float dt)
+{}
+
+
+void PNode::debug()
+{
+  printf("PNode::debug() - absCoord: (%f, %f, %f)\n", 
+	 this->absCoordinate.x, 
+	 this->absCoordinate.y,
+	 this->absCoordinate.z);
+}
+
+
+/*
+  \brief set the name of the node
+
+  for debug purposes realy usefull, not used to work properly
+*/
+void PNode::setName (char* newName)
+{
+  this->objectName = newName;
+}
+
+
+/*
+  \brief gets the name of the node
+*/
+char* PNode::getName ()
+{
+  return this->objectName;
+}
Index: orxonox/trunk/src/p_node.h
===================================================================
--- orxonox/trunk/src/p_node.h	(revision 3364)
+++ orxonox/trunk/src/p_node.h	(revision 3365)
@@ -14,6 +14,6 @@
     this conditions make it cheaper to recalculate the tree (reduces redundant work).
 
-    remember: if you have to change the coordinates, because the object (point) did move,
-    don't forget to reset both relCoor and absCoor (offset is the same)
+    remember: if you have to change the coordinates or the directions, use the functions
+    that are defined to execute this operation - otherwhise there will be big problems...
 */
 
@@ -24,28 +24,62 @@
 #include "stdincl.h"
 
+class PNode; /* forward decleration, so that parentEntry has access to PNode */
 
-class PNode {
+typedef enum parentingMode {MOVEMENT = 0, ROTATION, ALL};
+#define DEFAULT_MODE ALL
+
+class PNode : public BaseObject {
 
  public:
   PNode ();
-  ~PNode ();
+  PNode (Vector* absCoordinate, PNode* pNode);
+  virtual ~PNode ();
+
+  void destroy ();
+
+  PNode* parent; //! a pointer to the parent node
+  tList<PNode>* children; //! list of the children
+
+  parentingMode mode;
 
   Vector getRelCoor ();
-  void setRelCoor (Vector relCoord);
+  void setRelCoor (Vector* relCoord);
+  //void setRelCoor (Vector relCoord);
   Vector getAbsCoor ();
-  void setAbsCoor (Vector absCoord);
+  void setAbsCoor (Vector* absCoord);
+  //void setAbsCoor (Vector absCoord);
+  void shiftCoor (Vector* shift);
+  //void shiftCoor (Vector shift);
 
   Quaternion getRelDir ();
-  void setRelDir (Quaternion relDir);
+  void setRelDir (Quaternion* relDir);
   Quaternion getAbsDir ();
-  void setAbsCoor (Quaternion absDir);
+  void setAbsDir (Quaternion* absDir);
+  void shiftDir (Quaternion* shift);
 
   void addChild (PNode* pNode);
+  void addChild (PNode* pNode, parentingMode mode);
   void removeChild (PNode* pNode);
+  void setParent (PNode* parent);
+  void parentCoorChanged ();
+  void parentDirChanged ();
+  void setMode (parentingMode mode);
 
- private:
-  long timeStamp; //! this the timeStamp of when the abs{Coordinat, Direction} has been calculated
-  bool bCoorChanged;
-  bool bDirChanged;
+  virtual void update (float timeStamp);
+  void processTick (float dt);
+  virtual void tick (float dt);
+
+  void setName (char* newName);
+  char* getName ();
+
+
+  void debug ();
+
+  float timeStamp;   //! this the timeStamp of when the abs{Coordinat, Direction} has been calculated
+  char* objectName;
+  bool bAbsCoorChanged;
+  bool bRelCoorChanged;
+  bool bRelDirChanged;
+  bool bAbsDirChanged;
 
   Vector relCoordinate;  //! coordinates relative to the parent
@@ -54,6 +88,4 @@
   Quaternion absDirection; //! absolute direvtion in the world ( from (0,0,1) )
 
-  tList<PNode>* children; //! list of the children
-
 };
 
Index: orxonox/trunk/src/player.cc
===================================================================
--- orxonox/trunk/src/player.cc	(revision 3364)
+++ orxonox/trunk/src/player.cc	(revision 3365)
@@ -19,4 +19,5 @@
 #include "stdincl.h"
 #include "collision.h"
+#include "importer/model.h"
 
 using namespace std;
@@ -26,5 +27,5 @@
 {
 
-  this->obj = new Object("reaplow.obj");
+  this->model = new Model("reaplow.obj");
   /*
   objectList = glGenLists(1);
@@ -54,10 +55,10 @@
 }
 
-Player::~Player()
+Player::~Player ()
 {
-  delete this->obj;
+  delete this->model;
 }
 
-void Player::postSpawn()
+void Player::postSpawn ()
 {
   travelSpeed = 15.0;
@@ -69,23 +70,23 @@
 }
 
-void Player::tick(float time)
+void Player::tick (float time)
 {
   // movement
-  move (time);
+  this->move (time);
 }
 
-void Player::hit(WorldEntity* weapon, Vector loc)
+void Player::hit (WorldEntity* weapon, Vector loc)
 {
 }
 
-void Player::destroy()
+void Player::destroy ()
 {
 }
 
-void Player::collide(WorldEntity* other, Uint32 ownhitflags, Uint32 otherhitflags)
+void Player::collide (WorldEntity* other, Uint32 ownhitflags, Uint32 otherhitflags)
 {
 }
 
-void Player::command(Command* cmd)
+void Player::command (Command* cmd)
 {
   //printf("Player|recieved command [%s]\n", cmd->cmd);
@@ -97,5 +98,5 @@
 }
 
-void Player::draw()
+void Player::draw ()
 { 
   glMatrixMode(GL_MODELVIEW);
@@ -103,17 +104,16 @@
   float matrix[4][4];
   
-  glTranslatef(getPlacement()->r.x, getPlacement()->r.y, getPlacement()->r.z);
-  getPlacement()->w.matrix (matrix);
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  //rotate
+  this->getAbsDir ().matrix (matrix);
   glMultMatrixf((float*)matrix);
   
   glMatrixMode(GL_MODELVIEW);
-  glRotatef(-90, 0,1,0);
-  obj->draw();
+  this->model->draw();
   // glCallList(objectList);
-
-  
-  
 }
 
+
+/*PN
 void Player::getLookat(Location* locbuf)
 {
@@ -121,28 +121,30 @@
   //locbuf->dist += 5.0;
 }
+*/
 
-void Player::leftWorld()
+void Player::leftWorld ()
 {
 }
 
-void Player::move(float time)
+void Player::move (float time)
 {
   Vector accel(0.0, 0.0, 0.0);
   /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
-  Placement *pos = getPlacement();
+  //Placement *pos = getPlacement();
+  
   /* calculate the direction in which the craft is heading  */
-  Vector direction(0.0, 0.0, 1.0);
-  direction = pos->w.apply(direction);
-  Vector orthDirection(0.0, 0.0, 1.0);
-  orthDirection = orthDirection.cross(direction);
+  Vector direction (1.0, 0.0, 0.0);
+  //direction = this->absDirection.apply (direction);
+  Vector orthDirection (0.0, 0.0, 1.0);
+  //orthDirection = orthDirection.cross (direction);
 
   if( bUp) { accel = accel+(direction*acceleration); }
   if( bDown) { accel = accel-(direction*acceleration); }
-  if( bLeft ) { accel = accel + (orthDirection*acceleration); }
-  if( bRight ) { accel = accel - (orthDirection*acceleration); }
+  if( bLeft ) { accel = accel - (orthDirection*acceleration); }
+  if( bRight ) { accel = accel + (orthDirection*acceleration); }
   if( bAscend ) { /* not yet implemented but just: (0,0,1)*acceleration */}
   if( bDescend) {/* FIXME */} /* \todo up and down player movement */
 
-  Location* l = getLocation();
+  //Location* l = getLocation();
   
   // r(t) = r(0) + v(0)*t + 1/2*a*t^2
@@ -152,7 +154,12 @@
 
   /* this the base-speed of the player: determines how fast and how the player follows the track*/
-  l->dist = l->dist + travelSpeed * time;
-
+  //l->dist = l->dist + travelSpeed * time;
+  
+  Vector* shift = new Vector (this->travelSpeed * time, 0, 0);
+  this->shiftCoor (shift);
+  
   /* this updates the player position on the track - user interaction */
-  l->pos = l->pos + accel*time;
+  //l->pos = l->pos + accel*time;
+  Vector move = accel * time;
+  this->shiftCoor (&move);
 }
Index: orxonox/trunk/src/player.h
===================================================================
--- orxonox/trunk/src/player.h	(revision 3364)
+++ orxonox/trunk/src/player.h	(revision 3365)
@@ -8,5 +8,6 @@
 
 #include "world_entity.h"
-#include "importer/object.h"
+
+class Model;
 
 //! Basic controllable WorldEntity
@@ -27,5 +28,5 @@
   
   virtual void draw();
-  virtual void getLookat(Location* locbuf);
+  // virtual void getLookat(Location* locbuf);
   
   virtual void leftWorld();
@@ -38,5 +39,4 @@
   float acceleration;
   GLuint objectList;
-  Object* obj;
   
   void move(float time);
Index: orxonox/trunk/src/proto_class.cc
===================================================================
--- orxonox/trunk/src/proto_class.cc	(revision 3364)
+++ orxonox/trunk/src/proto_class.cc	(revision 3365)
@@ -27,5 +27,8 @@
    \todo this constructor is not jet implemented - do it
 */
-ProtoClass::ProtoClass () {}
+ProtoClass::ProtoClass () 
+{
+   this->setClassName ("ProtoClass");
+}
 
 
Index: orxonox/trunk/src/proto_class.h
===================================================================
--- orxonox/trunk/src/proto_class.h	(revision 3364)
+++ orxonox/trunk/src/proto_class.h	(revision 3365)
@@ -19,5 +19,5 @@
    here can be some longer description of this class
 */
-class ProtoClass {
+class ProtoClass : public BaseObject {
 
  public:
Index: orxonox/trunk/src/stdincl.h
===================================================================
--- orxonox/trunk/src/stdincl.h	(revision 3364)
+++ orxonox/trunk/src/stdincl.h	(revision 3365)
@@ -10,4 +10,6 @@
 
 #define null 0   //!< null
+
+typedef unsigned char byte;
 
 // this includes the information from configure/makefiles
@@ -31,5 +33,7 @@
 
 #include "vector.h"
-#include "coordinates.h"
+#include "matrix.h"
+#include "curve.h"
+//#include "coordinates.h"
 #include "list.h"
 #include "list_template.h"
@@ -38,4 +42,6 @@
 #include "message_structures.h"
 #include "orxonox.h"
+#include "data_tank.h"
+#include "base_object.h"
 
 #endif /* _STDINCL_H */
Index: orxonox/trunk/src/story_entity.h
===================================================================
--- orxonox/trunk/src/story_entity.h	(revision 3364)
+++ orxonox/trunk/src/story_entity.h	(revision 3365)
@@ -12,5 +12,5 @@
 
 //! A class that represents something to play in orxonox. it is a container for worlds, movies, mission briefings, etc...
-class StoryEntity {
+class StoryEntity : public BaseObject {
 
  public:
Index: orxonox/trunk/src/track.cc
===================================================================
--- orxonox/trunk/src/track.cc	(revision 3364)
+++ orxonox/trunk/src/track.cc	(revision 3365)
@@ -29,4 +29,5 @@
   this->end = NULL;
   this->nextID = 0;
+  this->setClassName ("Track");
 }
 
@@ -44,4 +45,5 @@
   this->end = finish;
   this->nextID = next;
+  this->setClassName ("Track");
 }
 
@@ -59,71 +61,5 @@
 
 
-/**
-   \brief calculate a camera Placement from a "look at"-Location
-   \param lookat: the Location the camera should be centered on
-   \param camplc: pointer to a buffer where the new camera Placement should be put into
-   
-   Theoretically you can place the camera wherever you want, but for the sake of 
-   common sense I suggest that you at least try to keep the thing that should be looked
-   at inside camera boundaries.
-*/
-void Track::mapCamera (Location* lookat, Placement* camplc)
-{
-  Line trace(*offset, *end - *offset);
-  float l = trace.len ();
-  
-  //	camplc->r = *offset + Vector(0,0,0.5);
-  //	camplc->w = Quaternion (trace.a, Vector(0,0,1));
-  float r = (lookat->dist)*PI / l;
-  camplc->r = trace.r + (trace.a * ((lookat->dist-10.0) / l)) + Vector(0,0,5.0);
-  
-  Vector w(0.0,0.0,0.0);
-  w=Vector(0,0,0) - ((trace.r + (trace.a * ((lookat->dist) / l)) - camplc->r));
-  //Vector up(0.0,sin(r),cos(r)); // corrupt...
-  Vector up(0.0, 0.0, 1.0);
 
-  camplc->w = Quaternion(w, up);
-
-  //printf("\n------\nup vector: [%f, %f, %f]\n", up.x, up.y, up.z);
-  //printf("direction: [%f, %f, %f]\n", w.x, w.y, w.z);
-  //printf("quaternion: w[ %f ], v[ %f, %f, %f ]\n", camplc->w.w, camplc->w.v.x, camplc->w.v.y, camplc->w.v.z);
-}
-
-/**
-   \brief calculate a Placement from a given Location
-   \param loc: the Location the entity is in
-   \param plc: a pointer to a buffer where the corresponding Placement should be put
-   into
-   \return: true if track changes - false if track stays
-   
-   There are no limitations to how you transform a Location into a Placement, but for 
-   the sake of placement compatibility between track parts you should make sure that 
-   the resulting Placement at dist == 0 is equal to the offset Vector and the Placement
-   at dist == len() is equal to the end Vector. Elseway there will be ugly artifacts 
-   when transfering between track parts.
-*/
-bool Track::mapCoords (Location* loc, Placement* plc)
-{
-  Line trace(*offset, *end - *offset);
-  float l = trace.len ();
-  
-  /* change to the next track? */
-  if( loc->dist > l)
-    {
-      loc->dist -= l;
-      loc->part = nextID;
-      //FIXME: loc->track = this;
-      return true;
-    }
-  
-  /* this quaternion represents the rotation from start-vector (0,0,1) to the direction of
-   * the track */
-  Quaternion dir(trace.a, Vector(0,0,1)); 
-  
-  plc->r = trace.r + (trace.a * ((loc->dist) / l)) + /*dir.apply*/(loc->pos);
-  plc->w = dir * loc->rot;
-  
-  return false;
-}
 
 
Index: orxonox/trunk/src/track.h
===================================================================
--- orxonox/trunk/src/track.h	(revision 3364)
+++ orxonox/trunk/src/track.h	(revision 3365)
@@ -14,5 +14,5 @@
    To create special levels with special camera movement, rules or whatever, derive from this base class.
 */
-class Track 
+class Track : public BaseObject
 {
  private:
@@ -35,6 +35,4 @@
   virtual void postLeave (WorldEntity* entity);
   virtual void tick (float deltaT);
-  virtual void mapCamera (Location* lookat, Placement* camplc);
-  virtual bool mapCoords (Location* loc, Placement* plc);	// this should return true if the entity left track boundaries
 };
 
Index: orxonox/trunk/src/track_manager.cc
===================================================================
--- orxonox/trunk/src/track_manager.cc	(revision 3365)
+++ orxonox/trunk/src/track_manager.cc	(revision 3365)
@@ -0,0 +1,544 @@
+
+
+/* 
+   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: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "track_manager.h"
+#include <stdarg.h>
+
+
+using namespace std;
+
+/**
+   \brief initializes a TrackElement (sets the default values)
+*/
+TrackElement::TrackElement(void)
+{
+  this->isFresh = true;
+  this->isHotPoint = false;
+  this->isSavePoint = false;
+  this->isFork = false;
+  this->isJoined = false;
+  this->mainJoin = false;
+  this->cond; //!< todo think!!
+  this->ID = -1;
+  this->startingTime = 0; //!< \todo eventually set this to the max time of TrackManager.
+  this->duration = 1;
+  this->curveType = BEZIERCURVE;
+  this->nodeCount = 0;
+  this->childCount = 0;
+  this->name = NULL;
+  this->startPoint = Vector(0,0,0);
+  this->startTangentPoint = Vector(0,0,0);
+  this->curve = NULL;
+  this->children = NULL;
+}
+
+/** 
+    \brief destroys all alocated memory)
+    \todo eventually when deleting a TrackElement you would not like to delete all its preceding TrackElements
+*/
+TrackElement::~TrackElement(void)
+{
+  if (this->name)
+    delete []name;
+  if (this->curve)
+    delete this->curve;
+  if ((!this->isJoined &&this->childCount > 0) || (this->isJoined && this->mainJoin))
+    {
+      for (int i=0; i < this->childCount; i++)
+	delete this->children[i];
+      delete this->children;
+    }
+}
+
+/**
+   \brief Searches through all the TrackElements for trackID.
+   \param trackID The ID to search for.
+   \returns The TrackElement if Found, NULL otherwise.
+   
+   \todo make this more modular, to search for different things
+*/
+TrackElement* TrackElement::findByID(unsigned int trackID)
+{
+  // return if Found.
+  if (this->ID == trackID)
+    return this;
+  // search on.
+  if (this->childCount > 0)
+    for (int i=0; i < this->childCount; i++)
+      {
+	TrackElement* tmpElem;
+	if ((tmpElem = this->children[i]->findByID(trackID)))
+	  return tmpElem;
+      }
+  else return NULL;
+}
+
+
+
+
+
+/////////////////////////////////////
+///// TRACKMANAGER //////////////////
+/////////////////////////////////////
+/**
+   \brief standard constructor
+
+*/
+TrackManager::TrackManager(void)
+{
+  this->setClassName ("TrackManager");
+
+  PRINTF(3)("Initializing the TrackManager\n");
+  this->firstTrackElem = new TrackElement();
+  this->firstTrackElem->ID = 1;
+  this->currentTrackElem = firstTrackElem;
+  this->localTime = 0;
+  this->maxTime = 0;
+  this->trackElemCount = 1;
+}
+
+
+/**
+   \brief standard destructor
+
+*/
+TrackManager::~TrackManager(void)
+{
+  PRINTF(3)("Destruct TrackManager\n");
+
+  PRINTF(3)("Deleting all the TrackElements\n");
+  delete this->firstTrackElem;
+
+  // we do not have a TrackManager anymore
+  singletonRef = NULL;
+}
+
+TrackManager* TrackManager::singletonRef = NULL;
+
+/**
+   \returns The reference on the TrackManager.
+
+   If the TrackManager does not exist, it will be created.
+*/
+TrackManager* TrackManager::getInstance(void) 
+{
+  if (singletonRef)
+    return singletonRef;
+  else
+    return singletonRef = new TrackManager();
+}
+
+/**
+   \brief reserves Space for childCount children
+   \param childCount The Count of children to make space for.
+*/
+void TrackManager::initChildren(unsigned int childCount)
+{
+  this->currentTrackElem->childCount = childCount;
+  this->currentTrackElem->children = new TrackElement*[childCount];
+  for (int i=0; i<childCount; i++)
+    {
+      this->currentTrackElem->children[i] = new TrackElement();
+      this->currentTrackElem->children[i]->ID = ++trackElemCount;
+      this->currentTrackElem->children[i]->startingTime = this->currentTrackElem->startingTime+this->currentTrackElem->duration;
+      this->currentTrackElem->children[i]->startPoint = this->currentTrackElem->curve->getNode(this->currentTrackElem->curve->getNodeCount());
+      this->currentTrackElem->children[i]->startTangentPoint = (this->currentTrackElem->children[i]->startPoint *2) - this->currentTrackElem->curve->getNode(this->currentTrackElem->curve->getNodeCount()-1);
+    }
+}
+
+/**
+   \brief Searches for a given trackID.
+   \param trackID the trackID to search for.
+   \returns The TrackElement #trackID if found, NULL otherwise.
+*/
+TrackElement* TrackManager::findTrackElementByID(unsigned int trackID) const
+{
+  return firstTrackElem->findByID(trackID);
+}
+
+// INITIALIZE //
+
+/**
+   \brief Sets the trackID we are working on.
+   \param trackID the trackID we are working on
+*/
+void TrackManager::workOn(unsigned int trackID)
+{
+  TrackElement* tmpElem = findTrackElementByID(trackID);
+  if (tmpElem)
+    this->currentTrackElem = tmpElem;
+  else
+    printf("TrackElement not Found, leaving unchanged\n");
+  printf("now Working on %d\n", this->currentTrackElem->ID);
+
+}
+
+/**
+   \brief Sets the Type of the Curve
+   \brief curveType The Type to set
+*/
+void TrackManager::setCurveType(CurveType curveType)
+{
+  if (!this->currentTrackElem->isFresh)
+    {
+      PRINTF(2)("It is not possible to change the type of a Curve after you have have appended some points to it\n");
+      return;
+    }
+  this->currentTrackElem->curveType = curveType;
+  switch (curveType)
+    {
+    case BEZIERCURVE:
+      this->currentTrackElem->curve = new BezierCurve();
+      break;
+    case UPOINTCURVE:
+      this->currentTrackElem->curve = new UPointCurve();
+      break;
+    }
+}
+
+/**
+   \brief Sets the duration of the current path in seconds.
+   \param time The duration in seconds.
+*/
+
+void TrackManager::setDuration(float time)
+{
+  this->currentTrackElem->duration = time;
+}
+
+/**
+   \brief adds a point to the current TrackElement
+   \param newPoint The point to add.
+*/
+bool TrackManager::addPoint(Vector newPoint)
+{
+  return this->addPoint(newPoint, this->currentTrackElem);
+}
+
+/**
+   \brief adds a point to trackElem
+   \param newPoint The point to add.
+   \param trackElem The TrackElement to add the Point to
+*/
+bool TrackManager::addPoint(Vector newPoint, TrackElement* trackElem)
+{
+  if (trackElem->isFresh)
+    {
+      this->setCurveType(BEZIERCURVE);
+      trackElem->isFresh = false;
+      if(trackElem != this->firstTrackElem)
+	{
+	  this->addPoint(trackElem->startPoint);
+	  this->addPoint(trackElem->startTangentPoint);
+	}
+    }
+  trackElem->curve->addNode(newPoint);
+  trackElem->nodeCount++;
+}
+
+/**
+   \brief adds save/splitpoint.
+   \param newPoint The point to add.
+   \returns A Pointer to a newly appended Curve
+*/
+int TrackManager::addHotPoint(Vector newPoint)
+{
+  printf("setting up a HotPoint\n");
+  if (this->currentTrackElem->isFresh)
+    {
+      this->setCurveType(BEZIERCURVE);
+      this->currentTrackElem->isFresh = false;
+    }
+
+  // \todo HotPoint Handling.
+  this->currentTrackElem->curve->addNode(newPoint);
+  this->currentTrackElem->nodeCount++;
+  this->initChildren(1);
+  this->currentTrackElem = this->currentTrackElem->children[0];
+}
+
+/**
+   \brief Sets the last HotPoint into a savePoint.
+   \returns A Pointer to a newly appended Curve
+   
+   If no HotPoint was defined the last added Point will be rendered into a savePoint. \n
+   If the HotPoint was defined as a fork the Point will \b not be set into a savePoint.
+*/
+int TrackManager::setSavePoint(void)
+{
+  printf("setting up a SavePoint.\n");
+  if (this->currentTrackElem->isFork || this->currentTrackElem->isSavePoint)
+    return this->currentTrackElem->children[1]->ID;
+  this->currentTrackElem->isSavePoint = true;
+  this->currentTrackElem->isHotPoint = true;
+
+  this->initChildren(1);
+  this->currentTrackElem = this->currentTrackElem->children[0];
+}
+
+/**
+   \brief adds some interessting non-linear movments through the level.
+   \param count The Count of childrens the current HotPoint will have.
+
+   If no HotPoint was defined the last added Point will be rendered into a fork. \n
+   If the HotPoint was defined as a savePoint the Point will \b not be set into a fork.
+*/
+void TrackManager::fork(unsigned int count, ...)
+{
+  int* trackIDs = new int[count];
+  this->forkV(count, trackIDs);
+  va_list ID;
+  va_start (ID, count);
+  for(int i = 0; i < count; i++)
+    {
+      *va_arg (ID, int*) = trackIDs[i];
+    }
+  va_end(ID);  
+  delete []trackIDs;
+}
+
+/**
+   \brief adds some interessting non-linear movments through the level.
+   \param count The Count of childrens the current HotPoint will have.
+   \param trackIDs A Pointer to an Array of ints which will hold the trackID's (the user will have to reserve space for this).
+
+   \see void TrackManager::fork(int count, ...)
+
+   \todo initialisation is wrong!! also in setSavePoint.
+*/
+void TrackManager::forkV(unsigned int count, int* trackIDs)
+{
+  printf("Forking with %d children\n", count);
+  if (this->currentTrackElem->isSavePoint)
+    return;
+  this->currentTrackElem->isFork = true;
+  this->currentTrackElem->isHotPoint = true;
+  for(int i = 0; i < count; i++)
+    trackIDs[i]=this->trackElemCount+1+i;
+  this->initChildren(count);
+}
+
+/**
+   \brief decides under what condition a certain Path will be chosen.
+   \param groupID the ID on which to choose the preceding move
+   \param cond \todo think about this
+*/
+void TrackManager::condition(unsigned int groupID, PathCondition cond)
+{
+  
+}
+
+/**
+   \brief joins some tracks together again. 
+   \param count The count of Paths to join.
+
+   Join will set the localTime to the longest time a Path has to get to this Point. \n
+   Join will join all curves to the first curve, meaning that all the tangents will be matched.
+*/
+void TrackManager::join(unsigned int count, ...)
+{
+  int* trackIDs = new int [count];
+  va_list ID;
+  va_start (ID, count);
+  for(int i = 0; i < count; i++)
+    {
+      trackIDs[i] = va_arg (ID, int);
+    }
+  va_end(ID);
+  this->joinV(count, trackIDs);
+  delete []trackIDs;
+}
+
+/**
+   \brief joins some tracks together again. 
+   \param count The count of Paths to join.
+   \param trackIDs an Array with the trackID's to join
+
+   \see void TrackManager::join(int count, ...)
+*/
+void TrackManager::joinV(unsigned int count, int* trackIDs)
+{
+  printf("Joining %d tracks to Track %d\n", count, trackIDs[0]);
+
+  // chanching work-on to temporary value. going back at the end.
+  int tmpCurrentWorkingID = this->currentTrackElem->ID;
+  this->workOn(trackIDs[0]);
+
+  TrackElement* firstJoint = this->currentTrackElem;
+  Vector tmpEndPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount());
+  Vector tmpTangentPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-1); 
+  firstJoint->isJoined = true;
+  firstJoint->mainJoin = true;
+  if(!firstJoint->isHotPoint)
+    this->setSavePoint();
+
+  for (int i = 1; i < count; i++)
+    {
+      TrackElement* tmpJoinElem = this->findTrackElementByID(trackIDs[i]);
+      if (tmpJoinElem->childCount > 0)
+	printf("!!This Curve has children, and as such will not be joined!!\n You can try joining other childless TrackElements to this one!");
+      else
+	{
+	  this->addPoint(tmpTangentPoint, tmpJoinElem);
+	  this->addPoint(tmpEndPoint, tmpJoinElem);
+	  
+	  //Copying Joint-Info
+	  tmpJoinElem->children = firstJoint->children;
+	  tmpJoinElem->childCount = firstJoint->childCount;
+	  tmpJoinElem->isSavePoint = firstJoint->isSavePoint;
+	  tmpJoinElem->isFork = firstJoint->isFork;
+	  
+	  tmpJoinElem->isJoined = true;
+	}
+    }
+  // returning to the TrackElement we were working on.
+  this->workOn(tmpCurrentWorkingID);
+}
+
+// RUNTIME //
+
+/**
+   \brief calculates the Position for the localTime of the Track.
+   \returns the calculated Position
+*/
+Vector TrackManager::calcPos() const
+{
+  //  PRINTF(0)("TrackElement:%d, localTime: %f\n",this->currentTrackElem->ID, this->localTime);
+  return this->currentTrackElem->curve->calcPos((this->localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
+}
+
+/**
+   \brief calculates the Rotation for the localTime of the Track.
+   \returns the calculated Rotation
+*/
+Vector TrackManager::calcDir() const
+{
+  return this->currentTrackElem->curve->calcDir((this->localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
+}
+
+/**
+   \brief Advances the local-time of the Track around dt
+   \param dt The time about which to advance.
+
+   This function also checks, if the TrackElement has to be changed.
+*/
+void TrackManager::tick(float dt)
+{
+  if (this->localTime <= this->firstTrackElem->duration)
+    this->jumpTo(this->localTime);
+  this->localTime += dt;
+  if (this->localTime > this->currentTrackElem->startingTime + this->currentTrackElem->duration && this->currentTrackElem->childCount > 0)
+    this->currentTrackElem = this->currentTrackElem->children[0];
+}
+
+/**
+   \brief Jumps to a certain point on the Track.
+   \param time The time on the Track to jump to.
+
+   This should be used to Jump backwards on a Track, because moving forward means to change between the Path. (it then tries to choose the default.)
+   Max is trackLengthMax.
+*/
+void TrackManager::jumpTo(float time)
+{
+  if (time == 0)
+    this->currentTrackElem = this->firstTrackElem;
+  this->localTime = time;
+}
+
+/**
+   \brief a Function that decides which Path we should follow.
+   \param graphID The Path to choose.
+   
+*/
+void TrackManager::choosePath(int graphID)
+{
+
+}
+
+
+
+// DEBUG //
+
+/**
+   \brief Imports a model of the Graph into the OpenGL-environment.
+   \param dt The Iterator used in seconds for Painting the Graph.
+
+   This is for testing facility only. Do this if you want to see the Path inside the Level.
+   eventually this will all be packed into a gl-list.
+*/
+void TrackManager::drawGraph(float dt) const
+{
+
+  for (int i = 1; i <= trackElemCount; i++)
+    {
+      glBegin(GL_LINE_STRIP);
+      TrackElement* tmpElem = this->findTrackElementByID(i);
+      if (tmpElem->curve)
+	for(float f = 0.0; f < 1.0; f+=dt)
+	  {
+	    //      printf("%f, %f, %f\n",trackManager->calcPos().x, trackManager->calcPos().y, trackManager->calcPos().z);
+	    Vector tmpVector = tmpElem->curve->calcPos(f);
+	    glVertex3f(tmpVector.x, tmpVector.y, tmpVector.z);
+	  }
+  glEnd();
+    }
+}
+
+void TrackManager::debug(unsigned int level) const
+{
+  printf("::CLASS TRACKMANAGER::debug information::\n");
+  //  printf("Status is: %
+  printf(" Consists of %d elements\n", this->trackElemCount);
+  printf(" localTime is: %f\n", this->localTime);
+  if (level >= 2)
+    {
+      for (int i = 1; i <= trackElemCount; i++)
+	{
+	  TrackElement* tmpElem = this->findTrackElementByID(i);
+	  printf("  ::TrackElement:%i::", tmpElem->ID);
+	  if(tmpElem->name)
+	    printf("name:%s::", tmpElem->name);
+	  if(tmpElem->isFresh)
+	    printf("   has not jet eddited in any way\n");
+	  printf("\n   TimeTable: starting at = %f; ends at = %f; duration = %f\n", tmpElem->startingTime, tmpElem->startingTime+tmpElem->duration, tmpElem->duration);
+	  printf("   consists of %d Points\n", tmpElem->nodeCount);
+	  if (tmpElem->childCount == 0)
+	    printf("   has no child\n");	    
+	  else if (tmpElem->childCount == 1)
+	    printf("   has 1 child: ==%d==\n", tmpElem->children[0]->ID);
+	  else if (tmpElem->childCount > 1)
+	    {
+	      printf("   has %d children: ", tmpElem->childCount);
+	      for(int i = 0; i < tmpElem->childCount; i++)
+		printf("=%d= ", tmpElem->children[i]->ID);
+	      printf("\n");
+	    }
+
+	  if(tmpElem->isHotPoint)
+	    printf("   is a special Point:\n");
+	  if(tmpElem->isSavePoint)
+	    printf("    is a SavePoint\n");
+	  if(tmpElem->isFork)
+	    {
+	      printf("    is A Fork with with %d children.", tmpElem->childCount);
+	    }
+	  if(tmpElem->isJoined)
+	    printf("   is Joined at the End\n");
+	}
+    }
+}
Index: orxonox/trunk/src/track_manager.h
===================================================================
--- orxonox/trunk/src/track_manager.h	(revision 3365)
+++ orxonox/trunk/src/track_manager.h	(revision 3365)
@@ -0,0 +1,141 @@
+/*! 
+    \file track_manager.h
+    \brief manages all tracks defined in the world and the path the player takes
+
+    it is a container for all tracks and all track-nodes. it manages the movement of
+    the track helper-parent (that drives the player). it is responsable for calculating
+    smooth curves etc.
+*/
+
+
+#ifndef _TRACK_MANAGER_H
+#define _TRACK_MANAGER_H
+
+#include "stdincl.h"
+
+
+//! condition for choosing a certain Path. \todo implement a useful way.
+struct PathCondition
+{
+  
+};
+  
+
+//! A Graph-Element, that holds the curve-structure of a Level.
+/**
+   A TrackElement is used, to define the structure of the Track itself.
+   It is a graph and not a tree, because paths can fork and join again.
+*/
+class TrackElement
+{
+ public:
+  TrackElement(void);
+  ~TrackElement(void);
+
+  TrackElement* findByID(unsigned int trackID);
+
+  bool isFresh;              //!< If no Points where added until now
+  bool isHotPoint;           //!< If the first node is a specialPoint;
+  bool isSavePoint;          //!< If the first node is a savePoint
+  bool isFork;               //!< If the first node is a Fork
+  bool isJoined;             //!< If the End of the Curve is joined.
+  bool mainJoin;             //!< If the End of the Curve is joined, and this is the one Curve the others join to.
+  PathCondition cond;        //!< The Split Condition;
+  int ID;                    //!< The ID of this TrackElement
+  float startingTime;        //!< The time at which this Track begins.
+  float duration;            //!< The time used to cross this TrackElement (curve).
+  CurveType curveType;       //!< The CurveType this will have.
+  int nodeCount;             //!< The count of points this TrackElement has.
+  char* name;                //!< A name for the Trac.
+  Vector startPoint;         //!< A Vector that Points to the first point of the containing Curve. (for c1-steadiness)
+  Vector startTangentPoint;  //!< A Vector that points into the direction of the previous Curve. (for c1-steadiness)
+  Curve* curve;              //!< The Curve of this TrackElement
+  int childCount;            //!< The number of Children This TrackElement has.
+  TrackElement** children;   //!< A TrackElement can have a Tree of following TrackElements.
+};
+
+
+
+//! The TrackManager handles the flow of the Players through the game.
+/**
+   \todo write the methodes
+
+   <b>The TrackManager works as followed:</b> \n
+     \n
+   <b>1. Initialize it, by setting up the Graph. You can do this by using the following Commands.</b>
+    \li workOn(): changes the ID that will be altered through the changes.
+    \li setCurveType(): lets you set the CurveType of the Curve we are Working on. (default is BezierCurve, set this as early as possible, for this uses resources).
+    \li setDuration(): sets the length of the current path in seconds.
+    \li addPoint(): adds a point to the Curve.
+    \li addHotPoint(): adds save/splitpoint.\n
+    \li fork(): adds some interessting non-linear movments through the level (fork will force addHotPoint if not done then).
+    \li condition(): decides under what condition a certain Path will be chosen.
+    \li join(): joins some tracks together again. Join will set the localTime to the longest time a Path has to get to this Point)
+    \li setSavePoint(): Sets a HotPoint into a savePoint. A Savepoint can be used as a rollbackpoint if a Player gets shot.
+
+    HotPoints and Joins are at the beginning of a TrackElement. \n
+    SavePoints and Forks are at the end of a TrackElement \n
+    look out: <b>SAVEPOINTS CAN NOT BE FORKS</b> (but joins), because the condition is really hard to guess if you do not give some impuls. \n
+\n
+   <b> 2. Runtime knows the following: </b>
+    \li calcPos(): returns the current position on the track
+    \li calcDir(): returns the current Direction the track is flying on.
+    \li tick(): makes a Step on the Path. increases localTime by dt.
+    \li choosePath(): a Function that decides which Path we should follow.
+   
+   TrackManager can be handled as a StateMachine.
+   \n\n
+    Names: 
+    \li TrackManager: handles Tracks
+    \li Track:        The Track that the ship can follow
+    \li Path:         one way through the Level, that is dependent on conditionals.
+    \li Conditional:  A decition making device, that chooses betwen different TrackElements for the Path.
+    \li TrackElement: A Part of A whole Track
+*/
+class TrackManager : public BaseObject
+{
+ private:
+  TrackManager(void);
+
+  static TrackManager* singletonRef;  //!< There may only be one TrackManager existing.
+  TrackElement* firstTrackElem;       //!< The first TrackElement that exists.
+  TrackElement* currentTrackElem;     //!< The TrackElement we are working on.
+  float localTime;                    //!< The time that has been passed since the traveling the Track.
+  float maxTime;                      //!< The maximal time the track has.
+  int trackElemCount;                 //!< The count of TrackElements that exist.
+  
+  void initChildren(unsigned int childCount);
+
+  TrackElement* findTrackElementByID(unsigned int trackID) const;
+  
+ public:
+  ~TrackManager(void);
+  static TrackManager* getInstance(void);
+
+  // Methods to change the Path (initialisation)
+  void workOn(unsigned int trackID);
+  void setCurveType(CurveType curveType);
+  void setDuration(float time);
+  bool addPoint(Vector newPoint);
+  bool addPoint(Vector newPoint, TrackElement* trackElem);
+  int addHotPoint(Vector newPoint);
+  int setSavePoint(void);
+  void fork(unsigned int count, ...);
+  void forkV(unsigned int count, int* trackIDs);
+  void condition(unsigned int groupID, PathCondition cond); //!< \todo really do this!!
+  void join(unsigned int count, ...);
+  void joinV(unsigned int count, int* trackIDs);
+
+  // Methods to calculate the position on the Path (runtime)
+  Vector calcPos(void) const;
+  Vector calcDir(void) const;
+  void tick(float dt);
+  void jumpTo(float time);
+  void choosePath(int graphID);
+
+  // DEBUG //
+  void drawGraph(float dt) const;
+  void debug(unsigned int level) const;
+};
+
+#endif /* _TRACK_MANAGER_H */
Index: orxonox/trunk/src/vector.cc
===================================================================
--- orxonox/trunk/src/vector.cc	(revision 3364)
+++ orxonox/trunk/src/vector.cc	(revision 3365)
@@ -844,122 +844,2 @@
 }
 
-
-/**
-   \brief Creates a new BezierCurve
-*/
-BezierCurve::BezierCurve (void)
-{
-  nodeCount = 0;
-  firstNode = new PathNode;
-  currentNode = firstNode;
-
-  firstNode->position = Vector (.0, .0, .0);
-  firstNode->number = 0;
-  firstNode->next = 0; // not sure if this really points to NULL!!
-
-  return;
-}
-
-/**
-   \brief Deletes a BezierCurve.
-   It does this by freeing all the space taken over from the nodes
-*/
-BezierCurve::~BezierCurve (void)
-{
-  PathNode* tmpNode;
-  currentNode = firstNode;
-  while (tmpNode != 0)
-    {
-      tmpNode = currentNode;
-      currentNode = currentNode->next;
-      delete tmpNode;
-    }
-}
-
-/**
-   \brief adds a new Node to the bezier Curve
-   \param newNode a Vector to the position of the new node
-*/
-void BezierCurve::addNode(const Vector& newNode)
-{
-  PathNode* tmpNode;
-  if (nodeCount == 0 )
-    tmpNode = firstNode;
-  else
-    {
-      tmpNode = new PathNode;
-      currentNode = currentNode->next = tmpNode;
-    }
-  tmpNode->position = newNode;
-  tmpNode->next = 0; // not sure if this really points to NULL!!
-  tmpNode->number = (++nodeCount);
-  return;
-}
-
-/**
-   \brief calculates the Position on the curve
-   \param t The position on the Curve (0<=t<=1)
-   \return the Position on the Path
-*/
-Vector BezierCurve::calcPos(float t) 
-{
-  if (nodeCount <=4)
-    {
-      //      if (verbose >= 1)
-      //      printf ("Please define at least 4 nodes, until now you have only defined %i.\n", nodeCount);
-      curvePoint = Vector(0,0,0);
-    }
-  PathNode* tmpNode = firstNode;
-    
-  int k,kn,nn,nkn;
-  double blend,muk,munk;
-  Vector b = Vector(0.0,0.0,0.0);
-  
-  muk = 1;
-  munk = pow(1-t,(double)nodeCount);
-  
-  for (k=0; k<=nodeCount; k++) {
-    nn = nodeCount;
-    kn = k;
-    nkn = nodeCount - k;
-    blend = muk * munk;
-    muk *= t;
-    munk /= (1-t);
-    while (nn >= 1) {
-      blend *= nn;
-      nn--;
-      if (kn > 1) {
-	blend /= (double)kn;
-	kn--;
-      }
-      if (nkn > 1) {
-	blend /= (double)nkn;
-	nkn--;
-      }
-    }
-    b.x += tmpNode->position.x * blend;
-    b.y += tmpNode->position.y * blend;
-    b.z += tmpNode->position.z * blend;
-
-    tmpNode = tmpNode->next;
-  }
-  return b;
-}
-
-Vector BezierCurve::calcDirection (float t)
-{
-  double diff = .00000000001;
-  
-  Vector diffV = ((calcPos(t+diff) - calcPos(t))/diff);
-  diffV.normalize();
-  return diffV;
-}
-
-/**
-  \brief returns the Position of the point calculated on the Curve
-  \return a Vector to the calculated position
-*/
-Vector BezierCurve::getPos() const
-{
-  return curvePoint;
-}
Index: orxonox/trunk/src/vector.h
===================================================================
--- orxonox/trunk/src/vector.h	(revision 3364)
+++ orxonox/trunk/src/vector.h	(revision 3365)
@@ -149,39 +149,3 @@
 };
 
-
-
-//! Bezier Curve
-/**
-   Class to handle bezier curves in 3-dimesnsional space
-   
-   needed for  the Tracking system in OrxOnoX.
-*/
-class BezierCurve
-{
- private:
-  int nodeCount;
-  Vector curvePoint;
-  
-  struct PathNode
-  {
-    int number;
-    Vector position;
-    PathNode* next;
-  };
-
-  PathNode* firstNode; 
-  PathNode* currentNode; 
-
- public:
-  BezierCurve (void);
-  ~BezierCurve (void);
-  void addNode (const Vector& newNode);
-  Vector calcPos (float t);
-  Vector calcDirection (float t);
-  
-  Vector getPos () const;
-};
-
-
-
 #endif /* _VECTOR_H */
Index: orxonox/trunk/src/world.cc
===================================================================
--- orxonox/trunk/src/world.cc	(revision 3364)
+++ orxonox/trunk/src/world.cc	(revision 3365)
@@ -18,4 +18,5 @@
 #include "world_entity.h"
 #include "collision.h"
+#include "track_manager.h"
 #include "track.h"
 #include "player.h"
@@ -23,4 +24,8 @@
 #include "camera.h"
 #include "environment.h"
+#include "p_node.h"
+#include "null_parent.h"
+#include "helper_parent.h"
+#include "glmenu_imagescreen.h"
 
 using namespace std;
@@ -34,4 +39,5 @@
 World::World (char* name)
 {
+  this->setClassName ("World");
   this->worldName = name;
   this->debugWorldNr = -1;
@@ -48,4 +54,7 @@
 /** 
     \brief remove the World from memory
+    
+    delete everything explicitly, that isn't contained in the parenting tree!
+    things contained in the tree are deleted automaticaly
 */
 World::~World ()
@@ -57,4 +66,9 @@
   this->localCamera->destroy();
 
+  this->nullParent->destroy ();
+
+  //delete this->trackManager;
+
+  /*
   WorldEntity* entity = entities->enumerate();  
   while( entity != NULL ) 
@@ -64,10 +78,18 @@
     }
   this->entities->destroy();
-
-  delete this->entities;
-  delete this->localCamera;
+  */
+
+  /* FIX the parent list has to be cleared - not possible if we got the old list also*/
+
+
+  //delete this->entities;
+  //delete this->localCamera;
   /* this->localPlayer hasn't to be deleted explicitly, it is 
      contained in entities*/
 }
+
+GLfloat ctrlpoints[4][3] = {
+  {20.0, 10.0, 5.0}, {40.0, -10.0, 0.0},
+  {60.0, -10.0, 5.0}, {80.0, 10.0, 5.0}};
 
 
@@ -78,5 +100,15 @@
   cn->addToWorld(this);
   cn->enable(true);
-}
+
+  //glMap1f (GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
+  //glEnable (GL_MAP1_VERTEX_3);
+  
+  //theNurb = gluNewNurbsRenderer ();
+  //gluNurbsProperty (theNurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
+  //gluNurbsProperty (theNurb, GLU_NURBS_VERTEX, vertexCallback );
+
+}
+
+
 
 ErrorMessage World::start()
@@ -99,4 +131,5 @@
 }
 
+
 ErrorMessage World::resume()
 {
@@ -104,13 +137,100 @@
 }
 
+
 void World::destroy()
 {
-
-}
+}
+
+
+void World::displayLoadScreen ()
+{
+  printf ("World::displayLoadScreen - start\n"); 
+  
+  //GLMenuImageScreen* 
+  glmis = new GLMenuImageScreen();
+  glmis->init();
+  glmis->draw();
+ 
+  printf ("World::displayLoadScreen - end\n"); 
+}
+
+
+void World::releaseLoadScreen ()
+{
+  printf ("World::releaseLoadScreen - start\n"); 
+
+  printf ("World::releaseLoadScreen - end\n"); 
+}
+
 
 void World::load()
 {
+  //  BezierCurve* tmpCurve = new BezierCurve();
   if(this->debugWorldNr != -1)
     {
+      trackManager = TrackManager::getInstance();
+      trackManager->addPoint(Vector(0,-5,0));
+      trackManager->addPoint(Vector(10,0,5));
+      trackManager->addPoint(Vector(20,0,-5));
+      trackManager->addPoint(Vector(30,0,5));
+      trackManager->addPoint(Vector(40,0,5));
+      trackManager->setDuration(.5);
+      trackManager->setSavePoint();
+      trackManager->addPoint(Vector(50,10,10));
+      trackManager->addPoint(Vector(60,0, 10));
+      trackManager->addPoint(Vector(70,0, 10));
+      trackManager->addPoint(Vector(80,0,-10));
+      trackManager->addPoint(Vector(90,0,-10));
+      trackManager->setDuration(.5);
+      trackManager->setSavePoint();
+      trackManager->addPoint(Vector(110,0,5));
+      trackManager->addPoint(Vector(120,0, 10));
+      trackManager->addPoint(Vector(130,0, 10));
+      trackManager->addPoint(Vector(140,0,-10));
+      trackManager->addPoint(Vector(150,0,-10));
+      trackManager->setDuration(.5);
+      int fork11, fork12, fork13, fork14;
+      trackManager->fork(4, &fork11, &fork12, &fork13, &fork14);
+      trackManager->workOn(fork11);
+      trackManager->addPoint(Vector(170, 0, -15));
+      trackManager->addPoint(Vector(180, 0, -15));
+      trackManager->workOn(fork12);
+      trackManager->addPoint(Vector(170, 0, 10));
+      trackManager->addPoint(Vector(180, 0, 10));
+      trackManager->addPoint(Vector(190,2,5));
+      trackManager->addPoint(Vector(200,2,5));
+      int fork21, fork22;
+      trackManager->fork(2, &fork21, &fork22);
+      trackManager->workOn(fork21);
+      trackManager->addPoint(Vector(220, 10,-10));
+      trackManager->addPoint(Vector(230, 0,-10));
+      trackManager->addPoint(Vector(240, 0, 2));
+      trackManager->addPoint(Vector(250, 0, 0));
+      trackManager->addPoint(Vector(260, 0, 5));
+      trackManager->join(2, fork12, fork11);
+      trackManager->workOn(fork22);
+      trackManager->addPoint(Vector(220, -10,10));
+      trackManager->addPoint(Vector(230, 0, 10));
+      trackManager->addPoint(Vector(240, 0, 10));
+      trackManager->addPoint(Vector(250, 0, 5));
+      trackManager->workOn(fork13);
+      trackManager->addPoint(Vector(200,-10,5));
+      trackManager->addPoint(Vector(250,-10,5));
+      printf("fork14: %d\n", fork14);
+      trackManager->workOn(fork14);
+      trackManager->addPoint(Vector(200,15,0));
+      trackManager->addPoint(Vector(210,0,10));
+
+
+
+      trackManager->join(4, fork21, fork22, fork13, fork14);
+
+      /*
+      tmpCurve->addNode(Vector(10,0,-10));
+      //tmpCurve->addNode(Vector(10,2,5));
+      //tmpCurve->addNode(Vector(10,3,-5));
+      //      tmpCurve->addNode(Vector(10,1,5));
+      tmpCurve->addNode(Vector(10,0,5));
+      */
       switch(this->debugWorldNr)
 	{
@@ -123,4 +243,7 @@
 	case DEBUG_WORLD_0:
 	  {
+	    this->nullParent = NullParent::getInstance ();
+	    this->nullParent->setName ("NullParent");
+
 	    // create some path nodes
 	    this->pathnodes = new Vector[6];
@@ -141,22 +264,31 @@
 	    // !\todo old track-system has to be removed
 
+	    //create helper for player
+	    HelperParent* hp = new HelperParent ();
+	    /* the player has to be added to this helper */
+
 	    // create a player
-	    WorldEntity* myPlayer = new Player();
-	    this->spawn(myPlayer);
+	    WorldEntity* myPlayer = new Player ();
+	    myPlayer->setName ("player");
+	    this->spawn (myPlayer);
 	    this->localPlayer = myPlayer;	    
 
 	    // bind input
-	    Orxonox *orx = Orxonox::getInstance();
+	    Orxonox *orx = Orxonox::getInstance ();
 	    orx->getLocalInput()->bind (myPlayer);
 	    
 	    // bind camera
 	    this->localCamera = new Camera(this);
-	    this->getCamera()->bind (myPlayer);	
-
-	    Placement* plc = new Placement;
-	    plc->r = Vector(100, 10, 10);
-	    plc->w = Quaternion();
+	    this->localCamera->setName ("camera");
+	    this->getCamera()->bind (myPlayer);
+	    this->localPlayer->addChild (this->localCamera);
+	    
+
+	    Vector* es = new Vector (50, 2, 0);
+	    Quaternion* qs = new Quaternion ();
 	    WorldEntity* env = new Environment();
-	    this->spawn(env, plc);
+	    env->setName ("env");
+	    this->spawn(env, es, qs);
+
 
 	    break;
@@ -164,4 +296,17 @@
 	case DEBUG_WORLD_1:
 	  {
+	    /*
+	    this->testCurve = new UPointCurve();
+	    this->testCurve->addNode(Vector( 0, 0, 0));
+	    this->testCurve->addNode(Vector(10, 0, 5));
+	    this->testCurve->addNode(Vector(20, -5,-5));
+	    this->testCurve->addNode(Vector(30, 5, 10));
+	    this->testCurve->addNode(Vector(40, 0,-10));
+	    this->testCurve->addNode(Vector(50, 0,-10));
+	    */
+
+	    this->nullParent = NullParent::getInstance ();
+	    this->nullParent->setName ("NullParent");
+
 	    // create some path nodes
 	    this->pathnodes = new Vector[6];
@@ -173,4 +318,7 @@
 	    this->pathnodes[5] = Vector(30, 50, 0);
 	    
+
+
+
 	    // create the tracks
 	    this->tracklen = 6;
@@ -183,4 +331,5 @@
 	    // create a player
 	    WorldEntity* myPlayer = new Player();
+	    myPlayer->setName ("player");
 	    this->spawn(myPlayer);
 	    this->localPlayer = myPlayer;	    
@@ -191,6 +340,8 @@
 	    
 	    // bind camera
-	    this->localCamera = new Camera(this);
+	    this->localCamera = new Camera (this);
+	    this->localCamera->setName ("camera");
 	    this->getCamera()->bind (myPlayer);	
+	    this->localPlayer->addChild (this->localCamera);
 	    break;
 	  }
@@ -212,16 +363,16 @@
 
   int sizeX = 100;
-  int sizeY = 80;
+  int sizeZ = 80;
   float length = 1000;
   float width = 200;
   float widthX = float (length /sizeX);
-  float widthY = float (width /sizeY);
-  
-  float height [sizeX][sizeY];
-  Vector normal_vectors[sizeX][sizeY];
+  float widthZ = float (width /sizeZ);
+  
+  float height [sizeX][sizeZ];
+  Vector normal_vectors[sizeX][sizeZ];
   
   
   for ( int i = 0; i<sizeX-1; i+=1)
-    for (int j = 0; j<sizeY-1;j+=1)
+    for (int j = 0; j<sizeZ-1;j+=1)
       //height[i][j] = rand()/20046 + (j-25)*(j-25)/30;
 #ifdef __WIN32__
@@ -231,20 +382,19 @@
 #endif
 
-  //Die Hügel ein wenig glätten
+  //Die Huegel ein wenig glaetten
   for (int h=1; h<2;h++)
     for (int i=1;i<sizeX-2 ;i+=1 )
-      for(int j=1;j<sizeY-2;j+=1)
+      for(int j=1;j<sizeZ-2;j+=1)
 	height[i][j]=(height[i+1][j]+height[i][j+1]+height[i-1][j]+height[i][j-1])/4;
   
   //Berechnung von normalen Vektoren
-
   for(int i=1;i<sizeX-2;i+=1)
-    for(int j=1;j<sizeY-2 ;j+=1)
+    for(int j=1;j<sizeZ-2 ;j+=1)
       {
-	Vector v1 = Vector (widthX*(1),      widthY*(j)  ,      height[i][j]);
-	Vector v2 = Vector (widthX*(i-1),    widthY*(j)  ,      height[i-1][j]);
-	Vector v3 = Vector (widthX*(i),      widthY*(j+1),      height[i][j+1]);
-	Vector v4 = Vector (widthX*(i+1),    widthY*(j),        height[i+1][j]);
-	Vector v5 = Vector (widthX*(i),      widthY*(j-1),      height[i][j-1]);
+	Vector v1 = Vector (widthX*(1),      height[i][j],      widthZ*(j) );
+	Vector v2 = Vector (widthX*(i-1),    height[i-1][j],    widthZ*(j));
+	Vector v3 = Vector (widthX*(i),      height[i][j+1],    widthZ*(j+1));
+	Vector v4 = Vector (widthX*(i+1),    height[i+1][j],    widthZ*(j));
+	Vector v5 = Vector (widthX*(i),      height[i][j-1],    widthZ*(j-1));
 	
 	Vector c1 = v2 - v1;
@@ -253,5 +403,5 @@
 	Vector c4 = v5 - v1;
 	Vector zero = Vector (0,0,0);
-	normal_vectors[i][j]=c1.cross(v4-v2)+c2.cross(v1-v3)+c3.cross(v2-v4)+c4.cross(v3-v1);
+	normal_vectors[i][j]=c1.cross(v3-v5)+c2.cross(v4-v2)+c3.cross(v5-v3)+c4.cross(v2-v4);
 	normal_vectors[i][j].normalize();
       }
@@ -259,10 +409,10 @@
   int snowheight=3;
   for ( int i = 0; i<sizeX; i+=1)
-    for (int j = 0; j<sizeY;j+=1)
+    for (int j = 0; j<sizeZ;j+=1)
       {	  
-	Vector v1 = Vector (widthX*(i),      widthY*(j)  -width/2,      height[i][j]-20 );
-	Vector v2 = Vector (widthX*(i+1),    widthY*(j)  -width/2,      height[i+1][j]-20);
-	Vector v3 = Vector (widthX*(i+1),    widthY*(j+1)-width/2,    height[i+1][j+1]-20);
-	Vector v4 = Vector (widthX*(i),      widthY*(j+1)-width/2,    height[i][j+1]-20);
+	Vector v1 = Vector (widthX*(i),      height[i][j]-20,       widthZ*(j)  -width/2);
+	Vector v2 = Vector (widthX*(i+1),    height[i+1][j]-20,     widthZ*(j)  -width/2);
+	Vector v3 = Vector (widthX*(i+1),    height[i+1][j+1]-20,   widthZ*(j+1)-width/2);
+	Vector v4 = Vector (widthX*(i),      height[i][j+1]-20,     widthZ*(j+1)-width/2);
 	float a[3];
 	if(height[i][j]<snowheight){
@@ -371,5 +521,5 @@
   //draw track
   glBegin(GL_LINES);
-  glColor3f(0,1,1);
+  glColor3f(0.0, 1.0, 1.0);
   for( int i = 0; i < tracklen; i++)
     {
@@ -378,4 +528,29 @@
     }
   glEnd();
+  
+  /*
+  glBegin(GL_LINE_STRIP);
+  glColor3f(1.0, 5.0, 1.0);
+  for( int i = 0; i <= 30; i++)
+    {
+      glEvalCoord1f ((GLfloat) i/30.0);
+    }
+  glEnd();
+  */
+
+  trackManager->drawGraph(.01);
+  trackManager->debug(2);
+  delete trackManager;
+  
+  /*
+  glBegin(GL_LINES);
+  float i;
+  for(i = 0.0; i<1; i+=.01)
+    {
+      printf("%f, %f, %f\n",tmpCurve->calcPos(i).x, tmpCurve->calcPos(i).y, tmpCurve->calcPos(i).z);
+      glVertex3f(tmpCurve->calcPos(i).x, tmpCurve->calcPos(i).y, tmpCurve->calcPos(i).z);
+    }
+  glEnd();
+  */
   glEndList();
 }
@@ -430,9 +605,6 @@
 void World::draw ()
 {
-  // draw geometry
-  
   // draw entities
   WorldEntity* entity;
-  
   entity = this->entities->enumerate();
   while( entity != NULL ) 
@@ -440,10 +612,11 @@
       if( entity->bDraw ) entity->draw();
       entity = this->entities->nextElement();
-    }
-  
-  
+    } 
+  
+  //glmis = new GLMenuImageScreen();
+  ///glmis->init();
+
   // draw debug coord system
   glCallList (objectList);
-
 
 }
@@ -459,4 +632,5 @@
 void World::update ()
 {
+  /*
   //List<WorldEntity> *l;
   WorldEntity* entity;
@@ -477,5 +651,4 @@
 	  t = loc->part;
 	  
-	  /* check if entity has still a legal track-id */
 	  if( t >= tracklen )
 	    {
@@ -500,14 +673,9 @@
       else
 	{
-	  /* \todo: implement check whether this particular free entity 
-	     is out of the game area
-	     \todo: call function to notify the entity that it left 
-	     the game area
-	  */
 	}
       
       entity = entities->nextElement();
     }
-  
+  */  
 }
 
@@ -522,4 +690,7 @@
   float seconds = deltaT / 1000.0;
   
+  this->nullParent->update (seconds);
+  //this->nullParent->processTick (seconds);
+
   entity = entities->enumerate(); 
   while( entity != NULL) 
@@ -542,15 +713,4 @@
 
 
-
-/**
-   \brief calls the correct mapping function to convert a given "look at"-Location to a 
-   Camera Placement
-*/
-void World::calcCameraPos (Location* loc, Placement* plc)
-{
-  track[loc->part].mapCamera (loc, plc);
-}
-
-
 void World::setTrackLen(Uint32 len)
 {
@@ -571,7 +731,54 @@
 void World::debug()
 {
-  //List<WorldEntity> *l;
+  printf ("World::debug() - starting debug\n");
+  PNode* p1 = NullParent::getInstance ();
+  PNode* p2 = new PNode (new Vector(2, 2, 2), p1);
+  PNode* p3 = new PNode (new Vector(4, 4, 4), p1);
+  PNode* p4 = new PNode (new Vector(6, 6, 6), p2);
+
+  p1->debug ();
+  p2->debug ();
+  p3->debug ();
+  p4->debug ();
+
+  p1->shiftCoor (new Vector(-1, -1, -1));
+
+  printf("World::debug() - shift\n");
+  p1->debug ();
+  p2->debug ();
+  p3->debug ();
+  p4->debug ();
+  
+  p1->update (1);
+
+  printf ("World::debug() - update\n");
+  p1->debug ();
+  p2->debug ();
+  p3->debug ();
+  p4->debug ();
+
+  p2->shiftCoor (new Vector(-1, -1, -1));
+  p1->update (2);
+
+  p1->debug ();
+  p2->debug ();
+  p3->debug ();
+  p4->debug ();
+
+  p2->setAbsCoor (new Vector(1,2,3));
+
+
+ p1->update (2);
+
+  p1->debug ();
+  p2->debug ();
+  p3->debug ();
+  p4->debug ();
+
+  p1->destroy ();
+  
+  
+  /*
   WorldEntity* entity;
-  
   printf("counting all entities\n");
   printf("World::debug() - enumerate()\n");
@@ -582,4 +789,5 @@
       entity = entities->nextElement();
     }
+  */
 }
 
@@ -594,12 +802,12 @@
 void World::mainLoop()
 {
-  this->lastFrame = SDL_GetTicks();
+  this->lastFrame = SDL_GetTicks ();
   printf("World::mainLoop() - Entering main loop\n");
   while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* \todo implement pause */
     {
       // Network
-      synchronize();
+      this->synchronize ();
       // Process input
-      handleInput();
+      this->handleInput ();
       if( this->bQuitCurrentGame || this->bQuitOrxonox)
 	{
@@ -608,11 +816,12 @@
 	}
       // Process time
-      timeSlice();
+      this->timeSlice ();
       // Process collision
-      collision();
+      this->collision ();
       // Draw
-      display();
-  
-      for(int i = 0; i < 10000000; i++) {}
+      this->display ();
+  
+      for( int i = 0; i < 5000000; i++) {}
+      /* \todo this is to slow down the program for openGl Software emulator computers, reimplement*/
     }
   printf("World::mainLoop() - Exiting the main loop\n");
@@ -701,6 +910,9 @@
   this->draw();
   // draw HUD
+  /* \todo draw HUD */
   // flip buffers
   SDL_GL_SwapBuffers();
+  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
+  //SDL_Flip (screen);
 }
 
@@ -723,19 +935,9 @@
 void World::spawn(WorldEntity* entity)
 {
-  Location zeroloc;
-  Location* loc = NULL;
-  WorldEntity* owner;
-
-  entities->add (entity);
-  zeroloc.dist = 0;
-  zeroloc.part = 0;
-  zeroloc.pos = Vector();
-  zeroloc.rot = Quaternion();
-  loc = &zeroloc;
-  entity->init (loc, owner);
-  if (entity->bFree)
-    {
-      this->track[loc->part].mapCoords( loc, entity->getPlacement());
-    }
+  if( this->nullParent != NULL && entity->parent == NULL)
+    this->nullParent->addChild (entity);
+
+  this->entities->add (entity);
+
   entity->postSpawn ();
 }
@@ -747,47 +949,17 @@
    \param location where to add
 */
-void World::spawn(WorldEntity* entity, Location* loc)
-{
-  Location zeroLoc;
-  WorldEntity* owner;
+void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
+{
+  entity->setAbsCoor (absCoor);
+  entity->setAbsDir (absDir);
+  
+  if( this->nullParent != NULL && entity->parent == NULL)
+    this->nullParent->addChild (entity);
+
   this->entities->add (entity);
-  if( loc == NULL)
-    {
-      zeroLoc.dist = 0;
-      zeroLoc.part = 0;
-      zeroLoc.pos = Vector();
-      zeroLoc.rot = Quaternion();
-      loc = &zeroLoc;
-    }
-  entity->init (loc, owner);
-  if (entity->bFree)
-    {
-      this->track[loc->part].mapCoords( loc, entity->getPlacement());
-    }
+
   entity->postSpawn ();
-  //return entity;
-}
-
-
-/**
-   \brief add and spawn a new entity to this world
-   \param entity to be added
-   \param place where to be added
-*/
-void World::spawn(WorldEntity* entity, Placement* plc)
-{
-  Placement zeroPlc;
-  WorldEntity* owner;
-  if( plc == NULL)
-    {
-      zeroPlc.r = Vector();
-      zeroPlc.w = Quaternion();
-      plc = &zeroPlc;
-    }
-  this->entities->add (entity);
-  entity->init (plc, owner);
-  entity->postSpawn ();
-  //return entity;
-}
+}
+
 
 
@@ -800,2 +972,13 @@
   return false;
 }
+
+
+
+
+void World::swap (unsigned char &a, unsigned char &b)
+{
+  unsigned char temp;
+  temp = a;
+  a    = b;
+  b    = temp;
+}
Index: orxonox/trunk/src/world.h
===================================================================
--- orxonox/trunk/src/world.h	(revision 3364)
+++ orxonox/trunk/src/world.h	(revision 3365)
@@ -11,8 +11,10 @@
 
 
-
+class TrackManager;
 class Track;
 class WorldEntity;
 class Camera;
+class PNode;
+class GLMenuImageScreen;
 
 //! The game environment
@@ -23,9 +25,4 @@
   World (int worldID);
   virtual ~World ();
-
-  template<typename T> 
-    T* spawn (Location* loc, WorldEntity* owner);	// template to be able to spawn any derivation of WorldEntity
-  template<typename T> 
-    T* spawn (Placement* plc, WorldEntity* owner);
   
   virtual ErrorMessage init ();
@@ -38,12 +35,16 @@
   virtual void destroy ();
 
+  //static void vertexCallback (GLfloat* vertex);
+
   void timeSlice (Uint32 deltaT);
   void collide ();
   void draw ();
   void update ();	// maps Locations to Placements
-  void calcCameraPos (Location* loc, Placement* plc);
+  //void calcCameraPos (Location* loc, Placement* plc);
 	
   void unload ();
   bool command (Command* cmd);
+  virtual void displayLoadScreen();
+  virtual void releaseLoadScreen();
   
   void setTrackLen (Uint32 tracklen);
@@ -53,10 +54,10 @@
 
   void spawn (WorldEntity* entity);
-  void spawn (WorldEntity* entity, Location* loc);
-  void spawn (WorldEntity* entity, Placement* plc);
+  void spawn (WorldEntity* entity, Vector* absCoor, Quaternion* absDir);
 
   tList<WorldEntity>* entities;
   
   // base level data
+  TrackManager* trackManager;
   Track* track;
   Uint32 tracklen;   // number of Tracks the World consist of
@@ -64,4 +65,6 @@
   Camera* localCamera;  
 
+
+  UPointCurve* testCurve;
  private:
   Uint32 lastFrame; //!> last time of frame
@@ -70,10 +73,15 @@
   bool bPause;
 
+  GLMenuImageScreen* glmis;
+
   char* worldName;
   int debugWorldNr;
   GLuint objectList;
+  SDL_Surface *loadImage;
 
   WorldEntity* localPlayer;
-  
+ 
+  PNode* nullParent;
+ 
   void mainLoop ();
   void synchronize ();
@@ -83,4 +91,6 @@
   void display ();
   void debug ();
+
+  void swap (unsigned char &a, unsigned char &b); /* \todo: this function doesn't belong here, this should be part of a image class*/
 };
 
Index: orxonox/trunk/src/world_entity.cc
===================================================================
--- orxonox/trunk/src/world_entity.cc	(revision 3364)
+++ orxonox/trunk/src/world_entity.cc	(revision 3365)
@@ -36,7 +36,7 @@
 WorldEntity::WorldEntity (bool isFree) : bFree(isFree)
 {
+  this->setClassName ("WorldEntity");
   this->bDraw = true;
   collisioncluster = NULL;
-  owner = NULL;
 }
 
@@ -53,8 +53,10 @@
    \return a pointer to location
 */
+/*PN
 Location* WorldEntity::getLocation ()
 {
   return &loc;
 }
+*/
 
 /**
@@ -62,9 +64,10 @@
    \return a pointer to placement
 */
+ /*PN
 Placement* WorldEntity::getPlacement ()
 {
   return &place;
 }
-
+ */
 /**
    \brief query whether the WorldEntity in question is free
@@ -89,4 +92,5 @@
 }
 
+
 /**
    \brief this method is called every frame
@@ -99,4 +103,26 @@
 }
 
+
+/** 
+    \brief process draw function 
+*/
+void WorldEntity::processDraw ()
+{
+  this->draw ();
+  PNode* pn = this->children->enumerate ();
+  while( pn != NULL) 
+    { 
+      ((WorldEntity*)pn)->processDraw ();
+      pn = this->children->nextElement();
+    } 
+}
+
+
+void WorldEntity::setDrawable (bool bDraw)
+{
+  this->bDraw = bDraw;
+}
+
+
 /**
    \brief the entity is drawn onto the screen with this function
@@ -105,6 +131,5 @@
 */
 void WorldEntity::draw() 
-{
-}
+{}
 
 /**
@@ -134,22 +159,4 @@
 void WorldEntity::destroy() {}
 
-
-/**
-   \brief basic initialisation for bound Entities
-*/
-void WorldEntity::init( Location* spawnloc, WorldEntity* spawnowner)
-{
-  loc = *spawnloc;
-  owner = spawnowner;
-}
-
-/**
-   \brief basic initialisation for free Entities
-*/
-void WorldEntity::init( Placement* spawnplc, WorldEntity* spawnowner)
-{
-  place = *spawnplc;
-  owner = spawnowner;
-}
 
 /**
@@ -181,7 +188,9 @@
    to look at the location you return with this.
 */
+/*PN
 void WorldEntity::getLookat (Location* locbuf)
 {
 }
+*/
 
 /**
Index: orxonox/trunk/src/world_entity.h
===================================================================
--- orxonox/trunk/src/world_entity.h	(revision 3364)
+++ orxonox/trunk/src/world_entity.h	(revision 3365)
@@ -8,18 +8,20 @@
 
 #include "stdincl.h"
+#include "p_node.h"
 
 class CollisionCluster;
+class Model;
 
 //! Basic class from which all interactive stuff in the world is derived from
-class WorldEntity
+class WorldEntity : public PNode
 {	
   friend class World;
-  
+
  public:
   WorldEntity (bool isFree = false);
   virtual ~WorldEntity ();
+
+  Model* model;
   
-  Location* getLocation ();
-  Placement* getPlacement ();
   void setCollision (CollisionCluster* newhull);
   
@@ -35,7 +37,8 @@
   virtual void collide (WorldEntity* other,  Uint32 ownhitflags, Uint32 otherhitflags);
   virtual void command (Command* cmd);
-  
+
+  void processDraw ();
   virtual void draw ();
-  virtual void getLookat (Location* locbuf);
+  void setDrawable (bool bDraw);
   
   virtual void leftWorld ();
@@ -45,12 +48,6 @@
   bool bCollide;
   bool bDraw;
-  
-  WorldEntity* owner;
+
   CollisionCluster* collisioncluster;
-  Placement place;
-  Location loc;
-  
-  void init( Location* spawnloc, WorldEntity* spawnowner);
-  void init( Placement* spawnplc, WorldEntity* spawnowner);
 };
 
