Index: orxonox/trunk/src/Makefile.am
===================================================================
--- orxonox/trunk/src/Makefile.am	(revision 2077)
+++ orxonox/trunk/src/Makefile.am	(revision 2190)
@@ -1,4 +1,4 @@
 AM_CXXFLAGS="-I/usr/X11R6/include"
-AM_LDFLAGS="-L/usr/Mesa-6.0.1/lib  -L/usr/X11R6/lib -lXt -lX11"
+AM_LDFLAGS="-L/usr/Mesa-6.0.1/lib  -L/usr/X11R6/lib -lXt -lX11" $(MWINDOWS)
 
 #"-O3 -pedantic -fPIC -ffast-math -I/usr/X11R6/include"
@@ -6,8 +6,8 @@
 
 bin_PROGRAMS=orxonox
-orxonox_SOURCES=orxonox.cc world.cc environment.cc player.cc npc.cc input_output.cc data_tank.cc ai.cc shoot_laser.cc shoot_rocket.cc world_entity.cc synchronisable.cc vector.cc ability.cc power_up.cc
+orxonox_SOURCES=orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc 
 
 #  uncomment the following if bencoder requires the math library
-#gui_LDADD=-lm
+#orxonox_LDADD=-lm
 
 #EXTRA_DIST=orxonox.lsm.in orxonox.spec.in orxonox.texinfo
Index: orxonox/trunk/src/Makefile.in
===================================================================
--- orxonox/trunk/src/Makefile.in	(revision 2077)
+++ orxonox/trunk/src/Makefile.in	(revision 2190)
@@ -112,10 +112,10 @@
 target_alias = @target_alias@
 AM_CXXFLAGS = "-I/usr/X11R6/include"
-AM_LDFLAGS = "-L/usr/Mesa-6.0.1/lib  -L/usr/X11R6/lib -lXt -lX11"
+AM_LDFLAGS = "-L/usr/Mesa-6.0.1/lib  -L/usr/X11R6/lib -lXt -lX11" $(MWINDOWS)
 
 
 #"-O3 -pedantic -fPIC -ffast-math -I/usr/X11R6/include"
 bin_PROGRAMS = orxonox
-orxonox_SOURCES = orxonox.cc world.cc environment.cc player.cc npc.cc input_output.cc data_tank.cc ai.cc shoot_laser.cc shoot_rocket.cc world_entity.cc synchronisable.cc vector.cc ability.cc power_up.cc
+orxonox_SOURCES = orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc 
 subdir = src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -126,10 +126,8 @@
 PROGRAMS = $(bin_PROGRAMS)
 
-am_orxonox_OBJECTS = orxonox.$(OBJEXT) world.$(OBJEXT) \
-	environment.$(OBJEXT) player.$(OBJEXT) npc.$(OBJEXT) \
-	input_output.$(OBJEXT) data_tank.$(OBJEXT) ai.$(OBJEXT) \
-	shoot_laser.$(OBJEXT) shoot_rocket.$(OBJEXT) \
-	world_entity.$(OBJEXT) synchronisable.$(OBJEXT) \
-	vector.$(OBJEXT) ability.$(OBJEXT) power_up.$(OBJEXT)
+am_orxonox_OBJECTS = orxonox.$(OBJEXT) world.$(OBJEXT) player.$(OBJEXT) \
+	data_tank.$(OBJEXT) world_entity.$(OBJEXT) vector.$(OBJEXT) \
+	camera.$(OBJEXT) collision.$(OBJEXT) command_node.$(OBJEXT) \
+	ini_parser.$(OBJEXT) keynames.$(OBJEXT) track.$(OBJEXT)
 orxonox_OBJECTS = $(am_orxonox_OBJECTS)
 orxonox_LDADD = $(LDADD)
@@ -140,12 +138,11 @@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
-@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/ability.Po ./$(DEPDIR)/ai.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/data_tank.Po ./$(DEPDIR)/environment.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/input_output.Po ./$(DEPDIR)/npc.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/orxonox.Po ./$(DEPDIR)/player.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/power_up.Po ./$(DEPDIR)/shoot_laser.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/shoot_rocket.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/synchronisable.Po ./$(DEPDIR)/vector.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/world.Po ./$(DEPDIR)/world_entity.Po
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/camera.Po ./$(DEPDIR)/collision.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/command_node.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/data_tank.Po ./$(DEPDIR)/ini_parser.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/keynames.Po ./$(DEPDIR)/orxonox.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/player.Po ./$(DEPDIR)/track.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/vector.Po ./$(DEPDIR)/world.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/world_entity.Po
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -200,16 +197,13 @@
 	-rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ability.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ai.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camera.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)/data_tank.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/environment.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input_output.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/npc.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)/orxonox.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/player.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/power_up.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shoot_laser.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shoot_rocket.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synchronisable.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/track.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@
@@ -414,5 +408,5 @@
 
 #  uncomment the following if bencoder requires the math library
-#gui_LDADD=-lm
+#orxonox_LDADD=-lm
 
 #EXTRA_DIST=orxonox.lsm.in orxonox.spec.in orxonox.texinfo
