Index: branches/playability/src/world_entities/effects/trail.cc
===================================================================
--- branches/playability/src/world_entities/effects/trail.cc	(revision 10081)
+++ branches/playability/src/world_entities/effects/trail.cc	(revision 10081)
@@ -0,0 +1,402 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 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:
+
+   Trail system for engine output trails.
+   uses a catmull rom spline to interpolate the curve which is subdivided
+   into sections parts.
+   main-programmer: Marc Schaerer
+*/
+
+#include "trail.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "quaternion.h"
+#include "vector.h"
+
+#include "graphics_engine.h"
+#include "material.h"
+#include "glincl.h"
+#include "state.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinition(Trail);
+CREATE_FACTORY(Trail);
+
+/**
+ * standart constructor
+ * @param maxLength maximum length of the trail. You will later need to set the actual length used.
+ * @param sections number of sections into which the trail polygon shall be splited. Higher number for more smooth curves
+ * @param radius radius of the trail cross.
+ * 
+ */
+Trail::Trail (float maxLength, int sections, float radius)
+{
+  this->maxLength = maxLength;
+  this->length    = 1.0;
+  this->sections  = sections;
+  this->radius    = radius;
+
+  this->nodeList  = new Vector[sections];
+
+
+  this->init();
+}
+
+Trail::Trail (const TiXmlElement* root)
+{
+  this->init();
+
+  if( root)
+    this->loadParams(root);
+}
+
+/**
+ * destroys a Trail
+ */
+Trail::~Trail ()
+{
+  if (this->material)
+    delete this->material;
+  delete this->nodeList;
+}
+
+
+/**
+ * initializes the Trail
+ */
+void Trail::init()
+{
+  this->registerObject(this, Trail::_objectList);
+  this->setName("Trail");
+
+  this->material = new Material();
+  this->material->setIllum(3);
+  this->material->setDiffuse(1.0,1.0,1.0);
+  this->material->setSpecular(0.0,0.0,0.0);
+  this->material->setAmbient(1.0, 1.0, 1.0);
+
+  this->setAbsCoor(0, 0, 0);
+  this->setVisibiliy(true);
+
+  this->nodeList[0] = (this->getAbsCoor());
+  //PRINTF(0)("Trail data: N%i (%f,%f,%f)",0,this->getAbsCoor().x,this->getAbsCoor().y,this->getAbsCoor().z);
+  for( int i = 1; i < sections; i++)
+  {
+    this->nodeList[i] = (this->getAbsCoor() - ((Vector(1,0,0) * (i * this->maxLength / sections))));
+    //PRINTF(0)(" N%i (%f,%f,%f)",i,this->nodeList[i].x,this->nodeList[i].y,this->nodeList[i].z);
+  }
+  //PRINTF(0)("\n");
+}
+
+
+/**
+ *  load params
+ * @param root TiXmlElement object
+ */
+void Trail::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams( root);
+}
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load
+ */
+void Trail::setTexture(const std::string& textureFile)
+{
+  this->material->setDiffuseMap(textureFile);
+}
+
+
+/**
+ * ticks the Trail
+ * @param dt the time to ticks
+ */
+void Trail::tick(float dt)
+{
+  // Update node positions
+  float secLen  = this->maxLength / this->sections;
+  this->nodeList[0] = (this->getAbsCoor());
+  for(int i = 1; i < this->sections; i++)
+  {
+    this->nodeList[i] = this->nodeList[i-1] - (this->nodeList[i-1] - this->nodeList[i]).getNormalized()*secLen;
+  }
+  /*
+  this->length  = this->maxLength / (this->getAbsCoor() - this->nodeList[this->sections-1]).len();
+  if (!likely(this->length == 1.0))
+    for(int i = 1; i < this->sections; i++)
+      this->nodeList[i] = this->getAbsCoor()- (this->getAbsCoor() - this->nodeList[i])*this->length;
+  */
+  /*PRINTF(0)("TRAIL POS ");
+  for( int i=0; i < this->sections; i++)
+  {
+    PRINTF(0)("N%i (%f,%f,%f)",i,this->nodeList[i].x,this->nodeList[i].y,this->nodeList[i].z);
+  }
+  PRINTF(0)("\n");*/
+}
+
+
+/**
+ * draws the trail
+ * the trail has a cone shape
+ */
+void Trail::draw() const
+{
+  if(!this->isVisible())
+    return;
+
+  Vector* Q = new Vector[4];
+  Vector targ;
+  Vector now, later;
+  float fact  = 1.0/this->sections;
+  float rad0, rad1;
+
+  //glPushAttrib(GL_ENABLE_BIT);
+  
+  glPushMatrix();
+  //glMatrixMode(GL_MODELVIEW);
+  //glLoadIdentity();
+  glTranslatef(-this->getAbsCoor().x,-this->getAbsCoor().y,-this->getAbsCoor().z);
+  glScalef(1,1,1);
+  this->material->select();
+  /*
+  glBegin(GL_TRIANGLESTRIP);
+  for( int i = 0; i < this->sections-1; i++)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i+1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i+1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // vertical polygon
+    Q[0]  = now + Vector(0,rad1,0) ;
+    Q[1]  = later + Vector(0,rad0,0) ;
+    Q[2]  = later + Vector(0,-rad0,0) ;
+    Q[3]  = now + Vector(0,-rad1,0) ;
+    //PRINTF(0)("Debug output: Q0 (%f,%f,%f) :: Q1 (%f,%f,%f) :: Q2 (%f,%f,%f) :: Q3 (%f,%f,%f)\n",Q[0].x,Q[0].y,Q[0].z,Q[1].x,Q[1].y,Q[1].z,Q[2].x,Q[2].y,Q[2].z,Q[3].x,Q[3].y,Q[3].z);
+
+      glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+      glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+      glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+      glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+    
+  }
+  glEnd();
+  glBegin(GL_TRIANGLESTRIP);
+  for( int i = 0; i < this->sections-1; i++)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i+1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i+1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // vertical polygon
+    Q[0]  = now + Vector(0,rad1,0) ;
+    Q[1]  = later + Vector(0,rad0,0) ;
+    Q[2]  = later + Vector(0,-rad0,0) ;
+    Q[3]  = now + Vector(0,-rad1,0) ;
+    //PRINTF(0)("Debug output: Q0 (%f,%f,%f) :: Q1 (%f,%f,%f) :: Q2 (%f,%f,%f) :: Q3 (%f,%f,%f)\n",Q[0].x,Q[0].y,Q[0].z,Q[1].x,Q[1].y,Q[1].z,Q[2].x,Q[2].y,Q[2].z,Q[3].x,Q[3].y,Q[3].z);
+
+      glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+      glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+      glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+      glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+    
+  }
+  glEnd();*/
+  glBegin(GL_TRIANGLE_STRIP);
+  for( int i = 1; i < this->sections-1; i++)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i+1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i+1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // horizontal polygon
+    Q[0]  = now + Vector(0,rad1,0) ;
+    Q[3]  = now + Vector(0,-rad1,0) ;
+    
+    glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+	glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+
+    if( i == this->sections - 1)
+    {
+      
+      Q[1]  = later + Vector(0,rad0,0) ;
+      Q[2]  = later + Vector(0,-rad0,0) ;
+      glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+      glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+    }
+
+
+  }
+  glEnd();
+  glBegin(GL_TRIANGLE_STRIP);
+  for( int i = this->sections-1; i > 0; i--)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i-1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i-1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // horizontal polygon
+    Q[0]  = now + Vector(0,rad1,0) ;
+    Q[3]  = now + Vector(0,-rad1,0) ;
+
+	glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+	glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+
+    if( i == 1)
+    {
+        Q[1]  = later + Vector(0,rad0,0) ;
+        Q[2]  = later + Vector(0,-rad0,0) ;
+		glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+		glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+	}
+
+  }
+  glEnd();
+
+
+  glBegin(GL_TRIANGLE_STRIP);
+  for( int i = 1; i < this->sections-1; i++)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i+1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i+1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // horizontal polygon
+    Q[0]  = now + targ.cross(Vector(0,rad1,0)) ;
+    Q[3]  = now + targ.cross(Vector(0,-rad1,0)) ;
+    
+	glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+	glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+
+    if( i == this->sections-1)
+    {
+      Q[1]  = later + targ.cross(Vector(0,rad0,0)) ;
+      Q[2]  = later + targ.cross(Vector(0,-rad0,0)) ;
+      glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+      glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+    }
+
+
+  }
+  glEnd();
+  glBegin(GL_TRIANGLE_STRIP);
+  for( int i = this->sections-1; i > 0; i--)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i-1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i-1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // horizontal polygon
+    Q[0]  = now + targ.cross(Vector(0,rad1,0)) ;
+    Q[3]  = now + targ.cross(Vector(0,-rad1,0)) ;
+
+	glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+	glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+
+    if( i == 1)
+    {
+        Q[1]  = later + targ.cross(Vector(0,rad0,0)) ;
+        Q[2]  = later + targ.cross(Vector(0,-rad0,0)) ;
+		glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+		glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+	}
+
+  }
+  glEnd();
+  this->material->unselect();
+
+  glPopMatrix();
+  //glPopAttrib();
+/*
+  //glTranslatef(this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
+  //glTranslatef(0,0,0);
+
+  const PNode* camera = State::getCameraNode();  //!< @todo MUST be different
+  Vector cameraPos = camera->getAbsCoor();
+  Vector cameraTargetPos = State::getCameraTargetNode()->getAbsCoor();
+  Vector view = cameraTargetPos - cameraPos;
+  Vector up = Vector(0, 1, 0);
+  up = camera->getAbsDir().apply(up);
+  Vector h = up.cross(view);
+  Vector v = h.cross(view);
+  h.normalize();
+  v.normalize();
+
+  v *= sizeX;
+  h *= sizeY;
+
+//v += this->getAbsCoor();
+    //PRINTF(0)("sizeX: %f sizeY: %f\n", sizeX, sizeY);
+  glBegin(GL_QUADS);
+  glTexCoord2f(0.0f, 0.0f);
+  glVertex3f(this->getAbsCoor().x - h.x - v.x,
+             this->getAbsCoor().y - h.y - v.y,
+             this->getAbsCoor().z - h.z - v.z);
+  glTexCoord2f(1.0f, 0.0f);
+  glVertex3f( this->getAbsCoor().x + h.x - v.x,
+              this->getAbsCoor().y + h.y - v.y,
+              this->getAbsCoor().z + h.z - v.z);
+  glTexCoord2f(1.0f, 1.0f);
+  glVertex3f(this->getAbsCoor().x + h.x + v.x,
+             this->getAbsCoor().y + h.y + v.y,
+             this->getAbsCoor().z + h.z + v.z);
+  glTexCoord2f(0.0f, 1.0f);
+  glVertex3f(this->getAbsCoor().x - h.x + v.x,
+             this->getAbsCoor().y - h.y + v.y,
+             this->getAbsCoor().z - h.z + v.z);
+  glEnd();
+
+
+  glPopMatrix();
+
+  glPopAttrib();*/
+}
Index: branches/playability/src/world_entities/effects/trail.h
===================================================================
--- branches/playability/src/world_entities/effects/trail.h	(revision 10081)
+++ branches/playability/src/world_entities/effects/trail.h	(revision 10081)
@@ -0,0 +1,62 @@
+/*!
+ * @file trail.h
+ */
+
+#ifndef _TRAIL_H_
+#define _TRAIL_H_
+
+#include "world_entity.h"
+
+class Material;
+
+
+
+class Trail : public WorldEntity
+{
+  ObjectListDeclaration(Trail);
+  public:
+    Trail(float maxLength, int sections, float radius);
+    Trail(const TiXmlElement* root = NULL);
+    virtual ~Trail();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void setTexture(const std::string& textureFile);
+
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+    /**
+     *  length of the trail.
+     */
+    inline void setLength(float length) { this->length = length;};
+    inline float getLength() { return this->length;};
+
+    /**
+     *  Amount of sections (parts) of the trail. The more, the rounder it will look
+     */
+    inline void setSections(int sections) { this->sections = sections;};
+    inline int getSections() { return this->sections;};
+
+    /**
+     *  Radius of the trail object
+     */
+    inline void setRadius(float radius) { this->radius = radius;};
+    inline float getRadius() { return this->radius;};
+
+  private:
+    void init();
+    inline Vector catmull(Vector P0, Vector P1, Vector P2, Vector P3, float t) const {return (P1*2 + (P2 - P0)*t + (P0*2 - P1*5- P2*4 - P3)*t*t + (P1*3 -P0 - P2*3 + P3)*t*t*t); };
+
+
+    Material*              material;
+
+    float maxLength;
+    float length;
+    float radius;
+    int   sections;
+
+    Vector*  nodeList;
+};
+
+#endif /* _TRAIL_H_ */
