Index: /orxonox/branches/chris/src/camera.cc
===================================================================
--- /orxonox/branches/chris/src/camera.cc	(revision 2111)
+++ /orxonox/branches/chris/src/camera.cc	(revision 2112)
@@ -30,8 +30,4 @@
 {
 	bound = NULL;
-	desired_place.r = Vector (0,0,0);
-	desired_place.w = Rotation (0,0,0);
-	actual_place.r = Vector (0,0,0);
-	actual_place.w = Rotation (0,0,0);
 }
 
@@ -53,4 +49,5 @@
 {
 	update_desired_place ();
+	jump (NULL);
 }
 
@@ -73,5 +70,5 @@
 		{
 			desired_place.r = Vector (0,0,0);
-			desired_place.w = Rotation (0,0,0); 
+			desired_place.w = Quaternion (); 
 		}
 }
@@ -86,16 +83,27 @@
 {
 	glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
 		// view
 		// TO DO: implement options for frustum generation
-	glFrustum( -1.0,1.0,-1.0,1.0,1.5,20.0);
+	glFrustum( -1.0,1.0,-1.0,1.0,1.5,250.0);
+	glRotatef(h,1,0,0);
+	glRotatef(h/2,0,1,0);
+	glRotatef(h/4,0,0,1);
+	h += 3;
+//	glRotatef(90,0,0,1);
   	// rotation
-  float matrix[16];
-  actual_place.w.glmatrix (matrix);
-  glLoadMatrixf (matrix);
+  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);
+  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);
 }
 
Index: /orxonox/branches/chris/src/camera.h
===================================================================
--- /orxonox/branches/chris/src/camera.h	(revision 2111)
+++ /orxonox/branches/chris/src/camera.h	(revision 2112)
@@ -26,4 +26,6 @@
 	void update_desired_place ();
 	
+	float h;
+	
  public:
   Camera ();
Index: /orxonox/branches/chris/src/collision.cc
===================================================================
--- /orxonox/branches/chris/src/collision.cc	(revision 2111)
+++ /orxonox/branches/chris/src/collision.cc	(revision 2112)
@@ -180,6 +180,6 @@
   bool r = false;
   int ia, ib;
-  Vector mra = pa->r + rotate_vector( ta->m, pa->w);
-  Vector mrb = pb->r + rotate_vector( tb->m, pb->w);
+  Vector mra = pa->r + pa->w.apply(ta->m);
+  Vector mrb = pb->r + pb->w.apply(tb->m);
   CC_Tree* use_a, *use_b;
   
@@ -333,5 +333,5 @@
   bool r = false;
   int i;
-  Vector mr = p->r + rotate_vector( t->m, p->w);
+  Vector mr = p->r + p->w.apply (t->m);
   CC_Tree* use_t;
   Vector* ips;
Index: /orxonox/branches/chris/src/coordinates.h
===================================================================
--- /orxonox/branches/chris/src/coordinates.h	(revision 2111)
+++ /orxonox/branches/chris/src/coordinates.h	(revision 2112)
@@ -18,5 +18,5 @@
   float dist;           //!< The distance that has already been traveled on the track
   Vector pos;           //!< The position relative to the offset marked by the distance already covered
-  Rotation rot;         //!< The direction the object is heading (relative to track direction)
+  Quaternion rot;         //!< The direction the object is heading (relative to track direction)
 } Location;
 
@@ -28,5 +28,5 @@
 {
   Vector r;              //!< Absolute x/y/z coordinates
-  Rotation w;            //!< Absolute orientation
+  Quaternion w;            //!< Absolute orientation
 } Placement;
 
Index: /orxonox/branches/chris/src/orxonox.cc
===================================================================
--- /orxonox/branches/chris/src/orxonox.cc	(revision 2111)
+++ /orxonox/branches/chris/src/orxonox.cc	(revision 2112)
@@ -139,4 +139,5 @@
   glClearColor(0.0, 0.0, 0.0, 0.0);
   glEnable(GL_DEPTH_TEST);
+  glEnable(GL_COLOR);
   glShadeModel(GL_FLAT);
   
Index: /orxonox/branches/chris/src/player.cc
===================================================================
--- /orxonox/branches/chris/src/player.cc	(revision 2111)
+++ /orxonox/branches/chris/src/player.cc	(revision 2112)
@@ -33,5 +33,5 @@
 void Player::post_spawn ()
 {
-	travel_speed = 1.0;
+	travel_speed = 10.0;
 	velocity = Vector();
 	bUp = bDown = bLeft = bRight = bAscend = bDescend = false;
@@ -71,7 +71,7 @@
 {
 	glMatrixMode(GL_MODELVIEW);
-	float matrix[16];
-  get_placement()->w.glmatrix (matrix);
-  glLoadMatrixf (matrix);
+	float matrix[4][4];
+  get_placement()->w.matrix (matrix);
+  glLoadMatrixf ((float*)matrix);
 
 	glTranslatef(get_placement()->r.x,get_placement()->r.y,get_placement()->r.z);
@@ -85,4 +85,6 @@
 	glVertex3f(-1,+0.5,0);
 	glEnd();
+	
+	printf("Player@%f/%f/%f\n", get_placement()->r.x, get_placement()->r.y, get_placement()->r.z);
 }
 
@@ -90,5 +92,5 @@
 {
 	*locbuf = *get_location();
-	locbuf->dist += 5.0;
+	//locbuf->dist += 5.0;
 }
 
Index: /orxonox/branches/chris/src/track.cc
===================================================================
--- /orxonox/branches/chris/src/track.cc	(revision 2111)
+++ /orxonox/branches/chris/src/track.cc	(revision 2112)
@@ -42,13 +42,19 @@
 void Track::map_camera (Location* lookat, Placement* camplc)
 {
+printf("Track|Mapping camera: %d (%f)\n", lookat->part, lookat->dist);
 	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));