Index: orxonox/trunk/src/camera.cc
===================================================================
--- orxonox/trunk/src/camera.cc	(revision 2190)
+++ orxonox/trunk/src/camera.cc	(revision 2190)
@@ -0,0 +1,164 @@
+
+
+/* 
+   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: Christian Meyer
+   co-programmer: ...
+*/
+
+#include "camera.h"
+#include "world.h"
+#include "world_entity.h"
+
+using namespace std;
+
+/**
+   \brief creates a Camera
+   
+   This standard constructor sets all parameters to zero
+*/
+Camera::Camera ()
+{
+	bound = NULL;
+}
+
+/**
+   \brief default destructor
+*/
+Camera::~Camera ()
+{
+}
+
+/**
+   \brief time based actualisation of camera parameters
+   \param deltaT: The amount of time that has passed in milliseconds
+   
+   This is called by the World in every time_slice, use it to do fancy time dependant effects (such 
+   as smooth camera movement or swaying).
+*/
+void Camera::time_slice (Uint32 deltaT)
+{
+	update_desired_place ();
+	jump (NULL);
+}
+
+/**
+  \brief this calculates the location where the track wants the camera to be
+   
+	This refreshes the placement the camera should have according to the bound entity's position on the track.
+*/
+void Camera::update_desired_place ()
+{
+		Orxonox *orx = Orxonox::getInstance();
+		Location lookat;
+		
+		if( bound != NULL)
+		{
+			bound->get_lookat (&lookat);
+			orx->get_world()->calc_camera_pos (&lookat, &desired_place);
+		}
+		else
+		{
+			desired_place.r = Vector (0,0,0);
+			desired_place.w = Quaternion (); 
+		}
+}
+
+/**
+  \brief initialize rendering perspective according to this camera
+   
+	This is called immediately before the a rendering cycle starts, it sets all global rendering options as
+	well as the GL_PROJECTION matrix according to the camera.
+*/
+void Camera::apply ()
+{
+	glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+		// view
+		// TO DO: implement options for frustum generation
+	glFrustum( -1.0,1.0,-1.0,1.0,1.5,250.0);
+//Vector up(0,0,1);
+//Vector dir(1,0,0);
+//Quaternion q(dir,up);
+//float matrix[4][4];
+//q.conjugate().matrix (matrix);
+//glMultMatrixf ((float*)matrix);
+//glTranslatef (10,0,-5);
+//
+//dir = Vector(-1,-1,0);
+//q = Quaternion( dir, up);
+//glMatrixMode (GL_MODELVIEW);
+//glLoadIdentity ();
+//q.matrix (matrix);
+//glMultMatrixf ((float*)matrix);
+//glTranslatef (2,2,0);
+//
+//glBegin(GL_TRIANGLES);
+//glColor3f(1,0,0);
+//glVertex3f(0,0,0.5);
+//glColor3f(0,1,0);
+//glVertex3f(-0.5,0,-1);
+//glColor3f(0,0,1);
+//glVertex3f(0.5,0,-1);
+//glEnd();	
+
+  	// rotation
+  float matrix[4][4];
+  actual_place.w.conjugate().matrix (matrix);
+  glMultMatrixf ((float*)matrix);
+  	// translation
+  glTranslatef (-actual_place.r.x, -actual_place.r.y,- actual_place.r.z);
+  
+  glMatrixMode (GL_MODELVIEW);
+  glLoadIdentity ();
+  
+  printf("Camera@%f/%f/%f\n",actual_place.r.x,actual_place.r.y,actual_place.r.z);
+  Vector unique(1,0,0);
+  Vector test = actual_place.w.apply (unique);
+  printf("Camera&%f/%f/%f\n", test.x, test.y, test.z);
+}
+
+/**
+  \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)
+	{
+		actual_place = desired_place;
+	}
+	else
+	{
+		desired_place = *plc;
+		actual_place = *plc;
+	}
+}
+
+/**
+  \brief bind the camera to an entity
+  \param entity: The enitity to bind the camera to
+	
+	This sets the focus of the camera to the given entity. This means that it will use the given WorldEntity's
+	Location and get_lookat() to determine the viewpoint the camera will render from.
+	Note that you cannot bind a camera to a free entity.
+*/
+void Camera::bind (WorldEntity* entity)
+{
+	if( entity != NULL)
+	{
+		if( entity->isFree ()) printf("Cannot bind camera to free entity");
+		else bound = entity;
+	} 
+}
Index: orxonox/trunk/src/camera.h
===================================================================
--- orxonox/trunk/src/camera.h	(revision 2190)
+++ orxonox/trunk/src/camera.h	(revision 2190)
@@ -0,0 +1,39 @@
+/*! 
+    \file camera.h
+    \brief Viewpoint controlling class definitions
+*/ 
+
+#ifndef CAMERA_H
+#define CAMERA_H
+
+#include "stdincl.h"
+
+class WorldEntity;
+
+//! Camera
+/**
+ 	This class controls the viewpoint from which the World is rendered. To use the Camera it has
+ 	to be bound to a WorldEntity which serves as the reference focus point. The Camera itself calls
+ 	the WorldEntity::get_lookat() and World::calc_camera_pos() functions to calculate the position it
+ 	currently should be in.
+*/
+class Camera {
+ private:
+ 	WorldEntity* bound;		//!< the WorldEntity the Camera is bound to
+ 	Placement actual_place;	//!< the Camera's current position
+ 	Placement desired_place; //!< where the Camera should be according to calculations
+
+	void update_desired_place ();
+	
+ public:
+  Camera ();
+  ~Camera ();
+
+	void time_slice (Uint32 deltaT);
+	void apply ();
+	void bind (WorldEntity* entity);
+	void jump (Placement* plc);
+
+};
+
+#endif
Index: orxonox/trunk/src/collision.cc
===================================================================
--- orxonox/trunk/src/collision.cc	(revision 2190)
+++ orxonox/trunk/src/collision.cc	(revision 2190)
@@ -0,0 +1,381 @@
+
+
+/* 
+   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: Christian Meyer
+   co-programmer: ...
+*/
+
+
+#include "collision.h"
+
+using namespace std;
+
+/**
+   \brief simple CollisionCluster constructor
+   \param rad: the radius of the base sphere
+   \param mid: the middle point of the sphere
+*/
+CollisionCluster::CollisionCluster (float rad = 1.0, Vector mid = Vector(0,0,0))
+{
+  root = (CC_Tree*) malloc( sizeof( CC_Tree));
+  root->n = 0;
+  root->data.ID = 0;
+  root->r = rad;
+  root->m = mid;
+}
+
+/**
+   \brief loads a CollisionCluster from a data file
+   \param filename: self-explanatory
+*/
+CollisionCluster::CollisionCluster (char* filename)
+{
+  FILE* stream;
+  char hbuffer[3];
+  stream = fopen (filename, "rb");
+  if( stream == NULL)
+  {
+    root = NULL;
+    return;
+  }
+  if( fread (hbuffer, sizeof( char), 2, stream) != 2)
+  {
+    root = NULL;
+    return;
+  }
+  
+  hbuffer[2] = 0;
+  if( strcmp (hbuffer, "CC"))
+  {
+    root = NULL;
+    return;
+  }
+  
+  root = load_CC_Tree (stream);
+  fclose (stream);
+}
+
+/**
+   \brief Simple destructor that cleans up all the mess
+*/
+CollisionCluster::~CollisionCluster ()
+{
+  free_CC_Tree( root);
+}
+
+/**
+   \brief stores the CollisionCluster into a file
+   \param filename: self-explanatory
+   \return zero on success, -1 on error
+*/
+int CollisionCluster::store (char* filename)
+{
+  int r;
+  FILE* stream;
+  stream = fopen( filename, "wb");
+  if( stream == NULL) return -1;
+  r = save_CC_Tree (root, stream);
+  fclose (stream);
+  return r;
+}
+
+/**
+   \brief performs a collision check between a CollisionCluster and a Line
+   \param pa: pointer to the Placement of the CollisionCluster
+   \param a: pointer to the CollisionCluster
+   \param ahitflags: pointer to an unsigned long to store hitlocation data
+   \param trace: pointer to the Line
+   \param impactpoint: pointer to a Vector where the point of intersection is stored in
+   \return true on collision, false otherwise. If true is returned, the flag in ahitflags that symbolises the hit subsphere is set, and impactpoint is set to the Location where the intersection occured
+*/
+bool check_trace (const Placement* pa, const CollisionCluster* a, unsigned long* ahitflags, const Line* trace, Vector* impactpoint)
+{
+	CC_Tree* t;
+	if( (t = a->root) == NULL) return false;
+	
+  return cctree_trace( pa, t, ahitflags, trace, impactpoint);
+}
+
+/**
+   \brief performs a collision check between two CollisionClusters
+   \param pa: pointer to the Placement of the first CollisionCluster
+   \param a: pointer to the first CollisionCluster 
+   \param ahitflags: pointer to an unsigned long to store hitlocation data on the first CollisionCluster
+   \param pb: pointer to the Placement of the second CollisionCluster
+   \param b: pointer to the second CollisionCluster
+   \param bhitflags: pointer to an unsigned long to store hitlocation data on the second CollisionCluster
+   \return true on collision, false otherwise
+   If true is returned, all flags in ahitflags and bhitflags that symbolize intersecting subspheres in the respective CollisionCluster are set
+*/
+bool check_collision (const Placement* pa, const CollisionCluster* a, unsigned long* ahitflags, const Placement* pb, const CollisionCluster* b, unsigned long* bhitflags)
+{
+  CC_Tree* ta, *tb;
+  if( (ta = a->root) == NULL) return false;
+  if( (tb = b->root) == NULL) return false;
+  
+  return cctree_iterate(pa, ta, ahitflags, pb, tb, bhitflags);
+}
+
+/**
+   \brief performs an intersection check between two spheres
+   \param m1: center point of first sphere
+   \param r1: radius of first sphere
+   \param m2: center point of second sphere
+   \param r2: radius of second sphere
+   \return true on intersection, false otherwise
+*/
+bool sphere_sphere_collision( Vector m1, float r1, Vector m2, float r2)
+{
+  if ((m1-m2).len() < r1+r2) return true;
+  return false;
+}
+
+/**
+   \brief performs an intersection check between a Line and a sphere
+   \param m: center point of the sphere
+   \param r: radius of the sphere
+   \param l: pointer to the Line
+   \param impactpoint: pointer to a buffer to store the point of intersection
+   \return true on intersection, false otherwise. If true is returned, impactpoint is set to the loaction where the intersection occured
+*/
+bool trace_sphere_collision( Vector m, float r, const Line* l, Vector* impactpoint)
+{
+  float A, B, C, D, t[2];
+  Vector d = l->r - m;
+  int i;
+  
+  A = l->a * l->a;
+  B = 2 * (l->a * d);
+  C = (d*d) - r*r;
+  D = B*B - 4*A*C;
+  
+  if (D < 0) return false;
+  
+  t[0] = (-B+sqrt(D))/(2*A);
+  t[1] = (-B-sqrt(D))/(2*A);
+  
+  if( (t[0] > 1 || t[0] < 0) && (t[1] < 0 || t[1] > 1)) return false;
+  if( t[0] > t[1]) i = 0;
+  else i = 1;
+
+  impactpoint->x = (l->r + (l->a * t[i])).x;
+  impactpoint->y = (l->r + (l->a * t[i])).y;
+  impactpoint->z = (l->r + (l->a * t[i])).z;
+  
+  return true;
+}
+
+bool cctree_iterate(const Placement* pa, CC_Tree* ta, unsigned long* ahitflags, const Placement* pb, CC_Tree* tb, unsigned long* bhitflags)
+{
+  bool r = false;
+  int ia, ib;
+  Vector mra = pa->r + pa->w.apply(ta->m);
+  Vector mrb = pb->r + pb->w.apply(tb->m);
+  CC_Tree* use_a, *use_b;
+  
+  if( use_a == NULL || use_b == NULL) return false;
+  
+  if( sphere_sphere_collision( mra, ta->r, mrb, tb->r))
+  {
+    if( ta->n == 0 && tb->n == 0)
+    {
+      setflag( ahitflags, ta->data.ID);
+      setflag( bhitflags, tb->data.ID);
+      return true;
+    }
+    for( ia = 0; ia < ta->n || ta->n == 0; ia++)
+    {
+      if( ta->n == 0) use_a = ta;
+      else use_a = ta->data.b[ia];
+      for( ib = 0; ib < tb->n || ta->n == 0; ib++)
+      {
+        if( ta->n == 0) use_b = ta;
+        else use_b = ta->data.b[ib];
+        
+        r = r || cctree_iterate( pa, use_a, ahitflags, pb, use_b, bhitflags);
+        
+        if( tb->n == 0) break;
+      }
+      if( ta->n == 0) break;
+    }
+    return r;
+  }
+  
+  return false;
+}
+
+/**
+   \brief sets the <ID>th flag in flags
+   \param flags: pointer to the long used for flagging
+   \param ID: number of the flag to be set
+*/
+void setflag( unsigned long* flags, unsigned long ID)
+{
+  unsigned long f;
+  f = 1;
+  for( int i = 0; i < ID; i++)
+  {
+    f *= 2;
+  }
+  *flags = *flags | f;
+  return;
+}
+
+/**
+   \brief frees the memory allocated in a CC_Tree
+*/
+void free_CC_Tree( CC_Tree* tree)
+{
+  if (tree == NULL) return;
+  for (int i = 0; i < tree->n; i++)
+  {
+    free_CC_Tree( tree->data.b[i]);
+  }
+  free( tree);
+}
+
+/**
+   \brief loads a CC_Tree from a stream
+*/
+CC_Tree* load_CC_Tree (FILE* stream)
+{
+  CC_Tree* tree = NULL;
+  CC_Tree** branches = NULL;
+  float buf[4];
+  unsigned long n;
+  unsigned long ID;
+  
+  // first load vector and radius
+  if (fread( buf, sizeof (float), 4, stream) != 4) return NULL;
+  // then the amount of subbranches
+  if (fread( &n, sizeof(unsigned long), 1, stream) != 1) return NULL;
+  // then ID or the subbranches
+  if ( n == 0)
+  {
+    if (fread( &ID, sizeof(unsigned long), 1, stream) != 1) return NULL;
+  }
+  else
+  {
+    branches = (CC_Tree**)malloc( sizeof(CC_Tree*) * n);
+    for( int i = 0; i < n; i++)
+    {
+      if ((branches[i] = load_CC_Tree (stream)) == NULL)
+      {
+        for( int j = 0; j < i; j++)
+        {
+          free_CC_Tree (branches[j]);
+          free (branches);
+          return NULL;
+        }
+      }
+    }
+  }
+  
+  // assemble
+  tree = (CC_Tree*) malloc (sizeof(CC_Tree));
+  tree->m.x = buf[0];
+  tree->m.y = buf[1];
+  tree->m.z = buf[2];
+  tree->r = buf[3];
+  tree->n = n;
+  if( n == 0) tree->data.ID = ID;
+  else tree->data.b = branches;
+  
+  // then return
+  return tree;
+}
+
+/**
+   \brief saves a CC_Tree to a stream
+*/
+int save_CC_Tree (CC_Tree* tree, FILE* stream)
+{
+  float buf[4];
+  
+  buf[0] = tree->m.x;
+  buf[1] = tree->m.y;
+  buf[2] = tree->m.z;
+  buf[3] = tree->r;
+  
+  // first save vector and radius
+  if (fwrite( buf, sizeof (float), 4, stream) != 4) return -1;
+  // then the amount of subbranches
+  if (fwrite( &(tree->n), sizeof(unsigned long), 1, stream) != 1) return -1;
+  // then ID or the subbranches
+  if ( tree->n == 0)
+  {
+    if (fwrite( &(tree->data.ID), sizeof(unsigned long), 1, stream) != 1) return -1;
+  }
+  else
+  {
+    for( int i = 0; i < tree->n; i++)
+    {
+      if ( save_CC_Tree (tree->data.b[i], stream) == -1) return -1;
+    }
+  }
+    
+  // then return
+  return 0;
+}
+
+bool cctree_trace( const Placement* p, CC_Tree* t, unsigned long* hitflags, const Line* trace, Vector* impactpoint)
+{
+  bool r = false;
+  int i;
+  Vector mr = p->r + p->w.apply (t->m);
+  CC_Tree* use_t;
+  Vector* ips;
+  unsigned long* hfs;
+  
+  if( trace_sphere_collision (mr, t->r, trace, impactpoint))
+  {
+  	if( t->n == 0)
+  	{
+  		setflag (hitflags, t->data.ID);
+  		return true;
+  	}
+  	else
+  	{
+  		ips = new Vector[t->n];
+  		hfs = new unsigned long[t->n];
+  		for (i = 0; i < t->n; i++) hfs[i] = 0;
+  		for (i = 0; i < t->n; i++)
+  		{
+  			r = r || cctree_trace (p, t->data.b[i], &(hfs[i]), trace, &(ips[i]));
+  		}
+  		if( r)
+  		{
+  			float kl = 0.0;
+  			float l = 0.0;
+  			int k = 0;
+  			for (i = 0; i < t->n; i++)
+  			{
+  				if( (kl = (trace->r - ips[i]).len()) > l)
+  				{
+  					l = kl;
+  					k = i;
+  				}
+  			}
+  			impactpoint->x = ips[k].x;
+  			impactpoint->y = ips[k].y;
+  			impactpoint->z = ips[k].z;
+  			*hitflags = hfs[k];
+  		}
+  		delete ips;
+  		delete hfs;
+  	}
+  	return r;
+  }
+  
+  return false;
+}
Index: orxonox/trunk/src/collision.h
===================================================================
--- orxonox/trunk/src/collision.h	(revision 2190)
+++ orxonox/trunk/src/collision.h	(revision 2190)
@@ -0,0 +1,69 @@
+/*! 
+    \file collision.h
+    \brief Basic collision detection
+*/ 
+
+#ifndef COLLISION_H
+#define COLLISION_H
+
+#include "vector.h"
+#include "coordinates.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+//! Tree structure used by the CollisionCluster
+typedef struct CC_Tree
+{
+  unsigned long n;
+  union
+  {
+  struct CC_Tree** b;
+  unsigned long ID;
+  } data;
+  float r;
+  Vector m;
+} CC_Tree;
+
+//! Basic collision detection class
+/**
+  This class implements a more or less efficient collision system based on nested hitzones.
+  Instead of using a brute force approach (try if any hitzone intersects with any other hitzone)
+  this features a tree of spheric hitzones. Only some of them are actually the solid groundstones
+  the collision model bases on, the others serve to group them into sets of spheres that are only
+  checked for collision when the assigned top level sphere has registered a collision, preventing
+  unnessessary checks (like between every sphere of two collision clusters at the other end of the world)
+  from being performed.
+  The CollisionCluster features collision detection between multiple CollisionClusters as well as
+  traceing a collision between a line of defined length and a cluster. In both cases the base spheres
+  that have intersected are marked with a flag in an unsigned long for hitlocation queries. In the case
+  of a trace, the exact point of interception is returned as well.
+*/
+class CollisionCluster {
+  
+  CC_Tree* root;
+  
+  
+ public:
+  CollisionCluster (float r, Vector m); // simple cluster
+  CollisionCluster (char* filename); // get cluster from file
+  ~CollisionCluster ();
+  
+  int store (char* filename);
+  
+  friend bool cctree_trace( const Placement* p, CC_Tree* t, unsigned long* hitflags, const Line* trace, Vector* impactpoint);
+  friend bool cctree_iterate(const Placement* pa, CC_Tree* ta, unsigned long* ahitflags, const Placement* pb, CC_Tree* tb, unsigned long* bhitflags);
+  friend bool check_trace (const Placement* pa, const CollisionCluster* a, unsigned long* ahitflags, const Line* trace, Vector* impactpoint);
+  friend bool check_collision (const Placement* pa, const CollisionCluster* a, unsigned long* ahitflags, const Placement* pb, const CollisionCluster* b, unsigned long* bhitflags);
+};
+
+bool sphere_sphere_collision( Vector m1, float r1, Vector m2, float r2);
+bool trace_sphere_collision( Vector m, float r, const Line* l, Vector* impactpoint);
+
+void setflag( unsigned long* flags, unsigned long ID);
+
+void free_CC_Tree( CC_Tree* tree);
+CC_Tree* load_CC_Tree (FILE* stream);
+int save_CC_Tree (CC_Tree* tree, FILE* stream);
+
+#endif
Index: orxonox/trunk/src/command_node.cc
===================================================================
--- orxonox/trunk/src/command_node.cc	(revision 2190)
+++ orxonox/trunk/src/command_node.cc	(revision 2190)
@@ -0,0 +1,246 @@
+/* 
+   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: Christian Meyer
+   co-programmer: ...
+*/
+
+
+#include "command_node.h"
+#include "keynames.h"
+#include "ini_parser.h"
+#include "world_entity.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+using namespace std;
+
+/**
+	\brief constructs a CommandNode to handle remote input
+	\param ID: unique denumerator to identify the node in the network
+*/
+CommandNode::CommandNode (int ID)
+{
+	bound = new List<WorldEntity>();
+	aliases = NULL;
+	netID = ID;
+	bLocalInput = false;
+}
+
+/**
+	\brief constructs a CommandNode to handle local input
+	\param filename: The path and name of the file to load the key bindings from
+*/
+CommandNode::CommandNode (char* filename = DEFAULT_KEYBIND_FILE)
+{
+	aliases = NULL;
+	bLocalInput = true;
+	netID = 0;
+	bound = new List<WorldEntity>();
+	load_bindings (filename);
+}
+
+/**
+	\brief removes the CommandNode from memory
+*/
+CommandNode::~CommandNode ()
+{
+	if( aliases != NULL) free (aliases);
+	if( bound != NULL) delete bound;
+}
+
+/**
+	\brief loads new key bindings from a file
+	\param filename: The path and name of the file to load the bindings from
+*/
+void CommandNode::load_bindings (char* filename)
+{
+	FILE* stream;
+	
+	printf("Loading key bindings from %s\n", filename);
+	
+	if( filename == NULL) filename = DEFAULT_KEYBIND_FILE;
+	
+		// remove old bindings if present
+	if( aliases != NULL)
+	{
+		free (aliases);
+		aliases = NULL;
+	}
+			
+		// create parser
+	IniParser parser (filename);
+	if( parser.get_section ("Bindings") == -1)
+	{
+		printf("Could not find key bindings in %s\n", filename);
+		return;
+	}
+			// allocate empty lookup table
+	aliases = (KeyBindings*) calloc (1, sizeof (KeyBindings));
+	
+	char namebuf[256];
+	char valuebuf[256];
+	memset (namebuf, 0, 256);
+	memset (valuebuf, 0, 256);
+	int* index;
+
+	while( parser.next_var (namebuf, valuebuf) != -1)
+	{
+		index = name_to_index (namebuf);
+		switch( index[0])
+		{
+			case 0:
+				printf("Key binding %d(%s) set to %s\n", index[1], SDLK_to_keyname( index[1]), valuebuf);
+				strcpy (aliases->keys[index[1]], valuebuf);
+				break;
+			case 1:
+				printf("Button binding %d(%s) set to %s\n", index[1], SDLB_to_buttonname( index[1]), valuebuf);
+				strcpy (aliases->buttons[index[1]], valuebuf);
+				break;
+			default:
+				break;
+		}
+		memset (namebuf, 0, 256);
+		memset (valuebuf, 0, 256);
+	}
+}
+
+/**
+	\brief binds a WorldEntity to the CommandNode
+	\param entity: Pointer to the entity to bind
+*/
+void CommandNode::bind (WorldEntity* entity)
+{
+	bound->add (entity, LIST_ADD_NEXT, true);
+}
+
+/**
+	\brief removes an entity from the list of the CommandNode
+	\param entity: Pointer to the entity to relese
+*/
+void CommandNode::unbind (WorldEntity* entity)
+{
+	bound->remove (entity, LIST_FIND_FW);
+}
+
+int* CommandNode::name_to_index (char* name)
+{
+	coord[0] = -1;
+	coord[1] = -1;
+	int c;
+	if( (c = keyname_to_SDLK (name)) != -1)
+	{
+		coord[1] = c;
+		coord[0] = 0;
+	}
+	if( (c = buttonname_to_SDLB (name)) != -1)
+	{
+		coord[1] = c;
+		coord[0] = 1;
+	}
+	return coord;
+}
+
+/**
+	\brief tells the CommandNode to run through all pending events and relay them accordingly
+*/
+void CommandNode::process ()
+{
+	if( bLocalInput) process_local ();
+	else process_network ();
+}
+
+void CommandNode::process_local ()
+{
+	SDL_Event event;
+	Command cmd;
+	
+	while( SDL_PollEvent (&event))
+	{
+		memset (cmd.cmd, 0, CMD_LENGHT); 
+		switch( event.type)
+		{
+			case SDL_KEYDOWN:
+				strcpy (cmd.cmd, aliases->keys[event.key.keysym.sym]);
+				cmd.bUp = false;
+				if( strlen (cmd.cmd) > 0) relay (&cmd);
+				break;
+			case SDL_KEYUP:
+				strcpy( cmd.cmd, aliases->keys[event.key.keysym.sym]);
+				cmd.bUp = true;
+				if( strlen (cmd.cmd) > 0) relay (&cmd);
+				break;
+			case SDL_MOUSEMOTION:
+				strcpy( cmd.cmd, "cursor");
+				cmd.x = event.motion.x;
+				cmd.y = event.motion.y;
+				cmd.xrel = event.motion.xrel;
+				cmd.yrel = event.motion.yrel;
+				break;
+			case SDL_MOUSEBUTTONUP:
+				strcpy( cmd.cmd, aliases->buttons[event.button.button]);
+				cmd.bUp = true;
+				if( strlen (cmd.cmd) > 0) relay (&cmd);
+				break;
+			case SDL_MOUSEBUTTONDOWN:
+				strcpy( cmd.cmd, aliases->buttons[event.button.button]);
+				cmd.bUp = false;
+				if( strlen (cmd.cmd) > 0) relay (&cmd);
+				break;
+			case SDL_JOYAXISMOTION:
+			case SDL_JOYBALLMOTION:
+			case SDL_JOYHATMOTION:
+			case SDL_JOYBUTTONDOWN:
+			case SDL_JOYBUTTONUP:
+				break;
+			default:
+  				Orxonox *orx = Orxonox::getInstance();
+  				orx->event_handler (&event);
+				break;
+		}
+	}
+}
+
+void CommandNode::process_network ()
+{
+
+}
+
+void CommandNode::relay (Command* cmd)
+{
+printf("CommandNode|relay()\n");
+	List<WorldEntity>* plist = bound;
+	
+	Orxonox *orx = Orxonox::getInstance();
+	if( orx->system_command (cmd)) return;
+		
+	if( bLocalInput) send_over_network (cmd);
+	
+	while( (plist = plist->get_next()) != NULL)
+	{
+		plist->get_object()->command (cmd);
+	}
+}
+
+/**
+	\brief sets the network identifier of the CommandNode
+	\param ID: the new ID to use
+*/
+void CommandNode::set_netID (int ID)
+{
+	netID = ID;
+}
+
+void CommandNode::send_over_network (Command* cmd)
+{
+}
Index: orxonox/trunk/src/command_node.h
===================================================================
--- orxonox/trunk/src/command_node.h	(revision 2190)
+++ orxonox/trunk/src/command_node.h	(revision 2190)
@@ -0,0 +1,65 @@
+/*!
+    \file command_node.h
+    \brief Parses keyboard, mouse and remote input
+    
+    Contains methods to parse remote and local input and handles sending of input to remote CommandNodes
+*/
+
+#ifndef COMMAND_NODE_H
+#define COMMAND_NODE_H
+
+#include "stdincl.h"
+
+class WorldEntity;
+
+#define N_STD_KEYS SDLK_LAST
+#define N_BUTTONS 6
+#define DEFAULT_KEYBIND_FILE "default.ini"
+
+//! Key aliasing structure
+/**
+	This structure contains the key aliasing information, e.g. the command strings that
+	have been bound to the keys.
+*/
+typedef struct
+{
+	char keys[N_STD_KEYS][CMD_LENGHT];
+	char buttons[N_BUTTONS][CMD_LENGHT];
+} KeyBindings;
+
+//! Command Node
+/**
+	This class gathers all incoming SDL_Events and processes them. Keyboard, mouse and joystick input is
+	captured and translated into command messages which are passed down to the bound WorldEntities (via WorldEntity::command()).
+	Other SDL_Events are passed to Orxonox::event_handler() to deal with them. If the CommandNode has been created
+	with bLocalInput set to false, it will query the network class for incoming commands that match his netID and pass
+	them on to it's WorldEntities.
+*/
+class CommandNode {
+ private:
+ 	bool bLocalInput;	//!< Identifies the CommandNode that processes local input
+ 	int netID;	//!< Unique identifier that is used to determine between remote CommandNodes
+	KeyBindings* aliases;
+	List<WorldEntity>* bound;	//!< List of WorldEntites that recieve commands from this CommandNode
+	Sint32 coord[2];
+	
+	void relay (Command* cmd);
+	int* name_to_index (char* name);
+	void process_local ();
+	void process_network ();
+	void send_over_network (Command* cmd);
+	
+ public:
+  CommandNode (int ID);
+  CommandNode (char* filename);
+  ~CommandNode ();
+  
+  void load_bindings (char* filename);
+  void bind (WorldEntity* entity);
+  void unbind (WorldEntity* entity);
+  void process ();
+  
+  void set_netID (int ID);
+};
+
+#endif
Index: orxonox/trunk/src/data_tank.cc
===================================================================
--- orxonox/trunk/src/data_tank.cc	(revision 2077)
+++ orxonox/trunk/src/data_tank.cc	(revision 2190)
@@ -19,8 +19,4 @@
 using namespace std;
 
-float DataTank::xOffset = 0;
-float DataTank::yOffset = 0;
-float DataTank::zOffset = 0;
-
 DataTank::DataTank () {}
 DataTank::~DataTank () {}
Index: orxonox/trunk/src/data_tank.h
===================================================================
--- orxonox/trunk/src/data_tank.h	(revision 2077)
+++ orxonox/trunk/src/data_tank.h	(revision 2190)
@@ -10,8 +10,4 @@
   ~DataTank ();
 
-  static float xOffset;
-  static float yOffset;
-  static float zOffset;
-
 };
 
