Index: orxonox/branches/chris/src/collision.cc
===================================================================
--- orxonox/branches/chris/src/collision.cc	(revision 1982)
+++ orxonox/branches/chris/src/collision.cc	(revision 1982)
@@ -0,0 +1,388 @@
+
+
+/* 
+   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;
+}
+
+/**
+   \brief recursive implementation for collision detection within a CC_Tree
+*/
+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 + rotate_vector( ta->m, pa->w);
+  Vector mrb = pb->r + rotate_vector( tb->m, pb->w);
+  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;
+}
+
+/**
+   \brief recursive implementation for traceing detection within a CC_Tree
+*/
+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 + rotate_vector( t->m, p->w);
+  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/branches/chris/src/collision.h
===================================================================
--- orxonox/branches/chris/src/collision.h	(revision 1982)
+++ orxonox/branches/chris/src/collision.h	(revision 1982)
@@ -0,0 +1,50 @@
+
+#ifndef COLLISION_H
+#define COLLISION_H
+
+#include "vector.h"
+#include "coordinates.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+
+typedef struct CC_Tree
+{
+  unsigned long n;
+  union
+  {
+  struct CC_Tree** b;
+  unsigned long ID;
+  } data;
+  float r;
+  Vector m;
+} CC_Tree;
+
+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/branches/chris/src/coordinates.h
===================================================================
--- orxonox/branches/chris/src/coordinates.h	(revision 1982)
+++ orxonox/branches/chris/src/coordinates.h	(revision 1982)
@@ -0,0 +1,20 @@
+#ifndef COORDINATES_H
+#define COORDINATES_H
+
+#include "vector.h"
+
+typedef struct Location // place of a thing on the track system
+{
+  unsigned long part;   // ID of the track part the object is on
+  float dist;           // distance already traveled on a track
+  Vector pos;           // position relative to the distance already covered
+  Rotation rot;         // direction the object is heading (relative to track direction)
+} Location;
+
+typedef struct Placement // place of a thing in the rendered coordinate system
+{
+  Vector r;              // x/y/z coordinated
+  Rotation w;            // orientation
+} Placement;
+
+#endif
Index: orxonox/branches/chris/src/rotation.cc
===================================================================
--- orxonox/branches/chris/src/rotation.cc	(revision 1982)
+++ orxonox/branches/chris/src/rotation.cc	(revision 1982)
@@ -0,0 +1,124 @@
+
+
+/* 
+   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 "rotation.h"
+
+
+using namespace std;
+
+/**
+   \brief create a rotation from a vector
+   \param v: a vector
+*/
+Rotation::Rotation (const Vector& v)
+{
+  Vector x = Vector( 1, 0, 0);
+  Vector axis = x.cross( v);
+  axis.normalize();
+  float angle = angle_rad( x, v);
+  float ca = cos(angle);
+  float sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+   \brief creates a rotation from an axis and an angle (radians!)
+   \param axis: the rotational axis
+   \param angle: the angle in radians
+*/
+Rotation::Rotation (const Vector& axis, float angle)
+{
+  float ca, sa;
+  ca = cos(angle);
+  sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+   \brief creates a rotation from euler angles (pitch/yaw/roll)
+   \param pitch: rotation around z (in radians)
+   \param yaw: rotation around y (in radians)
+   \param roll: rotation around x (in radians)
+*/
+Rotation::Rotation ( float pitch, float yaw, float roll)
+{
+  float cy, sy, cr, sr, cp, sp;
+  cy = cos(yaw);
+  sy = sin(yaw);
+  cr = cos(roll);
+  sr = sin(roll);
+  cp = cos(pitch);
+  sp = sin(pitch);
+  m[0] = cy*cr;
+  m[1] = -cy*sr;
+  m[2] = sy;
+  m[3] = cp*sr+sp*sy*cr;
+  m[4] = cp*cr-sp*sr*sy;
+  m[5] = -sp*cy;
+  m[6] = sp*sr-cp*sy*cr;
+  m[7] = sp*cr+cp*sy*sr;
+  m[8] = cp*cy;
+}
+
+/**
+   \brief creates a nullrotation
+*/
+Rotation::Rotation ()
+{
+  m[0] = 1.0f;
+  m[1] = 0.0f;
+  m[2] = 0.0f;
+  m[3] = 0.0f;
+  m[4] = 1.0f;
+  m[5] = 0.0f;
+  m[6] = 0.0f;
+  m[7] = 0.0f;
+  m[8] = 1.0f;
+}
+
+/**
+   \brief rotates the vector by the given rotation
+   \param v: a vector
+   \param r: a rotation
+*/
+Vector rotate_vector( const Vector& v, const Rotation& r)
+{
+  Vector t;
+  
+  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
+  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
+  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
+
+  return t;
+}
Index: orxonox/branches/chris/src/rotation.h
===================================================================
--- orxonox/branches/chris/src/rotation.h	(revision 1982)
+++ orxonox/branches/chris/src/rotation.h	(revision 1982)
@@ -0,0 +1,24 @@
+
+#ifndef ROTATION_H
+#define ROTATION_H
+
+#include "data_tank.h"
+#include "stdincl.h"
+#include "vector.h"
+
+class Rotation {
+  public:
+  
+  float m[9];
+  
+  Rotation ( const Vector& v);
+  Rotation ( const Vector& axis, float angle);
+  Rotation ( float pitch, float yaw, float roll);
+  Rotation ();
+  ~Rotation () {}
+  
+};
+
+Vector rotate_vector( const Vector& v, const Rotation& r);
+
+#endif
Index: orxonox/branches/chris/src/vector.cc
===================================================================
--- orxonox/branches/chris/src/vector.cc	(revision 1982)
+++ orxonox/branches/chris/src/vector.cc	(revision 1982)
@@ -0,0 +1,401 @@
+
+
+/* 
+   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 "vector.h"
+
+
+using namespace std;
+
+/**
+   \brief add two vectors
+   \param v: the other vector
+   \return the sum of both vectors
+*/
+Vector Vector::operator+ (const Vector& v) const
+{
+  Vector r;
+  
+  r.x = x + v.x;
+  r.y = y + v.y;
+  r.z = z + v.z;
+  
+  return r;
+}
+
+/**
+   \brief subtract a vector from another
+   \param v: the other vector
+   \return the difference between the vectors
+*/
+Vector Vector::operator- (const Vector& v) const
+{
+  Vector r;
+  
+  r.x = x - v.x;
+  r.y = y - v.y;
+  r.z = z - v.z;
+  
+  return r;
+}
+
+/**
+   \brief calculate the dot product of two vectors
+   \param v: the other vector
+   \return the dot product of the vectors
+*/
+float Vector::operator* (const Vector& v) const
+{
+  return x*v.x+y*v.y+z*v.z;
+}
+
+/**
+   \brief multiply a vector with a float
+   \param f: the factor
+   \return the vector multipied by f
+*/
+Vector Vector::operator* (float f) const
+{  
+  Vector r;
+  
+  r.x = x * f;
+  r.y = y * f;
+  r.z = z * f;
+  
+  return r;
+}
+
+/**
+   \brief divide a vector with a float
+   \param f: the divisor
+   \return the vector divided by f   
+*/
+Vector Vector::operator/ (float f) const
+{
+  Vector r;
+  
+  if( f == 0.0)
+  {
+    // Prevent divide by zero
+    return Vector (0,0,0);
+  }
+  
+  r.x = x / f;
+  r.y = y / f;
+  r.z = z / f;
+  
+  return r;
+}
+
+/**
+   \brief calculate the dot product of two vectors
+   \param v: the other vector
+   \return the dot product of the vectors
+*/
+float Vector::dot (const Vector& v) const
+{
+  return x*v.x+y*v.y+z*v.z;
+}
+
+/**
+  \brief calculate the cross product of two vectors
+  \param v: the other vector
+	\return the cross product of the vectors
+*/
+Vector Vector::cross (const Vector& v) const
+{
+  Vector r;
+  
+  r.x = y * v.z - z * v.y;
+  r.y = z * v.x - x * v.z;
+  r.z = x * v.y - y * v.x;
+  
+  return r;
+}
+  
+/**
+   \brief normalizes the vector to lenght 1.0
+*/
+void Vector::normalize ()
+{
+  float l = len();
+  
+  if( l == 0.0)
+  {
+    // Prevent divide by zero
+    return;
+  }
+  
+  x = x / l;
+  y = y / l;
+  z = z / l;
+}
+ 
+/**
+   \brief calculates the lenght of the vector
+   \return the lenght of the vector
+*/
+float Vector::len () const
+{
+  return sqrt (x*x+y*y+z*z);
+}
+
+/**
+   \brief calculate the angle between two vectors in radiances
+   \param v1: a vector
+   \param v2: another vector
+   \return the angle between the vectors in radians
+*/
+float angle_rad (const Vector& v1, const Vector& v2)
+{
+  return acos( v1 * v2 / (v1.len() * v2.len()));
+}
+
+/**
+   \brief calculate the angle between two vectors in degrees
+   \param v1: a vector
+   \param v2: another vector
+   \return the angle between the vectors in degrees
+*/
+float angle_deg (const Vector& v1, const Vector& v2)
+{
+  float f;
+  f = acos( v1 * v2 / (v1.len() * v2.len()));
+  return f * 180 / PI;
+}
+
+/**
+   \brief create a rotation from a vector
+   \param v: a vector
+*/
+Rotation::Rotation (const Vector& v)
+{
+  Vector x = Vector( 1, 0, 0);
+  Vector axis = x.cross( v);
+  axis.normalize();
+  float angle = angle_rad( x, v);
+  float ca = cos(angle);
+  float sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+   \brief creates a rotation from an axis and an angle (radians!)
+   \param axis: the rotational axis
+   \param angle: the angle in radians
+*/
+Rotation::Rotation (const Vector& axis, float angle)
+{
+  float ca, sa;
+  ca = cos(angle);
+  sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+   \brief creates a rotation from euler angles (pitch/yaw/roll)
+   \param pitch: rotation around z (in radians)
+   \param yaw: rotation around y (in radians)
+   \param roll: rotation around x (in radians)
+*/
+Rotation::Rotation ( float pitch, float yaw, float roll)
+{
+  float cy, sy, cr, sr, cp, sp;
+  cy = cos(yaw);
+  sy = sin(yaw);
+  cr = cos(roll);
+  sr = sin(roll);
+  cp = cos(pitch);
+  sp = sin(pitch);
+  m[0] = cy*cr;
+  m[1] = -cy*sr;
+  m[2] = sy;
+  m[3] = cp*sr+sp*sy*cr;
+  m[4] = cp*cr-sp*sr*sy;
+  m[5] = -sp*cy;
+  m[6] = sp*sr-cp*sy*cr;
+  m[7] = sp*cr+cp*sy*sr;
+  m[8] = cp*cy;
+}
+
+/**
+   \brief creates a nullrotation (an identity rotation)
+*/
+Rotation::Rotation ()
+{
+  m[0] = 1.0f;
+  m[1] = 0.0f;
+  m[2] = 0.0f;
+  m[3] = 0.0f;
+  m[4] = 1.0f;
+  m[5] = 0.0f;
+  m[6] = 0.0f;
+  m[7] = 0.0f;
+  m[8] = 1.0f;
+}
+
+/**
+   \brief rotates the vector by the given rotation
+   \param v: a vector
+   \param r: a rotation
+   \return the rotated vector
+*/
+Vector rotate_vector( const Vector& v, const Rotation& r)
+{
+  Vector t;
+  
+  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
+  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
+  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
+
+  return t;
+}
+
+/**
+   \brief calculate the distance between two lines
+   \param l: the other line
+   \return the distance between the lines
+*/
+float Line::distance (const Line& l) const
+{
+  float q, d;
+  Vector n = a.cross(l.a);
+  q = n.dot(r-l.r);
+  d = n.len();
+  if( d == 0.0) return 0.0;
+  return q/d;
+}
+
+/**
+   \brief calculate the distance between a line and a point
+   \param v: the point
+   \return the distance between the Line and the point
+*/
+float Line::distance_point (const Vector& v) const
+{
+  Vector d = v-r;
+  Vector u = a * d.dot( a);
+  return (d - u).len();
+}
+
+/**
+   \brief calculate the two points of minimal distance of two lines
+   \param l: the other line
+   \return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
+*/
+Vector* Line::footpoints (const Line& l) const
+{
+  Vector* fp = new Vector[2];
+  Plane p = Plane (r + a.cross(l.a), r, r + a);
+  fp[1] = p.intersect_line (l);
+  p = Plane (fp[1], l.a);
+  fp[0] = p.intersect_line (*this);
+  return fp;
+}
+
+/**
+  \brief calculate the length of a line
+  \return the lenght of the line 
+*/
+float Line::len() const
+{
+  return a.len();
+}
+
+/**
+   \brief rotate the line by given rotation
+   \param rot: a rotation
+*/
+void Line::rotate (const Rotation& rot)
+{
+  Vector t = a + r;
+  t = rotate_vector( t, rot);
+  r = rotate_vector( r, rot),
+  a = t - r;
+}
+
+/**
+   \brief create a plane from three points
+   \param a: first point
+   \param b: second point
+   \param c: third point
+*/
+Plane::Plane (Vector a, Vector b, Vector c)
+{
+  n = (a-b).cross(c-b);
+  k = -(n.x*b.x+n.y*b.y+n.z*b.z);
+}
+
+/**
+   \brief create a plane from anchor point and normal
+   \param n: normal vector
+   \param p: anchor point
+*/
+Plane::Plane (Vector norm, Vector p)
+{
+  n = norm;
+  k = -(n.x*p.x+n.y*p.y+n.z*p.z);
+}
+
+/**
+   \brief returns the intersection point between the plane and a line
+   \param l: a line
+*/
+Vector Plane::intersect_line (const Line& l) const
+{
+  if (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z == 0.0) return Vector(0,0,0);
+  float t = (n.x*l.r.x+n.y*l.r.y+n.z*l.r.z+k) / (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z);
+  return l.r + (l.a * t);
+}
+
+/**
+   \brief returns the distance between the plane and a point
+   \param p: a Point
+   \return the distance between the plane and the point (can be negative)
+*/
+float Plane::distance_point (const Vector& p) const
+{
+  float l = n.len();
+  if( l == 0.0) return 0.0;
+  return (n.dot(p) + k) / n.len();
+}
+
+/**
+   \brief returns the side a point is located relative to a Plane
+   \param p: a Point
+   \return 0 if the point is contained within the Plane, positive(negative) if the point is in the positive(negative) semi-space of the Plane
+*/
+float Plane::locate_point (const Vector& p) const
+{
+  return (n.dot(p) + k);
+}
Index: orxonox/branches/chris/src/vector.h
===================================================================
--- orxonox/branches/chris/src/vector.h	(revision 1982)
+++ orxonox/branches/chris/src/vector.h	(revision 1982)
@@ -0,0 +1,85 @@
+
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include <math.h>
+#define PI 3.14159265359f
+
+class Vector {
+
+  public:
+ 
+  float x, y, z;
+
+  Vector (float x, float y, float z) : x(x), y(y), z(z) {}
+  Vector () : x(0), y(0), z(0) {}
+  ~Vector () {}
+
+  Vector operator+ (const Vector& v) const;
+  Vector operator- (const Vector& v) const;
+  float operator* (const Vector& v) const;
+  Vector operator* (float f) const;
+  Vector operator/ (float f) const;
+  float dot (const Vector& v) const;
+  Vector cross (const Vector& v) const;
+  float len() const;
+  void normalize();
+};
+
+float angle_deg (const Vector& v1, const Vector& v2);
+float angle_rad (const Vector& v1, const Vector& v2);
+
+float line_distance (Vector* l1, Vector* l2);
+
+class Rotation {
+  public:
+  
+  float m[9];
+  
+  Rotation ( const Vector& v);
+  Rotation ( const Vector& axis, float angle);
+  Rotation ( float pitch, float yaw, float roll);
+  Rotation ();
+  ~Rotation () {}
+  
+};
+
+Vector rotate_vector( const Vector& v, const Rotation& r);
+
+class Line
+{
+  public:
+  
+  Vector r, a;
+  
+  Line ( Vector r, Vector a) : r(r), a(a) {}
+  Line () : r(Vector(0,0,0)), a(Vector (1,1,1)) {}
+  ~Line () {}
+  
+  float distance (const Line& l) const;
+  float distance_point (const Vector& v) const;
+  Vector* footpoints (const Line& l) const;
+  float len () const;
+  
+  void rotate(const Rotation& rot);
+};
+
+class Plane
+{
+  public:
+  
+  Vector n;
+  float k;
+  
+  Plane (Vector a, Vector b, Vector c);
+  Plane (Vector norm, Vector p);
+  Plane (Vector n, float k) : n(n), k(k) {}
+  Plane () : n(Vector(1,1,1)), k(0) {}
+  ~Plane () {}
+  
+  Vector intersect_line (const Line& l) const;
+  float distance_point (const Vector& p) const;
+  float locate_point (const Vector& p) const;
+};
+
+#endif