+	
 	camplc->r = trace.r + (trace.a * ((lookat->dist-10.0) / l)) + Vector(0,0,5.0);
-	camplc->w = Rotation( (trace.r + (trace.a * ((lookat->dist) / l))) - camplc->r);
+	camplc->w = Quaternion((trace.r + (trace.a * ((lookat->dist) / l)) - camplc->r), Vector(0,0,1));
+	
 }
 
 bool Track::map_coords (Location* loc, Placement* plc)
 {
+printf("Track|Mapping coords: %d (%f)\n", loc->part, loc->dist);
 	Line trace(*offset, *end - *offset);
 	float l = trace.len ();
@@ -61,7 +67,7 @@
 	}
 	
-	Rotation dir(trace.a);
+	Quaternion dir(trace.a, Vector(0,0,1));
 	
-	plc->r = trace.r + (trace.a * ((loc->dist) / l)) + rotate_vector( loc->pos, dir);
+	plc->r = trace.r + (trace.a * ((loc->dist) / l)) + dir.apply(loc->pos);
 	plc->w = dir * loc->rot;
 	
Index: /orxonox/branches/chris/src/vector.cc
===================================================================
--- /orxonox/branches/chris/src/vector.cc	(revision 2111)
+++ /orxonox/branches/chris/src/vector.cc	(revision 2112)
@@ -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,224 @@
   f = acos( v1 * v2 / (v1.len() * v2.len()));
   return f * 180 / PI;
+}
+
+Quaternion::Quaternion ()
+{
+	w = 1;
+	v = Vector(0,0,0);
+}
+
+Quaternion::Quaternion (float angle, const Vector& axis)
+{
+	w = cos(angle/2);
+	v = axis * sin(angle/2);
+}
+
+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);
+}
+
+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;
+}
+
+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;
+}
+
+Quaternion Quaternion::operator+(const Quaternion& q) const
+{
+	Quaternion r(*this);
+	r.w = r.w + q.w;
+	r.v = r.v + q.v;
+	return r;
+}
+
+Quaternion Quaternion::operator- (const Quaternion& q) const
+{
+	Quaternion r(*this);
+	r.w = r.w - q.w;
+	r.v = r.v - q.v;
+	return r;
+}
+
+Vector Quaternion::apply (Vector& v) const
+{
+	Quaternion q;
+	q.v = v;
+	q.w = 0;
+	q = *this * q * conjugate();
+	return q.v;
+}
+
+Quaternion Quaternion::operator*(const float& f) const
+{
+	Quaternion r(*this);
+	r.w = r.w*f;
+	r.v = r.v*f;
+	return r;
+}
+
+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;
+}
+
+Quaternion Quaternion::conjugate() const
+{
+	Quaternion r(*this);
+	r.v = Vector() - r.v;
+	return r;
+}
+
+float Quaternion::norm() const
+{
+	return w*w + v.x*v.x + v.y*v.y + v.z*v.z;
+}
+
+Quaternion Quaternion::inverse() const
+{
+	float n = norm();
+	if (n != 0)
+	{
+		return conjugate() / norm();
+	}
+	else return Quaternion();
+}
+
+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;
+}
+
+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];
+  }
 }
 
Index: /orxonox/branches/chris/src/vector.h
===================================================================
--- /orxonox/branches/chris/src/vector.h	(revision 2111)
+++ /orxonox/branches/chris/src/vector.h	(revision 2112)
@@ -36,5 +36,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;
+	float w;
+
+ 	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.
Index: /orxonox/branches/chris/src/world.cc
===================================================================
--- /orxonox/branches/chris/src/world.cc	(revision 2111)
+++ /orxonox/branches/chris/src/world.cc	(revision 2112)
@@ -90,4 +90,43 @@
 	  l = l->get_next();
 	}
+	
+	// draw debug coord system
+	glLoadIdentity();
+	glBegin(GL_LINES);
+	glColor3f(1,0,0);
+/*	for( float x = -128.0; x < 128.0; x += 5.0)
+	{
+		for( float y = -128.0; y < 128.0; y += 5.0)
+		{
+			glVertex3f(x,y,-128.0);
+			glVertex3f(x,y,128.0);
+		}
+	}
+	glColor3f(0,1,0);
+	for( float y = -128.0; y < 128.0; y += 5.0)
+	{
+		for( float z = -128.0; z < 128.0; z += 5.0)
+		{
+			glVertex3f(-128.0,y,z);
+			glVertex3f(128.0,y,z);
+		}
+	}
+	glColor3f(0,0,1);
+	for( float x = -128.0; x < 128.0; x += 5.0)
+	{
+		for( float z = -128.0; z < 128.0; z += 5.0)
+		{
+			glVertex3f(x,-128.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();
 }
 
Index: /orxonox/branches/chris/src/world.h
===================================================================
--- /orxonox/branches/chris/src/world.h	(revision 2111)
+++ /orxonox/branches/chris/src/world.h	(revision 2112)
@@ -50,5 +50,5 @@
 		zeroloc.part = 0;
 		zeroloc.pos = Vector();
-		zeroloc.rot = Rotation();
+		zeroloc.rot = Quaternion();
 		loc = &zeroloc;
 	}
Index: /orxonox/branches/chris/src/world_entity.cc
===================================================================
--- /orxonox/branches/chris/src/world_entity.cc	(revision 2111)
+++ /orxonox/branches/chris/src/world_entity.cc	(revision 2112)
@@ -83,5 +83,5 @@
 void WorldEntity::draw() 
 {
-  cout << "WorldEntity::draw()" << endl;
+printf("WorldEntity|draw()\n");
 }
 