Index: orxonox/trunk/src/ini_parser.cc
===================================================================
--- orxonox/trunk/src/ini_parser.cc	(revision 2190)
+++ orxonox/trunk/src/ini_parser.cc	(revision 2190)
@@ -0,0 +1,163 @@
+/* 
+   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: Christian Meyer
+   co-programmer: ...
+*/
+
+
+#include "ini_parser.h"
+
+using namespace std;
+
+/**
+	\brief constructs an IniParser using a file
+	\param filename: the path and name of the file to parse
+*/
+IniParser::IniParser (char* filename)
+{
+	stream = NULL;
+	bInSection = false;
+	open_file (filename);
+}
+
+/**
+	\brief removes the IniParser from memory
+*/
+IniParser::~IniParser ()
+{
+	if( stream != NULL) fclose (stream);
+}
+
+/**
+	\brief opens another file to parse
+	\param filename: path and name of the new file to parse
+	\return zero on success or -1 if an error occured;
+*/
+int IniParser::open_file( char* filename)
+{
+	if( filename == NULL) return -1;
+	if( stream != NULL)	fclose (stream);
+	if( (stream = fopen (filename, "r")) == NULL)
+	{
+		printf("IniParser could not open %s\n", filename);
+		return -1;
+	}
+	bInSection = false;
+	return 0;
+}
+
+/**
+	\brief set the parsing cursor to the specified section
+	\param section: the name of the section to set the cursor to
+	\return zero on success or -1 if the section could not be found
+*/
+int IniParser::get_section( char* section)
+{
+	bInSection = false;
+	if( stream == NULL) return -1;
+	
+	char linebuffer[PARSELINELENGHT];
+	char secbuffer[PARSELINELENGHT];
+	char* ptr;
+	
+	rewind (stream);
+	while( !feof( stream))
+	{
+			// get next line
+		fgets (linebuffer, PARSELINELENGHT, stream);
+			// remove newline char
+		if( (ptr = strchr( linebuffer, '\n')) != NULL) *ptr = 0;
+			// check for section identifyer
+		if( sscanf (linebuffer, "[%s", secbuffer) == 1)
+		{
+			if( (ptr = strchr( secbuffer, ']')) != NULL)
+			{
+				*ptr = 0;
+				if( !strcmp( secbuffer, section))
+				{
+					bInSection = true;
+					return 0;
+				}
+			}
+		}
+	}
+	return -1;
+}
+
+/**
+	\brief gets the next VarName=VarValue pair from the parsing stream
+	\param name: a pointer to a buffer to store the name of the entry
+	\param value: a pointer to a buffer to store the value of the entry
+	\return zero if the buffers have been filled with data or -1 if there are no entries left in the current section
+*/
+int IniParser::next_var( char* name, char* value)
+{
+	if( stream == NULL)
+	{
+		bInSection = false;
+		return -1;
+	}
+	if( !bInSection) return -1;
+	
+	char linebuffer[PARSELINELENGHT];
+	char* ptr;
+
+	while( !feof( stream))
+	{
+			// get next line
+		fgets (linebuffer, PARSELINELENGHT, stream);
+			// remove newline char
+		if( (ptr = strchr( linebuffer, '\n')) != NULL) *ptr = 0;
+		if( linebuffer[0] == '[')
+		{
+			bInSection = false;
+			return -1;
+		}
+		if( (ptr = strchr( linebuffer, '=')) != NULL)
+		{
+			if( ptr == linebuffer) continue;
+			strcpy (value, &ptr[1]);
+			strncpy (name, linebuffer, strlen (linebuffer) - strlen (value) - 1);
+			return 0;
+		}
+	}
+	return -1;	
+}
+
+/**
+	\brief directly acesses an entry in a section
+	\param name: the name of the entry to find
+	\param section: the section where the entry is to be found
+	\param defvalue: what should be returned in case the entry cannot be found
+	\return a pointer to a buffer conatining the value of the specified entry. This buffer will contain the data specified in defvalue in case the entry wasn't found
+
+	The returned pointer points to an internal buffer, so do not free it on your own. Do not give a NULL pointer to defvalue, this will certainly
+	lead to unwanted behaviour.
+*/
+char* IniParser::get_var( char* name, char* section, char* defvalue = "")
+{
+	strcpy (internbuf, defvalue);
+	if( get_section (section) == -1) return internbuf;
+	
+	char namebuf[PARSELINELENGHT];
+	char valuebuf[PARSELINELENGHT];
+	
+	while( next_var (namebuf, valuebuf) != -1)
+	{
+		if( !strcmp (name, namebuf))
+		{
+			strcpy (internbuf, valuebuf);
+			return internbuf;
+		}
+	}
+	return internbuf;
+}
Index: orxonox/trunk/src/ini_parser.h
===================================================================
--- orxonox/trunk/src/ini_parser.h	(revision 2190)
+++ orxonox/trunk/src/ini_parser.h	(revision 2190)
@@ -0,0 +1,37 @@
+/*!
+    \file ini_parser.h
+    \brief A small ini file parser
+    
+    Can be used to find a defined [Section] in an ini file and get the VarName=Value entries
+*/
+
+#ifndef INI_PARSER_H
+#define INI_PARSER_H
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define PARSELINELENGHT 512
+
+//! ini-file parser
+/**
+	This class can be used to load an initializer file and parse it's contents for variablename=value pairs.
+*/
+class IniParser {
+ private:
+	FILE* stream;
+	bool bInSection;
+	char internbuf[PARSELINELENGHT];
+	
+ public:
+  IniParser (char* filename);
+  ~IniParser ();
+  
+  char* get_var( char* name, char* section, char* defvalue);
+	int open_file( char* name);
+  int get_section( char* section);
+  int next_var( char* name, char* value);
+};
+
+#endif
Index: orxonox/trunk/src/input_output.cc
===================================================================
--- orxonox/trunk/src/input_output.cc	(revision 2077)
+++ 	(revision )
@@ -1,79 +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: ...
-   co-programmer: ...
-*/
-
-#include <iostream>
-
-#include "world.h"
-#include "input_output.h"
-#include "player.h"
-
-#include "input_output.h"
-
-using namespace std;
-
-
-/** 
-   \brief InputOutput Module for each player
-   \param wld A reference to the game-world
-   
-   This Class registers all moves, a player makes and passes it to the player object. ToDo: extend to support network players...
-*/
-InputOutput::InputOutput (World* world, Player* player) 
-{
-  this->world = world;
-  this->player = player;
-}
-
-
-
-InputOutput::~InputOutput () {}
-
-
-void InputOutput::setPlayerStep(float step)
-{
-  cout << "setting player step to: " << step << endl;
-  this->step = step;
-}
-
-
-void InputOutput::goUp() 
-{
-  //cout << "InoutOutput::goUp" << endl;
-  (*player).goY(step);
-}
-
-void InputOutput::goDown() 
-{
-  (*player).goY(-step);
-}
-
-void InputOutput::goLeft()
-{
-  (*player).goX(-step);
-
-}
-
-void InputOutput::goRight()
-{
-
-  (*player).goX(step);
-}
-
-void InputOutput::shoot()
-{
-  (*player).shoot(1);
-}
Index: orxonox/trunk/src/input_output.h
===================================================================
--- orxonox/trunk/src/input_output.h	(revision 2077)
+++ 	(revision )
@@ -1,36 +1,0 @@
-
-
-
-#ifndef INPUT_OUTPUT_H
-#define INPUT_OUTPUT_H
-
-
-
-#include "data_tank.h"
-
-class World;
-class Player;
-
-class InputOutput {
-
- private:
-  World* world;
-  Player* player;
-
-  float step;
-
- public:
-  InputOutput (World* wld, Player* player);
-  ~InputOutput ();
-
-  void setPlayerStep(float step);
-  void goUp(void);
-  void goDown(void);
-  void goLeft(void);
-  void goRight(void);
-  void shoot(void);
-
-
-};
-
-#endif
Index: orxonox/trunk/src/keynames.cc
===================================================================
--- orxonox/trunk/src/keynames.cc	(revision 2190)
+++ orxonox/trunk/src/keynames.cc	(revision 2190)
@@ -0,0 +1,317 @@
+/* 
+   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: Christian Meyer
+   co-programmer: ...
+*/
+#include <SDL/SDL.h>
+
+#include "keynames.h"
+
+#include <string.h>
+
+using namespace std;
+
+int buttonname_to_SDLB( char* name)
+{
+	if( !strcmp (name, "BUTTON_LEFT")) return SDL_BUTTON_LEFT;
+	if( !strcmp (name, "BUTTON_MIDDLE")) return SDL_BUTTON_MIDDLE;
+	if( !strcmp (name, "BUTTON_RIGHT")) return SDL_BUTTON_RIGHT;
+//	if( !strcmp (name, "BUTTON_WHEELUP")) return SDL_BUTTON_WHEELUP;
+//	if( !strcmp (name, "BUTTON_WHEELDOWN")) return SDL_BUTTON_WHEELDOWN;
+	return -1;
+}
+
+char* SDLB_to_buttonname( int button)
+{
+	if( button == SDL_BUTTON_LEFT) return "BUTTON_LEFT";
+	if( button == SDL_BUTTON_MIDDLE) return "BUTTON_MIDDLE";
+	if( button == SDL_BUTTON_RIGHT) return "BUTTON_RIGHT";
+//	if( button == SDL_BUTTON_WHEELUP) return "BUTTON_WHEELUP";
+//	if( button == SDL_BUTTON_WHEELDOWN) return "BUTTON_WHEELDOWN";
+	return "UNKNOWN";
+}
+
+int keyname_to_SDLK( char* name)
+{
+	if( !strcmp (name, "BACKSPACE")) return SDLK_BACKSPACE;
+	if( !strcmp (name, "TAB")) return SDLK_TAB;
+	if( !strcmp (name, "CLEAR")) return SDLK_CLEAR;
+	if( !strcmp (name, "RETURN")) return SDLK_RETURN;
+	if( !strcmp (name, "ESCAPE")) return SDLK_ESCAPE;
+	if( !strcmp (name, "SPACE")) return SDLK_SPACE;
+	if( !strcmp (name, "EXCLAIM")) return SDLK_EXCLAIM;
+	if( !strcmp (name, "QUOTEDBL")) return SDLK_QUOTEDBL;
+	if( !strcmp (name, "HASH")) return SDLK_HASH;
+	if( !strcmp (name, "PAUSE")) return SDLK_PAUSE;
+	if( !strcmp (name, "DOLLAR")) return SDLK_DOLLAR;
+	if( !strcmp (name, "AMPERSAND")) return SDLK_AMPERSAND;
+	if( !strcmp (name, "QUOTE")) return SDLK_QUOTE;
+	if( !strcmp (name, "LEFTPAREN")) return SDLK_LEFTPAREN;
+	if( !strcmp (name, "RIGHTPAREN")) return SDLK_RIGHTPAREN;
+	if( !strcmp (name, "ASTERISK")) return SDLK_ASTERISK;
+	if( !strcmp (name, "PLUS")) return SDLK_PLUS;
+	if( !strcmp (name, "COMMA")) return SDLK_COMMA;
+	if( !strcmp (name, "MINUS")) return SDLK_MINUS;
+	if( !strcmp (name, "PERIOD")) return SDLK_PERIOD;
+	if( !strcmp (name, "SLASH")) return SDLK_SLASH;
+	if( !strcmp (name, "0")) return SDLK_0;
+	if( !strcmp (name, "1")) return SDLK_1;
+	if( !strcmp (name, "2")) return SDLK_2;
+	if( !strcmp (name, "3")) return SDLK_3;
+	if( !strcmp (name, "4")) return SDLK_4;
+	if( !strcmp (name, "5")) return SDLK_5;
+	if( !strcmp (name, "6")) return SDLK_6;
+	if( !strcmp (name, "7")) return SDLK_7;
+	if( !strcmp (name, "8")) return SDLK_8;
+	if( !strcmp (name, "9")) return SDLK_9;
+	if( !strcmp (name, "COLON")) return SDLK_COLON;
+	if( !strcmp (name, "SEMICOLON")) return SDLK_SEMICOLON;
+	if( !strcmp (name, "LESS")) return SDLK_LESS;
+	if( !strcmp (name, "EQUALS")) return SDLK_EQUALS;
+	if( !strcmp (name, "GREATER")) return SDLK_GREATER;
+	if( !strcmp (name, "QUESTION")) return SDLK_QUESTION;
+	if( !strcmp (name, "AT")) return SDLK_AT;
+	if( !strcmp (name, "LEFTBRACKET")) return SDLK_LEFTBRACKET;
+	if( !strcmp (name, "BACKSLASH")) return SDLK_BACKSLASH;
+	if( !strcmp (name, "RIGHTBRACKET")) return SDLK_RIGHTBRACKET;
+	if( !strcmp (name, "CARET")) return SDLK_CARET;
+	if( !strcmp (name, "UNDERSCORE")) return SDLK_UNDERSCORE;
+	if( !strcmp (name, "BACKQUOTE")) return SDLK_BACKQUOTE;
+	if( !strcmp (name, "a")) return SDLK_a;
+	if( !strcmp (name, "b")) return SDLK_b;
+	if( !strcmp (name, "c")) return SDLK_c;
+	if( !strcmp (name, "d")) return SDLK_d;
+	if( !strcmp (name, "e")) return SDLK_e;
+	if( !strcmp (name, "f")) return SDLK_f;
+	if( !strcmp (name, "g")) return SDLK_g;
+	if( !strcmp (name, "h")) return SDLK_h;
+	if( !strcmp (name, "i")) return SDLK_i;
+	if( !strcmp (name, "j")) return SDLK_j;
+	if( !strcmp (name, "k")) return SDLK_k;
+	if( !strcmp (name, "l")) return SDLK_l;
+	if( !strcmp (name, "m")) return SDLK_m;
+	if( !strcmp (name, "n")) return SDLK_n;
+	if( !strcmp (name, "o")) return SDLK_o;
+	if( !strcmp (name, "p")) return SDLK_p;
+	if( !strcmp (name, "q")) return SDLK_q;
+	if( !strcmp (name, "r")) return SDLK_r;
+	if( !strcmp (name, "s")) return SDLK_s;
+	if( !strcmp (name, "t")) return SDLK_t;
+	if( !strcmp (name, "u")) return SDLK_u;
+	if( !strcmp (name, "v")) return SDLK_v;
+	if( !strcmp (name, "w")) return SDLK_w;
+	if( !strcmp (name, "x")) return SDLK_x;
+	if( !strcmp (name, "y")) return SDLK_y;
+	if( !strcmp (name, "z")) return SDLK_z;
+	if( !strcmp (name, "DELETE")) return SDLK_DELETE;
+	if( !strcmp (name, "KP0")) return SDLK_KP0;
+	if( !strcmp (name, "KP1")) return SDLK_KP1;
+	if( !strcmp (name, "KP2")) return SDLK_KP2;
+	if( !strcmp (name, "KP3")) return SDLK_KP3;
+	if( !strcmp (name, "KP4")) return SDLK_KP4;
+	if( !strcmp (name, "KP5")) return SDLK_KP5;
+	if( !strcmp (name, "KP6")) return SDLK_KP6;
+	if( !strcmp (name, "KP7")) return SDLK_KP7;
+	if( !strcmp (name, "KP8")) return SDLK_KP8;
+	if( !strcmp (name, "KP9")) return SDLK_KP9;
+	if( !strcmp (name, "KP_PERIOD")) return SDLK_KP_PERIOD;
+	if( !strcmp (name, "KP_DIVIDE")) return SDLK_KP_DIVIDE;
+	if( !strcmp (name, "KP_MULTIPLY")) return SDLK_KP_MULTIPLY;
+	if( !strcmp (name, "KP_MINUS")) return SDLK_KP_MINUS;
+	if( !strcmp (name, "KP_PLUS")) return SDLK_KP_PLUS;
+	if( !strcmp (name, "KP_ENTER")) return SDLK_KP_ENTER;
+	if( !strcmp (name, "KP_EQUALS")) return SDLK_KP_EQUALS;
+	if( !strcmp (name, "UP")) return SDLK_UP;
+	if( !strcmp (name, "DOWN")) return SDLK_DOWN;
+	if( !strcmp (name, "RIGHT")) return SDLK_RIGHT;
+	if( !strcmp (name, "LEFT")) return SDLK_LEFT;
+	if( !strcmp (name, "INSERT")) return SDLK_INSERT;
+	if( !strcmp (name, "HOME")) return SDLK_HOME;
+	if( !strcmp (name, "END")) return SDLK_END;
+	if( !strcmp (name, "PAGEUP")) return SDLK_PAGEUP;
+	if( !strcmp (name, "PAGEDOWN")) return SDLK_PAGEDOWN;
+	if( !strcmp (name, "F1")) return SDLK_F1;
+	if( !strcmp (name, "F2")) return SDLK_F2;
+	if( !strcmp (name, "F3")) return SDLK_F3;
+	if( !strcmp (name, "F4")) return SDLK_F4;
+	if( !strcmp (name, "F5")) return SDLK_F5;
+	if( !strcmp (name, "F6")) return SDLK_F6;
+	if( !strcmp (name, "F7")) return SDLK_F7;
+	if( !strcmp (name, "F8")) return SDLK_F8;
+	if( !strcmp (name, "F9")) return SDLK_F9;
+	if( !strcmp (name, "F10")) return SDLK_F10;
+	if( !strcmp (name, "F11")) return SDLK_F11;
+	if( !strcmp (name, "F12")) return SDLK_F12;
+	if( !strcmp (name, "F13")) return SDLK_F13;
+	if( !strcmp (name, "F14")) return SDLK_F14;
+	if( !strcmp (name, "F15")) return SDLK_F15;
+	if( !strcmp (name, "NUMLOCK")) return SDLK_NUMLOCK;
+	if( !strcmp (name, "CAPSLOCK")) return SDLK_CAPSLOCK;
+	if( !strcmp (name, "SCROLLOCK")) return SDLK_SCROLLOCK;
+	if( !strcmp (name, "RSHIFT")) return SDLK_RSHIFT;
+	if( !strcmp (name, "LSHIFT")) return SDLK_LSHIFT;
+	if( !strcmp (name, "RCTRL")) return SDLK_RCTRL;
+	if( !strcmp (name, "LCTRL")) return SDLK_LCTRL;
+	if( !strcmp (name, "RALT")) return SDLK_RALT;
+	if( !strcmp (name, "LALT")) return SDLK_LALT;
+	if( !strcmp (name, "RMETA")) return SDLK_RMETA;
+	if( !strcmp (name, "LMETA")) return SDLK_LMETA;
+	if( !strcmp (name, "LSUPER")) return SDLK_LSUPER;
+	if( !strcmp (name, "RSUPER")) return SDLK_RSUPER;
+	if( !strcmp (name, "MODE")) return SDLK_MODE;
+	if( !strcmp (name, "HELP")) return SDLK_HELP;
+	if( !strcmp (name, "PRINT")) return SDLK_PRINT;
+	if( !strcmp (name, "SYSREQ")) return SDLK_SYSREQ;
+	if( !strcmp (name, "BREAK")) return SDLK_BREAK;
+	if( !strcmp (name, "MENU")) return SDLK_MENU;
+	if( !strcmp (name, "POWER")) return SDLK_POWER;
+	if( !strcmp (name, "EURO")) return SDLK_EURO;
+	return -1;
+}
+
+char* SDLK_to_keyname( int key)
+{
+	if( key == SDLK_BACKSPACE) return "BACKSPACE";
+	if( key == SDLK_TAB) return "TAB";
+	if( key == SDLK_CLEAR) return "CLEAR";
+	if( key == SDLK_RETURN) return "RETURN";
+	if( key == SDLK_SPACE) return "SPACE";
+	if( key == SDLK_ESCAPE) return "ESCAPE";
+	if( key == SDLK_EXCLAIM) return "EXCLAIM";
+	if( key == SDLK_QUOTEDBL) return "QUOTEDBL";
+	if( key == SDLK_HASH) return "HASH";
+	if( key == SDLK_PAUSE) return "PAUSE";
+	if( key == SDLK_DOLLAR) return "DOLLAR";
+	if( key == SDLK_AMPERSAND) return "AMPERSAND";
+	if( key == SDLK_QUOTE) return "QUOTE";
+	if( key == SDLK_LEFTPAREN) return "LEFTPAREN";
+	if( key == SDLK_RIGHTPAREN) return "RIGHTPAREN";
+	if( key == SDLK_ASTERISK) return "ASTERISK";
+	if( key == SDLK_PLUS) return "PLUS";
+	if( key == SDLK_COMMA) return "COMMA";
+	if( key == SDLK_MINUS) return "MINUS";
+	if( key == SDLK_PERIOD) return "PERIOD";
+	if( key == SDLK_SLASH) return "SLASH";
+	if( key == SDLK_0) return "0";
+	if( key == SDLK_1) return "1";
+	if( key == SDLK_2) return "2";
+	if( key == SDLK_3) return "3";
+	if( key == SDLK_4) return "4";
+	if( key == SDLK_5) return "5";
+	if( key == SDLK_6) return "6";
+	if( key == SDLK_7) return "7";
+	if( key == SDLK_8) return "8";
+	if( key == SDLK_9) return "9";
+	if( key == SDLK_COLON) return "COLON";
+	if( key == SDLK_SEMICOLON) return "SEMICOLON";
+	if( key == SDLK_LESS) return "LESS";
+	if( key == SDLK_EQUALS) return "EQUALS";
+	if( key == SDLK_GREATER) return "GREATER";
+	if( key == SDLK_QUESTION) return "QUESTION";
+	if( key == SDLK_AT) return "AT";
+	if( key == SDLK_LEFTBRACKET) return "LEFTBRACKET";
+	if( key == SDLK_BACKSLASH) return "BACKSLASH";
+	if( key == SDLK_RIGHTBRACKET) return "RIGHTBRACKET";
+	if( key == SDLK_CARET) return "CARET";
+	if( key == SDLK_UNDERSCORE) return "UNDERSCORE";
+	if( key == SDLK_BACKQUOTE) return "BACKQUOTE";
+	if( key == SDLK_a) return "a";
+	if( key == SDLK_b) return "b";
+	if( key == SDLK_c) return "c";
+	if( key == SDLK_d) return "d";
+	if( key == SDLK_e) return "e";
+	if( key == SDLK_f) return "f";
+	if( key == SDLK_g) return "g";
+	if( key == SDLK_h) return "h";
+	if( key == SDLK_i) return "i";
+	if( key == SDLK_j) return "j";
+	if( key == SDLK_k) return "k";
+	if( key == SDLK_l) return "l";
+	if( key == SDLK_m) return "m";
+	if( key == SDLK_n) return "n";
+	if( key == SDLK_o) return "o";
+	if( key == SDLK_p) return "p";
+	if( key == SDLK_q) return "q";
+	if( key == SDLK_r) return "r";
+	if( key == SDLK_s) return "s";
+	if( key == SDLK_t) return "t";
+	if( key == SDLK_u) return "u";
+	if( key == SDLK_v) return "v";
+	if( key == SDLK_w) return "w";
+	if( key == SDLK_x) return "x";
+	if( key == SDLK_y) return "y";
+	if( key == SDLK_z) return "z";
+	if( key == SDLK_DELETE) return "DELETE";
+	if( key == SDLK_KP0) return "KP0";
+	if( key == SDLK_KP1) return "KP1";
+	if( key == SDLK_KP2) return "KP2";
+	if( key == SDLK_KP3) return "KP3";
+	if( key == SDLK_KP4) return "KP4";
+	if( key == SDLK_KP5) return "KP5";
+	if( key == SDLK_KP6) return "KP6";
+	if( key == SDLK_KP7) return "KP7";
+	if( key == SDLK_KP8) return "KP8";
+	if( key == SDLK_KP9) return "KP9";
+	if( key == SDLK_KP_PERIOD) return "KP_PERIOD";
+	if( key == SDLK_KP_DIVIDE) return "KP_DIVIDE";
+	if( key == SDLK_KP_MULTIPLY) return "KP_MULTIPLY";
+	if( key == SDLK_KP_MINUS) return "KP_MINUS";
+	if( key == SDLK_KP_PLUS) return "KP_PLUS";
+	if( key == SDLK_KP_ENTER) return "KP_ENTER";
+	if( key == SDLK_KP_EQUALS) return "KP_EQUALS";
+	if( key == SDLK_UP) return "UP";
+	if( key == SDLK_DOWN) return "DOWN";
+	if( key == SDLK_RIGHT) return "RIGHT";
+	if( key == SDLK_LEFT) return "LEFT";
+	if( key == SDLK_INSERT) return "INSERT";
+	if( key == SDLK_HOME) return "HOME";
+	if( key == SDLK_END) return "END";
+	if( key == SDLK_PAGEUP) return "PAGEUP";
+	if( key == SDLK_PAGEDOWN) return "PAGEDOWN";
+	if( key == SDLK_F1) return "F1";
+	if( key == SDLK_F2) return "F2";
+	if( key == SDLK_F3) return "F3";
+	if( key == SDLK_F4) return "F4";
+	if( key == SDLK_F5) return "F5";
+	if( key == SDLK_F6) return "F6";
+	if( key == SDLK_F7) return "F7";
+	if( key == SDLK_F8) return "F8";
+	if( key == SDLK_F9) return "F9";
+	if( key == SDLK_F10) return "F10";
+	if( key == SDLK_F11) return "F11";
+	if( key == SDLK_F12) return "F12";
+	if( key == SDLK_F13) return "F13";
+	if( key == SDLK_F14) return "F14";
+	if( key == SDLK_F15) return "F15";
+	if( key == SDLK_NUMLOCK) return "NUMLOCK";
+	if( key == SDLK_CAPSLOCK) return "CAPSLOCK";
+	if( key == SDLK_SCROLLOCK) return "SCROLLOCK";
+	if( key == SDLK_RSHIFT) return "RSHIFT";
+	if( key == SDLK_LSHIFT) return "LSHIFT";
+	if( key == SDLK_RCTRL) return "RCTRL";
+	if( key == SDLK_LCTRL) return "LCTRL";
+	if( key == SDLK_RALT) return "RALT";
+	if( key == SDLK_LALT) return "LALT";
+	if( key == SDLK_RMETA) return "RMETA";
+	if( key == SDLK_LMETA) return "LMETA";
+	if( key == SDLK_LSUPER) return "LSUPER";
+	if( key == SDLK_RSUPER) return "RSUPER";
+	if( key == SDLK_MODE) return "MODE";
+	if( key == SDLK_HELP) return "HELP";
+	if( key == SDLK_PRINT) return "PRINT";
+	if( key == SDLK_SYSREQ) return "SYSREQ";
+	if( key == SDLK_BREAK) return "BREAK";
+	if( key == SDLK_MENU) return "MENU";
+	if( key == SDLK_POWER) return "POWER";
+	if( key == SDLK_EURO) return "EURO";
+	return "UNKNOWN";
+}
Index: orxonox/trunk/src/keynames.h
===================================================================
--- orxonox/trunk/src/keynames.h	(revision 2190)
+++ orxonox/trunk/src/keynames.h	(revision 2190)
@@ -0,0 +1,41 @@
+/*!
+    \file keynames.h
+    \brief Key/button naming functions
+    
+		Converts strings to SDLK/SDL_BUTTON values and vice versa
+*/
+
+#ifdef __WIN32__
+#include <windows.h>
+#endif
+
+#include <SDL/SDL.h>
+
+/**
+	\brief converts a button name string to a integer representing the corresponding SDL mouse button identifier
+	\param name: the name of the mouse button
+	\return an int containing the SDL identifier of the mouse button or -1 if the button name is not valid
+*/
+int buttonname_to_SDLB( char* name);
+
+/**
+	\brief converst a SDL mouse button identifier to a name string
+	\param button: an SDL mouse button identifier
+	\return a pointer to a string containing the name of the mouse button
+*/
+char* SDLB_to_buttonname( int button);
+
+/**
+	\brief converts a key name string to a integer representing the corresponding SDLK sym
+	\param name: the name of the key
+	\return the SDLK sym of the named key or -1 if the key name is not valid
+*/
+int keyname_to_SDLK( char* name);
+
+/**
+	\brief converts an SDLK sym to a name string
+	\param key: the SDLK sym
+	\return a pointer to a string containig the name of the key
+*/
+char* SDLK_to_keyname( int key);
+
Index: orxonox/trunk/src/message_structures.h
===================================================================
--- orxonox/trunk/src/message_structures.h	(revision 2190)
+++ orxonox/trunk/src/message_structures.h	(revision 2190)
@@ -0,0 +1,28 @@
+/*!
+	\file message_structures.h
+	\brief contains defintitons of messages that can be passed between classes
+*/
+
+#ifndef _MESSAGESTRUCTURES_H
+#define _MESSAGESTRUCTURES_H
+
+#define CMD_LENGHT 16
+
+//! structure that contains a command message
+typedef struct
+{
+	char cmd[CMD_LENGHT];	//!< the command delivered
+	bool bUp;	//!< false = command was activated / true = command was deactivated
+	
+	//! if cmd is "cursor" the coordinates of the mouse cursor are stored here
+	//!@{
+	Uint16 x, y;
+	//!@}
+	
+	//! if cmd is "cursor" the relative motion of the mouse cursor is stored here
+	//!@{
+	Sint16 xrel, yrel; 
+	//!@}
+} Command;
+
+#endif
Index: orxonox/trunk/src/orxonox.cc
===================================================================
--- orxonox/trunk/src/orxonox.cc	(revision 2077)
+++ orxonox/trunk/src/orxonox.cc	(revision 2190)
@@ -21,54 +21,39 @@
    ### File Specific:
    main-programmer: Patrick Boenzli
-   co-programmer:
-*/
-
-#include <iostream>
-#include <cstdio>
-#include <GL/glut.h>
-
-#include "environment.h"
+   co-programmer: Christian Meyer
+*/
+
+#include "orxonox.h"
 #include "world.h"
-#include "input_output.h"
+#include "camera.h"
 #include "data_tank.h"
-#include "stdincl.h"
-#include "player.h"
-#include "npc.h"
-#include "shoot_laser.h"
-
-#include "orxonox.h"
+#include "command_node.h"
+#include <string.h>
 
 using namespace std;
 
-
-Orxonox::Orxonox () 
+/**
+	\brief create a new Orxonox
+*/
+Orxonox::Orxonox ()
 {
   pause = false;
 }
 
-
-
+/**
+	\brief remove Orxonox from memory
+*/
 Orxonox::~Orxonox () 
-{}
-
-
-/* this is a singleton class to prevent dublicates */
+{
+	Orxonox::singleton_ref = NULL;
+	if( world != NULL) delete world;
+	if( localinput != NULL) delete world;
+	if( localcamera != NULL) delete localcamera;
+	if( resources != NULL) delete resources;
+}
+
+
+/* this is a singleton class to prevent duplicates */
 Orxonox* Orxonox::singleton_ref = 0;
-World* Orxonox::world = 0;
-InputOutput* Orxonox::io = 0;
-Player* Orxonox::localPlayer = 0;
-bool Orxonox::pause = false;
-bool Orxonox::inputEnabled = false;
-bool Orxonox::upWeGo = false;
-bool Orxonox::downWeGo = false;
-bool Orxonox::rightWeGo = false;
-bool Orxonox::leftWeGo = false;
-bool Orxonox::shoot1 = false;
-int Orxonox::fps = 0;
-int Orxonox::alpha = 0;
-int Orxonox::beta = 0;
-//int Orxonox::offsetX = 0;
-//int Orxonox::offsetY = 0;
-
 
 Orxonox* Orxonox::getInstance (void)
@@ -79,262 +64,314 @@
 }
 
-
-int Orxonox::globalInit (int argc, char** argv) 
-{
-  glutInit(&argc, argv);
-  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+/**
+	\brief this finds the config file
+	
+	Since the config file varies from user to user and since one may want to specify different config files
+	for certain occasions or platforms this function finds the right config file for every occasion and stores
+	it's path and name into configfilename
+*/
+void Orxonox::get_config_file (int argc, char** argv)
+{
+/*	char* path;
+	#ifdef __WIN32__
+	path = getenv("");
+	#else
+	path = getenv("HOME");
+	#endif
+	
+	if( path != NULL) strcpy (configfilename, path);
+	else strcpy (configfilename, "./");
+	strcat (configfilename, "/.orxonox.conf");*/
+	
+	strcpy (configfilename, "orxonox.conf");
+}
+
+/**
+	\brief initialize Orxonox with command line
+*/
+int Orxonox::init (int argc, char** argv)
+{
+		// parse command line
+		// config file
+		
+	get_config_file (argc, argv);
+	
+		// initialize SDL
+  printf("> Initializing SDL\n");
+  if( SDL_Init (SDL_INIT_EVERYTHING) == -1)
+  {
+    printf ("Could not SDL_Init(): %s\n", SDL_GetError());
+    return -1;
+  }
+  
+  	// initialize everything
+  printf("> Initializing video\n");
+	if( init_video () == -1) return -1;
+  printf("> Initializing sound\n");
+	if( init_sound () == -1) return -1;
+  printf("> Initializing input\n");
+	if( init_input () == -1) return -1;
+  printf("> Initializing networking\n");
+	if( init_networking () == -1) return -1;
+  printf("> Initializing resources\n");
+	if( init_resources () == -1) return -1;
+  printf("> Initializing world\n");
+	if( init_world () == -1) return -1;
+	
+	return 0;
+}
+
+/**
+	\brief initializes SDL and OpenGL
+*/
+int Orxonox::init_video () 
+{
+  // 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);
+  
+  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)
+  {
+    printf ("Could not SDL_SetVideoMode(%d, %d, %d, %d): %s\n", width, height, bpp, flags, SDL_GetError());
+    SDL_Quit();
+    return -1;
+  }
+  
+  // Set window labeling
+  // TO DO: Add version information to caption
+  SDL_WM_SetCaption( "Orxonox", "Orxonox");
+  
+  // TO DO: Create a cool icon and use it here
+  // SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask);  
+
+  // OpenGL stuff
+  // (Is this all we initialize globally???)
+  glClearColor(0.0, 0.0, 0.0, 0.0);
   glEnable(GL_DEPTH_TEST);
-  glutInitWindowSize(500, 500);
-  //glutFullScreen();
-  glutInitWindowPosition(100, 100);
-  glutCreateWindow("OrxonoX");
+  glEnable(GL_COLOR);
   glShadeModel(GL_FLAT);
-  /* window event dispatchers */
-  glutDisplayFunc(display);
-  glutReshapeFunc(reshape);
-  glutKeyboardFunc(keyboard);
-  glutKeyboardUpFunc(upKeyboard);
-
-  glutTimerFunc(1000, timeSlice, 0);
-  cout << "measuring performance...";
-}
-
-
-int Orxonox::menuInit (void)
-{
-  glClearColor(0.0, 0.0, 0.0, 0.0);
-}
-
-
-int Orxonox::gameInit (void) 
-{
-  glClearColor(0.0, 0.0, 0.0, 0.0);
-  
-  /* world init, shouldnt be done here later */
-  world = new World;
-  (*world).initEnvironement();
-  localPlayer = new Player;
-  localPlayer->setPosition(0.0, -10.0, 3.0);
-  localPlayer->setCollisionRadius(2.0);
-  io = new InputOutput(world, localPlayer);
-  (*world).addPlayer(localPlayer);
-  Environment *env = new Environment;
-  (*world).addEnv(env);
-  NPC* npc = new NPC;
-  npc->setPosition(3.0, 0.0, 3.0);
-  npc->setCollisionRadius(1.0);
-  world->addNPC(npc);
-
-  NPC* npc2 = new NPC;
-  npc2->setPosition(-2.0, 10.0, 3.0);
-  npc2->setCollisionRadius(1.0);
-  world->addNPC(npc2);
-
-  glutSpecialFunc(specFunc); 
-  glutSpecialUpFunc(releaseKey);
-
-  glutIdleFunc(continousRedraw);
-  //cout << "Orxonox::gameInit" << endl;
-}
-
-
-/* this is the time triggered function. heart beat*/
-
-void Orxonox::timeSlice(int value)
-{
-  cout << "got " << fps << " fps" << endl;
-  /* this is very very unsafe: io could be uninit */
-  io->setPlayerStep(19.2/fps); /* set player to propper speed */
-  localPlayer->shootLaser->setShootStep(20.0/fps); /* set shoot speed */
-  world->setWorldStep(7.0/fps); /* set the speed of the terrain moving away */
-  fps = 0;
-  inputEnabled = true;
-  glutTimerFunc(1000, timeSlice, 0);
-}
-
-
-
-void Orxonox::keyboard(unsigned char key, int x, int y)
-{
-  switch(key) {
-
-    /* perspectiv control */
-  case 'w':
-    beta -= 1;
-    break;
-  case 's':
-    beta += 1;
-    break;
-  case 'a':
-    alpha -= 1;
-    break;
-  case 'd':
-    alpha += 1;
-    break;
-
-    /* game controls */
-  case 'p':
-    if (pause) 
-      {
-	cout << "unset pause" << endl;
-	glutIdleFunc(continousRedraw);
-	pause = false;
-      }
-    else 
-      {
-	cout << "set pause" << endl;
-	glutIdleFunc(NULL);
-	pause = true;
-      }
-    break;
-  case 32:
-    shoot1 = true;
-    break;
-  case 27:
-  case 'q':
-    quitGame();
-    break;
+  
+  // create camera
+  localcamera = new Camera();
+  
+  return 0;
+}
+
+/**
+	\brief initializes the sound engine
+*/
+int Orxonox::init_sound () 
+{
+	printf("Not yet implemented\n");
+	return 0;
+}
+
+/**
+	\brief initializes input functions
+*/
+int Orxonox::init_input () 
+{
+	// create localinput
+	localinput = new CommandNode( configfilename);
+	
+	return 0;
+}
+
+/**
+	\brief initializes network system
+*/
+int Orxonox::init_networking () 
+{
+	printf("Not yet implemented\n");
+	return 0;
+}
+
+/**
+	\brief initializes and loads resource files
+*/
+int Orxonox::init_resources () 
+{
+	printf("Not yet implemented\n");
+	return 0;
+}
+
+/**
+	\brief initializes the world
+*/
+int Orxonox::init_world () 
+{
+	world = new World();
+	
+	// TO DO: replace this with a menu/intro
+	world->load_debug_level();
+	
+	return 0;
+}
+
+/**
+	\brief exits Orxonox
+*/
+void Orxonox::quitGame() 
+{
+	bQuitOrxonox = true;
+}
+
+/**
+	\brief this runs all of Orxonox
+*/
+void Orxonox::mainLoop()
+{
+	lastframe = SDL_GetTicks();
+	bQuitOrxonox = false;
+  // This is where everything is run
+printf("Orxonox|Entering main loop\n");
+  while( !bQuitOrxonox)
+  {
+  	// Network
+  	synchronize();
+    // Process input
+    handle_input();
+    // Process time
+    time_slice();
+    // Process collision
+    collision();
+    // Draw
+    display();
   }
-}
-
-
-void Orxonox::upKeyboard(unsigned char key, int x, int y) 
-{
-  switch(key) {
-  case 32:
-    shoot1 = false;
-    break;
-  }
-}
-
-
-void Orxonox::quitGame() 
-{
-  //cout << "finished garbage colletion, quitting..." << endl;
-  exit(0);
-}
-
-
-void Orxonox::releaseKey(int key, int x, int y) 
-{  
-  switch(key) {
-  case GLUT_KEY_UP:
-    upWeGo = false;
-    break;
-  case GLUT_KEY_DOWN:
-    downWeGo = false;
-    break;
-  case GLUT_KEY_RIGHT:
-    rightWeGo = false;
-    break;
-  case GLUT_KEY_LEFT:
-    leftWeGo = false;
-    break;
-  }
-}
-
-
-/** 
-   \brief special keys function. called by glut
-   
-   Here are all special key function defined.
-*/
-void Orxonox::specFunc(int key, int x, int y)
-{
-  switch(key) {
-    /* spacecraft controls */
-  case GLUT_KEY_UP:
-    upWeGo = true;
-    break;
-  case GLUT_KEY_DOWN:
-    downWeGo = true;
-    break;
-  case GLUT_KEY_RIGHT:
-    rightWeGo = true;
-    break;
-  case GLUT_KEY_LEFT:
-    leftWeGo = true;
-    break;
-  }
-}
-
-
-void Orxonox::display() 
-{
-  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-  glColor3f(0.0, 0.5, 0.6);
-  glLoadIdentity();
-  gluLookAt(0.0, -14.0, 15.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
-  (*world).drawWorld();
-
-  glutSwapBuffers();
-} 
-
-
-void Orxonox::continousRedraw()
-{
-  /* increment the frames-per-second counter*/
-  fps++;
-  /* check for collisions */
-  world->detectCollision();
-
-  /* check for input to pass it over */
-  if ( !pause && inputEnabled && 
-       (rightWeGo || leftWeGo || upWeGo || downWeGo || shoot1)) 
-    {
-      if (upWeGo)
-	(*io).goUp();
-      if (downWeGo)
-      (*io).goDown();
-      if (rightWeGo)
-	(*io).goRight();
-      if (leftWeGo)
-      (*io).goLeft();
-      if (shoot1) 
-	(*io).shoot();
-    }
-  /* request repaint */
-  glutPostRedisplay();
-  //cout << "Orxonox::continousRedraw" << endl;
-}
-
-
-void Orxonox::reshape (int w, int h)
-{
-  glViewport(0, 0, (GLsizei) w, (GLsizei) h);
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
-  glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 200.0);
-  glMatrixMode(GL_MODELVIEW);
-  glLoadIdentity(); //pb why a second time?
-}
-
-
-void Orxonox::testTheShit() 
-{
-  //Player* pl = new Player;
-  //(*pl).setPosition(1, 1, 1);
-  //(*world).addPlayer(pl);
-  
-  //NPC* nl = new NPC;
-  //(*world).addNPC(nl);
-  //(*world).addNPC(nl);
-  //(*world).addNPC(nl);
-  //(*world).addNPC(nl);
-  //(*world).addNPC(nl);
-  //(*world).addNPC(nl);
-  //(*world).testThaTest();
-}
-
+printf("Orxonox|Exiting the main loop\n");
+}
+
+/**
+	\brief handles sprecial events from localinput
+	\param event: an event not handled by the CommandNode 
+*/
+void Orxonox::event_handler (SDL_Event* event)
+{
+	// Handle special events such as reshape, quit, focus changes
+}
+
+/**
+	\brief synchronize local data with remote data
+*/
+void Orxonox::synchronize ()
+{
+	// Get remote input
+	// Update synchronizables
+}
+
+/**
+	\brief run all input processing
+*/
+void Orxonox::handle_input ()
+{
+	// localinput
+		localinput->process();
+	// remoteinput
+}
+
+/**
+	\brief advance the timeline
+*/
+void Orxonox::time_slice ()
+{
+	Uint32 curframe = SDL_GetTicks();
+	if( !pause)
+	{
+		world->time_slice (curframe - lastframe);
+		world->update ();
+		localcamera->time_slice (curframe - lastframe);
+	}
+	lastframe = curframe;
+}
+
+/**
+	\brief compute collision detection
+*/
+void Orxonox::collision ()
+{
+	world->collide ();
+}
+
+/**
+	\brief handle keyboard commands that are not meant for WorldEntities
+	\param cmd: the command to handle
+	\return true if the command was handled by the system or false if it may be passed to the WorldEntities
+*/
+bool Orxonox::system_command (Command* cmd)
+{
+	if( !strcmp( cmd->cmd, "quit"))
+	{
+		if( !cmd->bUp) bQuitOrxonox = true;
+		return true;
+	}
+	return false;
+}
+
+/**
+	\brief render the current frame
+*/
+void Orxonox::display ()
+{
+		// clear buffer
+	glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+		// set camera
+	localcamera->apply ();
+		// draw world
+	world->draw ();
+		// draw HUD
+		// flip buffers
+	SDL_GL_SwapBuffers();
+}
+
+/**
+	\brief retrieve a pointer to the local Camera
+	\return a pointer to localcamera
+*/
+Camera* Orxonox::get_camera ()
+{
+	return localcamera;
+}
+
+/**
+	\brief retrieve a pointer to the local CommandNode
+	\return a pointer to localinput
+*/
+CommandNode* Orxonox::get_localinput ()
+{
+	return localinput;
+}
+
+/**
+	\brief retrieve a pointer to the local World
+	\return a pointer to world
+*/
+World* Orxonox::get_world ()
+{
+	return world;
+}
 
 int main (int argc, char** argv) 
 {  
+	printf(">>> Starting Orxonox <<<\n");
   Orxonox *orx = Orxonox::getInstance();
-  (*orx).globalInit(argc, argv);
-  //(*orx).menuInit(); pb: directly jump to the game, no menu
-  (*orx).gameInit();
-
-  glutMainLoop();  
+  
+  if( (*orx).init(argc, argv) == -1)
+  {
+    printf("! Orxonox initialization failed\n");
+    return -1;
+  }
+	
+  (*orx).mainLoop();
+
+  //delete orx;
+  
   return 0;
 }
Index: orxonox/trunk/src/orxonox.conf
===================================================================
--- orxonox/trunk/src/orxonox.conf	(revision 2190)
+++ orxonox/trunk/src/orxonox.conf	(revision 2190)
@@ -0,0 +1,11 @@
+[Bindings]
+UP=up
+DOWN=down
+LEFT=left
+RIGHT=right
+SPACE=fire
+ESCAPE=quit
+q=quit
+BUTTON_LEFT=fire
+BUTTON_RIGHT=altfire
+b=benscho
Index: orxonox/trunk/src/orxonox.h
===================================================================
--- orxonox/trunk/src/orxonox.h	(revision 2077)
+++ orxonox/trunk/src/orxonox.h	(revision 2190)
@@ -1,11 +1,23 @@
+/*! 
+    \file orxonox.h
+    \brief Orxonox core functions
+*/ 
 
 #ifndef ORXONOX_H
 #define ORXONOX_H
 
+#include <SDL/SDL.h>
+
+#include "stdincl.h"
+
+class CommandNode;
+class WorldEntity;
+class DataTank;
 class World;
-class InputOutput;
-class Player;
+class Camera;
 
-
+//! Orxonox core singleton class
+/**
+*/
 class Orxonox {
 
@@ -14,38 +26,47 @@
   Orxonox ();
   ~Orxonox ();
-  static World* world;
-  static InputOutput* io;
-  static Player* localPlayer;
-  static bool pause;
-  static bool inputEnabled;
-  static bool upWeGo;
-  static bool downWeGo;
-  static bool rightWeGo;
-  static bool leftWeGo;
-  static bool shoot1;
-  static int fps;
+  
+  char configfilename[256];
+  World* world;
+  DataTank* resources;
+  CommandNode* localinput;
+  Camera* localcamera;
+  SDL_Surface* screen;
+  
+  bool bQuitOrxonox;
+  bool pause;
+	Uint32 lastframe;
 
-  static int alpha;
-  static int beta;
-  static int offsetX;
-  static int offsetY;
+	void get_config_file (int argc, char** argv);
+	
+		// main loop functions
+  void synchronize ();
+  void handle_input ();
+  void time_slice ();
+  void collision ();
+  void display ();
+  
+  	// subsystem initialization
+  int init_video ();
+  int init_sound ();
+  int init_input ();
+  int init_networking ();
+  int init_resources ();
+  int init_world ();
+  
+ public:
+  static Orxonox* getInstance ();
+  void quitGame();
 
-  static void timeSlice(int value);
+  void event_handler (SDL_Event* event);
+  bool system_command (Command* cmd);
 
- public:
-  static Orxonox* getInstance (void);
-
-  int globalInit (int argc, char** argv);
-  int menuInit (void);
-  int gameInit (void);
-  void testTheShit(void);
-  static void display (void);
-  static void continousRedraw(void);
-  static void reshape (int w, int h);
-  static void keyboard(unsigned char key, int x, int y);
-  static void upKeyboard(unsigned char key, int x, int y);
-  static void releaseKey(int key, int x, int y);
-  static void specFunc(int key, int x, int y);
-  static void quitGame(void); 
+  int init (int argc, char** argv);
+	
+	CommandNode* get_localinput();
+	Camera* get_camera();
+	World* get_world();
+	
+  void mainLoop();
 };
 
Index: orxonox/trunk/src/player.cc
===================================================================
--- orxonox/trunk/src/player.cc	(revision 2077)
+++ orxonox/trunk/src/player.cc	(revision 2190)
@@ -13,118 +13,117 @@
    ### File Specific:
    main-programmer: Patrick Boenzli
-   co-programmer:
+   co-programmer: Christian Meyer
 */
 
-#include <iostream>
-#include <stdlib.h>
-#include <GL/glut.h>
-
-#include "shoot_laser.h"
-#include "shoot_rocket.h"
-#include "data_tank.h"
-
 #include "player.h"
+#include "stdincl.h"
+#include "collision.h"
 
 using namespace std;
 
 
-Player::Player() 
-   : WorldEntity() {
-  //cout << "Player::Player" << endl;
-  xCor = yCor = zCor = 0;
-  shootLaser = new ShootLaser;
-  shootRocket = new ShootRocket;
+Player::Player(bool isFree) : WorldEntity(isFree)
+{
 }
 
 Player::~Player () 
 {
-  //delete shootLaser;
 }
 
-
-void Player::setPosition( float x, float y, float z)
+void Player::post_spawn ()
 {
-  xCor = x; yCor = y; zCor = z;
+	travel_speed = 10.0;
+	velocity = Vector();
+	bUp = bDown = bLeft = bRight = bAscend = bDescend = false;
+	bFire = false;
+	acceleration = 10.0;
+	set_collision (new CollisionCluster (1.0, Vector(0,0,0)));
 }
 
-
-void Player::getPosition(float* x, float* y, float* z)
+void Player::tick (float time)
 {
-  *x = xCor; *y = yCor; *z = zCor;
+	// movement
+	move (time);
 }
 
-
-void Player::setCollisionRadius(float radius) 
+void Player::hit (WorldEntity* weapon, Vector loc)
 {
-  collisionRadius = radius;
 }
 
-
-void Player::goX(float x) 
+void Player::destroy ()
 {
-  xCor += x;
 }
 
-
-void Player::goY(float y)
+void Player::collide (WorldEntity* other,  Uint32 ownhitflags, Uint32 otherhitflags)
 {
-  yCor += y;
 }
 
-void Player::goZ(float z)
+void Player::command (Command* cmd)
 {
-  zCor += z;
+	printf("Player|recieved command [%s]\n", cmd->cmd);
+	if( !strcmp( cmd->cmd, "up")) bUp = !cmd->bUp;
+	else if( !strcmp( cmd->cmd, "down")) bDown = !cmd->bUp;
+	else if( !strcmp( cmd->cmd, "left")) bLeft = !cmd->bUp;
+	else if( !strcmp( cmd->cmd, "right")) bRight = !cmd->bUp;
+	else if( !strcmp( cmd->cmd, "fire")) bFire = !cmd->bUp;
 }
 
+void Player::draw ()
+{
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+	float matrix[4][4];
 
-
-void Player::shoot(int n) 
-{
-
-  //  if (shootLaser->inhibitor++ <= 100)
-  shootLaser->addShoot(xCor, yCor, zCor);
-  // else if (shootLaser->inhibitor++ <= 200)
-  shootLaser->addShootExt(xCor, yCor, zCor, .1, .4, .0);
-  //  else if (shootLaser->inhibitor++ <= 300)
-  shootLaser->addShootExt(xCor, yCor, zCor, -0.1, .4, .0);
-  //  else
-  shootLaser->inhibitor =0;
-  
-  //  if (shootRocket->inhibitor++ >=80)
-  {
-    shootRocket->addBackParable(xCor, yCor, zCor);
-    shootRocket->addSideAcc(xCor, yCor, zCor, RIGHT);
-    shootRocket->addSideAcc(xCor, yCor, zCor, LEFT);
-    shootRocket->addRotater(xCor, yCor, zCor);
-    //  if (shootRocket->inhibitor >=90)
-    //        shootRocket->inhibitor =0;
-  }
-  //cout << "Player::shoot" << endl;
-  
-  /*
-  shootLaser->addShoot(xCor, yCor, zCor);
-  shootLaser->addShootExt(xCor, yCor, zCor, .1, .4, .0);
-  shootLaser->addShootExt(xCor, yCor, zCor, -0.1, .4, .0);
-  //shootRocket->addShoot(xCor, yCor, zCor);
-  //cout << "Player::shoot" << endl;
-  */
+	glTranslatef(get_placement()->r.x,get_placement()->r.y,get_placement()->r.z);
+  get_placement()->w.matrix (matrix);
+  glMultMatrixf ((float*)matrix);
+	
+	glBegin(GL_TRIANGLES);
+	glColor3f(1,0,0);
+	glVertex3f(0,0,0.5);
+	glColor3f(0,1,0);
+	glVertex3f(-0.5,0,-1);
+	glColor3f(0,0,1);
+	glVertex3f(0.5,0,-1);
+	glEnd();
+	
+	printf("Player@%f/%f/%f\n", get_placement()->r.x, get_placement()->r.y, get_placement()->r.z);
 }
 
+void Player::get_lookat (Location* locbuf)
+{
+	*locbuf = *get_location();
+	//locbuf->dist += 5.0;
+}
 
-//void Player::addIO(InputOutput *io) {}
+void Player::left_world ()
+{
+}
 
-
-void Player::paint() 
+void Player::move (float time)
 {
-  //cout << "Player::drawPlayer" << endl;
-  glPushMatrix();
-  glTranslatef(xCor, yCor, 3.0);
-  glScalef(1.0, 3.0, 1.0);
-  glutWireCube(1.0);
-  glPopMatrix();
-  /* draw all the shoots additionaly */
-  shootLaser->drawShoot();
-  shootRocket->drawShoot();
-  //cout << "Player::drawPlayer, end" << endl;
+	float xAccel, yAccel, zAccel;
+	xAccel = yAccel = zAccel = 0;
+	if( bUp) xAccel += acceleration;
+	if( bDown) xAccel -= acceleration;
+	if( bLeft) yAccel += acceleration;
+	if( bRight) yAccel -= acceleration;
+	if( bAscend) zAccel += acceleration;
+	if( bDescend) zAccel -= acceleration;
+	
+	Vector accel( xAccel, yAccel, zAccel);
+	
+	Location* l = get_location();
+	
+	// r(t) = r(0) + v(0)*t + 1/2*a*t^2
+	// r = position
+	// v = velocity
+	// a = acceleration
+	
+	l->pos = l->pos + velocity*time + (accel*(0.5*time*time));
+	l->dist += travel_speed * time;
+	
+	velocity = velocity + (accel * time);
+	printf("Player|velocity %f/%f/%f\n", velocity.x, velocity.y, velocity.z);
 }
 
@@ -146,10 +145,2 @@
 
 
-
-
-
-
-
-
-
-
Index: orxonox/trunk/src/player.h
===================================================================
--- orxonox/trunk/src/player.h	(revision 2077)
+++ orxonox/trunk/src/player.h	(revision 2190)
@@ -1,2 +1,6 @@
+/*! 
+    \file player.h
+    \brief Implements a basic controllable WorldEntity
+*/
 
 #ifndef PLAYER_H
@@ -5,41 +9,34 @@
 #include "world_entity.h"
 
-class ShootLaser;
-class ShootRocket;
-
-
+//! Basic controllable WorldEntity
 class Player : public WorldEntity 
 {
+	friend class World;
 
  public:
-  Player ();
+  Player (bool isFree = false);
   ~Player ();
 
-  /* position of the spacecraft */
-  float xCor;
-  float yCor;
-  float zCor;
+	virtual void post_spawn ();
+  virtual void tick (float time);
+  virtual void hit (WorldEntity* weapon, Vector loc);
+  virtual void destroy ();
+  virtual void collide (WorldEntity* other,  Uint32 ownhitflags, Uint32 otherhitflags);
+ 	virtual void command (Command* cmd);
   
-  float collisionRadius;
+  virtual void draw ();
+  virtual void get_lookat (Location* locbuf);
 
-
-  /* this player wanna shoot? so include a ref to ShootLaser */
-  ShootLaser* shootLaser;
-  ShootRocket* shootRocket;
-
-  void setPosition(float x, float y, float z);
-  void getPosition(float* x, float* y, float* z);
-  void setCollisionRadius(float radius);
-  void paint();
-  void goX(float x);
-  void goY(float y);
-  void goZ(float x);
-  void shoot(int n);
-  //  void addIO(InputOutput *io);
-  void drawPlayer(void);
+	virtual void left_world ();
 
  private:
-
-
+ 	bool bUp, bDown, bLeft, bRight, bAscend, bDescend;
+ 	bool bFire;
+ 	Vector velocity;
+ 	float travel_speed;
+ 	float acceleration;
+ 	
+ 	void move (float time);
+ 	
 };
 
Index: orxonox/trunk/src/stdincl.h
===================================================================
--- orxonox/trunk/src/stdincl.h	(revision 2077)
+++ orxonox/trunk/src/stdincl.h	(revision 2190)
@@ -5,3 +5,15 @@
 #define null 0
 
+#ifdef __WIN32__
+#include <windows.h>
 #endif
+#include <SDL/SDL.h>
+#include <GL/gl.h>
+
+#include "vector.h"
+#include "coordinates.h"
+#include "list.h"
+#include "message_structures.h"
+#include "orxonox.h"
+
+#endif
Index: orxonox/trunk/src/track.cc
===================================================================
--- orxonox/trunk/src/track.cc	(revision 2190)
+++ orxonox/trunk/src/track.cc	(revision 2190)
@@ -0,0 +1,138 @@
+
+
+/* 
+   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: Christian Meyer
+   co-programmer: ...
+*/
+
+#include "track.h"
+
+using namespace std;
+
+/**
+	\brief creates a null Track part
+*/
+Track::Track ()
+{
+	ID = 0;
+	offset = NULL;
+	end = NULL;
+	nextID = 0;
+}
+
+/**
+	\brief creates a functional base Track part
+	\param number: the ID if this Track part
+	\param next: the ID of the next Track part
+	\param start: pointer to an anchor point (Vector) representing the offset of this part
+	\param finish: pointer to an anchor point (Vector) representing the end of this part
+*/
+Track::Track (Uint32 number, Uint32 next, Vector* start, Vector* finish)
+{
+	ID = number;
+	offset = start;
+	end = finish;
+	nextID = next;
+}
+
+/**
+	\brief removes the Track part from memory
+*/
+Track::~Track ()
+{
+}
+
+/**
+	\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::map_camera (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);
+	camplc->w = Quaternion(Vector(0,0,0) - ((trace.r + (trace.a * ((lookat->dist) / l)) - camplc->r)), Vector(0,sin(r),cos(r)));
+	
+}
+
+/**
+	\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
+	
+	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::map_coords (Location* loc, Placement* plc)
+{
+	Line trace(*offset, *end - *offset);
+	float l = trace.len ();
+	
+	if( loc->dist > l)
+	{
+		loc->dist -= l;
+		loc->part = nextID;
+		return true;
+	}
+	
+	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;
+}
+
+/**
+	\brief this is called when a WorldEntity enters a Track part
+	\param entity: pointer to the WorldEntity in question
+	
+	You can do stuff like add or remove effects, do some coordinate finetuning or whatever in here.
+*/
+void Track::post_enter (WorldEntity* entity)
+{
+}
+
+/**
+	\brief this is called when a WorldEntity leaves a Track part
+	\param entity: pointer to the WorldEntity in question
+	
+	You can do stuff like add or remove effects, do some coordinate finetuning or whatever in here.
+*/
+void Track::post_leave (WorldEntity* entity)
+{
+}
+
+/**
+	\brief this is called every frame
+	\param deltaT: amount of time passed since the last frame in seconds
+	
+	Do time based or polling scripts here. 
+*/
+void Track::tick (float deltaT)
+{
+}
+
+
+
+
+
Index: orxonox/trunk/src/track.h
===================================================================
--- orxonox/trunk/src/track.h	(revision 2190)
+++ orxonox/trunk/src/track.h	(revision 2190)
@@ -0,0 +1,36 @@
+/*! 
+    \file track.h
+    \brief Basic level architecture
+*/ 
+
+#ifndef TRACK_H
+#define TRACK_H
+
+#include "stdincl.h"
+
+//!	The Red Line through a level
+/**
+	Handles level boundaries, bound movement mapping, camera placement and scripting.
+	To create special levels with special camera movement, rules or whatever, derive from this base class.
+*/
+class Track 
+{
+ private:
+ 	Uint32 ID;
+ 	Vector* offset;
+ 	Vector* end;
+ 	Uint32 nextID;
+ 	
+ public:
+ 	Track ();
+  Track (Uint32 number, Uint32 next, Vector* start, Vector* finish);
+  ~Track ();
+	
+	virtual void post_enter (WorldEntity* entity);	// handle coordinate transition in here !!! (when dist < 0 or dist > lasttracklenght)
+	virtual void post_leave (WorldEntity* entity);
+	virtual void tick (float deltaT);
+	virtual void map_camera (Location* lookat, Placement* camplc);
+	virtual bool map_coords (Location* loc, Placement* plc);	// this should return true if the entity left track boundaries
+};
+
+#endif
Index: orxonox/trunk/src/vector.cc
===================================================================
--- orxonox/trunk/src/vector.cc	(revision 2077)
+++ orxonox/trunk/src/vector.cc	(revision 2190)
@@ -14,4 +14,6 @@
    main-programmer: Christian Meyer
    co-programmer: ...
+   
+   Quaternion code borrowed from an Gamasutra article by Nick Bobick and Ken Shoemake
 */
 
@@ -177,4 +179,303 @@
   f = acos( v1 * v2 / (v1.len() * v2.len()));
   return f * 180 / PI;
+}
+
+/**
+	\brief creates a multiplicational identity Quaternion
+*/
+Quaternion::Quaternion ()
+{
+	w = 1;
+	v = Vector(0,0,0);
+}
+
+/**
+	\brief turns a rotation along an axis into a Quaternion
+	\param angle: the amount of radians to rotate
+	\param axis: the axis to rotate around
+*/
+Quaternion::Quaternion (float angle, const Vector& axis)
+{
+	w = cos(angle/2);
+	v = axis * sin(angle/2);
+}
+
+/**
+	\brief calculates a look_at rotation
+	\param dir: the direction you want to look
+	\param up: specify what direction up should be
+	
+	Mathematically this determines the rotation a (0,0,1)-Vector has to undergo to point the same way as dir.
+	If you want to use this with cameras, you'll have to reverse the dir Vector (Vector(0,0,0) - your viewing direction)
+	or you'll point the wrong way. You can use this for meshes as well (then you do not have to reverse the vector), but keep in mind that if you do that, the model's front
+	has to point in +z direction, and left and right should be -x or +x respectively or the mesh wont rotate correctly.
+*/
+Quaternion::Quaternion (const Vector& dir, const Vector& up)
+{
+	Vector z = dir;
+  z.normalize(); 
+  Vector x = up.cross(z);
+  x.normalize(); 
+  Vector y = z.cross(x);
+  
+  float m[4][4];
+  m[0][0] = x.x;
+  m[0][1] = x.y;
+  m[0][2] = x.z;
+  m[0][3] = 0;
+  m[1][0] = y.x;
+  m[1][1] = y.y;
+  m[1][2] = y.z;
+  m[1][3] = 0;
+  m[2][0] = z.x;
+  m[2][1] = z.y;
+  m[2][2] = z.z;
+  m[2][3] = 0;
+  m[3][0] = 0;
+  m[3][1] = 0;
+  m[3][2] = 0;
+  m[3][3] = 1;
+  
+  *this = Quaternion (m);
+}
+
+/**
+	\brief calculates a rotation from euler angles
+	\param roll: the roll in radians
+	\param pitch: the pitch in radians
+	\param yaw: the yaw in radians
+	
+	I DO HONESTLY NOT EXACTLY KNOW WHICH ANGLE REPRESENTS WHICH ROTATION. And I do not know in what order they are applied,
+	I just copy-pasted the code.
+*/
+Quaternion::Quaternion (float roll, float pitch, float yaw)
+{
+	float cr, cp, cy, sr, sp, sy, cpcy, spsy;
+	
+	// calculate trig identities
+	cr = cos(roll/2);
+	cp = cos(pitch/2);
+	cy = cos(yaw/2);
+	
+	sr = sin(roll/2);
+	sp = sin(pitch/2);
+	sy = sin(yaw/2);
+	
+	cpcy = cp * cy;
+	spsy = sp * sy;
+	
+	w = cr * cpcy + sr * spsy;
+	v.x = sr * cpcy - cr * spsy;
+	v.y = cr * sp * cy + sr * cp * sy;
+	v.z = cr * cp * sy - sr * sp * cy;
+}
+
+/**
+	\brief rotates one Quaternion by another
+	\param q: another Quaternion to rotate this by
+	\return a quaternion that represents the first one rotated by the second one (WARUNING: this operation is not commutative! e.g. (A*B) != (B*A))
+*/
+Quaternion Quaternion::operator*(const Quaternion& q) const
+{
+	float A, B, C, D, E, F, G, H;
+	Quaternion r;
+	
+	A = (w   + v.x)*(q.w   + q.v.x);
+	B = (v.z - v.y)*(q.v.y - q.v.z);
+	C = (w   - v.x)*(q.v.y + q.v.z); 
+	D = (v.y + v.z)*(q.w   - q.v.x);
+	E = (v.x + v.z)*(q.v.x + q.v.y);
+	F = (v.x - v.z)*(q.v.x - q.v.y);
+	G = (w   + v.y)*(q.w   - q.v.z);
+	H = (w   - v.y)*(q.w   + q.v.z);
+	
+	r.w = B +  (-E - F + G + H)/2;
+	r.v.x = A - (E + F + G + H)/2; 
+	r.v.y = C + (E - F + G - H)/2; 
+	r.v.z = D + (E - F - G + H)/2;
+	
+	return r;
+}
+
+/**
+	\brief add two Quaternions
+	\param q: another Quaternion
+	\return the sum of both Quaternions
+*/
+Quaternion Quaternion::operator+(const Quaternion& q) const
+{
+	Quaternion r(*this);
+	r.w = r.w + q.w;
+	r.v = r.v + q.v;
+	return r;
+}
+
+/**
+	\brief subtract two Quaternions
+	\param q: another Quaternion
+	\return the difference of both Quaternions
+*/
+Quaternion Quaternion::operator- (const Quaternion& q) const
+{
+	Quaternion r(*this);
+	r.w = r.w - q.w;
+	r.v = r.v - q.v;
+	return r;
+}
+
+/**
+	\brief rotate a Vector by a Quaternion
+	\param v: the Vector
+	\return a new Vector representing v rotated by the Quaternion
+*/
+Vector Quaternion::apply (Vector& v) const
+{
+	Quaternion q;
+	q.v = v;
+	q.w = 0;
+	q = *this * q * conjugate();
+	return q.v;
+}
+
+/**
+	\brief multiply a Quaternion with a real value
+	\param f: a real value
+	\return a new Quaternion containing the product
+*/
+Quaternion Quaternion::operator*(const float& f) const
+{
+	Quaternion r(*this);
+	r.w = r.w*f;
+	r.v = r.v*f;
+	return r;
+}
+
+/**
+	\brief divide a Quaternion by a real value
+	\param f: a real value
+	\return a new Quaternion containing the quotient
+*/
+Quaternion Quaternion::operator/(const float& f) const
+{
+	if( f == 0) return Quaternion();
+	Quaternion r(*this);
+	r.w = r.w/f;
+	r.v = r.v/f;
+	return r;
+}
+
+/**
+	\brief calculate the conjugate value of the Quaternion
+	\return the conjugate Quaternion
+*/
+Quaternion Quaternion::conjugate() const
+{
+	Quaternion r(*this);
+	r.v = Vector() - r.v;
+	return r;
+}
+
+/**
+	\brief calculate the norm of the Quaternion
+	\return the norm of The Quaternion
+*/
+float Quaternion::norm() const
+{
+	return w*w + v.x*v.x + v.y*v.y + v.z*v.z;
+}
+
+/**
+	\brief calculate the inverse value of the Quaternion
+	\return the inverse Quaternion
+	
+	Note that this is equal to conjugate() if the Quaternion's norm is 1
+*/
+Quaternion Quaternion::inverse() const
+{
+	float n = norm();
+	if (n != 0)
+	{
+		return conjugate() / norm();
+	}
+	else return Quaternion();
+}
+
+/**
+	\brief convert the Quaternion to a 4x4 rotational glMatrix
+	\param m: a buffer to store the Matrix in
+*/
+void Quaternion::matrix (float m[4][4]) const
+{
+	float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; 
+
+	// calculate coefficients
+	x2 = v.x + v.x;
+  y2 = v.y + v.y; 
+	z2 = v.z + v.z;
+	xx = v.x * x2; xy = v.x * y2; xz = v.x * z2;
+	yy = v.y * y2; yz = v.y * z2; zz = v.z * z2;
+	wx = w * x2; wy = w * y2; wz = w * z2;
+	
+	m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz;
+	m[2][0] = xz + wy; m[3][0] = 0.0;
+	
+	m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz);
+	m[2][1] = yz - wx; m[3][1] = 0.0;
+	
+	m[0][2] = xz - wy; m[1][2] = yz + wx;
+	m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0;
+	
+	m[0][3] = 0; m[1][3] = 0;
+	m[2][3] = 0; m[3][3] = 1;
+}
+
+/**
+	\brief convert a rotational 4x4 glMatrix into a Quaternion
+	\param m: a 4x4 matrix in glMatrix order
+*/
+Quaternion::Quaternion (float m[4][4])
+{
+	
+  float  tr, s, q[4];
+  int    i, j, k;
+
+  int nxt[3] = {1, 2, 0};
+
+  tr = m[0][0] + m[1][1] + m[2][2];
+
+  	// check the diagonal
+  if (tr > 0.0) 
+  {
+    s = sqrt (tr + 1.0);
+    w = s / 2.0;
+    s = 0.5 / s;
+    v.x = (m[1][2] - m[2][1]) * s;
+    v.y = (m[2][0] - m[0][2]) * s;
+    v.z = (m[0][1] - m[1][0]) * s;
+	} 
+	else 
+	{
+ 		// diagonal is negative
+  	i = 0;
+  	if (m[1][1] > m[0][0]) i = 1;
+    if (m[2][2] > m[i][i]) i = 2;
+    j = nxt[i];
+    k = nxt[j];
+
+    s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + 1.0);
+      
+    q[i] = s * 0.5;
+            
+    if (s != 0.0) s = 0.5 / s;
+	
+	  q[3] = (m[j][k] - m[k][j]) * s;
+    q[j] = (m[i][j] + m[j][i]) * s;
+    q[k] = (m[i][k] + m[k][i]) * s;
+
+  	v.x = q[0];
+  	v.y = q[1];
+  	v.z = q[2];
+  	w = q[3];
+  }
 }
 
@@ -266,4 +567,57 @@
 
 /**
+   \brief fills the specified buffer with a 4x4 glmatrix
+   \param buffer: Pointer to an array of 16 floats
+   
+   Use this to get the rotation in a gl-compatible format
+*/
+void Rotation::glmatrix (float* buffer)
+{
+	buffer[0] = m[0];
+	buffer[1] = m[3];
+	buffer[2] = m[6];
+	buffer[3] = m[0];
+	buffer[4] = m[1];
+	buffer[5] = m[4];
+	buffer[6] = m[7];
+	buffer[7] = m[0];
+	buffer[8] = m[2];
+	buffer[9] = m[5];
+	buffer[10] = m[8];
+	buffer[11] = m[0];
+	buffer[12] = m[0];
+	buffer[13] = m[0];
+	buffer[14] = m[0];
+	buffer[15] = m[1];
+}
+
+/**
+   \brief multiplies two rotational matrices
+   \param r: another Rotation
+   \return the matrix product of the Rotations
+   
+   Use this to rotate one rotation by another
+*/
+Rotation Rotation::operator* (const Rotation& r)
+{
+	Rotation p;
+	
+	p.m[0] = m[0]*r.m[0] + m[1]*r.m[3] + m[2]*r.m[6];
+	p.m[1] = m[0]*r.m[1] + m[1]*r.m[4] + m[2]*r.m[7];
+	p.m[2] = m[0]*r.m[2] + m[1]*r.m[5] + m[2]*r.m[8];
+	
+	p.m[3] = m[3]*r.m[0] + m[4]*r.m[3] + m[5]*r.m[6];
+	p.m[4] = m[3]*r.m[1] + m[4]*r.m[4] + m[5]*r.m[7];
+	p.m[5] = m[3]*r.m[2] + m[4]*r.m[5] + m[5]*r.m[8];
+
+	p.m[6] = m[6]*r.m[0] + m[7]*r.m[3] + m[8]*r.m[6];
+	p.m[7] = m[6]*r.m[1] + m[7]*r.m[4] + m[8]*r.m[7];
+	p.m[8] = m[6]*r.m[2] + m[7]*r.m[5] + m[8]*r.m[8];
+	
+	return p;
+}
+
+
+/**
    \brief rotates the vector by the given rotation
    \param v: a vector
Index: orxonox/trunk/src/vector.h
===================================================================
--- orxonox/trunk/src/vector.h	(revision 2077)
+++ orxonox/trunk/src/vector.h	(revision 2190)
@@ -12,9 +12,7 @@
 #define PI 3.14159265359f
 
-//! 3D vector
+//! 3D Vector
 /**
-  Class for 3-dimensional vector calculation
-  
-  Supports all common vector operations (dot, cross, lenght and so on)
+	Class to handle 3D Vectors
 */
 class Vector {
@@ -42,5 +40,33 @@
 float angle_rad (const Vector& v1, const Vector& v2);
 
-//! 3D rotation
+//! Quaternion
+/**
+	Class to handle 3-dimensional rotation efficiently
+*/
+class Quaternion
+{
+ public:
+	Vector v;	//!< Imaginary Vector
+	float w; //!< Real part of the number
+
+ 	Quaternion ();
+ 	Quaternion (float m[4][4]);
+ 	Quaternion (float angle, const Vector& axis);
+ 	Quaternion (const Vector& dir, const Vector& up);
+ 	Quaternion (float roll, float pitch, float yaw);
+ 	
+ 	Quaternion operator/ (const float& f) const;
+ 	Quaternion operator* (const float& f) const;
+ 	Quaternion operator* (const Quaternion& q) const;
+	Quaternion operator+ (const Quaternion& q) const;
+	Quaternion operator- (const Quaternion& q) const;
+	Quaternion conjugate () const;
+	Quaternion inverse () const;
+ 	Vector apply (Vector& f) const;
+	float norm () const;
+	void matrix (float m[4][4]) const;
+};
+
+//! 3D rotation (OBSOLETE)
 /**
   Class to handle 3-dimensional rotations.
@@ -58,4 +84,7 @@
   ~Rotation () {}
   
+  Rotation operator* (const Rotation& r);
+  
+  void glmatrix (float* buffer);
 };
 
Index: orxonox/trunk/src/world.cc
===================================================================
--- orxonox/trunk/src/world.cc	(revision 2077)
+++ orxonox/trunk/src/world.cc	(revision 2190)
@@ -12,25 +12,14 @@
    ### File Specific:
    main-programmer: Patrick Boenzli
-   co-programmer:
-*/
-
-#include <iostream>
-#include <stdlib.h>
-#include <cmath>
-#include <GL/glut.h>
-
-#include "npc.h"
+   co-programmer: Christian Meyer
+*/
+
+#include "world.h"
+#include "world_entity.h"
+#include "collision.h"
+#include "track.h"
 #include "player.h"
-#include "environment.h"
-#include "shoot_laser.h"
-#include "shoot_rocket.h"
-#include "stdincl.h"
-#include "data_tank.h"
-
-#include "list.h"
-#include "world_entity.h"
-
-#include "world.h"
-
+#include "command_node.h"
+#include "camera.h"
 
 using namespace std;
@@ -38,461 +27,254 @@
 
 /** 
-   \brief Create a new World
+   \brief create a new World
    
-   This creates a new, empty world!
-*/
-World::World () {
-  //lastPlayer = null;
-  //lastNPC = null;
-  //lastEnv = null;
-  primitiveMove = 0;
-  step = 0;
-
-  //List<int> *list = new List<int>();
-  npcList = new List<WorldEntity*>();
-  playerList = new List<WorldEntity*>();
-  envList = new List<WorldEntity*>();
-}
-
-
-World::~World () {}
-
-
-
-/** 
-   \brief Load a new World
+   This creates a new empty world!
+*/
+World::World ()
+{
+	entities = new List<WorldEntity>();
+}
+
+/** 
+   \brief remove the World from memory
+*/
+World::~World ()
+{
+	unload ();
+	delete entities;
+}
+
+/** 
+   \brief checks for collisions
    
-   Load a new world. The old world (if any) will be unloaded and becomes unrecoverable. 
-*/
-void World::loadWorld() {}
-
-
-/** 
-   \brief Unloads a new World
+   This method runs through all WorldEntities known to the world and checks for collisions between them.
+   In case of collisions the collide() method of the corresponding entities is called.
+*/
+void World::collide ()
+{
+	List<WorldEntity> *a, *b;
+	WorldEntity *aobj, *bobj;
+	
+	a = entities->get_next();
+	
+	while( a != NULL)
+	{
+		aobj = a->get_object();
+		if( aobj->bCollide && aobj->collisioncluster != NULL)
+		{
+			b = a->get_next();
+			while( b != NULL)
+			{
+				bobj = b->get_object();
+				if( bobj->bCollide && bobj->collisioncluster != NULL)
+				{
+					unsigned long ahitflg, bhitflg;
+					if( check_collision ( &aobj->place, aobj->collisioncluster, &ahitflg, &bobj->place, bobj->collisioncluster, &bhitflg));
+					{
+						aobj->collide (bobj, ahitflg, bhitflg);
+						bobj->collide (aobj, bhitflg, ahitflg);
+					}
+				}
+				b = b->get_next();
+			}
+		}
+		a = a->get_next();
+	}
+}
+
+/** 
+   \brief runs through all entities calling their draw() methods
+*/
+void World::draw ()
+{
+	// draw geometry
+	
+	// draw entities
+	List<WorldEntity> *l;
+	WorldEntity* entity;
+	
+	l = entities->get_next();  
+	while( l != NULL) 
+	{ 
+		entity = l->get_object();
+	 	if(	entity->bDraw) entity->draw();
+	  l = l->get_next();
+	}
+	
+	// draw debug coord system
+	glLoadIdentity();
+	glBegin(GL_LINES);
+	for( float x = -128.0; x < 128.0; x += 25.0)
+	{
+		for( float y = -128.0; y < 128.0; y += 25.0)
+		{
+			glColor3f(1,0,0);
+			glVertex3f(x,y,-128.0);
+			glVertex3f(x,y,0.0);
+			glColor3f(0.5,0,0);
+			glVertex3f(x,y,0.0);
+			glVertex3f(x,y,128.0);
+		}
+	}
+	for( float y = -128.0; y < 128.0; y += 25.0)
+	{
+		for( float z = -128.0; z < 128.0; z += 25.0)
+		{
+			glColor3f(0,1,0);
+			glVertex3f(-128.0,y,z);
+			glVertex3f(0.0,y,z);
+			glColor3f(0,0.5,0);
+			glVertex3f(0.0,y,z);
+			glVertex3f(128.0,y,z);
+		}
+	}
+	for( float x = -128.0; x < 128.0; x += 25.0)
+	{
+		for( float z = -128.0; z < 128.0; z += 25.0)
+		{
+			glColor3f(0,0,1);
+			glVertex3f(x,-128.0,z);
+			glVertex3f(x,0.0,z);
+			glColor3f(0,0,0.5);
+			glVertex3f(x,0.0,z);
+			glVertex3f(x,128.0,z);
+		}
+	}
+	//draw track
+	glColor3f(0,1,1);
+	for( int i = 0; i < tracklen; i++)
+	{
+		glVertex3f(pathnodes[i].x,pathnodes[i].y,pathnodes[i].z);
+		glVertex3f(pathnodes[(i+1)%tracklen].x,pathnodes[(i+1)%tracklen].y,pathnodes[(i+1)%tracklen].z);
+	}
+	glEnd();
+}
+
+/** 
+   \brief updates Placements and notifies entities when they left the world
    
-   Unloads a world and frees the memory. You cant game until you have a new world loaded.
-*/
-void World::unloadWorld() {}
-
-
-/** 
-   \brief Pause the game
-   
-   Pauses the game until the pause is released. During this time nothing moves at all and nothing is calculated. Use it if you have to go out of the game to read some mails...
-*/
-void World::pauseWorld() {}
-
-
-/** 
-   \brief Save the game to file
-   \param filename: the filename where the savegame should be saved to
-   
-   Saves the state of the game to a file. The state is catched like in a multiplayer game over a synchronisable interface.
-*/
-void World::saveGameState(char* filename) {}
-
-
-
-/** 
-   \brief Add Player
-   \param player A reference to the new player object
-   
-   Add a new Player to the game. Player has to be initialised previously 
-*/
-bool World::addPlayer(Player* player) 
-{
-  WorldEntity *we;
-  playerList->add(we);
-  /*
-  playerList* listMember = new playerList;
-  listMember->player = player;
-  if ( lastPlayer != null ) 
-    {
-      listMember->number = lastPlayer->number + 1;
-      listMember->next = lastPlayer;
-    }
-  else 
-    {
-      listMember->number = 0;
-      listMember->next = null;
-    }
-  lastPlayer = listMember;
-  */
-}
-
-/** 
-   \brief Remove Player
-   \param player A reference to the new npc object
-   
-   Remove a new Player to the game. This kills the player objects.
-*/
-bool World::removePlayer(Player* player) {
-  playerList->remove(player, LIST_FIND_BW);
-}
-
-/** 
-   \brief Returns the player-entity controlled by the local gamer
-   \return pointer to player object
-   
-   Remove a new Player to the game. This kills the player objects.
-*/
-Player* World::getLocalPlayer() 
-{
-  return localPlayer;
-}
-
-
-/** 
-   \brief Add Non-Player-Character
-   \param player A reference to the new npc object
-   
-   Add a new Non-Player-Character to the game. Player has to be initialised previously 
-*/
-bool World::addNPC(NPC* npc) 
-{
-  npcList->add(npc, LIST_ADD_NEXT);
-  /*
-  npcList* listMember = new npcList;
-  listMember->npc = npc;
-  if ( lastNPC != null ) 
-    {
-      listMember->number = lastNPC->number + 1;
-      listMember->next = lastNPC;
-    }
-  else 
-    {
-      listMember->number = 0;
-      listMember->next = null;
-    }
-  lastNPC = listMember;
-  */
-}
-
-
-/** 
-   \brief Remove Non-Player Character
-   \param player A reference to the npc object
-   
-   Remove a Non-Player-Character to the game.
-*/
-bool World::removeNPC(NPC* npc) 
-{
-  npcList->remove(npc, LIST_FIND_FW);
-  /*
-  npcList* npcRef = lastNPC;
-  npcList* lastRef = lastNPC;
-  while ( npcRef != null ) 
-    {
-      if ( npcRef->npc == npc ) {
-	cout <
-< "found" << endl;
-	if ( npcRef == lastRef ) {
-	  lastNPC = lastNPC->next;
-	  delete npcRef;
-	  npcRef = lastNPC;
-	  lastRef = lastNPC;
-	}
-	else {
-	  lastRef->next = npcRef->next;
-	  delete npcRef;
-	  npcRef = lastRef->next;
-	}
-	cout << "killed ..." << endl;
-      }
-      else {
-	lastRef = npcRef;
-	npcRef = npcRef->next;
-      }
-    }
-  cout << "npc left" << endl;
-  */
-}
-
-
-
-/** 
-   \brief Add environmental object
-   \param player A reference to the new env object
-   
-   Add a new Environment to the world. Env has to be initialised before.
-*/
-bool World::addEnv(Environment* env) 
-{
-  /*
-  envList* listMember = new envList;
-  listMember->env = env;
-  if ( lastEnv != null ) 
-    {
-      listMember->number = lastEnv->number + 1;
-      listMember->next = lastEnv;
-    }
-  else 
-    {
-      listMember->number = 0;
-      listMember->next = null;
-    }
-  lastEnv = listMember;
-  */
-}
-
-/** 
-   \brief Remove an environmental object
-   \param player A reference to the env object
-   
-   Remove a environment from the game.
-*/
-bool World::removeEnv(Environment* env) 
-{
+   This runs trough all WorldEntities and maps Locations to Placements if they are bound, checks
+   whether they left the level boundaries and calls appropriate functions.
+*/
+void World::update ()
+{
+	List<WorldEntity> *l;
+	WorldEntity* entity;
+	Location* loc;
+	Placement* plc;
+	Uint32 t;
+	
+	l = entities->get_next();  
+	while( l != NULL) 
+	{ 
+		entity = l->get_object();
+		
+		if( !entity->isFree())
+		{
+		 	loc = entity->get_location();
+		 	plc = entity->get_placement();
+		 	t = loc->part;
+		 	
+		 	if( t >= tracklen)
+		 	{
+		 		printf("An entity is out of the game area\n");
+				entity->left_world ();
+		 	}
+		 	else
+		 	{
+		 		while( track[t].map_coords( loc, plc))
+		 		{
+		 			track[t].post_leave (entity);
+		 			if( loc->part >= tracklen)
+		 			{
+		 				printf("An entity has left the game area\n");
+		 				entity->left_world ();
+		 				break;
+		 			}
+		 			track[loc->part].post_enter (entity);
+		 		}
+		 	}
+		}
+		else
+		{
+			// TO DO: implement check whether this particular free entity is out of the game area
+			// TO DO: call function to notify the entity that it left the game area
+		}
+	 	
+	  l = l->get_next();
+	}
+	
+}
+
+/** 
+  \brief relays the passed time since the last frame to entities and Track parts
+	\param deltaT: the time passed since the last frame in milliseconds
+*/
+void World::time_slice (Uint32 deltaT)
+{
+	List<WorldEntity> *l;
+	WorldEntity* entity;
+	float seconds = deltaT;
+	
+	seconds /= 1000;
+	
+	l = entities->get_next();  
+	while( l != NULL) 
+	{ 
+		entity = l->get_object();
+	 	entity->tick (seconds);
+	  l = l->get_next();
+	}
+	
+	for( int i = 0; i < tracklen; i++) track[i].tick (seconds);
+}
+
+/**
+	\brief removes level data from memory
+*/
+void World::unload()
+{
+	if( pathnodes) delete []pathnodes;
+	if( track) delete []pathnodes;
+}
+
+/**
+	\brief loads a simple level for testing purposes
+*/
+void World::load_debug_level()
+{
+	// create some path nodes
+	pathnodes = new Vector[6];
+	pathnodes[0] = Vector(0, 0, 0);
+	pathnodes[1] = Vector(-100, 40, 0);
+	pathnodes[2] = Vector(-100, 140, 0);
+	pathnodes[3] = Vector(0, 180, 0);
+	pathnodes[4] = Vector(100, 140, 0);
+	pathnodes[5] = Vector(100, 40, 0);	
+	
+	// create the tracks
+	tracklen = 6;
+	track = new Track[6];
+	for( int i = 0; i < tracklen; i++)
+	{
+		track[i] = Track( i, (i+1)%tracklen, &pathnodes[i], &pathnodes[(i+1)%tracklen]);
+	}
+	
+	// create a player
+	WorldEntity* myPlayer = (WorldEntity*) spawn<Player>();
+	
+	// bind input
+  Orxonox *orx = Orxonox::getInstance();
+  orx->get_localinput()->bind (myPlayer);
   
-}
-
-
-
-
-/** 
-   \brief Draws the World and all Objects contained
-   
-   Calls the draw function of all: Objects, Players, Environement. This is the core of all graphics here.
-*/
-void World::drawWorld(void) 
-{
-
-  glLoadIdentity();
-  gluLookAt(0.0, -14.0 + DataTank::yOffset, 15.0, 0.0, 0.0 + DataTank::yOffset, 0.0, 0.0, 1.0, 0.0);
-  /* first draw all players */
-
-
-  /*
-  playerList* tmpPlayer = lastPlayer;
-  Player* player = tmpPlayer->player;
-  while( tmpPlayer != null ) 
-    {
-      tmpPlayer->player->paint();
-      tmpPlayer = tmpPlayer->next;
-    }
-  */
-  /* second draw all npcs */
-  /*
-  npcList* tmpNPC = lastNPC;
-  while( tmpNPC != null )
-    {
-      (*tmpNPC->npc).paint();
-      tmpNPC = tmpNPC->next;
-    }
-  */
-
-  /* now draw the rest of the world: environement */
-  /*
-  envList* tmpEnv = lastEnv;
-  while( tmpEnv != null )
-    {
-      (*tmpEnv->env).drawEnvironment();
-      tmpEnv = tmpEnv->next;
-    }
-  */
-
-  /* draw the ground grid  */
-  glColor3f(0.0, 1.0, 0.0); 
-  glBegin(GL_LINES);
-  /* for the moment, we've got only pseudo moving ground */
-  for (int y = 0; y < 60; y += 2)
-    {
-      for (int x = 0; x < 60; x += 2)
-	{
-	  glVertex3f((float)(x - 30), (float)(y - 30), surface[x][y]);
-	  glVertex3f((float)(x - 28), (float)(y - 30), surface[x+2][y]);
-	}
-    }
-  glEnd();
-  
-  glBegin(GL_LINES);
-  for (int x = 0; x < 60; x += 2)
-    {
-      for (int y = 0; y < 60; y += 2)
-	{
-	  glVertex3f((float)(x - 30), (float)(y - 30), surface[x][y]);
-	  glVertex3f((float)(x - 30), (float)(y - 28), surface[x][y+2]);
-	}
-    }
-  glEnd();
-
-  //primitiveMove+=0.07;
-  DataTank::yOffset += step;
-
-  /*
-  tmpPlayer = lastPlayer;
-  while( tmpPlayer != null ) 
-    {
-      tmpPlayer->player->yCor += step;
-      tmpPlayer = tmpPlayer->next;
-    }
-  */
-
-}
-
-
-void World::initEnvironement()
-{
-
- for (int x = 0; x < 60; x += 2)
-    {
-      for (int y = 0; y < 60; y += 2)
-	{
-	  surface[x][y] = 0;
-	}
-    }
-}
-
-
-void World::setWorldStep(float step)
-{
-  //cout << "World::setWorldStep(" << step << ");" << endl;
-  this->step = step;
-  //cout << "setting speed to " << step << endl;
-}
-
-
-
-/** 
-   \brief Updates the world and all its objects
-   
-   Calculates the new state of the world. User-input and AI of
-   the enemies are accounted for.
-*/
-void World::updateWorld(void) 
-{
-  
-
-}
-
-
-/* collision detection */
-/* fix: bad efficency: stupid brute force */
-
-void World::detectCollision() 
-{
-  /*
-  //cout << "World::detectCollision" << endl;
-  float xOff, yOff, zOff, radius;
-  npcList* tmpNPC, *tmpRef;
-  */
-  //cout << "World::detectCollsions" << endl;
-  /* first: check if any player's shoots trigger a collision */
-  /*
-  playerList* tmpPlayer = lastPlayer;
-  Player* player = tmpPlayer->player;
-  int state;
-  while( tmpPlayer != null ) 
-    {
-      tmpNPC = lastNPC;
-      while( tmpNPC != null )
-	{
-	  //cout << "npc != null" << endl;
-	  radius = tmpNPC->npc->collisionRadius;
-	  //cout << "worki" << endl;
-	  ShootLaser::shoot* shoota = tmpPlayer->player->shootLaser->lastShoot;
-	  while( shoota != null )
-	    {
-	      xOff = shoota->xCor - tmpNPC->npc->xCor;
-	      yOff = shoota->yCor - tmpNPC->npc->yCor;
-	      zOff = shoota->zCor - tmpNPC->npc->zCor;
-	      if ( sqrt(xOff*xOff + yOff*yOff + zOff*zOff) < radius ) 
-		{
-		  //cout << "COLLISION " << endl;
-		  int state = tmpNPC->npc->hit();
-  */
-		  /* state is a value that marks if the ship dies or not */
-		  /* if state == 0 the ship dies and we have to remove it */
-		  /*
-		  if ( state == 0 ) {
-		    tmpRef = tmpNPC;
-		    tmpNPC = tmpNPC->next;
-		    removeNPC(tmpRef->npc);
-		    break;
-		  }
-		  
-		}
-	      shoota = shoota->next;
-	    }
-	  //cout << "changing npc..." << endl;
-	  tmpNPC = tmpNPC->next;
-	  //cout << "..changing npc done" << endl;
-	}
-      //cout << "changing play..." << endl;
-      tmpPlayer = tmpPlayer->next;
-      //cout << "changing play done" << endl;
-      
-    }
-		  */
-  //cout << "World::detectCollisions middle" << endl;
-
-  /* second: check if any player hits an enemy */
-/*
-  tmpPlayer = lastPlayer;
-  while( tmpPlayer != null ) 
-    {
-      tmpNPC = lastNPC;
-      while( tmpNPC != null )
-	{
- 	  radius = tmpNPC->npc->collisionRadius + tmpPlayer->player->collisionRadius;
-	  xOff = tmpPlayer->player->xCor - tmpNPC->npc->xCor;
-	  yOff = tmpPlayer->player->yCor - tmpNPC->npc->yCor;
-	  zOff = tmpPlayer->player->zCor - tmpNPC->npc->zCor;
-	  if ( sqrt(xOff*xOff + yOff*yOff + zOff*zOff) < radius ) {
-	    //cout << "COLLISION " << endl;
-	    tmpNPC->npc->hit();
-	  }
-	  
-	  tmpNPC = tmpNPC->next;
-	}
-      
-      tmpPlayer = tmpPlayer->next;
-    }
-  
-  
-*/
-  /* third: check if any enemy shoots a player */
-
-  //cout << "World::detectCollisions end" << endl;
-}
-
-
-
-/** 
-   \brief Routine for testing purposes.
-   
-   testing, testing, testing...
-*/
-void World::testThaTest(void) 
-{
-/*
-  cout << "World::testThaTest() called" << endl;
-
-  cout << "addPlayer test..." << endl;
-  playerList* pl = lastPlayer;
-  while ( pl != null )
-    {
-      cout << "player " << pl->number << " was found" << endl;
-      pl = pl->next;
-    }
-
-
-  cout << "addNPC test..." << endl;
-  npcList* nl = lastNPC;
-  while ( nl != null )
-    {
-      cout << "npc " << nl->number << " was found" << endl;
-      nl = nl->next;
-    }
-
-
-
-  cout << "addEnv test..." << endl;
-  envList* en = lastEnv;
-  while ( en != null )
-    {
-      cout << "env " << en->number << " was found" << endl;
-      en = en->next;
-    }
-*/
-}
+	// bind camera
+	orx->get_camera()->bind (myPlayer);
+}
+
+/**
+	\brief calls the correct mapping function to convert a given "look at"-Location to a Camera Placement
+*/
+void World::calc_camera_pos (Location* loc, Placement* plc)
+{
+  track[loc->part].map_camera (loc, plc);
+}
Index: orxonox/trunk/src/world.h
===================================================================
--- orxonox/trunk/src/world.h	(revision 2077)
+++ orxonox/trunk/src/world.h	(revision 2190)
@@ -1,26 +1,16 @@
-/**
-  Class representating the game-world
-  
-  It contains a list of players (if multiplayer game), a list of Non-Player-Characters (nps), a list of Environment Entities. All this things together are building the orxonox-world. This class also handels the story-line (track), the world start/stop, init/uninit abilities. It is the middle point of every orxonox world.
-*/
+/*! 
+    \file world.h
+    \brief Holds and manages all game data
+*/ 
 
 #ifndef WORLD_H
 #define WORLD_H
 
-class Player;
-class NPC;
-class Environment;
+#include "stdincl.h"
+
+class Track;
 class WorldEntity;
 
-template<class T> class List;
-
-
-
-//! World Class
-/**
-  Class for World representation
-  
-  It contains a list of players (if multiplayer game), a list of Non-Player-Characters (nps), a list of Environment Entities. All this things together are building the orxonox-world. This class also handels the story-line (track), the world start/stop, init/uninit abilities. It is the middle point of every orxonox world.
-*/
+//! The game environment
 class World {
 
@@ -29,68 +19,89 @@
   ~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);
 
-
-  float primitiveMove; //!< deprecated, do not use
-
-  Player *localPlayer; //!< a pointer to the local player object
-  Player *player1;     //!< a pointer to the second player object
-  Player *player2;     //!< a pointer to the third player object 
-
-  /*
-  struct playerList {
-    playerList* next;
-    Player* player;
-    int number;
-  };
-  playerList* lastPlayer;
-
-  struct npcList {
-    npcList* next;
-    NPC* npc;
-    int number;
-  };
-  npcList* lastNPC;
-
-  struct envList {
-    envList* next;
-    Environment* env;
-    int number;
-  };
-  envList* lastEnv;
-  */
-
-
-  void loadWorld();
-  void unloadWorld();
-  void pauseWorld();
-  void saveGameState(char* filename);
-  
-
-  bool addPlayer(Player* player);
-  bool removePlayer(Player* player);
-  Player* getLocalPlayer();
-  bool addNPC(NPC* npc);
-  bool removeNPC(NPC* npc);
-  bool addEnv(Environment* env);
-  bool removeEnv(Environment* env);
-
-  
-  void drawWorld(void);
-  void initEnvironement(void);
-  void setWorldStep(float step);
-  void updateWorld(void);
-  void detectCollision(void);
-  void testThaTest(void);
-
+	void time_slice (Uint32 deltaT);
+	void collide ();
+	void draw ();
+	void update ();	// maps Locations to Placements
+	void calc_camera_pos (Location* loc, Placement* plc);
+	
+	void unload ();
+	
+	void load_debug_level ();
+	
  private:
-  float surface[120][120]; //!< deprecated: used to build a surface
-  float step; //!< this is the step
-
-  List<WorldEntity*> *playerList; //!< the list of players, usualy very short
-  List<WorldEntity*> *npcList;  //!< list of non player characters (npc)
-  List<WorldEntity*> *envList;  //!< list of environment objects
-
+ 
+	List<WorldEntity>* entities;
+	
+		// base level data
+	Track* track;
+	Uint32 tracklen;
+	Vector* pathnodes;
 
 };
 
+/**
+    \brief spawn a new WorldEntity at a Location
+    \param loc: the Location where the Entity should be spawned
+    \param owner: a pointer to the parent of the Entity
+    \return a pointer to the new WorldEntity or NULL if there was an error
+    
+    You can use this function to spawn any derivation of WorldEntity you want, just specify the desired
+    class within the template specification brackets. Do not attempt to spawn any classes that have NOT been
+    derived from WorldEntity, you won't even be able to compile the code. Note that this version of spawn()
+    works with both free and bound WorldEntities.
+*/ 
+template<typename T> T* World::spawn(Location* loc = NULL, WorldEntity* owner = NULL)
+{
+	Location zeroloc;
+	T* entity = new T();
+	entities->add ((WorldEntity*)entity, LIST_ADD_NEXT);
+	if( loc == NULL)
+	{
+		zeroloc.dist = 0;
+		zeroloc.part = 0;
+		zeroloc.pos = Vector();
+		zeroloc.rot = Quaternion();
+		loc = &zeroloc;
+	}
+	entity->init (loc, owner);
+	if (entity->bFree)
+	{
+		track[loc->part].map_coords( loc, entity->get_placement());
+	}
+	entity->post_spawn ();
+	return entity;
+}
+
+/**
+    \brief spawn a new WorldEntity at a Placement
+    \param lplc: the placement where the Entity should be spawned
+    \param owner: a pointer to the parent of the Entity
+    \return a pointer to the new WorldEntity or NULL if there was an error
+    
+    You can use this function to spawn any FREE derivation of WorldEntity you want, just specify the desired
+    class within the template specification brackets. Do not attempt to spawn any classes that have NOT been
+    derived from WorldEntity, you won't even be able to compile the code. Note that this version of spawn()
+    works with free WorldEntities only, you will provoke an error message if you try to spawn a bound Entity with 
+    a Placement.
+*/ 
+template<typename T> T* World::spawn(Placement* plc, WorldEntity* owner = NULL)
+{
+	T* entity = new T();
+	entities->add ((WorldEntity*)entity, LIST_ADD_NEXT);
+	entity->init (plc, owner);
+	if (!entity->bFree)
+	{
+		printf("Can't spawn unfree entity with placement\n"); 
+		entities->remove( (WorldEntity*)entity, LIST_FIND_FW);
+		return NULL;
+	}
+	entity->post_spawn ();
+	return entity;
+}
+
 #endif
Index: orxonox/trunk/src/world_entity.cc
===================================================================
--- orxonox/trunk/src/world_entity.cc	(revision 2077)
+++ orxonox/trunk/src/world_entity.cc	(revision 2190)
@@ -13,5 +13,5 @@
    ### File Specific:
    main-programmer: Patrick Boenzli
-   co-programmer: ...
+   co-programmer: Christian Meyer
 */
 
@@ -19,115 +19,101 @@
 
 #include "world_entity.h"
-
-#include "vector.h"
+#include "stdincl.h"
+#include "collision.h"
 
 using namespace std;
 
-
 /**
-   \brief 
-   \param v:
-   \return 
+   \brief standard constructor
+   
+   Every derived contructor HAS to call the previous one supplying the isFree parameter. This is necessary to distunguish
+   between free and bound entities. The difference between them is simply the fact that the movement of a free entity is
+   not bound to the track of a world. Use this to implement projectile or effect classes that do not have to travel along the track.
+   To specify an entity to be free or bound set the default parameter in the declaration of the constructor.
+   Theoretically you should never have to call the constructor of an Entity directly, for it is called by the spawn() function of the World
+   class. So if you want to create a new entity at any time, call World::spawn(). It will handle everything that is necessary.
 */
-
-/**
-   \brief Constructor
-
-   This Constructor initializises the all WorldEntities. Everything, that is a part of the game-world is a child of WorldEntity. This class implements empty functions for all sort of operation a WorldEntity has to or can implement.
-This is some sort of standard interface to all WorldEntities...
-*/
-WorldEntity::WorldEntity () 
+WorldEntity::WorldEntity (bool isFree) : bFree(isFree)
 {
-  health = 100;
-  speed = 0;
-}
-
-
-WorldEntity::~WorldEntity () {}
-
-/**
-   \brief sets the position of this entity
-   \param position: Vector, pointing (from 0,0,0) to the new position
-*/
-void WorldEntity::setPosition(Vector* position) {} 
-
-/**
-   \brief gets the postion of this entity
-   \return a Vector, pointing (from 0,0,0) to the new position
-*/
-Vector* getPosition() {}
-
-/**
-   \brief sets orientation of this entity
-   \param orientation: vector specifying in which direction the entity looks
-*/
-void WorldEntity::setOrientation(Vector* orientation) {}
-
-/**
-   \brief gets orientation of this entity
-   \return vector specifying in which direction the entity looks
-*/
-Vector* WorldEntity::getOrientation() {}
-
-/**
-   \brief sets the speed of the entity, if any
-   \param speed: the speed in points (openGL points) per seconds
-*/
-void WorldEntity::setSpeed(float speed)
-{
-  this->speed = speed;
+	collisioncluster = NULL;
+	owner = NULL;
 }
 
 /**
-   \brief gets the speed of the entity, if any
-   \return the speed in points (openGL points) per seconds
+	\brief standard destructor
 */
-float WorldEntity::getSpeed()
+WorldEntity::~WorldEntity ()
 {
-  return speed;
+	if( collisioncluster != NULL) delete collisioncluster;
 }
 
 /**
-   \brief sets the health of the entity
-   \param health: number for the life count, normaly {0..100}
+	\brief get the Location of the WorldEntity
+	\return a pointer to location
 */
-void WorldEntity::setHealth(float health)
+Location* WorldEntity::get_location ()
 {
-  this->health = health;
+	return &loc;
 }
 
 /**
-   \brief gets the health of the entity
-   \return number for the life count, normaly {0..100}
+	\brief get the Placement of the WorldEntity
+	\return a pointer to placement
 */
-float WorldEntity::getHealth()
+Placement* WorldEntity::get_placement ()
 {
-  return health;
+	return &place;
 }
 
 /**
-   \brief this method is called every tick
-   \param time: the time since the last frame was painted
-
-   This function is called before every repaint of the world, to update every time dependent variable of the entity. If the entity moves, it has to calculate the new position every tick here in this function. Do not use this for animations.
+	\brief query whether the WorldEntity in question is free
+	\return true if the WorldEntity is free or false if it isn't
 */
-void WorldEntity::tick(float dt) 
-{}
+bool WorldEntity::isFree ()
+{
+  return bFree;
+}
 
 /**
-   \brief the entity is painted to the screen with this function
+	\brief set the WorldEntity's collision hull
+	\param newhull: a pointer to a completely assembled CollisionCluster
+	
+	Any previously assigned collision hull will be deleted on reassignment
+*/
+void WorldEntity::set_collision (CollisionCluster* newhull)
+{
+	if( newhull == NULL) return;
+	if( collisioncluster != NULL) delete collisioncluster;
+	collisioncluster = newhull;
+}
+
+/**
+	\brief this method is called every frame
+	\param time: the time in seconds that has passed since the last tick
+	
+	Handle all stuff that should update with time inside this method (movement, animation, etc.)
+*/
+void WorldEntity::tick(float time) 
+{
+}
+
+/**
+   \brief the entity is drawn onto the screen with this function
 
    This is a central function of an entity: call it to let the entity painted to the screen. Just override this function with whatever you want to be drawn.
 */
-void WorldEntity::paint() 
-{}
+void WorldEntity::draw() 
+{
+}
 
-/* virtual void WorldEntity::actionEvent(Event* event); */
 /**
-   \brief this function is called, when two entities collide
-   \param we: the world entity, with whom it collides
-   \param loc: place where the collision happens
+	\brief this function is called, when two entities collide
+	\param other: the world entity with whom it collides
+	\param ownhitflags: flags to the CollisionCluster subsections that registered an impact
+	\param otherhitflags: flags to the CollisionCluster subsections of the other entity that registered an impact
+
+	Implement behaviour like damage application or other miscellaneous collision stuff in this function
 */
-void WorldEntity::collide(WorldEntity* we, Vector loc) {}
+void WorldEntity::collide(WorldEntity* other, Uint32 ownhitflags, Uint32 otherhitflags) {}
 
 /**
@@ -141,5 +127,5 @@
 
 /**
-   \brief this function is called, if the entity is to be destroied
+   \brief this function is called when the entity is to be destroied
    
    This can be called, if eg. something realy bad happens :)
@@ -147,23 +133,62 @@
 void WorldEntity::destroy() {}
 
-/**
-   \brief this function is automatically called before the entity enters the world
-*/
-void WorldEntity::entityPreEnter() {}
 
 /**
-   \brief this function is automatically called after the entity enters the world
-
+	\brief basic initialisation for bound Entities
 */
-void WorldEntity::entityPostEnter() {}
+void WorldEntity::init( Location* spawnloc, WorldEntity* spawnowner)
+{
+	loc = *spawnloc;
+	owner = spawnowner;
+}
 
 /**
-   \brief this function is automatically called before the entity quits the world
-
+	\brief basic initialisation for free Entities
 */
-void WorldEntity::entityPreQuit() {}
+void WorldEntity::init( Placement* spawnplc, WorldEntity* spawnowner)
+{
+	place = *spawnplc;
+	owner = spawnowner;
+}
 
 /**
-   \brief this function is automatically called after the entity quits the world
+	\brief this is called immediately after the Entity has been constructed and initialized
+	
+	Put any initialisation code that requires knowledge of location (placement if the Entity is free) and owner of the entity here.
+	DO NOT place such code in the constructor, those variables are set AFTER the entity is constucted.
 */
-void WorldEntity::entityPostQuit() {}
+void WorldEntity::post_spawn ()
+{
+}
+
+/**
+	\brief this handles incoming command messages
+	\param cmd: a pointer to the incoming Command structure
+	
+	Put all code that handles Command messages here, this will mainly be called by the assigned CommandNode but can also be used
+	to send commands from one WorldEntity to another.
+*/
+void WorldEntity::command (Command* cmd)
+{
+}
+
+/**
+	\brief this is called by the local Camera to determine the point it should look at on the WorldEntity
+	\param locbuf: a pointer to the buffer to fill with a location to look at
+	
+	You may put any Location you want into locbuf, the Camera will determine via the corresponding Track how
+	to look at the location you return with this.
+*/
+void WorldEntity::get_lookat (Location* locbuf)
+{
+}
+
+/**
+	\brief this method is called by the world if the WorldEntity leaves valid gamespace
+	
+	For free entities this means it left the Track boundaries. With bound entities it means its Location adresses a
+	place that is not in the world anymore. In both cases you might have to take extreme measures (a.k.a. call destroy).
+*/
+void WorldEntity::left_world ()
+{
+}
Index: orxonox/trunk/src/world_entity.h
===================================================================
--- orxonox/trunk/src/world_entity.h	(revision 2077)
+++ orxonox/trunk/src/world_entity.h	(revision 2190)
@@ -1,70 +1,56 @@
 /*! 
     \file world_entity.h
-    \brief A base class for all objects in the world
-    
-    This is the base class of all objects in the game-world. If you want to have an object in the world, that can realy interact with other objects and that is also dispbayable etc. you have to extend this class and override the needed functions.
-*/ 
-
-
+    \brief Definition of the basic WorldEntity
+*/
 
 #ifndef WORLD_ENTITY_H
 #define WORLD_ENTITY_H
 
-#include "data_tank.h"
+#include "stdincl.h"
 
-class Vector;
-class Ability;
+class CollisionCluster;
 
-//! WorldEntity
-/**
-  A base class for all objects in the world
-
-  This is the base class of all objects in the game-world. If you want to have an object in the world, that can realy interact with other objects and that is also dispbayable etc. you have to extend this class and override the needed functions.
-*/
-class WorldEntity {
+//! Basic class from which all interactive stuff in the world is derived from
+class WorldEntity
+{	
+	friend class World;
 
  public:
-  WorldEntity ();
+  WorldEntity (bool isFree = false);
   ~WorldEntity ();
 
+ 	Location* get_location ();
+ 	Placement* get_placement ();
+ 	void set_collision (CollisionCluster* newhull);
 
-  void setPosition(Vector* position);
-  Vector* getPosition();
-  void setOrientation(Vector* orientation);
-  Vector* getOrientation();
-  void setSpawnPoint(Vector* place);
-  void setSpeed(float speed);
-  float getSpeed();
-  void setHealth(float health);
-  float getHealth();
+ 	bool isFree ();
+ 	
+  //void addAbility(Ability* ability);
+  //void removeAbility(Ability* ability);
 
-  void addAbility(Ability* ability);
-  void removeAbility(Ability* ability);
+	virtual void post_spawn ();
+  virtual void tick (float time);
+  virtual void hit (WorldEntity* weapon, Vector loc);
+  virtual void destroy ();
+  virtual void collide (WorldEntity* other,  Uint32 ownhitflags, Uint32 otherhitflags);
+ 	virtual void command (Command* cmd);
+  
+  virtual void draw ();
+  virtual void get_lookat (Location* locbuf);
 
-  virtual void tick(float dt);
-  virtual void paint();
-  /* virtual void actionEvent(Event* event); */
-  virtual void collide(WorldEntity* we, Vector loc);
-  virtual void hit(WorldEntity* weapon, Vector loc);
-  virtual void destroy();
-
-  virtual void entityPreEnter();
-  virtual void entityPostEnter();
-  virtual void entityPreQuit();
-  virtual void entityPostQuit();
-
- 
+	virtual void left_world ();
 
  private:
-  Vector* position;    //!< position of the entity
-  Vector* orientation; //!< orientation of the entity
-  /* List of abilities */ 
-  float health; //!< health of the entity, if any
-  float speed; //!< speed of the entity if any
-  /* entity can be in the air or at ground: */
-  int airGround; //!< is it air or bound to the ground (ground=0, air=1)
+  const bool bFree;	
+  bool bCollide;
+  bool bDraw;
+  
+ 	WorldEntity* owner;
+ 	CollisionCluster* collisioncluster;
+ 	Placement place;
+ 	Location loc;
 
-  
-
+	void init( Location* spawnloc, WorldEntity* spawnowner);
+	void init( Placement* spawnplc, WorldEntity* spawnowner);
 };
 
