Index: code/trunk/src/orxonox/objects/worldentities/Backlight.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Backlight.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Backlight.cc	(revision 2662)
@@ -30,13 +30,13 @@
 #include "Backlight.h"
 
-#include <OgreBillboard.h>
 #include <OgreRibbonTrail.h>
 #include <OgreSceneManager.h>
 
+#include "core/Core.h"
 #include "core/CoreIncludes.h"
-#include "core/ConfigValueIncludes.h"
 #include "core/Executor.h"
-#include "util/Math.h"
-#include "GraphicsEngine.h"
+#include "core/XMLPort.h"
+#include "objects/Scene.h"
+#include "util/Exception.h"
 
 namespace orxonox
@@ -44,42 +44,38 @@
     CreateFactory(Backlight);
 
-    float Backlight::timeFactor_s = 1.0;
-
-    Backlight::Backlight(float maxspeed, float brakingtime, float scale)
+    Backlight::Backlight(BaseObject* creator) : FadingBillboard(creator)
     {
         RegisterObject(Backlight);
 
-        this->setConfigValues();
-        this->traillength_ = 1;
-
-        this->configure(maxspeed, brakingtime, scale);
-    }
-    
-    bool Backlight::create(){
-      if(!WorldEntity::create())
-        return false;
-      
-      this->getNode()->setInheritScale(false);
-
-      this->billboard_.setBillboardSet("Flares/backlightflare");
-      this->attachObject(this->billboard_.getBillboardSet());
-
-      this->ribbonTrail_ = GraphicsEngine::getInstance().getLevelSceneManager()->createRibbonTrail(this->getName() + "RibbonTrail");
-      this->ribbonTrailNode_ = GraphicsEngine::getInstance().getLevelSceneManager()->getRootSceneNode()->createChildSceneNode(this->getName() + "RibbonTrailNode");
-      this->ribbonTrailNode_->attachObject(this->ribbonTrail_);
-      this->ribbonTrail_->addNode(this->getNode());
-
-
-      this->ribbonTrail_->setTrailLength(this->maxTraillength_);
-      this->ribbonTrail_->setMaterialName("Trail/backlighttrail");
-
-        //this->setTimeFactor(Orxonox::getInstance().getTimeFactor());
-      this->setTimeFactor(1.0f);
-      
-      this->ribbonTrail_->setMaxChainElements(this->maxTrailsegments_);
-      this->ribbonTrail_->setTrailLength(this->traillength_ = 2 * this->maxTrailsegments_);
-      this->ribbonTrail_->setInitialWidth(0, this->width_ * this->getScale());
-      this->ribbonTrail_->setWidthChange(0, this->width_ * this->getScale() / this->maxLifeTime_ * Backlight::timeFactor_s);
-      return true;
+        this->ribbonTrail_ = 0;
+        this->ribbonTrailNode_ = 0;
+
+        this->width_ = 0;
+        this->length_ = 1.0f;
+        this->lifetime_ = 0.001f;
+        this->maxelements_ = 1;
+
+        this->tickcount_ = 0;
+
+        if (Core::showsGraphics())
+        {
+            if (!this->getScene())
+                ThrowException(AbortLoading, "Can't create Backlight, no scene given.");
+            if (!this->getScene()->getSceneManager())
+                ThrowException(AbortLoading, "Can't create Backlight, no scene manager given.");
+            if (!this->getScene()->getRootSceneNode())
+                ThrowException(AbortLoading, "Can't create Backlight, no root scene node given.");
+
+            this->ribbonTrail_ = this->getScene()->getSceneManager()->createRibbonTrail(this->getNode()->getName());
+
+            this->ribbonTrailNode_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
+            this->ribbonTrailNode_->attachObject(this->ribbonTrail_);
+
+            this->ribbonTrail_->setMaxChainElements(this->maxelements_);
+            this->ribbonTrail_->setTrailLength(this->length_);
+            this->ribbonTrail_->setInitialWidth(0, 0);
+        }
+
+        this->registerVariables();
     }
 
@@ -88,83 +84,151 @@
         if (this->isInitialized())
         {
-            this->detachObject(this->billboard_.getBillboardSet());
-            GraphicsEngine::getInstance().getLevelSceneManager()->destroySceneNode(this->getName() + "RibbonTrailNode");
-            GraphicsEngine::getInstance().getLevelSceneManager()->destroyRibbonTrail(this->ribbonTrail_);
-        }
-    }
-
-    void Backlight::setConfigValues()
-    {
-        SetConfigValue(maxLifeTime_, 4.0).description("The maximal amount of seconds the trail behind a SpaceShip stays visible");
-        SetConfigValue(trailSegmentLength_, 50).description("The length of one segment of the trail behind a SpaceShip (lower values make it more smooth)");
-        SetConfigValue(width_, 7.0).description("The width of the trail");
-    }
-
-    void Backlight::setTimeFactor(float factor)
-    {
-        Backlight::timeFactor_s = factor;
-        float change = Backlight::timeFactor_s / this->maxLifeTime_;
-        this->ribbonTrail_->setWidthChange(0, this->width_ * change);
-        this->updateColourChange();
-    }
-
-    void Backlight::updateColourChange()
-    {
-        this->ribbonTrail_->setColourChange(0, ColourValue(0, 0, 0, this->maxTraillength_ / this->traillength_ / this->maxLifeTime_ * Backlight::timeFactor_s));
-    }
-    
-    
-    void Backlight::XMLPort(Element& xmlelement, XMLPort::Mode mode){
-      SUPER(Backlight, XMLPort, xmlelement, mode);
-      
-      Backlight::create();
+            if (this->ribbonTrail_)
+            {
+                if (this->ribbonTrailNode_)
+                {
+                    this->ribbonTrailNode_->detachObject(this->ribbonTrail_);
+                    this->getScene()->getSceneManager()->destroySceneNode(this->ribbonTrailNode_->getName());
+                }
+                this->getScene()->getSceneManager()->destroyRibbonTrail(this->ribbonTrail_);
+            }
+        }
+    }
+
+    void Backlight::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Backlight, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Backlight, "length",        setLength,        getLength,        xmlelement, mode).defaultValues(100.0f);
+        XMLPortParam(Backlight, "width",         setWidth,         getWidth,         xmlelement, mode).defaultValues(1.0f);
+        XMLPortParam(Backlight, "elements",      setMaxElements,   getMaxElements,   xmlelement, mode).defaultValues(10);
+        XMLPortParam(Backlight, "lifetime",      setLifetime,      getLifetime,      xmlelement, mode).defaultValues(1.0f);
+        XMLPortParam(Backlight, "trailmaterial", setTrailMaterial, getTrailMaterial, xmlelement, mode);
+    }
+
+    void Backlight::registerVariables()
+    {
+        registerVariable(this->width_,         variableDirection::toclient, new NetworkCallback<Backlight>(this, &Backlight::update_width));
+        registerVariable(this->lifetime_,      variableDirection::toclient, new NetworkCallback<Backlight>(this, &Backlight::update_lifetime));
+        registerVariable(this->length_,        variableDirection::toclient, new NetworkCallback<Backlight>(this, &Backlight::update_length));
+        registerVariable(this->maxelements_,   variableDirection::toclient, new NetworkCallback<Backlight>(this, &Backlight::update_maxelements));
+        registerVariable(this->trailmaterial_, variableDirection::toclient, new NetworkCallback<Backlight>(this, &Backlight::update_trailmaterial));
+    }
+
+    void Backlight::changedColour()
+    {
+        FadingBillboard::changedColour();
+
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setInitialColour(0, this->getFadedColour());
+    }
+
+    void Backlight::update_width()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setInitialWidth(0, this->width_ * this->getWorldScale());
+        this->update_lifetime();
+    }
+
+    void Backlight::update_lifetime()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+        {
+            this->ribbonTrail_->setWidthChange(0, this->width_ * this->getWorldScale() / this->lifetime_ * this->getTimeFactor());
+            this->ribbonTrail_->setColourChange(0, 0, 0, 0, 1.0f / this->lifetime_ * this->getTimeFactor());
+        }
+    }
+
+    void Backlight::update_length()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setTrailLength(this->length_ * this->getWorldScale());
+    }
+
+    void Backlight::update_maxelements()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setMaxChainElements(this->maxelements_);
+    }
+
+    void Backlight::update_trailmaterial()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setMaterialName(this->trailmaterial_);
+    }
+
+    void Backlight::changedVisibility()
+    {
+        SUPER(Backlight, changedVisibility);
+
+        if (this->ribbonTrail_)
+            this->ribbonTrail_->setVisible(this->isVisible());
+    }
+
+    void Backlight::startturnonoff()
+    {
+        FadingBillboard::startturnonoff();
+
+        if (this->ribbonTrail_ && this->isActive() && this->isVisible())
+            this->ribbonTrail_->setVisible(true);
+    }
+
+    void Backlight::stopturnonoff()
+    {
+        this->postprocessingtime_ = max(0.0f, this->lifetime_ - this->turnofftime_);
+
+        FadingBillboard::stopturnonoff();
+
+        if (this->ribbonTrail_)
+            this->ribbonTrail_->setInitialColour(0, this->getFadedColour());
+    }
+
+    void Backlight::poststopturnonoff()
+    {
+        FadingBillboard::poststopturnonoff();
+
+        if (this->ribbonTrail_)
+            this->ribbonTrail_->setVisible(false);
+    }
+
+    void Backlight::changedScale()
+    {
+        SUPER(Backlight, changedScale);
+
+        this->update_width();
+        this->update_length();
     }
 
     void Backlight::tick(float dt)
     {
+        if (this->tickcount_ < 2)
+        {
+            ++this->tickcount_;
+            if (this->tickcount_ == 2)
+            {
+                this->changedColour();
+                this->update_width();
+                this->update_lifetime();
+                this->update_length();
+                this->update_maxelements();
+                this->update_trailmaterial();
+                if (this->ribbonTrail_)
+                    this->ribbonTrail_->addNode(this->node_);
+            }
+        }
+
         SUPER(Backlight, tick, dt);
 
-        if (this->isActive())
-        {
-            if (this->traillength_ < this->maxTraillength_)
-            {
-                this->traillength_ = min<float>(this->maxTraillength_, this->traillength_ + dt * this->maxTraillength_ / this->maxLifeTime_);
-                this->updateColourChange();
-            }
-        }
-        else
-        {
-            if (this->traillength_ > 1)
-            {
-                this->traillength_ = max<float>(1, this->traillength_ - this->brakefactor_ * dt * this->maxTraillength_ / this->maxLifeTime_);
-                this->updateColourChange();
-            }
-        }
-
-        this->ribbonTrail_->setTrailLength(this->traillength_);
-    }
-
-    void Backlight::setColour(const ColourValue& colour)
-    {
-        this->billboard_.getBillboardSet()->getBillboard(0)->setColour(colour);
-        this->ribbonTrail_->setInitialColour(0, ColourValue(colour.r / 4 + 0.75, colour.g / 4 + 0.75, colour.b / 4 + 0.75));
-    }
-
-    void Backlight::configure(float maxspeed, float brakingtime, float scale)
-    {
-        this->maxTraillength_ = this->maxLifeTime_ * maxspeed;
-        this->maxTrailsegments_ = (size_t)(this->maxTraillength_ / this->trailSegmentLength_);
-
-        this->brakefactor_ = this->maxLifeTime_ / brakingtime;
-
-        this->scale(scale);
-    }
-
-    void Backlight::changedVisibility()
-    {
-        SUPER(Backlight, changedVisibility);
-
-        this->billboard_.setVisible(this->isVisible());
-        this->ribbonTrail_->setVisible(this->isVisible());
+        if (this->ribbonTrail_ && this->changedirection_ != 0)
+        {
+            // we use alpha_blend, only adjust alpha
+            const ColourValue& colour = this->getColour();
+            this->ribbonTrail_->setInitialColour(0, colour.r, colour.g, colour.b, this->getFadedColour().a);
+        }
+    }
+
+    void Backlight::changedTimeFactor(float factor_new, float factor_old)
+    {
+        this->update_lifetime();
     }
 }
Index: code/trunk/src/orxonox/objects/worldentities/Backlight.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Backlight.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Backlight.h	(revision 2662)
@@ -31,44 +31,70 @@
 
 #include "OrxonoxPrereqs.h"
-
-#include "PositionableEntity.h"
-#include "tools/BillboardSet.h"
+#include "FadingBillboard.h"
+#include "gamestates/GSRoot.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Backlight : public PositionableEntity
+    class _OrxonoxExport Backlight : public FadingBillboard, public TimeFactorListener
     {
         public:
-            Backlight(float maxspeed = 1.0, float brakingtime = 1.0, float scale = 1.0);
+            Backlight(BaseObject* creator);
             virtual ~Backlight();
 
-            void setConfigValues();
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
             virtual void tick(float dt);
             virtual void changedVisibility();
-            virtual bool create();
 
-            void setColour(const ColourValue& colour);
-            void setTimeFactor(float factor);
+            inline void setWidth(float width)
+                { this->width_ = width; this->update_width(); }
+            inline float getWidth() const
+                { return this->width_; }
+
+            inline void setLifetime(float lifetime)
+                { this->lifetime_ = lifetime; this->update_lifetime(); }
+            inline float getLifetime() const
+                { return this->lifetime_; }
+
+            inline void setLength(float length)
+                { this->length_ = length; this->update_length(); }
+            inline float getLength() const
+                { return this->length_; }
+
+            inline void setMaxElements(size_t maxelements)
+                { this->maxelements_ = maxelements; this->update_maxelements(); }
+            inline size_t getMaxElements() const
+                { return this->maxelements_; }
+
+            inline void setTrailMaterial(const std::string& material)
+                { this->trailmaterial_ = material; this->update_trailmaterial(); }
+            inline const std::string& getTrailMaterial() const
+                { return this->trailmaterial_; }
+
+            virtual void changedScale();
+
+        protected:
+            virtual void changedTimeFactor(float factor_new, float factor_old);
 
         private:
-            void configure(float maxspeed, float brakingtime, float scale = 1);
-            void updateColourChange();
+            virtual void startturnonoff();
+            virtual void stopturnonoff();
+            virtual void poststopturnonoff();
+            virtual void changedColour();
+            void update_width();
+            void update_lifetime();
+            void update_length();
+            void update_maxelements();
+            void update_trailmaterial();
 
-            static float timeFactor_s;
-            BillboardSet billboard_;
+            Ogre::RibbonTrail* ribbonTrail_;
             Ogre::SceneNode* ribbonTrailNode_;
-            Ogre::RibbonTrail* ribbonTrail_;
-
-            float maxLifeTime_;
-            float trailSegmentLength_;
             float width_;
-
-            float brakefactor_;
-
-            float maxTraillength_;
-            float traillength_;
-
-            size_t maxTrailsegments_;
+            float length_;
+            float lifetime_;
+            size_t maxelements_;
+            std::string trailmaterial_;
+            char tickcount_;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/Billboard.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Billboard.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Billboard.cc	(revision 2662)
@@ -30,6 +30,9 @@
 #include "Billboard.h"
 
+#include <OgreBillboardSet.h>
+
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
+#include "core/Core.h"
 #include "objects/Scene.h"
 
@@ -38,7 +41,10 @@
     CreateFactory(Billboard);
 
-    Billboard::Billboard(BaseObject* creator) : PositionableEntity(creator)
+    Billboard::Billboard(BaseObject* creator) : StaticEntity(creator)
     {
         RegisterObject(Billboard);
+
+        this->material_ = "";
+        this->colour_ = ColourValue::White;
 
         this->registerVariables();
@@ -50,5 +56,5 @@
         {
             if (this->isInitialized() && this->billboard_.getBillboardSet())
-                this->getNode()->detachObject(this->billboard_.getName());
+                this->detachOgreObject(this->billboard_.getBillboardSet());
         }
     }
@@ -64,17 +70,20 @@
     void Billboard::registerVariables()
     {
-        REGISTERSTRING(this->material_, direction::toclient, new NetworkCallback<Billboard>(this, &Billboard::changedMaterial));
-        REGISTERDATA  (this->colour_,   direction::toclient, new NetworkCallback<Billboard>(this, &Billboard::changedColour));
+        registerVariable(this->material_, variableDirection::toclient, new NetworkCallback<Billboard>(this, &Billboard::changedMaterial));
+        registerVariable(this->colour_,   variableDirection::toclient, new NetworkCallback<Billboard>(this, &Billboard::changedColour));
     }
 
     void Billboard::changedMaterial()
     {
+        if (this->material_ == "")
+            return;
+
         if (!this->billboard_.getBillboardSet())
         {
-            if (this->getScene() && this->getScene()->getSceneManager())
+            if (this->getScene() && Core::showsGraphics())
             {
                 this->billboard_.setBillboardSet(this->getScene()->getSceneManager(), this->material_, this->colour_, 1);
                 if (this->billboard_.getBillboardSet())
-                    this->getNode()->attachObject(this->billboard_.getBillboardSet());
+                     this->attachOgreObject(this->billboard_.getBillboardSet());
                 this->billboard_.setVisible(this->isVisible());
             }
@@ -88,11 +97,13 @@
         if (!this->billboard_.getBillboardSet())
         {
-            if (this->getScene() && this->getScene()->getSceneManager())
+/*
+            if (this->getScene() && Core::showsGraphics() && (this->material_ != ""))
             {
                 this->billboard_.setBillboardSet(this->getScene()->getSceneManager(), this->material_, this->colour_, 1);
                 if (this->billboard_.getBillboardSet())
-                    this->getNode()->attachObject(this->billboard_.getBillboardSet());
+                    this->attachOgreObject(this->billboard_.getBillboardSet());
                 this->billboard_.setVisible(this->isVisible());
             }
+*/
         }
         else
Index: code/trunk/src/orxonox/objects/worldentities/Billboard.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Billboard.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Billboard.h	(revision 2662)
@@ -31,5 +31,5 @@
 
 #include "OrxonoxPrereqs.h"
-#include "PositionableEntity.h"
+#include "StaticEntity.h"
 #include "util/Math.h"
 #include "tools/BillboardSet.h"
@@ -37,5 +37,5 @@
 namespace orxonox
 {
-    class _OrxonoxExport Billboard : public PositionableEntity
+    class _OrxonoxExport Billboard : public StaticEntity
     {
         public:
@@ -61,7 +61,12 @@
                 { return this->colour_; }
 
+        protected:
+            inline BillboardSet& getBillboardSet()
+                { return this->billboard_; }
+
+            virtual void changedColour();
+
         private:
             void changedMaterial();
-            void changedColour();
 
             BillboardSet billboard_;
Index: code/trunk/src/orxonox/objects/worldentities/BlinkingBillboard.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/BlinkingBillboard.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/BlinkingBillboard.cc	(revision 2662)
@@ -68,11 +68,13 @@
     void BlinkingBillboard::registerVariables()
     {
-//        REGISTERDATA(this->amplitude_, direction::toclient);
-//        REGISTERDATA(this->frequency_, direction::toclient);
-//        REGISTERDATA(this->phase_,     direction::toclient);
+//        registerVariable(this->amplitude_, variableDirection::toclient);
+//        registerVariable(this->frequency_, variableDirection::toclient);
+//        registerVariable(this->phase_,     variableDirection::toclient);
     }
 
     void BlinkingBillboard::tick(float dt)
     {
+        SUPER(BlinkingBillboard, tick, dt);
+
         if (Core::isMaster() && this->isActive())
         {
Index: code/trunk/src/orxonox/objects/worldentities/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/CMakeLists.txt	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/CMakeLists.txt	(revision 2662)
@@ -1,17 +1,22 @@
 SET( SRC_FILES
   WorldEntity.cc
-  PositionableEntity.cc
+  StaticEntity.cc
   MovableEntity.cc
+  MobileEntity.cc
   ControllableEntity.cc
-  Model.cc
+
+  Backlight.cc
   Billboard.cc
   BlinkingBillboard.cc
+  ExplosionChunk.cc
+  FadingBillboard.cc
   Light.cc
   Camera.cc
   CameraPosition.cc
-  SpawnPoint.cc
+  Model.cc
   ParticleEmitter.cc
   ParticleSpawner.cc
-#  Backlight.cc
+  Planet.cc
+  SpawnPoint.cc
 )
 
Index: code/trunk/src/orxonox/objects/worldentities/Camera.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Camera.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Camera.cc	(revision 2662)
@@ -36,5 +36,4 @@
 #include <OgreSceneManager.h>
 #include <OgreSceneNode.h>
-#include <OgreViewport.h>
 
 #include "util/Exception.h"
@@ -48,13 +47,19 @@
     CreateFactory(Camera);
 
-    Camera::Camera(BaseObject* creator) : PositionableEntity(creator)
+    Camera::Camera(BaseObject* creator) : StaticEntity(creator)
     {
         RegisterObject(Camera);
 
-        if (!this->getScene() || !this->getScene()->getSceneManager())
-            ThrowException(AbortLoading, "Can't create Camera, no scene or no scene manager given.");
+        if (!this->getScene())
+            ThrowException(AbortLoading, "Can't create Camera, no scene.");
+        if (!this->getScene()->getSceneManager())
+            ThrowException(AbortLoading, "Can't create Camera, no scene-manager given.");
+        if (!this->getScene()->getRootSceneNode())
+            ThrowException(AbortLoading, "Can't create Camera, no root-scene-node given.");
 
         this->camera_ = this->getScene()->getSceneManager()->createCamera(getUniqueNumberString());
-        this->getNode()->attachObject(this->camera_);
+        this->cameraNode_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
+        this->attachNode(this->cameraNode_);
+        this->cameraNode_->attachObject(this->camera_);
 
         this->bHasFocus_ = false;
@@ -66,6 +71,4 @@
         this->setConfigValues();
         this->configvaluecallback_changedNearClipDistance();
-
-        this->requestFocus(); // ! HACK ! REMOVE THIS !
     }
 
@@ -75,4 +78,13 @@
         {
             this->releaseFocus();
+
+            this->cameraNode_->detachAllObjects();
+            this->getScene()->getSceneManager()->destroyCamera(this->camera_);
+
+            if (this->bDrag_)
+                this->detachNode(this->cameraNode_);
+
+            if (this->getScene()->getSceneManager())
+                this->getScene()->getSceneManager()->destroySceneNode(this->cameraNode_->getName());
         }
     }
@@ -90,13 +102,17 @@
     void Camera::tick(float dt)
     {
-/*
-        // this stuff here may need some adjustments
-        float coeff = (this->bDrag_) ? min(1.0f, 15.0f * dt) : (1.0f);
+        SUPER(Camera, tick, dt);
 
-        Vector3 offset = this->getNode()->getWorldPosition() - this->cameraNode_->getWorldPosition();
-        this->cameraNode_->translate(coeff * offset);
+        if (this->bDrag_)
+        {
+            // this stuff here may need some adjustments
+            float coeff = min(1.0f, 15.0f * dt);
 
-        this->cameraNode_->setOrientation(Quaternion::Slerp(coeff, this->cameraNode_->getWorldOrientation(), this->getWorldOrientation(), false));
-*/
+            Vector3 offset = this->getWorldPosition() - this->cameraNode_->getWorldPosition();
+            this->cameraNode_->translate(coeff * offset);
+
+            this->cameraNode_->setOrientation(Quaternion::Slerp(coeff, this->cameraNode_->getWorldOrientation(), this->getWorldOrientation(), true));
+            //this->cameraNode_->setOrientation(this->getWorldOrientation());
+        }
     }
 
@@ -120,8 +136,29 @@
     }
 
-    void Camera::setFocus(Ogre::Viewport* viewport)
+    void Camera::setFocus()
     {
         this->bHasFocus_ = true;
-        viewport->setCamera(this->camera_);
+        CameraManager::getInstance().useCamera(this->camera_);
+    }
+
+    void Camera::setDrag(bool bDrag)
+    {
+        if (bDrag != this->bDrag_)
+        {
+            this->bDrag_ = bDrag;
+
+            if (!bDrag)
+            {
+                this->attachNode(this->cameraNode_);
+                this->cameraNode_->setPosition(Vector3::ZERO);
+                this->cameraNode_->setOrientation(Quaternion::IDENTITY);
+            }
+            else
+            {
+                this->detachNode(this->cameraNode_);
+                this->cameraNode_->setPosition(this->getWorldPosition());
+                this->cameraNode_->setOrientation(this->getWorldOrientation());
+            }
+        }
     }
 }
Index: code/trunk/src/orxonox/objects/worldentities/Camera.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Camera.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Camera.h	(revision 2662)
@@ -33,10 +33,10 @@
 
 #include <OgrePrerequisites.h>
-#include "objects/worldentities/PositionableEntity.h"
+#include "objects/worldentities/StaticEntity.h"
 #include "objects/Tickable.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Camera : public PositionableEntity, public Tickable
+    class _OrxonoxExport Camera : public StaticEntity, public Tickable
     {
         friend class CameraManager;
@@ -55,6 +55,5 @@
                 { return this->bHasFocus_; }
 
-            inline void setDrag(bool bDrag)
-                { this->bDrag_ = bDrag; }
+            void setDrag(bool bDrag);
             inline bool getDrag() const
                 { return this->bDrag_; }
@@ -62,11 +61,12 @@
         private:
             void removeFocus();
-            void setFocus(Ogre::Viewport* viewport);
+            void setFocus();
             void configvaluecallback_changedNearClipDistance();
 
-            Ogre::Camera*   camera_;
-            float           nearClipDistance_;
-            bool            bHasFocus_;
-            bool            bDrag_;
+            Ogre::Camera*    camera_;
+            Ogre::SceneNode* cameraNode_;
+            float            nearClipDistance_;
+            bool             bHasFocus_;
+            bool             bDrag_;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/CameraPosition.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/CameraPosition.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/CameraPosition.cc	(revision 2662)
@@ -38,9 +38,10 @@
     CreateFactory(CameraPosition);
 
-    CameraPosition::CameraPosition(BaseObject* creator) : PositionableEntity(creator)
+    CameraPosition::CameraPosition(BaseObject* creator) : StaticEntity(creator)
     {
         RegisterObject(CameraPosition);
 
         this->bDrag_ = false;
+        this->bAllowMouseLook_ = false;
 
         this->setObjectMode(0x0);
@@ -56,10 +57,16 @@
 
         XMLPortParam(CameraPosition, "drag", setDrag, getDrag, xmlelement, mode).defaultValues(false);
+        XMLPortParam(CameraPosition, "mouselook", setAllowMouseLook, getAllowMouseLook, xmlelement, mode).defaultValues(false);
     }
 
     void CameraPosition::attachCamera(Camera* camera)
     {
-        camera->setDrag(this->bDrag_);
+        if (!this->bDrag_)
+            camera->setDrag(false);
+
         this->attach(camera);
+
+        if (this->bDrag_)
+            camera->setDrag(true);
     }
 }
Index: code/trunk/src/orxonox/objects/worldentities/CameraPosition.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/CameraPosition.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/CameraPosition.h	(revision 2662)
@@ -32,9 +32,9 @@
 #include "OrxonoxPrereqs.h"
 
-#include "objects/worldentities/PositionableEntity.h"
+#include "objects/worldentities/StaticEntity.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport CameraPosition : public PositionableEntity
+    class _OrxonoxExport CameraPosition : public StaticEntity
     {
         public:
@@ -49,8 +49,14 @@
                 { return this->bDrag_; }
 
+            inline void setAllowMouseLook(bool bAllow)
+                { this->bAllowMouseLook_ = bAllow; }
+            inline bool getAllowMouseLook() const
+                { return this->bAllowMouseLook_; }
+
             void attachCamera(Camera* camera);
 
         private:
             bool bDrag_;
+            bool bAllowMouseLook_;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/ControllableEntity.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/ControllableEntity.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/ControllableEntity.cc	(revision 2662)
@@ -23,5 +23,5 @@
  *      Fabian 'x3n' Landau
  *   Co-authors:
- *      ...
+ *      Reto Grieder
  *
  */
@@ -30,12 +30,17 @@
 #include "ControllableEntity.h"
 
+#include <OgreSceneManager.h>
+
 #include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
 #include "core/Core.h"
 #include "core/XMLPort.h"
 #include "core/Template.h"
 
+#include "objects/Scene.h"
 #include "objects/infos/PlayerInfo.h"
 #include "objects/worldentities/Camera.h"
 #include "objects/worldentities/CameraPosition.h"
+#include "objects/gametypes/Gametype.h"
 #include "overlays/OverlayGroup.h"
 
@@ -44,9 +49,11 @@
     CreateFactory(ControllableEntity);
 
-    ControllableEntity::ControllableEntity(BaseObject* creator) : WorldEntity(creator)
+    ControllableEntity::ControllableEntity(BaseObject* creator) : MobileEntity(creator)
     {
         RegisterObject(ControllableEntity);
 
-        this->bControlled_ = false;
+        this->bHasLocalController_ = false;
+        this->bHasHumanController_ = false;
+
         this->server_overwrite_ = 0;
         this->client_overwrite_ = 0;
@@ -56,15 +63,24 @@
         this->camera_ = 0;
         this->bDestroyWhenPlayerLeft_ = false;
-
-        this->velocity_ = Vector3::ZERO;
-        this->acceleration_ = Vector3::ZERO;
-
-        this->server_position_ = Vector3::ZERO;
-        this->client_position_ = Vector3::ZERO;
-        this->server_velocity_ = Vector3::ZERO;
-        this->client_velocity_ = Vector3::ZERO;
-        this->server_orientation_ = Quaternion::IDENTITY;
-        this->client_orientation_ = Quaternion::IDENTITY;
-
+        this->cameraPositionRootNode_ = this->node_->createChildSceneNode();
+        this->bMouseLook_ = false;
+        this->mouseLookSpeed_ = 200;
+
+        this->gtinfo_ = 0;
+        this->gtinfoID_ = OBJECTID_UNKNOWN;
+        this->changedGametype();
+
+        this->server_position_         = Vector3::ZERO;
+        this->client_position_         = Vector3::ZERO;
+        this->server_linear_velocity_  = Vector3::ZERO;
+        this->client_linear_velocity_  = Vector3::ZERO;
+        this->server_orientation_      = Quaternion::IDENTITY;
+        this->client_orientation_      = Quaternion::IDENTITY;
+        this->server_angular_velocity_ = Vector3::ZERO;
+        this->client_angular_velocity_ = Vector3::ZERO;
+
+
+        this->setConfigValues();
+        this->setPriority( priority::very_high );
         this->registerVariables();
     }
@@ -74,6 +90,11 @@
         if (this->isInitialized())
         {
-            if (this->bControlled_)
-                this->stopLocalControl();
+            this->bDestroyWhenPlayerLeft_ = false;
+
+            if (this->bHasLocalController_ && this->bHasHumanController_)
+                this->stopLocalHumanControl();
+
+            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
+                this->getPlayer()->stopControl(this, false);
 
             if (this->hud_)
@@ -83,6 +104,9 @@
                 delete this->camera_;
 
-            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
-                this->getPlayer()->stopControl(this, false);
+            for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
+                delete (*it);
+
+            if (this->getScene()->getSceneManager())
+                this->getScene()->getSceneManager()->destroySceneNode(this->cameraPositionRootNode_->getName());
         }
     }
@@ -98,7 +122,30 @@
     }
 
+    void ControllableEntity::setConfigValues()
+    {
+        SetConfigValue(mouseLookSpeed_, 3.0f);
+    }
+
+    void ControllableEntity::changedGametype()
+    {
+        //SUPER(ControllableEntity, changedGametype);
+        WorldEntity::changedGametype();
+
+        this->gtinfo_ = 0;
+        this->gtinfoID_ = OBJECTID_UNKNOWN;
+
+        if (this->getGametype() && this->getGametype()->getGametypeInfo())
+        {
+            this->gtinfo_ = this->getGametype()->getGametypeInfo();
+            this->gtinfoID_ = this->gtinfo_->getObjectID();
+        }
+    }
+
     void ControllableEntity::addCameraPosition(CameraPosition* position)
     {
-        this->attach(position);
+        if (position->getAllowMouseLook())
+            position->attachToNode(this->cameraPositionRootNode_);
+        else
+            this->attach(position);
         this->cameraPositions_.push_back(position);
     }
@@ -141,7 +188,33 @@
             else
             {
-                this->attach(this->camera_);
+                this->camera_->attachToNode(this->cameraPositionRootNode_);
             }
         }
+    }
+
+    void ControllableEntity::mouseLook()
+    {
+        this->bMouseLook_ = !this->bMouseLook_;
+
+        if (!this->bMouseLook_)
+            this->cameraPositionRootNode_->setOrientation(Quaternion::IDENTITY);
+    }
+
+    void ControllableEntity::rotateYaw(const Vector2& value)
+    {
+        if (this->bMouseLook_)
+            this->cameraPositionRootNode_->yaw(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
+    }
+
+    void ControllableEntity::rotatePitch(const Vector2& value)
+    {
+        if (this->bMouseLook_)
+            this->cameraPositionRootNode_->pitch(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
+    }
+
+    void ControllableEntity::rotateRoll(const Vector2& value)
+    {
+        if (this->bMouseLook_)
+            this->cameraPositionRootNode_->roll(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
     }
 
@@ -156,14 +229,15 @@
         this->player_ = player;
         this->playerID_ = player->getObjectID();
-        this->bControlled_ = (player->isLocalPlayer() && player->isHumanPlayer());
-        if (this->bControlled_)
-        {
-            this->startLocalControl();
+        this->bHasLocalController_ = player->isLocalPlayer();
+        this->bHasHumanController_ = player->isHumanPlayer();
+
+        if (this->bHasLocalController_ && this->bHasHumanController_)
+        {
+            this->startLocalHumanControl();
 
             if (!Core::isMaster())
             {
                 this->client_overwrite_ = this->server_overwrite_;
-COUT(0) << "CE: bidirectional synchronization" << std::endl;
-                this->setObjectMode(direction::bidirectional);
+                this->setObjectMode(objectDirection::bidirectional);
             }
         }
@@ -172,11 +246,12 @@
     void ControllableEntity::removePlayer()
     {
-        if (this->bControlled_)
-            this->stopLocalControl();
+        if (this->bHasLocalController_ && this->bHasHumanController_)
+            this->stopLocalHumanControl();
 
         this->player_ = 0;
         this->playerID_ = OBJECTID_UNKNOWN;
-        this->bControlled_ = false;
-        this->setObjectMode(direction::toclient);
+        this->bHasLocalController_ = false;
+        this->bHasHumanController_ = false;
+        this->setObjectMode(objectDirection::toclient);
 
         if (this->bDestroyWhenPlayerLeft_)
@@ -195,52 +270,80 @@
     }
 
-    void ControllableEntity::startLocalControl()
-    {
-//        std::cout << this->getObjectID() << " ###### start local control" << std::endl;
-        this->camera_ = new Camera(this);
-        this->camera_->requestFocus();
-        if (this->cameraPositionTemplate_ != "")
-            this->addTemplate(this->cameraPositionTemplate_);
-        if (this->cameraPositions_.size() > 0)
-            this->cameraPositions_.front()->attachCamera(this->camera_);
-        else
-            this->attach(this->camera_);
-
-        if (this->hudtemplate_ != "")
-        {
-            this->hud_ = new OverlayGroup(this);
-            this->hud_->addTemplate(this->hudtemplate_);
-        }
-    }
-
-    void ControllableEntity::stopLocalControl()
-    {
-//        std::cout << "###### stop local control" << std::endl;
-        this->camera_->detachFromParent();
-        delete this->camera_;
-        this->camera_ = 0;
-
-        delete this->hud_;
-        this->hud_ = 0;
+    void ControllableEntity::networkcallback_changedgtinfoID()
+    {
+        if (this->gtinfoID_ != OBJECTID_UNKNOWN)
+        {
+            this->gtinfo_ = dynamic_cast<GametypeInfo*>(Synchronisable::getSynchronisable(this->gtinfoID_));
+
+            if (!this->gtinfo_)
+                this->gtinfoID_ = OBJECTID_UNKNOWN;
+        }
+    }
+
+    void ControllableEntity::startLocalHumanControl()
+    {
+        if (!this->camera_)
+        {
+            this->camera_ = new Camera(this);
+            this->camera_->requestFocus();
+            if (this->cameraPositionTemplate_ != "")
+                this->addTemplate(this->cameraPositionTemplate_);
+            if (this->cameraPositions_.size() > 0)
+                this->cameraPositions_.front()->attachCamera(this->camera_);
+            else
+                this->camera_->attachToNode(this->cameraPositionRootNode_);
+        }
+
+        if (!this->hud_)
+        {
+            if (this->hudtemplate_ != "")
+            {
+                this->hud_ = new OverlayGroup(this);
+                this->hud_->addTemplate(this->hudtemplate_);
+                this->hud_->setOwner(this);
+            }
+        }
+    }
+
+    void ControllableEntity::stopLocalHumanControl()
+    {
+        if (this->camera_)
+        {
+            this->camera_->detachFromParent();
+            delete this->camera_;
+            this->camera_ = 0;
+        }
+
+        if (this->hud_)
+        {
+            delete this->hud_;
+            this->hud_ = 0;
+        }
     }
 
     void ControllableEntity::tick(float dt)
     {
+        MobileEntity::tick(dt);
+
         if (this->isActive())
         {
-            this->velocity_ += (dt * this->acceleration_);
-            this->node_->translate(dt * this->velocity_, Ogre::Node::TS_LOCAL);
-
-            if (Core::isMaster())
+            // Check whether Bullet doesn't do the physics for us
+            if (!this->isDynamic())
             {
-                this->server_velocity_ = this->velocity_;
-                this->server_position_ = this->node_->getPosition();
+                if (Core::isMaster())
+                {
+                    this->server_position_ = this->getPosition();
+                    this->server_orientation_ = this->getOrientation();
+                    this->server_linear_velocity_ = this->getVelocity();
+                    this->server_angular_velocity_ = this->getAngularVelocity();
+                }
+                else if (this->bHasLocalController_)
+                {
+                    this->client_position_ = this->getPosition();
+                    this->client_orientation_ = this->getOrientation();
+                    this->client_linear_velocity_ = this->getVelocity();
+                    this->client_angular_velocity_ = this->getAngularVelocity();
+                }
             }
-            else if (this->bControlled_)
-            {
-//                COUT(2) << "setting client position" << endl;
-                this->client_velocity_ = this->velocity_;
-                this->client_position_ = this->node_->getPosition();
-            }
         }
     }
@@ -248,46 +351,56 @@
     void ControllableEntity::registerVariables()
     {
-        REGISTERSTRING(this->cameraPositionTemplate_, direction::toclient);
-
-        REGISTERDATA(this->client_overwrite_,   direction::toserver);
-        
-        REGISTERDATA(this->server_position_,    direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
-        REGISTERDATA(this->server_velocity_,    direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerVelocity));
-        REGISTERDATA(this->server_orientation_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
-        REGISTERDATA(this->server_overwrite_,   direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
-
-        REGISTERDATA(this->client_position_,    direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
-        REGISTERDATA(this->client_velocity_,    direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientVelocity));
-        REGISTERDATA(this->client_orientation_, direction::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
-
-
-        REGISTERDATA(this->playerID_, direction::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
+        registerVariable(this->cameraPositionTemplate_,  variableDirection::toclient);
+        registerVariable(this->hudtemplate_,             variableDirection::toclient);
+
+        registerVariable(this->server_position_,         variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
+        registerVariable(this->server_linear_velocity_,  variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerLinearVelocity));
+        registerVariable(this->server_orientation_,      variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
+        registerVariable(this->server_angular_velocity_, variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerAngularVelocity));
+
+        registerVariable(this->server_overwrite_,        variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
+        registerVariable(this->client_overwrite_,        variableDirection::toserver);
+
+        registerVariable(this->client_position_,         variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
+        registerVariable(this->client_linear_velocity_,  variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientLinearVelocity));
+        registerVariable(this->client_orientation_,      variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
+        registerVariable(this->client_angular_velocity_, variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientAngularVelocity));
+
+        registerVariable(this->playerID_,                variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
+        registerVariable(this->gtinfoID_,                variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedgtinfoID));
     }
 
     void ControllableEntity::processServerPosition()
     {
-        if (!this->bControlled_)
-            this->node_->setPosition(this->server_position_);
-    }
-
-    void ControllableEntity::processServerVelocity()
-    {
-        if (!this->bControlled_)
-            this->velocity_ = this->server_velocity_;
+        if (!this->bHasLocalController_)
+            MobileEntity::setPosition(this->server_position_);
+    }
+
+    void ControllableEntity::processServerLinearVelocity()
+    {
+        if (!this->bHasLocalController_)
+            MobileEntity::setVelocity(this->server_linear_velocity_);
     }
 
     void ControllableEntity::processServerOrientation()
     {
-        if (!this->bControlled_)
-            this->node_->setOrientation(this->server_orientation_);
+        if (!this->bHasLocalController_)
+            MobileEntity::setOrientation(this->server_orientation_);
+    }
+
+    void ControllableEntity::processServerAngularVelocity()
+    {
+        if (!this->bHasLocalController_)
+            MobileEntity::setAngularVelocity(this->server_angular_velocity_);
     }
 
     void ControllableEntity::processOverwrite()
     {
-        if (this->bControlled_)
+        if (this->bHasLocalController_)
         {
             this->setPosition(this->server_position_);
-            this->setVelocity(this->server_velocity_);
             this->setOrientation(this->server_orientation_);
+            this->setVelocity(this->server_linear_velocity_);
+            this->setAngularVelocity(this->server_angular_velocity_);
 
             this->client_overwrite_ = this->server_overwrite_;
@@ -299,18 +412,15 @@
         if (this->server_overwrite_ == this->client_overwrite_)
         {
-//            COUT(2) << "callback: setting client position" << endl;
-            this->node_->setPosition(this->client_position_);
-            this->server_position_ = this->client_position_;
-        }
-//        else
-//          COUT(2) << "callback: not setting client position" << endl;
-    }
-
-    void ControllableEntity::processClientVelocity()
+            MobileEntity::setPosition(this->client_position_);
+            this->server_position_ = this->getPosition();
+        }
+    }
+
+    void ControllableEntity::processClientLinearVelocity()
     {
         if (this->server_overwrite_ == this->client_overwrite_)
         {
-            this->velocity_ = this->client_velocity_;
-            this->server_velocity_ = this->client_velocity_;
+            MobileEntity::setVelocity(this->client_linear_velocity_);
+            this->server_linear_velocity_ = this->getVelocity();
         }
     }
@@ -320,9 +430,17 @@
         if (this->server_overwrite_ == this->client_overwrite_)
         {
-            this->node_->setOrientation(this->client_orientation_);
-            this->server_orientation_ = this->client_orientation_;
-        }
-    }
-
+            MobileEntity::setOrientation(this->client_orientation_);
+            this->server_orientation_ = this->getOrientation();
+        }
+    }
+
+    void ControllableEntity::processClientAngularVelocity()
+    {
+        if (this->server_overwrite_ == this->client_overwrite_)
+        {
+            MobileEntity::setAngularVelocity(this->client_angular_velocity_);
+            this->server_angular_velocity_ = this->getAngularVelocity();
+        }
+    }
 
     void ControllableEntity::setPosition(const Vector3& position)
@@ -330,12 +448,27 @@
         if (Core::isMaster())
         {
-            this->node_->setPosition(position);
-            this->server_position_ = position;
+            MobileEntity::setPosition(position);
+            this->server_position_ = this->getPosition();
             ++this->server_overwrite_;
         }
-        else if (this->bControlled_)
-        {
-            this->node_->setPosition(position);
-            this->client_position_ = position;
+        else if (this->bHasLocalController_)
+        {
+            MobileEntity::setPosition(position);
+            this->client_position_ = this->getPosition();
+        }
+    }
+
+    void ControllableEntity::setOrientation(const Quaternion& orientation)
+    {
+        if (Core::isMaster())
+        {
+            MobileEntity::setOrientation(orientation);
+            this->server_orientation_ = this->getOrientation();
+            ++this->server_overwrite_;
+        }
+        else if (this->bHasLocalController_)
+        {
+            MobileEntity::setOrientation(orientation);
+            this->client_orientation_ = this->getOrientation();
         }
     }
@@ -345,132 +478,46 @@
         if (Core::isMaster())
         {
-            this->velocity_ = velocity;
-            this->server_velocity_ = velocity;
+            MobileEntity::setVelocity(velocity);
+            this->server_linear_velocity_ = this->getVelocity();
             ++this->server_overwrite_;
         }
-        else if (this->bControlled_)
-        {
-            this->velocity_ = velocity;
-            this->client_velocity_ = velocity;
-        }
-    }
-
-    void ControllableEntity::translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo)
+        else if (this->bHasLocalController_)
+        {
+            MobileEntity::setVelocity(velocity);
+            this->client_linear_velocity_ = this->getVelocity();
+        }
+    }
+
+    void ControllableEntity::setAngularVelocity(const Vector3& velocity)
     {
         if (Core::isMaster())
         {
-            this->node_->translate(distance, relativeTo);
-            this->server_position_ = this->node_->getPosition();
+            MobileEntity::setAngularVelocity(velocity);
+            this->server_angular_velocity_ = this->getAngularVelocity();
             ++this->server_overwrite_;
         }
-        else if (this->bControlled_)
-        {
-            this->node_->translate(distance, relativeTo);
-            this->client_position_ = this->node_->getPosition();
-        }
-    }
-
-    void ControllableEntity::setOrientation(const Quaternion& orientation)
-    {
+        else if (this->bHasLocalController_)
+        {
+            MobileEntity::setAngularVelocity(velocity);
+            this->client_angular_velocity_ = this->getAngularVelocity();
+        }
+    }
+
+    void ControllableEntity::setWorldTransform(const btTransform& worldTrans)
+    {
+        MobileEntity::setWorldTransform(worldTrans);
         if (Core::isMaster())
         {
-            this->node_->setOrientation(orientation);
-            this->server_orientation_ = orientation;
-            ++this->server_overwrite_;
-        }
-        else if (this->bControlled_)
-        {
-            this->node_->setOrientation(orientation);
-            this->client_orientation_ = orientation;
-        }
-    }
-
-    void ControllableEntity::rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo)
-    {
-        if (Core::isMaster())
-        {
-            this->node_->rotate(rotation, relativeTo);
-            this->server_orientation_ = this->node_->getOrientation();
-            ++this->server_overwrite_;
-        }
-        else if (this->bControlled_)
-        {
-            this->node_->rotate(rotation, relativeTo);
-            this->client_orientation_ = this->node_->getOrientation();
-        }
-    }
-
-    void ControllableEntity::yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
-    {
-        if (Core::isMaster())
-        {
-            this->node_->yaw(angle, relativeTo);
-            this->server_orientation_ = this->node_->getOrientation();
-            ++this->server_overwrite_;
-        }
-        else if (this->bControlled_)
-        {
-            this->node_->yaw(angle, relativeTo);
-            this->client_orientation_ = this->node_->getOrientation();
-        }
-    }
-
-    void ControllableEntity::pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
-    {
-        if (Core::isMaster())
-        {
-            this->node_->pitch(angle, relativeTo);
-            this->server_orientation_ = this->node_->getOrientation();
-            ++this->server_overwrite_;
-        }
-        else if (this->bControlled_)
-        {
-            this->node_->pitch(angle, relativeTo);
-            this->client_orientation_ = this->node_->getOrientation();
-        }
-    }
-
-    void ControllableEntity::roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
-    {
-        if (Core::isMaster())
-        {
-            this->node_->roll(angle, relativeTo);
-            this->server_orientation_ = this->node_->getOrientation();
-            ++this->server_overwrite_;
-        }
-        else if (this->bControlled_)
-        {
-            this->node_->roll(angle, relativeTo);
-            this->client_orientation_ = this->node_->getOrientation();
-        }
-    }
-
-    void ControllableEntity::lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
-    {
-        if (Core::isMaster())
-        {
-            this->node_->lookAt(target, relativeTo, localDirectionVector);
-            this->server_orientation_ = this->node_->getOrientation();
-            ++this->server_overwrite_;
-        }
-        else if (this->bControlled_)
-        {
-            this->node_->lookAt(target, relativeTo, localDirectionVector);
-            this->client_orientation_ = this->node_->getOrientation();
-        }
-    }
-
-    void ControllableEntity::setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
-    {
-        if (Core::isMaster())
-        {
-            this->node_->setDirection(direction, relativeTo, localDirectionVector);
-            this->server_orientation_ = this->node_->getOrientation();
-            ++this->server_overwrite_;
-        }
-        else if (this->bControlled_)
-        {
-            this->node_->setDirection(direction, relativeTo, localDirectionVector);
-            this->client_orientation_ = this->node_->getOrientation();
+            this->server_position_ = this->getPosition();
+            this->server_orientation_ = this->getOrientation();
+            this->server_linear_velocity_ = this->getVelocity();
+            this->server_angular_velocity_ = this->getAngularVelocity();
+        }
+        else if (this->bHasLocalController_)
+        {
+            this->client_position_ = this->getPosition();
+            this->client_orientation_ = this->getOrientation();
+            this->client_linear_velocity_ = this->getVelocity();
+            this->client_angular_velocity_ = this->getAngularVelocity();
         }
     }
Index: code/trunk/src/orxonox/objects/worldentities/ControllableEntity.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/ControllableEntity.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/ControllableEntity.h	(revision 2662)
@@ -23,5 +23,5 @@
  *      Fabian 'x3n' Landau
  *   Co-authors:
- *      ...
+ *      Reto Grieder
  *
  */
@@ -32,10 +32,10 @@
 #include "OrxonoxPrereqs.h"
 
-#include "WorldEntity.h"
-#include "objects/Tickable.h"
+#include "MobileEntity.h"
+#include "objects/weaponSystem/WeaponSystem.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport ControllableEntity : public WorldEntity, public Tickable
+    class _OrxonoxExport ControllableEntity : public MobileEntity
     {
         public:
@@ -46,4 +46,7 @@
             virtual void tick(float dt);
             void registerVariables();
+            void setConfigValues();
+
+            virtual void changedGametype();
 
             virtual void setPlayer(PlayerInfo* player);
@@ -61,50 +64,34 @@
             virtual void moveUpDown(const Vector2& value) {}
 
-            virtual void rotateYaw(const Vector2& value) {}
-            virtual void rotatePitch(const Vector2& value) {}
-            virtual void rotateRoll(const Vector2& value) {}
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
 
-            virtual void fire() {}
-            virtual void altFire() {}
+            inline void moveFrontBack(float value)
+                { this->moveFrontBack(Vector2(value, 0)); }
+            inline void moveRightLeft(float value)
+                { this->moveRightLeft(Vector2(value, 0)); }
+            inline void moveUpDown(float value)
+                { this->moveUpDown(Vector2(value, 0)); }
 
+            inline void rotateYaw(float value)
+                { this->rotateYaw(Vector2(value, 0)); }
+            inline void rotatePitch(float value)
+                { this->rotatePitch(Vector2(value, 0)); }
+            inline void rotateRoll(float value)
+                { this->rotateRoll(Vector2(value, 0)); }
+
+            virtual void fire(WeaponMode::Enum fireMode) {}
+            virtual void altFire(WeaponMode::Enum fireMode) {}
+
+            virtual void boost() {}
             virtual void greet() {}
             virtual void use() {}
+            virtual void dropItems() {}
             virtual void switchCamera();
+            virtual void mouseLook();
 
-            inline const Vector3& getVelocity() const
-                { return this->velocity_; }
-            inline const Vector3& getAcceleration() const
-                { return this->acceleration_; }
             inline const std::string& getHudTemplate() const
                 { return this->hudtemplate_; }
-
-            using WorldEntity::setPosition;
-            using WorldEntity::translate;
-            using WorldEntity::setOrientation;
-            using WorldEntity::rotate;
-            using WorldEntity::yaw;
-            using WorldEntity::pitch;
-            using WorldEntity::roll;
-            using WorldEntity::lookAt;
-            using WorldEntity::setDirection;
-
-            void setPosition(const Vector3& position);
-            void translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void setOrientation(const Quaternion& orientation);
-            void rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z);
-            void setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z);
-
-            void setVelocity(const Vector3& velocity);
-            inline void setVelocity(float x, float y, float z)
-                { this->velocity_.x = x; this->velocity_.y = y; this->velocity_.z = z; }
-
-            inline void setAcceleration(const Vector3& acceleration)
-                { this->acceleration_ = acceleration; }
-            inline void setAcceleration(float x, float y, float z)
-                { this->acceleration_.x = x; this->acceleration_.y = y; this->acceleration_.z = z; }
 
             inline Camera* getCamera() const
@@ -123,15 +110,33 @@
                 { return this->cameraPositionTemplate_; }
 
+            using WorldEntity::setPosition;
+            using WorldEntity::setOrientation;
+            using MobileEntity::setVelocity;
+            using MobileEntity::setAngularVelocity;
+
+            void setPosition(const Vector3& position);
+            void setOrientation(const Quaternion& orientation);
+            void setVelocity(const Vector3& velocity);
+            void setAngularVelocity(const Vector3& velocity);
+
+            inline bool hasLocalController() const
+                { return this->bHasLocalController_; }
+            inline bool hasHumanController() const
+                { return this->bHasHumanController_; }
+
+            inline const GametypeInfo* getGametypeInfo() const
+                { return this->gtinfo_; }
+
+            inline bool isInMouseLook() const
+                { return this->bMouseLook_; }
+            inline float getMouseLookSpeed() const
+                { return this->mouseLookSpeed_; }
+
         protected:
-            virtual void startLocalControl();
-            virtual void stopLocalControl();
+            virtual void startLocalHumanControl();
+            virtual void stopLocalHumanControl();
 
             inline void setHudTemplate(const std::string& name)
                 { this->hudtemplate_ = name; }
-
-            inline bool isLocallyControlled() const
-                { return this->bControlled_; }
-
-            Vector3 acceleration_;
 
         private:
@@ -140,35 +145,50 @@
 
             void processServerPosition();
-            void processServerVelocity();
+            void processServerLinearVelocity();
             void processServerOrientation();
+            void processServerAngularVelocity();
 
             void processClientPosition();
-            void processClientVelocity();
+            void processClientLinearVelocity();
             void processClientOrientation();
+            void processClientAngularVelocity();
 
             void networkcallback_changedplayerID();
+            void networkcallback_changedgtinfoID();
+
+            // Bullet btMotionState related
+            void setWorldTransform(const btTransform& worldTrans);
 
             unsigned int server_overwrite_;
             unsigned int client_overwrite_;
 
-            Vector3 velocity_;
+            bool bHasLocalController_;
+            bool bHasHumanController_;
+            bool bDestroyWhenPlayerLeft_;
 
-            bool bControlled_;
             Vector3 server_position_;
             Vector3 client_position_;
-            Vector3 server_velocity_;
-            Vector3 client_velocity_;
+            Vector3 server_linear_velocity_;
+            Vector3 client_linear_velocity_;
             Quaternion server_orientation_;
             Quaternion client_orientation_;
+            Vector3 server_angular_velocity_;
+            Vector3 client_angular_velocity_;
 
             PlayerInfo* player_;
             unsigned int playerID_;
+
             std::string hudtemplate_;
             OverlayGroup* hud_;
+
             Camera* camera_;
-            bool bDestroyWhenPlayerLeft_;
-
+            bool bMouseLook_;
+            float mouseLookSpeed_;
+            Ogre::SceneNode* cameraPositionRootNode_;
             std::list<CameraPosition*> cameraPositions_;
             std::string cameraPositionTemplate_;
+
+            const GametypeInfo* gtinfo_;
+            unsigned int gtinfoID_;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/ExplosionChunk.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/ExplosionChunk.cc	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/ExplosionChunk.cc	(revision 2662)
@@ -0,0 +1,160 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "ExplosionChunk.h"
+
+#include <OgreParticleSystem.h>
+
+#include "core/Core.h"
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "objects/Scene.h"
+#include "tools/ParticleInterface.h"
+#include "util/Exception.h"
+
+namespace orxonox
+{
+    CreateFactory(ExplosionChunk);
+
+    ExplosionChunk::ExplosionChunk(BaseObject* creator) : MovableEntity(creator)
+    {
+        RegisterObject(ExplosionChunk);
+
+        if (!this->getScene() || !Core::showsGraphics() || !this->getScene()->getSceneManager())
+            ThrowException(AbortLoading, "Can't create ExplosionChunk, no scene or no scene manager given.");
+
+        this->bStop_ = false;
+        this->LOD_ = LODParticle::normal;
+
+        try
+        {
+            this->fire_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
+            this->attachOgreObject(this->fire_->getParticleSystem());
+            this->smoke_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
+            this->attachOgreObject(this->smoke_->getParticleSystem());
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Couln't load particle effect in ExplosionChunk." << std::endl;
+            this->fire_ = 0;
+            this->smoke_ = 0;
+        }
+
+        if (Core::isMaster())
+        {
+            Vector3 velocity(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1));
+            velocity.normalise();
+            velocity *= rnd(60, 80);
+            this->setVelocity(velocity);
+
+            this->destroyTimer_.setTimer(rnd(1, 2), false, this, createExecutor(createFunctor(&ExplosionChunk::stop)));
+        }
+
+        this->registerVariables();
+    }
+
+    ExplosionChunk::~ExplosionChunk()
+    {
+        if (this->isInitialized())
+        {
+            if (this->fire_)
+            {
+                this->detachOgreObject(this->fire_->getParticleSystem());
+                delete this->fire_;
+            }
+            if (this->smoke_)
+            {
+                this->detachOgreObject(this->smoke_->getParticleSystem());
+                delete this->smoke_;
+            }
+        }
+    }
+
+    void ExplosionChunk::registerVariables()
+    {
+        registerVariable((int&)(this->LOD_), variableDirection::toclient, new NetworkCallback<ExplosionChunk>(this, &ExplosionChunk::LODchanged));
+        registerVariable(this->bStop_,       variableDirection::toclient, new NetworkCallback<ExplosionChunk>(this, &ExplosionChunk::checkStop));
+    }
+
+    void ExplosionChunk::LODchanged()
+    {
+        if (this->fire_)
+            this->fire_->setDetailLevel(this->LOD_);
+        if (this->smoke_)
+            this->smoke_->setDetailLevel(this->LOD_);
+    }
+
+    void ExplosionChunk::checkStop()
+    {
+        if (this->bStop_)
+            this->stop();
+    }
+
+    void ExplosionChunk::stop()
+    {
+        if (this->fire_)
+            this->fire_->setEnabled(false);
+        if (this->smoke_)
+            this->smoke_->setEnabled(false);
+
+        if (Core::isMaster())
+        {
+            this->bStop_ = true;
+            this->destroyTimer_.setTimer(1.0f, false, this, createExecutor(createFunctor(&ExplosionChunk::destroy)));
+        }
+    }
+
+    void ExplosionChunk::destroy()
+    {
+        delete this;
+    }
+
+    void ExplosionChunk::tick(float dt)
+    {
+        static const unsigned int CHANGES_PER_SECOND = 5;
+
+        if (Core::isMaster() && rnd() < dt*CHANGES_PER_SECOND)
+        {
+            float length = this->getVelocity().length();
+
+            Vector3 change(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1));
+            change.normalise();
+            change *= rnd(0.4, 0.8);
+            Vector3 velocity = this->getVelocity();
+            velocity.normalise();
+            velocity += change;
+            velocity.normalise();
+            velocity *= length * rnd(0.8, 1.0);
+
+            this->setVelocity(velocity);
+        }
+
+        SUPER(ExplosionChunk, tick, dt);
+    }
+}
Index: code/trunk/src/orxonox/objects/worldentities/ExplosionChunk.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/ExplosionChunk.h	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/ExplosionChunk.h	(revision 2662)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ExplosionChunk_H__
+#define _ExplosionChunk_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "MovableEntity.h"
+#include "tools/Timer.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport ExplosionChunk : public MovableEntity
+    {
+        public:
+            ExplosionChunk(BaseObject* creator);
+            virtual ~ExplosionChunk();
+
+            virtual void tick(float dt);
+            void registerVariables();
+
+            inline void setLOD(LODParticle::LOD level)
+                { this->LOD_ = level; this->LODchanged(); }
+            inline LODParticle::LOD getLOD() const
+                { return this->LOD_; }
+
+        private:
+            void LODchanged();
+            void checkStop();
+            void stop();
+            void destroy();
+
+            bool                  bStop_;
+            ParticleInterface*    fire_;
+            ParticleInterface*    smoke_;
+            LODParticle::LOD      LOD_;
+            Timer<ExplosionChunk> destroyTimer_;
+    };
+}
+
+#endif /* _ExplosionChunk_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/FadingBillboard.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/FadingBillboard.cc	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/FadingBillboard.cc	(revision 2662)
@@ -0,0 +1,165 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "FadingBillboard.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(FadingBillboard);
+
+    FadingBillboard::FadingBillboard(BaseObject* creator) : Billboard(creator)
+    {
+        RegisterObject(FadingBillboard);
+
+        this->turnontime_ = 0.0f;
+        this->turnofftime_ = 0.0f;
+        this->postprocessingtime_ = 0.0f;
+        this->changedirection_ = 0;
+
+        this->fadedColour_ = ColourValue::White;
+
+        this->registerVariables();
+    }
+
+    FadingBillboard::~FadingBillboard()
+    {
+    }
+
+    void FadingBillboard::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(FadingBillboard, XMLPort, xmlelement, mode);
+
+        XMLPortParam(FadingBillboard, "turnontime",  setTurnOnTime,  getTurnOnTime,  xmlelement, mode).defaultValues(0.5f);
+        XMLPortParam(FadingBillboard, "turnofftime", setTurnOffTime, getTurnOffTime, xmlelement, mode).defaultValues(0.5f);
+    }
+
+    void FadingBillboard::registerVariables()
+    {
+        registerVariable(this->turnontime_,  variableDirection::toclient);
+        registerVariable(this->turnofftime_, variableDirection::toclient);
+    }
+
+    void FadingBillboard::changedColour()
+    {
+        Billboard::changedColour();
+
+        if (this->isActive())
+            this->fadedColour_ = this->getColour();
+        else
+            this->fadedColour_ = ColourValue::ZERO;
+
+        this->getBillboardSet().setColour(this->fadedColour_);
+    }
+
+    void FadingBillboard::changedActivity()
+    {
+        SUPER(FadingBillboard, changedActivity);
+
+        this->startturnonoff();
+    }
+
+    void FadingBillboard::changedVisibility()
+    {
+        SUPER(FadingBillboard, changedVisibility);
+
+        if (this->isVisible() && !this->isActive() && this->changedirection_ == 0)
+        {
+            // Billboard shouldn't be visible
+            this->getBillboardSet().setVisible(false);
+        }
+    }
+
+    void FadingBillboard::startturnonoff()
+    {
+        if (this->isActive())
+        {
+            this->changedirection_ = 1;
+            this->turnonofftimer_.setTimer(this->turnontime_, false, this, createExecutor(createFunctor(&FadingBillboard::stopturnonoff)));
+
+            if (this->isVisible())
+                this->getBillboardSet().setVisible(true);
+        }
+        else
+        {
+            this->changedirection_ = -1;
+            this->turnonofftimer_.setTimer(this->turnofftime_, false, this, createExecutor(createFunctor(&FadingBillboard::stopturnonoff)));
+        }
+    }
+
+    void FadingBillboard::stopturnonoff()
+    {
+        if (this->changedirection_ > 0)
+        {
+            this->fadedColour_ = this->getColour();
+            this->getBillboardSet().setColour(this->fadedColour_);
+        }
+        else if (this->changedirection_ < 0)
+        {
+            this->fadedColour_ = ColourValue::ZERO;
+            this->getBillboardSet().setColour(this->fadedColour_);
+            this->turnonofftimer_.setTimer(this->postprocessingtime_, false, this, createExecutor(createFunctor(&FadingBillboard::poststopturnonoff)));
+        }
+        this->changedirection_ = 0;
+    }
+
+    void FadingBillboard::poststopturnonoff()
+    {
+        this->getBillboardSet().setVisible(false);
+    }
+
+    void FadingBillboard::tick(float dt)
+    {
+        SUPER(FadingBillboard, tick, dt);
+
+        if (this->changedirection_ > 0 && (this->fadedColour_.a < this->getColour().a))
+        {
+            ColourValue colour = this->fadedColour_ + this->getColour() / this->turnontime_ * dt;
+
+            if (colour.a < this->getColour().a)
+            {
+                this->fadedColour_ = colour;
+                this->getBillboardSet().setColour(this->fadedColour_);
+            }
+        }
+        else if (this->changedirection_ < 0 && (this->fadedColour_.a > 0))
+        {
+            ColourValue colour = this->fadedColour_ - this->getColour() / this->turnofftime_ * dt;
+
+            if (colour.a > 0)
+            {
+                this->fadedColour_ = colour;
+                this->getBillboardSet().setColour(this->fadedColour_);
+            }
+        }
+    }
+}
Index: code/trunk/src/orxonox/objects/worldentities/FadingBillboard.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/FadingBillboard.h	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/FadingBillboard.h	(revision 2662)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FadingBillboard_H__
+#define _FadingBillboard_H__
+
+#include "OrxonoxPrereqs.h"
+#include "Billboard.h"
+#include "objects/Tickable.h"
+#include "tools/Timer.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport FadingBillboard : public Billboard, public Tickable
+    {
+        public:
+            FadingBillboard(BaseObject* creator);
+            virtual ~FadingBillboard();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void tick(float dt);
+            virtual void changedActivity();
+            virtual void changedVisibility();
+
+            inline void setTurnOnTime(float turnontime)
+                { this->turnontime_ = turnontime; }
+            inline float getTurnOnTime() const
+                { return this->turnontime_; }
+
+            inline void setTurnOffTime(float turnofftime)
+                { this->turnofftime_ = turnofftime; }
+            inline float getTurnOffTime() const
+                { return this->turnofftime_; }
+
+            inline const ColourValue& getFadedColour() const
+                { return this->fadedColour_; }
+
+        protected:
+            virtual void startturnonoff();
+            virtual void stopturnonoff();
+            virtual void poststopturnonoff();
+            virtual void changedColour();
+
+            float turnontime_;
+            float turnofftime_;
+            float postprocessingtime_;
+            Timer<FadingBillboard> turnonofftimer_;
+            char changedirection_;
+            ColourValue fadedColour_;
+    };
+}
+
+#endif /* _FadingBillboard_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/Light.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Light.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Light.cc	(revision 2662)
@@ -36,5 +36,6 @@
 
 #include "util/String.h"
-#include "util/Convert.h"
+#include "util/Exception.h"
+#include "core/Core.h"
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
@@ -43,15 +44,37 @@
 namespace orxonox
 {
-    unsigned int Light::lightCounter_s = 0;
-
     CreateFactory(Light);
 
-    Light::Light(BaseObject* creator) : PositionableEntity(creator)
+    Light::Light(BaseObject* creator) : StaticEntity(creator)
     {
         RegisterObject(Light);
 
-        if (this->getScene() && this->getScene()->getSceneManager())
-        this->light_ = this->getScene()->getSceneManager()->createLight("Light" + convertToString(Light::lightCounter_s++));
-        this->getNode()->attachObject(this->light_);
+        this->light_ = 0;
+        this->diffuse_ = ColourValue::White;
+        this->specular_ = ColourValue::White;
+        this->type_ = Ogre::Light::LT_POINT;
+        this->attenuation_ = Vector4(100000, 1, 0, 0);
+        this->spotlightRange_ = Vector3(40.0f, 30.0f, 1.0f);
+
+        if (Core::showsGraphics())
+        {
+            if (!this->getScene())
+                ThrowException(AbortLoading, "Can't create Light, no scene given.");
+            if (!this->getScene()->getSceneManager())
+                ThrowException(AbortLoading, "Can't create Light, no scene manager given.");
+
+            if (this->getScene() && this->getScene()->getSceneManager())
+            {
+                this->light_ = this->getScene()->getSceneManager()->createLight("Light" + getUniqueNumberString());
+                this->light_->setDirection(WorldEntity::FRONT);
+                this->attachOgreObject(this->light_);
+
+                this->updateType();
+                this->updateDiffuseColour();
+                this->updateSpecularColour();
+                this->updateAttenuation();
+                this->updateSpotlightRange();
+            }
+        }
 
         this->registerVariables();
@@ -71,66 +94,42 @@
         SUPER(Light, XMLPort, xmlelement, mode);
 
-        XMLPortParam(Light, "type", setTypeString, getTypeString, xmlelement, mode).defaultValues("point");
-        XMLPortParamExternTemplate(Light, Ogre::Light, this->light_, "diffuse",   setDiffuseColour,  getDiffuseColour,  xmlelement, mode, const ColourValue&);
-        XMLPortParamExternTemplate(Light, Ogre::Light, this->light_, "specular",  setSpecularColour, getSpecularColour, xmlelement, mode, const ColourValue&);
-        XMLPortParamExternTemplate(Light, Ogre::Light, this->light_, "direction", setDirection,      getDirection,      xmlelement, mode, const Vector3&);
+        XMLPortParam(Light, "type",           setTypeString,     getTypeString,     xmlelement, mode).defaultValues("point");
+        XMLPortParam(Light, "diffuse",        setDiffuseColour,  getDiffuseColour,  xmlelement, mode).defaultValues(ColourValue::White);
+        XMLPortParam(Light, "specular",       setSpecularColour, getSpecularColour, xmlelement, mode).defaultValues(ColourValue::White);
+        XMLPortParam(Light, "attenuation",    setAttenuation,    getAttenuation,    xmlelement, mode).defaultValues(Vector4(100000, 1, 0, 0));
+        XMLPortParam(Light, "spotlightrange", setSpotlightRange, getSpotlightRange, xmlelement, mode).defaultValues(Vector3(40.0f, 30.0f, 1.0f));
     }
 
     void Light::registerVariables()
     {
-        REGISTERDATA(this->type_, direction::toclient, new NetworkCallback<Light>(this, &Light::changedType));
-        REGISTERDATA(this->light_->getDiffuseColour(), direction::toclient);
-        REGISTERDATA(this->light_->getSpecularColour(), direction::toclient);
-        REGISTERDATA(this->light_->getDirection(), direction::toclient);
+        registerVariable((int&)this->type_,     variableDirection::toclient, new NetworkCallback<Light>(this, &Light::updateType));
+        registerVariable(this->diffuse_,        variableDirection::toclient, new NetworkCallback<Light>(this, &Light::updateDiffuseColour));
+        registerVariable(this->specular_,       variableDirection::toclient, new NetworkCallback<Light>(this, &Light::updateSpecularColour));
+        registerVariable(this->attenuation_,    variableDirection::toclient, new NetworkCallback<Light>(this, &Light::updateAttenuation));
+        registerVariable(this->spotlightRange_, variableDirection::toclient, new NetworkCallback<Light>(this, &Light::updateSpotlightRange));
     }
 
-    const std::string& Light::getName() const
+    void Light::updateDiffuseColour()
     {
         if (this->light_)
-            return this->light_->getName();
-        else
-            return BLANKSTRING;
+            this->light_->setDiffuseColour(this->diffuse_);
     }
 
-    void Light::setDiffuseColour(const ColourValue& colour)
+    void Light::updateSpecularColour()
     {
         if (this->light_)
-            this->light_->setDiffuseColour(colour);
+            this->light_->setSpecularColour(this->specular_);
     }
 
-    const ColourValue& Light::getDiffuseColour() const
+    void Light::updateAttenuation()
     {
-        if (this->light_)
-            return this->light_->getDiffuseColour();
-        else
-            return ColourValue::White;
+        if (this->light_ && this->type_ != Ogre::Light::LT_DIRECTIONAL)
+            this->light_->setAttenuation(this->attenuation_.x, this->attenuation_.y, this->attenuation_.z, this->attenuation_.w);
     }
 
-    void Light::setSpecularColour(const ColourValue& colour)
+    void Light::updateSpotlightRange()
     {
-        if (this->light_)
-            this->light_->setSpecularColour(colour);
-    }
-
-    const ColourValue& Light::getSpecularColour() const
-    {
-        if (this->light_)
-            return this->light_->getSpecularColour();
-        else
-            return ColourValue::White;
-    }
-
-    void Light::setDirection(const Vector3& direction)
-    {
-        if (this->light_)
-            this->light_->setDirection(direction);
-    }
-
-    const Vector3& Light::getDirection() const
-    {
-        if (this->light_)
-            return this->light_->getDirection();
-        else
-            return Vector3::ZERO;
+        if (this->light_ && this->type_ == Ogre::Light::LT_SPOTLIGHT)
+            this->light_->setSpotlightRange(Degree(this->spotlightRange_.x), Degree(this->spotlightRange_.y), this->spotlightRange_.z);
     }
 
@@ -157,11 +156,19 @@
             case Ogre::Light::LT_POINT:
             default:
-                return "poinT";
+                return "point";
         }
     }
 
-    void Light::changedType()
+    void Light::updateType()
     {
-        this->light_->setType(this->type_);
+        if (this->light_)
+        {
+            this->light_->setType(this->type_);
+
+            if (this->type_ != Ogre::Light::LT_DIRECTIONAL)
+                this->updateAttenuation();
+            if (this->type_ == Ogre::Light::LT_SPOTLIGHT)
+                this->updateSpotlightRange();
+        }
     }
 
@@ -170,5 +177,6 @@
         SUPER(Light, changedVisibility);
 
-        this->light_->setVisible(this->isVisible());
+        if (this->light_)
+            this->light_->setVisible(this->isVisible());
     }
 }
Index: code/trunk/src/orxonox/objects/worldentities/Light.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Light.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Light.h	(revision 2662)
@@ -31,5 +31,5 @@
 
 #include "OrxonoxPrereqs.h"
-#include "PositionableEntity.h"
+#include "StaticEntity.h"
 
 #include <string>
@@ -40,5 +40,5 @@
 namespace orxonox
 {
-    class _OrxonoxExport Light : public PositionableEntity
+    class _OrxonoxExport Light : public StaticEntity
     {
         public:
@@ -54,19 +54,67 @@
                 { return this->light_; }
 
-            const std::string& getName() const;
-
             inline void setType(Ogre::Light::LightTypes type)
-                { this->type_ = type; this->changedType(); }
-            Ogre::Light::LightTypes getType() const
+                { this->type_ = type; this->updateType(); }
+            inline Ogre::Light::LightTypes getType() const
                 { return this->type_; }
 
-            void setDiffuseColour(const ColourValue& colour);
-            const ColourValue& getDiffuseColour() const;
+            inline void setDiffuseColour(const ColourValue& colour)
+                { this->diffuse_ = colour; this->updateDiffuseColour(); }
+            inline const ColourValue& getDiffuseColour() const
+                { return this->diffuse_; }
 
-            void setSpecularColour(const ColourValue& colour);
-            const ColourValue& getSpecularColour() const;
+            inline void setSpecularColour(const ColourValue& colour)
+                { this->specular_ = colour; this->updateSpecularColour(); }
+            inline const ColourValue& getSpecularColour() const
+                { return this->specular_; }
 
-            void setDirection(const Vector3& direction);
-            const Vector3& getDirection() const;
+            /**
+                @brief Sets the attenuation parameters of the light source i.e. how it diminishes with distance.
+
+                @param attenuation.x range (The absolute upper range of the light in world units)
+                @param attenuation.y constant (The constant factor in the attenuation formula: 1.0 means never attenuate, 0.0 is complete attenuation)
+                @param attenuation.z linear (The linear factor in the attenuation formula: 1 means attenuate evenly over the distance)
+                @param attenuation.w quadratic (The quadratic factor in the attenuation formula: adds a curvature to the attenuation formula)
+
+                Quote from the Ogre API:
+                Lights normally get fainter the further they are away. Also, each light is given a maximum range beyond which it cannot affect any objects.
+                Light attenuation is not applicable to directional lights since they have an infinite range and constant intensity.
+                This follows a standard attenuation approach - see any good 3D text for the details of what they mean since i don't have room here!
+
+                Quote from the Ogre wiki:
+                "Using these numbers, the light has 100% intensity at 0 distance, and
+                trails off to near black at a distance equal to the Range. Keep in mind
+                that most of the light falls in the first 20% of the range."
+
+                Range   Constant   Linear     Quadratic
+                3250,     1.0,     0.0014,    0.000007
+                600,      1.0,     0.007,     0.0002
+                325,      1.0,     0.014,     0.0007
+                200,      1.0,     0.022,     0.0019
+                160,      1.0,     0.027,     0.0028
+                100,      1.0,     0.045,     0.0075
+                65,       1.0,     0.07,      0.017
+                50,       1.0,     0.09,      0.032
+                32,       1.0,     0.14,      0.07
+                20,       1.0,     0.22,      0.20
+                13,       1.0,     0.35,      0.44
+                7,        1.0,     0.7,       1.8
+            */
+            inline void setAttenuation(const Vector4& attenuation)
+                { this->attenuation_ = attenuation; this->updateAttenuation(); }
+            inline const Vector4& getAttenuation() const
+                { return this->attenuation_; }
+
+            /**
+                @brief Sets the range of a spotlight, i.e. the angle of the inner and outer cones and the rate of falloff between them.
+
+                @param spotlightRange.x innerAngle (The angle covered by the bright inner cone)
+                @param spotlightRange.x outerAngle (The angle covered by the outer cone)
+                @param spotlightRange.x falloff (The rate of falloff between the inner and outer cones. 1.0 means a linear falloff, less means slower falloff, higher means faster falloff.)
+            */
+            inline void setSpotlightRange(const Vector3& spotlightRange)
+                { this->spotlightRange_ = spotlightRange; this->updateSpotlightRange(); }
+            inline const Vector3& getSpotlightRange() const
+                { return this->spotlightRange_; }
 
         private:
@@ -74,10 +122,16 @@
             std::string getTypeString() const;
 
-            void changedType();
+            void updateType();
+            void updateDiffuseColour();
+            void updateSpecularColour();
+            void updateAttenuation();
+            void updateSpotlightRange();
 
-            static unsigned int lightCounter_s;
             Ogre::Light* light_;
             Ogre::Light::LightTypes type_;
-
+            ColourValue diffuse_;
+            ColourValue specular_;
+            Vector4 attenuation_;
+            Vector3 spotlightRange_;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/MobileEntity.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/MobileEntity.cc	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/MobileEntity.cc	(revision 2662)
@@ -0,0 +1,206 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      Martin Stypinski
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "MobileEntity.h"
+
+#include <OgreSceneNode.h>
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
+#include "util/Debug.h"
+#include "util/MathConvert.h"
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+#include "objects/Scene.h"
+
+namespace orxonox
+{
+    MobileEntity::MobileEntity(BaseObject* creator) : WorldEntity(creator)
+    {
+        RegisterObject(MobileEntity);
+
+        this->linearAcceleration_  = Vector3::ZERO;
+        this->linearVelocity_      = Vector3::ZERO;
+        this->angularAcceleration_ = Vector3::ZERO;
+        this->angularVelocity_     = Vector3::ZERO;
+
+        this->registerVariables();
+    }
+
+    MobileEntity::~MobileEntity()
+    {
+    }
+
+    void MobileEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(MobileEntity, XMLPort, xmlelement, mode);
+
+        XMLPortParamTemplate(MobileEntity, "velocity",     setVelocity,     getVelocity,     xmlelement, mode, const Vector3&);
+
+        Vector3 rotationAxis(this->getRotationAxis());
+        Degree rotationRate = this->getRotationRate();
+        XMLPortParamVariable(MobileEntity, "rotationaxis", rotationAxis, xmlelement, mode);
+        XMLPortParamVariable(MobileEntity, "rotationrate", rotationRate, xmlelement, mode);
+        if (mode == XMLPort::LoadObject)
+        {
+            if (rotationAxis == Vector3::ZERO)
+                this->setAngularVelocity(Vector3::ZERO);
+            else
+                this->setAngularVelocity(rotationAxis.normalisedCopy() * rotationRate.valueRadians());
+        }
+    }
+
+    void MobileEntity::tick(float dt)
+    {
+        if (this->isActive())
+        {
+            // Check whether Bullet doesn't do the physics for us
+            if (!this->isDynamic())
+            {
+                // Linear part
+                this->linearVelocity_.x += this->linearAcceleration_.x * dt;
+                this->linearVelocity_.y += this->linearAcceleration_.y * dt;
+                this->linearVelocity_.z += this->linearAcceleration_.z * dt;
+                this->node_->translate(this->linearVelocity_ * dt);
+
+                // Angular part
+                // Note: angularVelocity_ is a Quaternion with w = 0 while angularAcceleration_ is a Vector3
+                this->angularVelocity_.x += angularAcceleration_.x * dt;
+                this->angularVelocity_.y += angularAcceleration_.y * dt;
+                this->angularVelocity_.z += angularAcceleration_.z * dt;
+                // Calculate new orientation with quaternion derivative. This is about 30% faster than with angle/axis method.
+                float mult = dt * 0.5;
+                // TODO: this could be optimized by writing it out. The calls currently create 4 new Quaternions!
+                Quaternion newOrientation(0.0f, this->angularVelocity_.x * mult, this->angularVelocity_.y * mult, this->angularVelocity_.z * mult);
+                newOrientation = this->node_->getOrientation() + newOrientation * this->node_->getOrientation();
+                newOrientation.normalise();
+                this->node_->setOrientation(newOrientation);
+            }
+        }
+    }
+
+    void MobileEntity::setPosition(const Vector3& position)
+    {
+        if (this->isDynamic())
+        {
+            btTransform transf = this->physicalBody_->getWorldTransform();
+            transf.setOrigin(btVector3(position.x, position.y, position.z));
+            this->physicalBody_->setWorldTransform(transf);
+        }
+
+        this->node_->setPosition(position);
+    }
+
+    void MobileEntity::setOrientation(const Quaternion& orientation)
+    {
+        if (this->isDynamic())
+        {
+            btTransform transf = this->physicalBody_->getWorldTransform();
+            transf.setRotation(btQuaternion(orientation.x, orientation.y, orientation.z, orientation.w));
+            this->physicalBody_->setWorldTransform(transf);
+        }
+
+        this->node_->setOrientation(orientation);
+    }
+
+    void MobileEntity::setVelocity(const Vector3& velocity)
+    {
+        if (this->isDynamic())
+            this->physicalBody_->setLinearVelocity(btVector3(velocity.x, velocity.y, velocity.z));
+
+        this->linearVelocity_ = velocity;
+    }
+
+    void MobileEntity::setAngularVelocity(const Vector3& velocity)
+    {
+        if (this->isDynamic())
+            this->physicalBody_->setAngularVelocity(btVector3(velocity.x, velocity.y, velocity.z));
+
+        this->angularVelocity_ = velocity;
+    }
+
+    void MobileEntity::setAcceleration(const Vector3& acceleration)
+    {
+        if (this->isDynamic())
+            this->physicalBody_->applyCentralForce(btVector3(acceleration.x * this->getMass(), acceleration.y * this->getMass(), acceleration.z * this->getMass()));
+
+        this->linearAcceleration_ = acceleration;
+    }
+
+    void MobileEntity::setAngularAcceleration(const Vector3& acceleration)
+    {
+        if (this->isDynamic())
+        {
+            btVector3 inertia(btVector3(1, 1, 1) / this->physicalBody_->getInvInertiaDiagLocal());
+            this->physicalBody_->applyTorque(btVector3(acceleration.x, acceleration.y, acceleration.z) * inertia);
+        }
+
+        this->angularAcceleration_ = acceleration;
+    }
+
+    bool MobileEntity::isCollisionTypeLegal(WorldEntity::CollisionType type) const
+    {
+        if (type == WorldEntity::Static)
+        {
+            CCOUT(1) << "Error: Cannot tell a MobileEntity to have static collision type! Ignoring." << std::endl;
+            assert(false); // Only in debug mode
+            return false;
+        }
+        else
+            return true;
+    }
+
+    void MobileEntity::setWorldTransform(const btTransform& worldTrans)
+    {
+        // We use a dynamic body. So we translate our node accordingly.
+        this->node_->setPosition(Vector3(worldTrans.getOrigin().x(), worldTrans.getOrigin().y(), worldTrans.getOrigin().z()));
+        this->node_->setOrientation(Quaternion(worldTrans.getRotation().w(), worldTrans.getRotation().x(), worldTrans.getRotation().y(), worldTrans.getRotation().z()));
+        this->linearVelocity_.x = this->physicalBody_->getLinearVelocity().x();
+        this->linearVelocity_.y = this->physicalBody_->getLinearVelocity().y();
+        this->linearVelocity_.z = this->physicalBody_->getLinearVelocity().z();
+        this->angularVelocity_.x = this->physicalBody_->getAngularVelocity().x();
+        this->angularVelocity_.y = this->physicalBody_->getAngularVelocity().y();
+        this->angularVelocity_.z = this->physicalBody_->getAngularVelocity().z();
+    }
+
+    void MobileEntity::getWorldTransform(btTransform& worldTrans) const
+    {
+        // We use a kinematic body
+        worldTrans.setOrigin(btVector3(node_->getPosition().x, node_->getPosition().y, node_->getPosition().z));
+        worldTrans.setRotation(btQuaternion(node_->getOrientation().x, node_->getOrientation().y, node_->getOrientation().z, node_->getOrientation().w));
+        if (this->isDynamic())
+        {
+            // This function gets called only once for dynamic objects to set the initial conditions
+            // We have to set the velocities too.
+            this->physicalBody_->setLinearVelocity(btVector3(linearVelocity_.x, linearVelocity_.y, linearVelocity_.z));
+            this->physicalBody_->setAngularVelocity(btVector3(angularVelocity_.x, angularVelocity_.y, angularVelocity_.z));
+        }
+    }
+}
Index: code/trunk/src/orxonox/objects/worldentities/MobileEntity.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/MobileEntity.h	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/MobileEntity.h	(revision 2662)
@@ -0,0 +1,102 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      Martin Stypinski
+ *
+ */
+
+#ifndef _MobileEntity_H__
+#define _MobileEntity_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "WorldEntity.h"
+#include "objects/Tickable.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport MobileEntity : public WorldEntity, public Tickable
+    {
+        public:
+            MobileEntity(BaseObject* creator);
+            virtual ~MobileEntity();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+
+            virtual void setPosition(const Vector3& position);
+            virtual void setOrientation(const Quaternion& orientation);
+
+            virtual void setVelocity(const Vector3& velocity);
+            inline void setVelocity(float x, float y, float z)
+                { this->setVelocity(Vector3(x, y, z)); }
+            inline const Vector3& getVelocity() const
+                { return this->linearVelocity_; }
+            inline Vector3 getLocalVelocity() const
+                { return (this->getOrientation().Inverse() * this->getVelocity()); }
+
+            virtual void setAngularVelocity(const Vector3& velocity);
+            inline void setAngularVelocity(float x, float y, float z)
+                { this->setAngularVelocity(Vector3(x, y, z)); }
+            inline const Vector3& getAngularVelocity() const
+                { return this->linearAcceleration_; }
+
+            void setAcceleration(const Vector3& acceleration);
+            inline void setAcceleration(float x, float y, float z)
+                { this->setAcceleration(Vector3(x, y, z)); }
+            inline const Vector3& getAcceleration() const
+                { return this->linearAcceleration_; }
+
+            void setAngularAcceleration(const Vector3& acceleration);
+            inline void setAngularAcceleration(float x, float y, float z)
+                { this->setAngularAcceleration(Vector3(x, y, z)); }
+            inline const Vector3& getAngularAcceleration() const
+                { return this->angularAcceleration_; }
+
+            inline void setRotationRate(Degree rate)
+                { this->setAngularVelocity(this->getAngularVelocity().normalisedCopy() * rate.valueRadians()); }
+            inline Degree getRotationRate() const
+                { return Degree(this->getAngularVelocity().length()); }
+
+            inline void setRotationAxis(const Vector3& axis)
+                { this->setAngularVelocity(axis * this->getAngularVelocity().length()); }
+            inline Vector3 getRotationAxis() const
+                { return this->getAngularVelocity().normalisedCopy(); }
+
+        protected:
+            // Bullet btMotionState related
+            virtual void setWorldTransform(const btTransform& worldTrans);
+            void getWorldTransform(btTransform& worldTrans) const;
+
+            Vector3 linearAcceleration_;
+            Vector3 linearVelocity_;
+            Vector3 angularAcceleration_;
+            Vector3 angularVelocity_;
+
+        private:
+            virtual bool isCollisionTypeLegal(WorldEntity::CollisionType type) const;
+    };
+}
+
+#endif /* _MobileEntity_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/Model.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Model.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Model.cc	(revision 2662)
@@ -29,4 +29,5 @@
 #include "OrxonoxStableHeaders.h"
 
+#include <OgreEntity.h>
 #include "Model.h"
 #include "core/CoreIncludes.h"
@@ -38,7 +39,9 @@
     CreateFactory(Model);
 
-    Model::Model(BaseObject* creator) : PositionableEntity(creator)
+    Model::Model(BaseObject* creator) : StaticEntity(creator)
     {
         RegisterObject(Model);
+
+        this->bCastShadows_ = true;
 
         this->registerVariables();
@@ -48,5 +51,5 @@
     {
         if (this->isInitialized() && this->mesh_.getEntity())
-            this->getNode()->detachObject(this->mesh_.getEntity());
+            this->detachOgreObject(this->mesh_.getEntity());
     }
 
@@ -61,20 +64,23 @@
     void Model::registerVariables()
     {
-        REGISTERSTRING(this->meshSrc_,    direction::toclient, new NetworkCallback<Model>(this, &Model::changedMesh));
-        REGISTERDATA(this->bCastShadows_, direction::toclient, new NetworkCallback<Model>(this, &Model::changedShadows));
+        registerVariable(this->meshSrc_,    variableDirection::toclient, new NetworkCallback<Model>(this, &Model::changedMesh));
+        registerVariable(this->bCastShadows_, variableDirection::toclient, new NetworkCallback<Model>(this, &Model::changedShadows));
     }
 
     void Model::changedMesh()
     {
-        if (this->mesh_.getEntity())
-            this->getNode()->detachObject(this->mesh_.getEntity());
+        if (Core::showsGraphics())
+        {
+            if (this->mesh_.getEntity())
+                this->detachOgreObject(this->mesh_.getEntity());
 
-        this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
+            this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
 
-        if (this->mesh_.getEntity())
-        {
-            this->getNode()->attachObject(this->mesh_.getEntity());
-            this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
-            this->mesh_.setVisible(this->isVisible());
+            if (this->mesh_.getEntity())
+            {
+                this->attachOgreObject(this->mesh_.getEntity());
+                this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
+                this->mesh_.setVisible(this->isVisible());
+            }
         }
     }
Index: code/trunk/src/orxonox/objects/worldentities/Model.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Model.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/Model.h	(revision 2662)
@@ -31,10 +31,10 @@
 
 #include "OrxonoxPrereqs.h"
-#include "PositionableEntity.h"
+#include "StaticEntity.h"
 #include "tools/Mesh.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Model : public PositionableEntity
+    class _OrxonoxExport Model : public StaticEntity
     {
         public:
@@ -70,3 +70,3 @@
 }
 
-#endif /* _PositionableEntity_H__ */
+#endif /* _Model_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/MovableEntity.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/MovableEntity.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/MovableEntity.cc	(revision 2662)
@@ -22,4 +22,5 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder
  *   Co-authors:
  *      ...
@@ -33,24 +34,23 @@
 #include "core/XMLPort.h"
 #include "core/Executor.h"
-#include "tools/Timer.h"
+#include "core/Core.h"
 
 namespace orxonox
 {
     static const float MAX_RESYNCHRONIZE_TIME = 3.0f;
+    static const float CONTINUOUS_SYNCHRONIZATION_TIME = 10.0f;
 
     CreateFactory(MovableEntity);
 
-    MovableEntity::MovableEntity(BaseObject* creator) : WorldEntity(creator)
+    MovableEntity::MovableEntity(BaseObject* creator) : MobileEntity(creator)
     {
         RegisterObject(MovableEntity);
 
-        this->velocity_ = Vector3::ZERO;
-        this->acceleration_ = Vector3::ZERO;
-        this->rotationAxis_ = Vector3::ZERO;
-        this->rotationRate_ = 0;
-        this->momentum_ = 0;
+        this->overwrite_position_    = Vector3::ZERO;
+        this->overwrite_orientation_ = Quaternion::IDENTITY;
 
-        this->overwrite_position_ = Vector3::ZERO;
-        this->overwrite_orientation_ = Quaternion::IDENTITY;
+        this->continuousResynchroTimer_ = 0;
+
+        this->setPriority(priority::low);
 
         this->registerVariables();
@@ -59,4 +59,7 @@
     MovableEntity::~MovableEntity()
     {
+        if (this->isInitialized())
+            if (this->continuousResynchroTimer_)
+                delete this->continuousResynchroTimer_;
     }
 
@@ -64,51 +67,18 @@
     {
         SUPER(MovableEntity, XMLPort, xmlelement, mode);
-
-        XMLPortParamTemplate(MovableEntity, "velocity", setVelocity, getVelocity, xmlelement, mode, const Vector3&);
-        XMLPortParamTemplate(MovableEntity, "rotationaxis", setRotationAxis, getRotationAxis, xmlelement, mode, const Vector3&);
-        XMLPortParamTemplate(MovableEntity, "rotationrate", setRotationRate, getRotationRate, xmlelement, mode, const Degree&);
-    }
-
-    void MovableEntity::tick(float dt)
-    {
-        if (this->isActive())
-        {
-            this->velocity_ += (dt * this->acceleration_);
-            this->node_->translate(dt * this->velocity_);
-
-            this->rotationRate_ += (dt * this->momentum_);
-            this->node_->rotate(this->rotationAxis_, this->rotationRate_  * dt);
-        }
     }
 
     void MovableEntity::registerVariables()
     {
-        REGISTERDATA(this->velocity_.x, direction::toclient);
-        REGISTERDATA(this->velocity_.y, direction::toclient);
-        REGISTERDATA(this->velocity_.z, direction::toclient);
+        registerVariable(this->linearVelocity_,        variableDirection::toclient, new NetworkCallback<MovableEntity>(this, &MovableEntity::processLinearVelocity));
+        registerVariable(this->angularVelocity_,       variableDirection::toclient, new NetworkCallback<MovableEntity>(this, &MovableEntity::processAngularVelocity));
 
-        REGISTERDATA(this->rotationAxis_.x, direction::toclient);
-        REGISTERDATA(this->rotationAxis_.y, direction::toclient);
-        REGISTERDATA(this->rotationAxis_.z, direction::toclient);
-
-        REGISTERDATA(this->rotationRate_, direction::toclient);
-
-        REGISTERDATA(this->overwrite_position_,    direction::toclient, new NetworkCallback<MovableEntity>(this, &MovableEntity::overwritePosition));
-        REGISTERDATA(this->overwrite_orientation_, direction::toclient, new NetworkCallback<MovableEntity>(this, &MovableEntity::overwriteOrientation));
-    }
-
-    void MovableEntity::overwritePosition()
-    {
-        this->node_->setPosition(this->overwrite_position_);
-    }
-
-    void MovableEntity::overwriteOrientation()
-    {
-        this->node_->setOrientation(this->overwrite_orientation_);
+        registerVariable(this->overwrite_position_,    variableDirection::toclient, new NetworkCallback<MovableEntity>(this, &MovableEntity::overwritePosition));
+        registerVariable(this->overwrite_orientation_, variableDirection::toclient, new NetworkCallback<MovableEntity>(this, &MovableEntity::overwriteOrientation));
     }
 
     void MovableEntity::clientConnected(unsigned int clientID)
     {
-        new Timer<MovableEntity>(rnd() * MAX_RESYNCHRONIZE_TIME, false, this, createExecutor(createFunctor(&MovableEntity::resynchronize)), true);
+        this->resynchronizeTimer_.setTimer(rnd() * MAX_RESYNCHRONIZE_TIME, false, this, createExecutor(createFunctor(&MovableEntity::resynchronize)));
     }
 
@@ -119,60 +89,13 @@
     void MovableEntity::resynchronize()
     {
+        if (Core::isMaster() && !this->continuousResynchroTimer_)
+        {
+            // Resynchronise every few seconds because we only work with velocities (no positions)
+            continuousResynchroTimer_ = new Timer<MovableEntity>(CONTINUOUS_SYNCHRONIZATION_TIME + rnd(-1, 1),
+                true, this, createExecutor(createFunctor(&MovableEntity::resynchronize)), false);
+        }
+
         this->overwrite_position_ = this->getPosition();
         this->overwrite_orientation_ = this->getOrientation();
     }
-
-    void MovableEntity::setPosition(const Vector3& position)
-    {
-        this->node_->setPosition(position);
-        this->overwrite_position_ = this->node_->getPosition();
-    }
-
-    void MovableEntity::translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo)
-    {
-        this->node_->translate(distance, relativeTo);
-        this->overwrite_position_ = this->node_->getPosition();
-    }
-
-    void MovableEntity::setOrientation(const Quaternion& orientation)
-    {
-        this->node_->setOrientation(orientation);
-        this->overwrite_orientation_ = this->node_->getOrientation();
-    }
-
-    void MovableEntity::rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo)
-    {
-        this->node_->rotate(rotation, relativeTo);
-        this->overwrite_orientation_ = this->node_->getOrientation();
-    }
-
-    void MovableEntity::yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
-    {
-        this->node_->yaw(angle, relativeTo);
-        this->overwrite_orientation_ = this->node_->getOrientation();
-    }
-
-    void MovableEntity::pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
-    {
-        this->node_->pitch(angle, relativeTo);
-        this->overwrite_orientation_ = this->node_->getOrientation();
-    }
-
-    void MovableEntity::roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
-    {
-        this->node_->roll(angle, relativeTo);
-        this->overwrite_orientation_ = this->node_->getOrientation();
-    }
-
-    void MovableEntity::lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
-    {
-        this->node_->lookAt(target, relativeTo, localDirectionVector);
-        this->overwrite_orientation_ = this->node_->getOrientation();
-    }
-
-    void MovableEntity::setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
-    {
-        this->node_->setDirection(direction, relativeTo, localDirectionVector);
-        this->overwrite_orientation_ = this->node_->getOrientation();
-    }
 }
Index: code/trunk/src/orxonox/objects/worldentities/MovableEntity.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/MovableEntity.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/MovableEntity.h	(revision 2662)
@@ -22,4 +22,5 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder
  *   Co-authors:
  *      ...
@@ -32,11 +33,11 @@
 #include "OrxonoxPrereqs.h"
 
-#include "WorldEntity.h"
-#include "objects/Tickable.h"
+#include "MobileEntity.h"
 #include "network/ClientConnectionListener.h"
+#include "tools/Timer.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport MovableEntity : public WorldEntity, public Tickable, public ClientConnectionListener
+    class _OrxonoxExport MovableEntity : public MobileEntity, public ClientConnectionListener
     {
         public:
@@ -45,61 +46,13 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            virtual void tick(float dt);
             void registerVariables();
 
             using WorldEntity::setPosition;
-            using WorldEntity::translate;
             using WorldEntity::setOrientation;
-            using WorldEntity::rotate;
-            using WorldEntity::yaw;
-            using WorldEntity::pitch;
-            using WorldEntity::roll;
-            using WorldEntity::lookAt;
-            using WorldEntity::setDirection;
 
-            void setPosition(const Vector3& position);
-            void translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void setOrientation(const Quaternion& orientation);
-            void rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL);
-            void lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z);
-            void setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z);
-
-            inline void setVelocity(const Vector3& velocity)
-                { this->velocity_ = velocity; }
-            inline void setVelocity(float x, float y, float z)
-                { this->velocity_.x = x; this->velocity_.y = y; this->velocity_.z = z; }
-            inline const Vector3& getVelocity() const
-                { return this->velocity_; }
-
-            inline void setAcceleration(const Vector3& acceleration)
-                { this->acceleration_ = acceleration; }
-            inline void setAcceleration(float x, float y, float z)
-                { this->acceleration_.x = x; this->acceleration_.y = y; this->acceleration_.z = z; }
-            inline const Vector3& getAcceleration() const
-                { return this->acceleration_; }
-
-            inline void setRotationAxis(const Vector3& axis)
-                { this->rotationAxis_ = axis; this->rotationAxis_.normalise(); }
-            inline void setRotationAxis(float x, float y, float z)
-                { this->rotationAxis_.x = x; this->rotationAxis_.y = y; this->rotationAxis_.z = z; rotationAxis_.normalise(); }
-            inline const Vector3& getRotationAxis() const
-                { return this->rotationAxis_; }
-
-            inline void setRotationRate(const Degree& angle)
-                { this->rotationRate_ = angle; }
-            inline void setRotationRate(const Radian& angle)
-                { this->rotationRate_ = angle; }
-            inline const Degree& getRotationRate() const
-                { return this->rotationRate_; }
-
-            inline void setMomentum(const Degree& angle)
-                { this->momentum_ = angle; }
-            inline void setMomentum(const Radian& angle)
-                { this->momentum_ = angle; }
-            inline const Degree& getMomentum() const
-                { return this->momentum_; }
+            inline void setPosition(const Vector3& position)
+                { MobileEntity::setPosition(position); this->overwrite_position_ = this->getPosition(); }
+            inline void setOrientation(const Quaternion& orientation)
+                { MobileEntity::setOrientation(orientation); this->overwrite_orientation_ = this->getOrientation(); }
 
         private:
@@ -108,15 +61,19 @@
             void resynchronize();
 
-            void overwritePosition();
-            void overwriteOrientation();
+            inline void processLinearVelocity()
+                { this->setVelocity(this->linearVelocity_); }
+            inline void processAngularVelocity()
+                { this->setAngularVelocity(this->angularVelocity_); }
 
-            Vector3 velocity_;
-            Vector3 acceleration_;
-            Vector3 rotationAxis_;
-            Degree rotationRate_;
-            Degree momentum_;
+            inline void overwritePosition()
+                { this->setPosition(this->overwrite_position_); }
+            inline void overwriteOrientation()
+                { this->setOrientation(this->overwrite_orientation_); }
 
-            Vector3 overwrite_position_;
+            Vector3    overwrite_position_;
             Quaternion overwrite_orientation_;
+
+            Timer<MovableEntity> resynchronizeTimer_;
+            Timer<MovableEntity>* continuousResynchroTimer_;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/ParticleEmitter.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/ParticleEmitter.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/ParticleEmitter.cc	(revision 2662)
@@ -33,6 +33,7 @@
 
 #include "OrxonoxStableHeaders.h"
+#include "ParticleEmitter.h"
 
-#include "ParticleEmitter.h"
+#include <OgreParticleSystem.h>
 
 #include "tools/ParticleInterface.h"
@@ -46,10 +47,10 @@
     CreateFactory(ParticleEmitter);
 
-    ParticleEmitter::ParticleEmitter(BaseObject* creator) : PositionableEntity(creator)
+    ParticleEmitter::ParticleEmitter(BaseObject* creator) : StaticEntity(creator)
     {
         RegisterObject(ParticleEmitter);
 
-        if (!this->getScene() || !this->getScene()->getSceneManager())
-            ThrowException(AbortLoading, "Can't create Camera, no scene or no scene manager given.");
+        if (Core::showsGraphics() && (!this->getScene() || !this->getScene()->getSceneManager()))
+            ThrowException(AbortLoading, "Can't create ParticleEmitter, no scene or no scene manager given.");
 
         this->particles_ = 0;
@@ -62,5 +63,8 @@
     {
         if (this->isInitialized() && this->particles_)
+        {
+            this->detachOgreObject(this->particles_->getParticleSystem());
             delete this->particles_;
+        }
     }
 
@@ -75,6 +79,6 @@
     void ParticleEmitter::registerVariables()
     {
-        REGISTERSTRING(this->source_, direction::toclient, new NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::sourceChanged));
-        REGISTERDATA  (this->LOD_,    direction::toclient, new NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::LODchanged));
+        registerVariable(this->source_, variableDirection::toclient, new NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::sourceChanged));
+        registerVariable((int&)(this->LOD_),    variableDirection::toclient, new NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::LODchanged));
     }
 
@@ -98,12 +102,15 @@
     {
         if (this->particles_)
+        {
             delete this->particles_;
+            this->particles_ = 0;
+        }
 
-        if (this->getScene() && this->getScene()->getSceneManager())
+        if (Core::showsGraphics() && this->getScene() && this->getScene()->getSceneManager())
         {
             try
             {
                 this->particles_ = new ParticleInterface(this->getScene()->getSceneManager(), this->source_, this->LOD_);
-                this->particles_->addToSceneNode(this->getNode());
+                this->attachOgreObject(this->particles_->getParticleSystem());
                 this->particles_->setVisible(this->isVisible());
                 this->particles_->setEnabled(this->isActive());
@@ -115,6 +122,4 @@
             }
         }
-        else
-            this->particles_ = 0;
     }
 
Index: code/trunk/src/orxonox/objects/worldentities/ParticleEmitter.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/ParticleEmitter.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/ParticleEmitter.h	(revision 2662)
@@ -31,9 +31,9 @@
 
 #include "OrxonoxPrereqs.h"
-#include "PositionableEntity.h"
+#include "StaticEntity.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport ParticleEmitter : public PositionableEntity
+    class _OrxonoxExport ParticleEmitter : public StaticEntity
     {
         public:
Index: code/trunk/src/orxonox/objects/worldentities/Planet.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Planet.cc	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/Planet.cc	(revision 2662)
@@ -0,0 +1,173 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Marian Runo
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "Planet.h"
+
+#include <math.h>
+
+#include <OgreEntity.h>
+#include <OgreBillboardSet.h>
+#include <OgreHardwareVertexBuffer.h>
+#include <OgreMeshManager.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "objects/Scene.h"
+#include "CameraManager.h"
+#include "Camera.h"
+#include "GraphicsEngine.h"
+
+namespace orxonox
+{
+    CreateFactory(Planet);    
+
+    /**
+     * @brief Constructor
+     */
+    Planet::Planet(BaseObject* creator): MovableEntity(creator)
+    {
+        RegisterObject(Planet);
+        this->registerVariables();
+    }
+
+    /**
+     * @brief Destructor
+     */
+    Planet::~Planet()
+    {
+        if (this->isInitialized() && this->mesh_.getEntity())
+            this->detachOgreObject(this->mesh_.getEntity());
+    }    
+
+    void Planet::tick(float dt)
+    {
+        if(!this->isVisible())
+            return;
+
+        Camera* activeCamera = CameraManager::getInstance().getActiveCamera();
+        if(activeCamera)
+        {
+            Real distance = this->getPosition().distance( activeCamera->getWorldPosition() );
+            //             COUT(2) << distance << std::endl;
+            Real planetRadius = this->getScale();
+
+            Real newScale = 2 * distance / sqrt(distance*distance - planetRadius*planetRadius);
+            Real tempTest = newScale*(1+Real(this->atmosphereSize)/Real(this->imageSize));
+            newScale = tempTest;
+
+            this->billboard_.getBillboardSet()->setDefaultDimensions(newScale, newScale);
+        }
+
+        SUPER(Planet, tick, dt);
+    }
+
+    void Planet::init()
+    {
+        Real scaleFactor = this->getScale();
+
+        this->distList.push_back(10.0*scaleFactor);
+        this->distList.push_back(19.0*scaleFactor);
+        this->distList.push_back(27.0*scaleFactor);
+        this->distList.push_back(34.0*scaleFactor);
+        this->distList.push_back(40.0*scaleFactor);
+        this->distList.push_back(45.0*scaleFactor);
+        this->distList.push_back(49.0*scaleFactor);
+        this->distList.push_back(52.0*scaleFactor);
+        this->distList.push_back(54.0*scaleFactor);
+        this->distList.push_back(55.0*scaleFactor);
+
+        Real reductionValue = 0.2;
+
+        this->mesh_.getEntity()->getMesh()->generateLodLevels(distList, Ogre::ProgressiveMesh::VRQ_PROPORTIONAL, reductionValue);
+        billboard_.setBillboardSet(this->getScene()->getSceneManager(), this->atmosphere_, Vector3(0,0,0));
+
+        this->attachOgreObject(this->billboard_.getBillboardSet());    
+        this->billboard_.getBillboardSet()->setUseAccurateFacing(true);
+        this->setCastShadows(true);
+        this->billboard_.getBillboardSet()->setRenderQueueGroup(this->mesh_.getEntity()->getRenderQueueGroup());
+        this->mesh_.setCastShadows(true);
+    }
+
+    void Planet::changedMesh()
+    {
+        if (this->mesh_.getEntity())
+            this->detachOgreObject(this->mesh_.getEntity());
+
+        this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
+
+        if (this->mesh_.getEntity())
+        {
+            this->attachOgreObject(this->mesh_.getEntity());
+            this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
+            this->mesh_.setVisible(this->isVisible());
+        }
+        this->init();
+    }
+
+    void Planet::changedShadows()
+    {
+        this->mesh_.setCastShadows(this->bCastShadows_);
+    }
+
+    /**
+        @brief XML loading and saving.
+        @param xmlelement The XML-element
+        @param loading Loading (true) or saving (false)
+        @return The XML-element
+    */
+    void Planet::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Planet, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Planet, "atmosphere", setAtmosphere, getAtmosphere, xmlelement, mode).defaultValues("planet/Atmosphere");
+        XMLPortParam(Planet, "atmospheresize", setAtmosphereSize, getAtmosphereSize, xmlelement,mode);     
+        XMLPortParam(Planet, "imagesize", setImageSize, getImageSize, xmlelement,mode);         
+        XMLPortParam(Planet, "mesh", setMeshSource, getMeshSource, xmlelement, mode);
+        XMLPortParam(Planet, "shadow", setCastShadows, getCastShadows, xmlelement, mode).defaultValues(true);
+    }
+
+    void Planet::registerVariables()
+    {
+        registerVariable(this->atmosphere_, variableDirection::toclient);
+        registerVariable(this->meshSrc_, variableDirection::toclient, new NetworkCallback<Planet>(this, &Planet::changedMesh));
+        registerVariable(this->bCastShadows_, variableDirection::toclient, new NetworkCallback<Planet>(this, &Planet::changedShadows));
+        registerVariable(this->atmosphereSize, variableDirection::toclient);
+        registerVariable(this->imageSize, variableDirection::toclient);
+    }
+
+    void Planet::changedVisibility()
+    {
+        SUPER(Planet, changedVisibility);
+        if (this->isInitialized())
+        {
+            this->mesh_.setVisible(this->isVisible());
+            this->billboard_.setVisible(this->isVisible());
+        }
+    }
+}
Index: code/trunk/src/orxonox/objects/worldentities/Planet.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Planet.h	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/Planet.h	(revision 2662)
@@ -0,0 +1,118 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Marian Runo
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Planet_H__
+#define _Planet_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <OgreMesh.h>
+
+#include "tools/BillboardSet.h"
+#include "tools/Mesh.h"
+#include "MovableEntity.h"
+#include "objects/Tickable.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Planet : public MovableEntity
+    {
+        public:
+            Planet(BaseObject* creator);
+            
+            virtual ~Planet();
+            
+            void init();
+            virtual void tick(float dt);
+            
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            
+            virtual void changedVisibility();
+            
+            inline void setMeshSource(const std::string& meshname)
+                { this->meshSrc_ = meshname; this->changedMesh(); }
+                
+            inline const std::string& getMeshSource() const
+                { return this->meshSrc_; }
+
+            inline void setCastShadows(bool bCastShadows)
+                { this->bCastShadows_ = bCastShadows; this->changedShadows(); }
+                
+            inline bool getCastShadows() const
+                { return this->bCastShadows_; }            
+            
+            inline const std::string& getMesh() const{
+                return this->meshSrc_;
+            }
+            
+            inline void setAtmosphereSize(Real size){
+                this->atmosphereSize = size;
+            }
+            
+            inline Real getAtmosphereSize(){
+                return this->atmosphereSize;
+            }
+            
+            inline void setAtmosphere(const std::string& atmosphere){
+                this->atmosphere_ = atmosphere;
+            }
+            
+            inline const std::string& getAtmosphere(){
+                return this->atmosphere_;
+            }
+            
+            inline void setImageSize(Real size){
+                this->imageSize = size;
+            }
+            
+            inline Real getImageSize(){
+                return this->imageSize;
+            }
+
+        protected:
+            void registerVariables();
+
+        private:
+        
+            void changedMesh();
+            void changedShadows();
+            
+            std::string meshSrc_;
+            std::string atmosphere_;
+            Mesh mesh_;
+            Real atmosphereSize;
+            Real imageSize;
+            Ogre::Mesh::LodDistanceList distList;
+            BillboardSet billboard_;
+            bool bCastShadows_;
+
+    };
+}
+
+#endif
+
Index: code/trunk/src/orxonox/objects/worldentities/PositionableEntity.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/PositionableEntity.cc	(revision 2262)
+++ 	(revision )
@@ -1,59 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   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
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Fabian 'x3n' Landau
- *   Co-authors:
- *      ...
- *
- */
-
-#include "OrxonoxStableHeaders.h"
-#include "PositionableEntity.h"
-#include "core/CoreIncludes.h"
-
-namespace orxonox
-{
-    CreateFactory(PositionableEntity);
-
-    PositionableEntity::PositionableEntity(BaseObject* creator) : WorldEntity(creator)
-    {
-        RegisterObject(PositionableEntity);
-
-        this->registerVariables();
-    }
-
-    PositionableEntity::~PositionableEntity()
-    {
-    }
-
-    void PositionableEntity::registerVariables()
-    {
-        REGISTERDATA(this->getPosition().x, direction::toclient);
-        REGISTERDATA(this->getPosition().y, direction::toclient);
-        REGISTERDATA(this->getPosition().z, direction::toclient);
-
-        REGISTERDATA(this->getOrientation().w, direction::toclient);
-        REGISTERDATA(this->getOrientation().x, direction::toclient);
-        REGISTERDATA(this->getOrientation().y, direction::toclient);
-        REGISTERDATA(this->getOrientation().z, direction::toclient);
-    }
-}
Index: code/trunk/src/orxonox/objects/worldentities/PositionableEntity.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/PositionableEntity.h	(revision 2262)
+++ 	(revision )
@@ -1,76 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   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
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Fabian 'x3n' Landau
- *   Co-authors:
- *      ...
- *
- */
-
-#ifndef _PositionableEntity_H__
-#define _PositionableEntity_H__
-
-#include "OrxonoxPrereqs.h"
-#include "WorldEntity.h"
-
-namespace orxonox
-{
-    class _OrxonoxExport PositionableEntity : public WorldEntity
-    {
-        public:
-            PositionableEntity(BaseObject* creator);
-            virtual ~PositionableEntity();
-
-            void registerVariables();
-
-            using WorldEntity::setPosition;
-            using WorldEntity::translate;
-            using WorldEntity::setOrientation;
-            using WorldEntity::rotate;
-            using WorldEntity::yaw;
-            using WorldEntity::pitch;
-            using WorldEntity::roll;
-            using WorldEntity::lookAt;
-            using WorldEntity::setDirection;
-
-            inline void setPosition(const Vector3& position)
-                { this->node_->setPosition(position); }
-            inline void translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
-                { this->node_->translate(distance, relativeTo); }
-            inline void setOrientation(const Quaternion& orientation)
-                { this->node_->setOrientation(orientation); }
-            inline void rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
-                { this->node_->rotate(rotation, relativeTo); }
-            inline void yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
-                { this->node_->yaw(angle, relativeTo); }
-            inline void pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
-                { this->node_->pitch(angle, relativeTo); }
-            inline void roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
-                { this->node_->roll(angle, relativeTo); }
-            inline void lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z)
-                { this->node_->lookAt(target, relativeTo, localDirectionVector); }
-            inline void setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z)
-                { this->node_->setDirection(direction, relativeTo, localDirectionVector); }
-    };
-}
-
-#endif /* _PositionableEntity_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/SpawnPoint.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/SpawnPoint.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/SpawnPoint.cc	(revision 2662)
@@ -38,5 +38,5 @@
     CreateFactory(SpawnPoint);
 
-    SpawnPoint::SpawnPoint(BaseObject* creator) : PositionableEntity(creator)
+    SpawnPoint::SpawnPoint(BaseObject* creator) : StaticEntity(creator)
     {
         RegisterObject(SpawnPoint);
Index: code/trunk/src/orxonox/objects/worldentities/SpawnPoint.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/SpawnPoint.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/SpawnPoint.h	(revision 2662)
@@ -34,10 +34,10 @@
 #include "core/Identifier.h"
 #include "core/Template.h"
-#include "PositionableEntity.h"
 #include "objects/worldentities/pawns/Pawn.h"
+#include "objects/worldentities/StaticEntity.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport SpawnPoint : public PositionableEntity
+    class _OrxonoxExport SpawnPoint : public StaticEntity
     {
         public:
Index: code/trunk/src/orxonox/objects/worldentities/StaticEntity.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/StaticEntity.cc	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/StaticEntity.cc	(revision 2662)
@@ -0,0 +1,119 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder (physics)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "StaticEntity.h"
+
+#include <OgreSceneNode.h>
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(StaticEntity);
+
+    StaticEntity::StaticEntity(BaseObject* creator) : WorldEntity(creator)
+    {
+        RegisterObject(StaticEntity);
+        
+        this->setPriority(priority::very_low);
+
+        this->registerVariables();
+    }
+
+    StaticEntity::~StaticEntity()
+    {
+    }
+
+    void StaticEntity::registerVariables()
+    {
+        registerVariable(this->getPosition(),    variableDirection::toclient, new NetworkCallback<StaticEntity>(this, &StaticEntity::positionChanged));
+        registerVariable(this->getOrientation(), variableDirection::toclient, new NetworkCallback<StaticEntity>(this, &StaticEntity::orientationChanged));
+    }
+
+
+    void StaticEntity::setPosition(const Vector3& position)
+    {
+        if (this->addedToPhysicalWorld())
+        {
+            CCOUT(2) << "Warning: Attempting to change the position of a StaticEntity at physics run time. Ignoring change." << std::endl;
+            return;
+        }
+        if (this->isStatic())
+        {
+            btTransform transf = this->physicalBody_->getWorldTransform();
+            transf.setOrigin(btVector3(position.x, position.y, position.z));
+            this->physicalBody_->setWorldTransform(transf);
+        }
+
+        this->node_->setPosition(position);
+    }
+
+    void StaticEntity::setOrientation(const Quaternion& orientation)
+    {
+        if (this->addedToPhysicalWorld())
+        {
+            CCOUT(2) << "Warning: Attempting to change the orientation of a StaticEntity at physics run time. Ignoring change." << std::endl;
+            return;
+        }
+        if (this->isStatic())
+        {
+            btTransform transf = this->physicalBody_->getWorldTransform();
+            transf.setRotation(btQuaternion(orientation.x, orientation.y, orientation.z, orientation.w));
+            this->physicalBody_->setWorldTransform(transf);
+        }
+
+        this->node_->setOrientation(orientation);
+    }
+
+    bool StaticEntity::isCollisionTypeLegal(WorldEntity::CollisionType type) const
+    {
+        if (type == WorldEntity::Kinematic || type == WorldEntity::Dynamic)
+        {
+            CCOUT(1) << "Error: Cannot tell a StaticEntity to have kinematic or dynamic collision type! Ignoring." << std::endl;
+            assert(false); // Only in debug mode
+            return false;
+        }
+        else
+            return true;
+    }
+
+    void StaticEntity::setWorldTransform(const btTransform& worldTrans)
+    {
+        OrxAssert(false, "Setting world transform of a StaticEntity, which is CF_STATIC!");
+    }
+
+    void StaticEntity::getWorldTransform(btTransform& worldTrans) const
+    {
+        worldTrans.setOrigin(btVector3(node_->getPosition().x, node_->getPosition().y, node_->getPosition().z));
+        worldTrans.setRotation(btQuaternion(node_->getOrientation().x, node_->getOrientation().y, node_->getOrientation().z, node_->getOrientation().w));
+    }
+}
Index: code/trunk/src/orxonox/objects/worldentities/StaticEntity.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/StaticEntity.h	(revision 2662)
+++ code/trunk/src/orxonox/objects/worldentities/StaticEntity.h	(revision 2662)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _StaticEntity_H__
+#define _StaticEntity_H__
+
+#include "OrxonoxPrereqs.h"
+#include "WorldEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport StaticEntity : public WorldEntity
+    {
+        public:
+            StaticEntity(BaseObject* creator);
+            virtual ~StaticEntity();
+
+            void registerVariables();
+
+            using WorldEntity::setPosition;
+            using WorldEntity::setOrientation;
+
+            void setPosition(const Vector3& position);
+            void setOrientation(const Quaternion& orientation);
+
+        private:
+            bool isCollisionTypeLegal(CollisionType type) const;
+
+            // network callbacks
+            inline void positionChanged()
+                { this->setPosition(this->getPosition()); }
+            inline void orientationChanged()
+                { this->setOrientation(this->getOrientation()); }
+
+            // Bullet btMotionState related
+            void setWorldTransform(const btTransform& worldTrans);
+            void getWorldTransform(btTransform& worldTrans) const;
+    };
+}
+
+#endif /* _StaticEntity_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/WorldEntity.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/WorldEntity.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/WorldEntity.cc	(revision 2662)
@@ -22,4 +22,5 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder (physics)
  *   Co-authors:
  *      ...
@@ -31,12 +32,15 @@
 
 #include <cassert>
+#include <OgreSceneNode.h>
 #include <OgreSceneManager.h>
-
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
+#include "util/Exception.h"
+#include "util/Convert.h"
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
-#include "util/Convert.h"
-#include "util/Exception.h"
 
 #include "objects/Scene.h"
+#include "objects/collisionshapes/WorldEntityCollisionShape.h"
 
 namespace orxonox
@@ -49,4 +53,9 @@
     const Vector3 WorldEntity::UP    = Vector3::UNIT_Y;
 
+    /**
+    @brief
+        Creates a new WorldEntity that may immediately be used.
+        All the default values are being set here.
+    */
     WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
     {
@@ -64,14 +73,53 @@
         this->node_->setOrientation(Quaternion::IDENTITY);
 
+
+        // Default behaviour does not include physics
+        this->physicalBody_   = 0;
+        this->bPhysicsActive_ = false;
+        this->bPhysicsActiveSynchronised_    = false;
+        this->bPhysicsActiveBeforeAttaching_ = false;
+        this->collisionShape_ = new WorldEntityCollisionShape(this);
+        this->collisionType_             = None;
+        this->collisionTypeSynchronised_ = None;
+        this->mass_           = 0;
+        this->childrenMass_   = 0;
+        // Using bullet default values
+        this->restitution_    = 0;
+        this->angularFactor_  = 1;
+        this->linearDamping_  = 0;
+        this->angularDamping_ = 0;
+        this->friction_       = 0.5;
+        this->bCollisionCallbackActive_ = false;
+        this->bCollisionResponseActive_ = true;
+
         this->registerVariables();
     }
 
+    /**
+    @brief
+        Destroys the WorldEntity AND ALL its children with it.
+    */
     WorldEntity::~WorldEntity()
     {
         if (this->isInitialized())
         {
+            if (this->parent_)
+                this->detachFromParent();
+
+            for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); )
+                delete (*(it++));
+
+            if (this->physicalBody_)
+            {
+                this->deactivatePhysics();
+                delete this->physicalBody_;
+            }
+            delete this->collisionShape_;
+
             this->node_->detachAllObjects();
-            if (this->getScene()->getSceneManager())
-                this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName());
+            this->node_->removeAllChildren();
+
+            OrxAssert(this->getScene()->getSceneManager(), "No SceneManager defined in a WorldEntity.");
+            this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName());
         }
     }
@@ -81,30 +129,64 @@
         SUPER(WorldEntity, XMLPort, xmlelement, mode);
 
-        XMLPortParamTemplate(WorldEntity, "position", setPosition, getPosition, xmlelement, mode, const Vector3&);
+        XMLPortParamTemplate(WorldEntity, "position",    setPosition,    getPosition,    xmlelement, mode, const Vector3&);
         XMLPortParamTemplate(WorldEntity, "orientation", setOrientation, getOrientation, xmlelement, mode, const Quaternion&);
-        XMLPortParamLoadOnly(WorldEntity, "lookat", lookAt_xmlport, xmlelement, mode);
-        XMLPortParamLoadOnly(WorldEntity, "direction", setDirection_xmlport, xmlelement, mode);
-        XMLPortParamLoadOnly(WorldEntity, "yaw", yaw_xmlport, xmlelement, mode);
-        XMLPortParamLoadOnly(WorldEntity, "pitch", pitch_xmlport, xmlelement, mode);
-        XMLPortParamLoadOnly(WorldEntity, "roll", roll_xmlport, xmlelement, mode);
-        XMLPortParamTemplate(WorldEntity, "scale3D", setScale3D, getScale3D, xmlelement, mode, const Vector3&);
-        XMLPortParam(WorldEntity, "scale", setScale, getScale, xmlelement, mode);
-
+        XMLPortParamTemplate(WorldEntity, "scale3D",     setScale3D,     getScale3D,     xmlelement, mode, const Vector3&);
+        XMLPortParam        (WorldEntity, "scale",       setScale,       getScale,       xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "lookat",      lookAt_xmlport,       xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "direction",   setDirection_xmlport, xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "yaw",         yaw_xmlport,          xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "pitch",       pitch_xmlport,        xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "roll",        roll_xmlport,         xmlelement, mode);
+
+        // Physics
+        XMLPortParam(WorldEntity, "collisionType",     setCollisionTypeStr,  getCollisionTypeStr,  xmlelement, mode);
+        XMLPortParam(WorldEntity, "collisionResponse", setCollisionResponse, hasCollisionResponse, xmlelement, mode);
+        XMLPortParam(WorldEntity, "mass",              setMass,              getMass,              xmlelement, mode);
+        XMLPortParam(WorldEntity, "restitution",       setRestitution,       getRestitution,       xmlelement, mode);
+        XMLPortParam(WorldEntity, "angularFactor",     setAngularFactor,     getAngularFactor,     xmlelement, mode);
+        XMLPortParam(WorldEntity, "linearDamping",     setLinearDamping,     getLinearDamping,     xmlelement, mode);
+        XMLPortParam(WorldEntity, "angularDamping",    setAngularDamping,    getAngularDamping,    xmlelement, mode);
+        XMLPortParam(WorldEntity, "friction",          setFriction,          getFriction,          xmlelement, mode);
+
+        // Other attached WorldEntities
         XMLPortObject(WorldEntity, WorldEntity, "attached", attach, getAttachedObject, xmlelement, mode);
+        // Attached collision shapes
+        XMLPortObject(WorldEntity, CollisionShape, "collisionShapes", attachCollisionShape, getAttachedCollisionShape, xmlelement, mode);
     }
 
     void WorldEntity::registerVariables()
     {
-        REGISTERDATA(this->bActive_,  direction::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedActivity));
-        REGISTERDATA(this->bVisible_, direction::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedVisibility));
-
-        REGISTERDATA(this->getScale3D().x, direction::toclient);
-        REGISTERDATA(this->getScale3D().y, direction::toclient);
-        REGISTERDATA(this->getScale3D().z, direction::toclient);
-
-        REGISTERDATA(this->parentID_, direction::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::updateParent));
-    }
-
-    void WorldEntity::updateParent()
+        registerVariable(this->mainStateName_,  variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedMainState));
+
+        registerVariable(this->bActive_,        variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedActivity));
+        registerVariable(this->bVisible_,       variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedVisibility));
+
+        registerVariable(this->getScale3D(),    variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::scaleChanged));
+
+        // Physics stuff
+        registerVariable(this->mass_,           variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::massChanged));
+        registerVariable(this->restitution_,    variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::restitutionChanged));
+        registerVariable(this->angularFactor_,  variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::angularFactorChanged));
+        registerVariable(this->linearDamping_,  variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::linearDampingChanged));
+        registerVariable(this->angularDamping_, variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::angularDampingChanged));
+        registerVariable(this->friction_,       variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::frictionChanged));
+        registerVariable(this->bCollisionCallbackActive_,
+                                                variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::collisionCallbackActivityChanged));
+        registerVariable(this->bCollisionResponseActive_,
+                                                variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::collisionResponseActivityChanged));
+        registerVariable((int&)this->collisionTypeSynchronised_,
+                                                variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::collisionTypeChanged));
+        registerVariable(this->bPhysicsActiveSynchronised_,
+                                                variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::physicsActivityChanged));
+
+        // Attach to parent if necessary
+        registerVariable(this->parentID_,       variableDirection::toclient, new NetworkCallback<WorldEntity>(this, &WorldEntity::parentChanged));
+    }
+
+    /**
+    @brief
+        Network function that object this instance to its correct parent.
+    */
+    void WorldEntity::parentChanged()
     {
         if (this->parentID_ != OBJECTID_UNKNOWN)
@@ -116,32 +198,227 @@
     }
 
+    /**
+    @brief
+        Attaches this object to a parent SceneNode.
+    @Remarks
+        Only use this method if you know exactly what you're doing!
+        Normally, attaching works internally by attaching WE's.
+    */
+    void WorldEntity::attachToNode(Ogre::SceneNode* node)
+    {
+        Ogre::Node* parent = this->node_->getParent();
+        if (parent)
+            parent->removeChild(this->node_);
+        node->addChild(this->node_);
+    }
+
+    /**
+    @brief
+        Detaches this object from a parent SceneNode.
+    @Remarks
+        Only use this method if you know exactly what you're doing!
+        Normally, attaching works internally by attaching WE's.
+    */
+    void WorldEntity::detachFromNode(Ogre::SceneNode* node)
+    {
+        node->removeChild(this->node_);
+//        this->getScene()->getRootSceneNode()->addChild(this->node_);
+    }
+
+    /**
+    @brief
+        Network callback for the collision type. Only change the type if it was valid.
+    */
+    void WorldEntity::collisionTypeChanged()
+    {
+        if (this->collisionTypeSynchronised_ != Dynamic &&
+            this->collisionTypeSynchronised_ != Kinematic &&
+            this->collisionTypeSynchronised_ != Static &&
+            this->collisionTypeSynchronised_ != None)
+        {
+            CCOUT(1) << "Error when collsion Type was received over network. Unknown enum value:" << this->collisionTypeSynchronised_ << std::endl;
+        }
+        else if (this->collisionTypeSynchronised_ != collisionType_)
+        {
+            if (this->parent_)
+                CCOUT(2) << "Warning: Network connection tried to set the collision type of an attached WE. Ignoring." << std::endl;
+            else
+                this->setCollisionType(this->collisionTypeSynchronised_);
+        }
+    }
+
+    //! Network callback for this->bPhysicsActive_
+    void WorldEntity::physicsActivityChanged()
+    {
+        if (this->bPhysicsActiveSynchronised_)
+            this->activatePhysics();
+        else
+            this->deactivatePhysics();
+    }
+
+    //! Function sets whether Bullet should issue a callback on collisions
+    void WorldEntity::collisionCallbackActivityChanged()
+    {
+        if (this->hasPhysics())
+        {
+            if (this->bCollisionCallbackActive_)
+                this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() |
+                    btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
+            else
+                this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() &
+                    ~btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
+        }
+    }
+
+    //! Function sets whether Bullet should react itself to a collision
+    void WorldEntity::collisionResponseActivityChanged()
+    {
+        if (this->hasPhysics())
+        {
+            if (this->bCollisionResponseActive_)
+                this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() &
+                    ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
+            else
+                this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() |
+                    btCollisionObject::CF_NO_CONTACT_RESPONSE);
+        }
+    }
+
+    /**
+    @brief
+        Attaches a child WorldEntity to this object. This calls notifyBeingAttached()
+        of the child WE.
+    @Note
+        The collision shape of the child object gets attached nevertheless. That also means
+        that you can change the collision shape of the child and it correctly cascadeds the changes to this instance.
+        Be aware of this implication: When implementing attaching of kinematic objects to others, you have to change
+        this behaviour because you then might not want to merge the collision shapes.
+    */
     void WorldEntity::attach(WorldEntity* object)
     {
-        if (object->getParent())
-            object->detachFromParent();
-        else
-        {
-            Ogre::Node* parent = object->node_->getParent();
-            if (parent)
-                parent->removeChild(object->node_);
-        }
-
-        this->node_->addChild(object->node_);
+        if (object == this)
+        {
+            COUT(2) << "Warning: Can't attach a WorldEntity to itself." << std::endl;
+            return;
+        }
+
+        if (!object->notifyBeingAttached(this))
+            return;
+
+        this->attachNode(object->node_);
         this->children_.insert(object);
-        object->parent_ = this;
-        object->parentID_ = this->getObjectID();
-    }
-
+
+        this->attachCollisionShape(object->collisionShape_);
+        // mass
+        this->childrenMass_ += object->getMass();
+        recalculateMassProps();
+    }
+
+    /**
+    @brief
+        Function gets called when this object is being attached to a new parent.
+
+        This operation is only allowed if the collision types "like" each other.
+        - You cannot a attach a non physical object to a physical one.
+        - Dynamic object can NOT be attached at all.
+        - It is also not possible to attach a kinematic to a dynamic one.
+        - Attaching of kinematic objects otherwise is not yet supported.
+    */
+    bool WorldEntity::notifyBeingAttached(WorldEntity* newParent)
+    {
+        // check first whether attaching is even allowed
+        if (this->hasPhysics())
+        {
+            if (!newParent->hasPhysics())
+            {
+                COUT(2) << "Warning: Cannot attach a physical object to a non physical one." << std::endl;
+                return false;
+            }
+            else if (this->isDynamic())
+            {
+                COUT(2) << "Warning: Cannot attach a dynamic object to a WorldEntity." << std::endl;
+                return false;
+            }
+            else if (this->isKinematic() && newParent->isDynamic())
+            {
+                COUT(2) << "Warning: Cannot attach a kinematic object to a dynamic one." << std::endl;
+                return false;
+            }
+            else if (this->isKinematic())
+            {
+                COUT(2) << "Warning: Cannot attach a kinematic object to a static or kinematic one: Not yet implemented." << std::endl;
+                return false;
+            }
+        }
+
+        if (this->isPhysicsActive())
+            this->bPhysicsActiveBeforeAttaching_ = true;
+        this->deactivatePhysics();
+
+        if (this->parent_)
+            this->detachFromParent();
+
+        this->parent_ = newParent;
+        this->parentID_ = newParent->getObjectID();
+
+        // apply transform to collision shape
+        this->collisionShape_->setPosition(this->getPosition());
+        this->collisionShape_->setOrientation(this->getOrientation());
+        // TODO: Scale
+        
+        return true;
+    }
+
+    /**
+    @brief
+        Detaches a child WorldEntity from this instance.
+    */
     void WorldEntity::detach(WorldEntity* object)
     {
-        this->node_->removeChild(object->node_);
+        if (this->children_.find(object) == this->children_.end())
+        {
+            CCOUT(2) << "Warning: Cannot detach an object that is not a child." << std::endl;
+            return;
+        }
+
+        // collision shapes
+        this->detachCollisionShape(object->collisionShape_);
+
+        // mass
+        if (object->getMass() > 0.0f)
+        {
+            this->childrenMass_ -= object->getMass();
+            recalculateMassProps();
+        }
+
+        this->detachNode(object->node_);
         this->children_.erase(object);
-        object->parent_ = 0;
-        object->parentID_ = OBJECTID_UNKNOWN;
-
-//        this->getScene()->getRootSceneNode()->addChild(object->node_);
-    }
-
-    WorldEntity* WorldEntity::getAttachedObject(unsigned int index) const
+
+        object->notifyDetached();
+    }
+
+    /**
+    @brief
+        Function gets called when the object has been detached from its parent.
+    */
+    void WorldEntity::notifyDetached()
+    {
+        this->parent_ = 0;
+        this->parentID_ = OBJECTID_UNKNOWN;
+
+        // reset orientation of the collisionShape (cannot be set within a WE usually)
+        this->collisionShape_->setPosition(Vector3::ZERO);
+        this->collisionShape_->setOrientation(Quaternion::IDENTITY);
+        // TODO: Scale
+
+        if (this->bPhysicsActiveBeforeAttaching_)
+        {
+            this->activatePhysics();
+            this->bPhysicsActiveBeforeAttaching_ = false;
+        }
+    }
+
+    //! Returns an attached object (merely for XMLPort).
+    WorldEntity* WorldEntity::getAttachedObject(unsigned int index)
     {
         unsigned int i = 0;
@@ -154,3 +431,472 @@
         return 0;
     }
+
+    //! Attaches an Ogre::SceneNode to this WorldEntity.
+    void WorldEntity::attachNode(Ogre::SceneNode* node)
+    {
+        Ogre::Node* parent = node->getParent();
+        if (parent)
+            parent->removeChild(node);
+        this->node_->addChild(node);
+    }
+
+    //! Detaches an Ogre::SceneNode from this WorldEntity.
+    void WorldEntity::detachNode(Ogre::SceneNode* node)
+    {
+        this->node_->removeChild(node);
+//        this->getScene()->getRootSceneNode()->addChild(node);
+    }
+
+    //! Attaches an Ogre::MovableObject to this WorldEntity.
+    void WorldEntity::attachOgreObject(Ogre::MovableObject* object)
+    {
+        this->node_->attachObject(object);
+    }
+
+    //! Detaches an Ogre::MovableObject from this WorldEntity.
+    void WorldEntity::detachOgreObject(Ogre::MovableObject* object)
+    {
+        this->node_->detachObject(object);
+    }
+
+    //! Detaches an Ogre::MovableObject (by string) from this WorldEntity.
+    Ogre::MovableObject* WorldEntity::detachOgreObject(const Ogre::String& name)
+    {
+        return this->node_->detachObject(name);
+    }
+
+    //! Attaches a collision Shape to this object (delegated to the internal CompoundCollisionShape)
+    void WorldEntity::attachCollisionShape(CollisionShape* shape)
+    {
+        this->collisionShape_->attach(shape);
+        // Note: this->collisionShape_ already notifies us of any changes.
+    }
+
+    //! Detaches a collision Shape from this object (delegated to the internal CompoundCollisionShape)
+    void WorldEntity::detachCollisionShape(CollisionShape* shape)
+    {
+        // Note: The collision shapes may not be detached with this function!
+        this->collisionShape_->detach(shape);
+        // Note: this->collisionShape_ already notifies us of any changes.
+    }
+
+    //! Returns an attached collision Shape of this object (delegated to the internal CompoundCollisionShape)
+    CollisionShape* WorldEntity::getAttachedCollisionShape(unsigned int index)
+    {
+        return this->collisionShape_->getAttachedShape(index);
+    }
+
+    // Note: These functions are placed in WorldEntity.h as inline functions for the release build.
+#ifndef _NDEBUG
+    const Vector3& WorldEntity::getPosition() const
+    {
+        return this->node_->getPosition();
+    }
+
+    const Quaternion& WorldEntity::getOrientation() const
+    {
+        return this->node_->getOrientation();
+    }
+
+    const Vector3& WorldEntity::getScale3D() const
+    {
+        return this->node_->getScale();
+    }
+#endif
+
+    //! Returns the position relative to the root space
+    const Vector3& WorldEntity::getWorldPosition() const
+    {
+        return this->node_->_getDerivedPosition();
+    }
+
+    //! Returns the orientation relative to the root space
+    const Quaternion& WorldEntity::getWorldOrientation() const
+    {
+        return this->node_->_getDerivedOrientation();
+    }
+
+    //! Returns the scaling applied relative to the root space in 3 coordinates
+    const Vector3& WorldEntity::getWorldScale3D() const
+    {
+        return this->node_->_getDerivedScale();
+    }
+
+    /**
+    @brief
+        Returns the scaling applied relative to the root space in 3 coordinates
+    @return
+        Returns the scaling if it is uniform, 1.0f otherwise.
+    */
+    float WorldEntity::getWorldScale() const
+    {
+        Vector3 scale = this->getWorldScale3D();
+        return (scale.x == scale.y && scale.x == scale.z) ? scale.x : 1;
+    }
+
+    /**
+    @brief
+        Sets the three dimensional scaling of this object.
+    @Note
+        Scaling physical objects has not yet been implemented and is therefore forbidden.
+    */
+    void WorldEntity::setScale3D(const Vector3& scale)
+    {
+/*
+HACK HACK HACK
+        if (bScalePhysics && this->hasPhysics() && scale != Vector3::UNIT_SCALE)
+        {
+            CCOUT(2) << "Warning: Cannot set the scale of a physical object: Not yet implemented. Ignoring scaling." << std::endl;
+            return;
+        }
+HACK HACK HACK
+*/
+        this->node_->setScale(scale);
+
+        this->changedScale();
+    }
+
+    /**
+    @brief
+        Translates this WorldEntity by a vector.
+    @param relativeTo
+        @see TransformSpace::Enum
+    */
+    void WorldEntity::translate(const Vector3& distance, TransformSpace::Enum relativeTo)
+    {
+        switch (relativeTo)
+        {
+        case TransformSpace::Local:
+            // position is relative to parent so transform downwards
+            this->setPosition(this->getPosition() + this->getOrientation() * distance);
+            break;
+        case TransformSpace::Parent:
+            this->setPosition(this->getPosition() + distance);
+            break;
+        case TransformSpace::World:
+            // position is relative to parent so transform upwards
+            if (this->node_->getParent())
+                setPosition(getPosition() + (node_->getParent()->_getDerivedOrientation().Inverse() * distance)
+                    / node_->getParent()->_getDerivedScale());
+            else
+                this->setPosition(this->getPosition() + distance);
+            break;
+        }
+    }
+
+    /**
+    @brief
+        Rotates this WorldEntity by a quaternion.
+    @param relativeTo
+        @see TransformSpace::Enum
+    */
+    void WorldEntity::rotate(const Quaternion& rotation, TransformSpace::Enum relativeTo)
+    {
+        switch(relativeTo)
+        {
+        case TransformSpace::Local:
+            this->setOrientation(this->getOrientation() * rotation);
+            break;
+        case TransformSpace::Parent:
+            // Rotations are normally relative to local axes, transform up
+            this->setOrientation(rotation * this->getOrientation());
+            break;
+        case TransformSpace::World:
+            // Rotations are normally relative to local axes, transform up
+            this->setOrientation(this->getOrientation() * this->getWorldOrientation().Inverse()
+                * rotation * this->getWorldOrientation());
+            break;
+        }
+    }
+
+    /**
+    @brief
+        Makes this WorldEntity look a specific target location.
+    @param relativeTo
+        @see TransformSpace::Enum
+    @param localDirectionVector
+        The vector which normally describes the natural direction of the object, usually -Z.
+    */
+    void WorldEntity::lookAt(const Vector3& target, TransformSpace::Enum relativeTo, const Vector3& localDirectionVector)
+    {
+        Vector3 origin;
+        switch (relativeTo)
+        {
+        case TransformSpace::Local:
+            origin = Vector3::ZERO;
+            break;
+        case TransformSpace::Parent:
+            origin = this->getPosition();
+            break;
+        case TransformSpace::World:
+            origin = this->getWorldPosition();
+            break;
+        }
+        this->setDirection(target - origin, relativeTo, localDirectionVector);
+    }
+
+    /**
+    @brief
+        Makes this WorldEntity look in specific direction.
+    @param relativeTo
+        @see TransformSpace::Enum
+    @param localDirectionVector
+        The vector which normally describes the natural direction of the object, usually -Z.
+    */
+    void WorldEntity::setDirection(const Vector3& direction, TransformSpace::Enum relativeTo, const Vector3& localDirectionVector)
+    {
+        Quaternion savedOrientation(this->getOrientation());
+        Ogre::Node::TransformSpace ogreRelativeTo;
+        switch (relativeTo)
+        {
+        case TransformSpace::Local:
+            ogreRelativeTo = Ogre::Node::TS_LOCAL; break;
+        case TransformSpace::Parent:
+            ogreRelativeTo = Ogre::Node::TS_PARENT; break;
+        case TransformSpace::World:
+            ogreRelativeTo = Ogre::Node::TS_WORLD; break;
+        }
+        this->node_->setDirection(direction, ogreRelativeTo, localDirectionVector);
+        Quaternion newOrientation(this->node_->getOrientation());
+        this->node_->setOrientation(savedOrientation);
+        this->setOrientation(newOrientation);
+    }
+
+    //! Activates physics if the CollisionType is not None.
+    void WorldEntity::activatePhysics()
+    {
+        if (this->isActive() && this->hasPhysics() && !this->isPhysicsActive() && !this->parent_)
+        {
+            this->getScene()->addPhysicalObject(this);
+            this->bPhysicsActive_ = true;
+            this->bPhysicsActiveSynchronised_ = true;
+        }
+    }
+
+    //! Deactivates physics but the CollisionType does not change.
+    void WorldEntity::deactivatePhysics()
+    {
+        if (this->isPhysicsActive())
+        {
+            this->getScene()->removePhysicalObject(this);
+            this->bPhysicsActive_ = false;
+            this->bPhysicsActiveSynchronised_ = false;
+        }
+    }
+
+    //! Tells whether the object has already been added to the Bullet physics World.
+    bool WorldEntity::addedToPhysicalWorld() const
+    {
+        return this->physicalBody_ && this->physicalBody_->isInWorld();
+    }
+
+    /**
+    @brief
+        Sets the CollisionType. This alters the object significantly! @see CollisionType.
+    @Note
+        Operation does not work on attached WorldEntities.
+    */
+    void WorldEntity::setCollisionType(CollisionType type)
+    {
+        if (this->collisionType_ == type)
+            return;
+
+        // If we are already attached to a parent, this would be a bad idea..
+        if (this->parent_)
+        {
+            CCOUT(2) << "Warning: Cannot set the collision type of a WorldEntity with a parent." << std::endl;
+            return;
+        }
+
+        // Check for type legality. Could be StaticEntity or MobileEntity.
+        if (!this->isCollisionTypeLegal(type))
+            return;
+
+        if (this->isPhysicsActive())
+            this->deactivatePhysics();
+
+        bool bReactivatePhysics = true;
+        if (this->hasPhysics() && !this->isPhysicsActive())
+            bReactivatePhysics = false;
+
+        // Check whether we have to create or destroy.
+        if (type != None && this->collisionType_ == None)
+        {
+/*
+HACK HACK HACK
+            // Check whether there was some scaling applied.
+            if (!this->node_->getScale().positionEquals(Vector3(1, 1, 1), 0.001))
+            {
+                CCOUT(2) << "Warning: Cannot create a physical body if there is scaling applied to the node: Not yet implemented." << std::endl;
+                return;
+            }
+HACK HACK HACK
+*/
+            // Create new rigid body
+            btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, this->collisionShape_->getCollisionShape());
+            this->physicalBody_ = new btRigidBody(bodyConstructionInfo);
+            this->physicalBody_->setUserPointer(this);
+            this->physicalBody_->setActivationState(DISABLE_DEACTIVATION);
+        }
+        else if (type == None && this->collisionType_ != None)
+        {
+            // Destroy rigid body
+            assert(this->physicalBody_);
+            deactivatePhysics();
+            delete this->physicalBody_;
+            this->physicalBody_ = 0;
+            this->collisionType_ = None;
+            this->collisionTypeSynchronised_ = None;
+            return;
+        }
+
+        // Change type
+        switch (type)
+        {
+        case Dynamic:
+            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !(btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_KINEMATIC_OBJECT));
+            break;
+        case Kinematic:
+            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_KINEMATIC_OBJECT);
+            break;
+        case Static:
+            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT);
+            break;
+        case None:
+            assert(false); // Doesn't happen
+            return;
+        }
+        this->collisionType_ = type;
+        this->collisionTypeSynchronised_ = type;
+
+        // update mass and inertia tensor
+        recalculateMassProps();
+        internalSetPhysicsProps();
+        collisionCallbackActivityChanged();
+        collisionResponseActivityChanged();
+        if (bReactivatePhysics)
+            activatePhysics();
+    }
+
+    //! Sets the CollisionType by string (used for the XMLPort)
+    void WorldEntity::setCollisionTypeStr(const std::string& typeStr)
+    {
+        std::string typeStrLower = getLowercase(typeStr);
+        CollisionType type;
+        if (typeStrLower == "dynamic")
+            type = Dynamic;
+        else if (typeStrLower == "static")
+            type = Static;
+        else if (typeStrLower == "kinematic")
+            type = Kinematic;
+        else if (typeStrLower == "none")
+            type = None;
+        else
+            ThrowException(ParseError, std::string("Attempting to set an unknown collision type: '") + typeStr + "'.");
+        this->setCollisionType(type);
+    }
+
+    //! Gets the CollisionType by string (used for the XMLPort)
+    std::string WorldEntity::getCollisionTypeStr() const
+    {
+        switch (this->getCollisionType())
+        {
+            case Dynamic:
+                return "dynamic";
+            case Kinematic:
+                return "kinematic";
+            case Static:
+                return "static";
+            case None:
+                return "none";
+            default:
+                assert(false);
+                return "";
+        }
+    }
+
+    /**
+    @brief
+        Recalculates the accumulated child mass and calls recalculateMassProps()
+        and notifies the parent of the change.
+    @Note
+        Called by a child WE
+    */
+    void WorldEntity::notifyChildMassChanged()
+    {
+        // Note: CollisionShape changes of a child get handled over the internal CompoundCollisionShape already
+        // Recalculate mass
+        this->childrenMass_ = 0.0f;
+        for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); ++it)
+            this->childrenMass_ += (*it)->getMass();
+        recalculateMassProps();
+        // Notify parent WE
+        if (this->parent_)
+            parent_->notifyChildMassChanged();
+    }
+
+    /**
+    @brief
+        Undertakes the necessary steps to change the collision shape in Bullet, even at runtime.
+    @Note
+        - called by this->collisionShape_
+        - May have a REALLY big overhead when called continuously at runtime, because then we need
+          to remove the physical body from Bullet and add it again.
+    */
+    void WorldEntity::notifyCollisionShapeChanged()
+    {
+        if (hasPhysics())
+        {
+            // Bullet doesn't like sudden changes of the collision shape, so we remove and add it again
+            if (this->addedToPhysicalWorld())
+            {
+                this->deactivatePhysics();
+                this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
+                this->activatePhysics();
+            }
+            else
+                this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
+        }
+        recalculateMassProps();
+    }
+
+    //! Updates all mass dependent parameters (mass, inertia tensor and child mass)
+    void WorldEntity::recalculateMassProps()
+    {
+        // Store local inertia for faster access. Evaluates to (0,0,0) if there is no collision shape.
+        float totalMass = this->mass_ + this->childrenMass_;
+        this->collisionShape_->calculateLocalInertia(totalMass, this->localInertia_);
+        if (this->hasPhysics())
+        {
+            if (this->isStatic())
+            {
+                // Just set everything to zero
+                this->physicalBody_->setMassProps(0.0f, btVector3(0, 0, 0));
+            }
+            else if ((this->mass_ + this->childrenMass_) == 0.0f)
+            {
+                // Use default values to avoid very large or very small values
+                CCOUT(4) << "Warning: Setting the internal physical mass to 1.0 because mass_ is 0.0" << std::endl;
+                btVector3 inertia(0, 0, 0);
+                this->collisionShape_->calculateLocalInertia(1.0f, inertia);
+                this->physicalBody_->setMassProps(1.0f, inertia);
+            }
+            else
+            {
+                this->physicalBody_->setMassProps(totalMass, this->localInertia_);
+            }
+        }
+    }
+
+    //! Copies our own parameters for restitution, angular factor, dampings and friction to the bullet rigid body.
+    void WorldEntity::internalSetPhysicsProps()
+    {
+        if (this->hasPhysics())
+        {
+            this->physicalBody_->setRestitution(this->restitution_);
+            this->physicalBody_->setAngularFactor(this->angularFactor_);
+            this->physicalBody_->setDamping(this->linearDamping_, this->angularDamping_);
+            this->physicalBody_->setFriction(this->friction_);
+        }
+    }
 }
Index: code/trunk/src/orxonox/objects/worldentities/WorldEntity.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/WorldEntity.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/WorldEntity.h	(revision 2662)
@@ -22,4 +22,5 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder (physics)
  *   Co-authors:
  *      ...
@@ -32,16 +33,45 @@
 #include "OrxonoxPrereqs.h"
 
-#define OGRE_FORCE_ANGLE_TYPES
-
+#ifdef _NDEBUG
 #include <OgreSceneNode.h>
-
-#include "network/Synchronisable.h"
+#else
+#include <OgrePrerequisites.h>
+#endif
+#include "LinearMath/btMotionState.h"
+
+#include "util/Math.h"
 #include "core/BaseObject.h"
-#include "util/Math.h"
+#include "network/synchronisable/Synchronisable.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable
+    /**
+    @brief
+        The WorldEntity represents everything that can be put in a Scene at a certain location.
+
+        It is supposed to be the base class of everything you would call an 'object' in a Scene.
+        The class itself is abstract which means you cannot use it directly. You may use StaticEntity
+        as the simplest derivative or (derived from MobileEntity) MovableEntity and ControllableEntity
+        as more advanced ones.
+
+        The basic task of the WorldEntity is provide a location, a direction and a scaling and the possibility
+        to create an entire hierarchy of derivated objects.
+        It is also the basis for the physics interface to the Bullet physics engine.
+        Every WorldEntity can have a specific collision type: @see CollisionType
+        This would then imply that every scene object could have any collision type. To limit this, you can always
+        override this->isCollisionTypeLegal(CollisionType). Return false if the collision type is not supported
+        for a specific object.
+        There is also support for attaching WorldEntities with physics to each other. Currently, the collision shape
+        of both objects simply get merged into one larger shape (for static collision type).
+        The phyiscal body that is internally stored and administrated has the following supported properties:
+        - Restitution, angular factor, linear damping, angular damping, fricition, mass and collision shape.
+        You can get more information at the corresponding set function.
+
+        Collision shapes: These are controlled by the internal WorldEntityCollisionShape. @see WorldEntityCollisionShape.
+    */
+    class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable, public btMotionState
     {
+        friend class Scene;
+
         public:
             WorldEntity(BaseObject* creator);
@@ -51,5 +81,5 @@
             void registerVariables();
 
-            inline Ogre::SceneNode* getNode() const
+            inline const Ogre::SceneNode* getNode() const
                 { return this->node_; }
 
@@ -64,12 +94,13 @@
             inline void setPosition(float x, float y, float z)
                 { this->setPosition(Vector3(x, y, z)); }
-            inline const Vector3& getPosition() const
-                { return this->node_->getPosition(); }
-            inline const Vector3& getWorldPosition() const
-                { return this->node_->getWorldPosition(); }
-
-            virtual void translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0;
-            inline void translate(float x, float y, float z, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
+            const Vector3& getPosition() const;
+            const Vector3& getWorldPosition() const;
+
+            void translate(const Vector3& distance, TransformSpace::Enum relativeTo = TransformSpace::Parent);
+            inline void translate(float x, float y, float z, TransformSpace::Enum relativeTo = TransformSpace::Parent)
                 { this->translate(Vector3(x, y, z), relativeTo); }
+
+            virtual inline const Vector3& getVelocity() const
+                { return Vector3::ZERO; }
 
             virtual void setOrientation(const Quaternion& orientation) = 0;
@@ -80,54 +111,53 @@
             inline void setOrientation(const Vector3& axis, const Degree& angle)
                 { this->setOrientation(Quaternion(angle, axis)); }
-            inline const Quaternion& getOrientation() const
-                { return this->node_->getOrientation(); }
-            inline const Quaternion& getWorldOrientation() const
-                { return this->node_->getWorldOrientation(); }
-
-            virtual void rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0;
-            inline void rotate(const Vector3& axis, const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
+            const Quaternion& getOrientation() const;
+            const Quaternion& getWorldOrientation() const;
+
+            void rotate(const Quaternion& rotation, TransformSpace::Enum relativeTo = TransformSpace::Local);
+            inline void rotate(const Vector3& axis, const Degree& angle, TransformSpace::Enum relativeTo = TransformSpace::Local)
                 { this->rotate(Quaternion(angle, axis), relativeTo); }
-            inline void rotate(const Vector3& axis, const Radian& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
-                { this->rotate(Quaternion(angle, axis), relativeTo); }
-
-            virtual void yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0;
-            inline void yaw(const Radian& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
-                { this->yaw(Degree(angle), relativeTo); }
-            virtual void pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0;
-            inline void pitch(const Radian& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
-                { this->pitch(Degree(angle), relativeTo); }
-            virtual void roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL) = 0;
-            inline void roll(const Radian& angle, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL)
-                { this->roll(Degree(angle), relativeTo); }
-
-            virtual void lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z) = 0;
-            virtual void setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z) = 0;
-            inline void setDirection(float x, float y, float z, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TS_LOCAL, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z)
+
+            inline void yaw(const Degree& angle, TransformSpace::Enum relativeTo = TransformSpace::Local)
+                { this->rotate(Quaternion(angle, Vector3::UNIT_Y), relativeTo); }
+            inline void pitch(const Degree& angle, TransformSpace::Enum relativeTo = TransformSpace::Local)
+                { this->rotate(Quaternion(angle, Vector3::UNIT_X), relativeTo); }
+            inline void roll(const Degree& angle, TransformSpace::Enum relativeTo = TransformSpace::Local)
+                { this->rotate(Quaternion(angle, Vector3::UNIT_Z), relativeTo); }
+
+            void lookAt(const Vector3& target, TransformSpace::Enum relativeTo = TransformSpace::Parent, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z);
+            void setDirection(const Vector3& direction, TransformSpace::Enum relativeTo = TransformSpace::Local, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z);
+            inline void setDirection(float x, float y, float z, TransformSpace::Enum relativeTo = TransformSpace::Local, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z)
                 { this->setDirection(Vector3(x, y, z), relativeTo, localDirectionVector); }
 
-            inline void setScale3D(const Vector3& scale)
-                { this->node_->setScale(scale); }
+            virtual void setScale3D(const Vector3& scale);
             inline void setScale3D(float x, float y, float z)
-                { this->node_->setScale(x, y, z); }
-            inline const Vector3& getScale3D(void) const
-                { return this->node_->getScale(); }
+                { this->setScale3D(Vector3(x, y, z)); }
+            const Vector3& getScale3D(void) const;
+            const Vector3& getWorldScale3D() const;
 
             inline void setScale(float scale)
-                { this->node_->setScale(scale, scale, scale); }
+                { this->setScale3D(scale, scale, scale); }
             inline float getScale() const
                 { Vector3 scale = this->getScale3D(); return (scale.x == scale.y && scale.x == scale.z) ? scale.x : 1; }
+            float getWorldScale() const;
 
             inline void scale3D(const Vector3& scale)
-                { this->node_->scale(scale); }
+                { this->setScale3D(this->getScale3D() * scale); }
             inline void scale3D(float x, float y, float z)
-                { this->node_->scale(x, y, z); }
+                { this->scale3D(Vector3(x, y, z)); }
             inline void scale(float scale)
-                { this->node_->scale(scale, scale, scale); }
+                { this->scale3D(scale, scale, scale); }
+
+            virtual void changedScale() {}
 
             void attach(WorldEntity* object);
             void detach(WorldEntity* object);
-            WorldEntity* getAttachedObject(unsigned int index) const;
+            WorldEntity* getAttachedObject(unsigned int index);
             inline const std::set<WorldEntity*>& getAttachedObjects() const
                 { return this->children_; }
+
+            void attachOgreObject(Ogre::MovableObject* object);
+            void detachOgreObject(Ogre::MovableObject* object);
+            Ogre::MovableObject* detachOgreObject(const Ogre::String& name);
 
             inline void attachToParent(WorldEntity* parent)
@@ -138,10 +168,15 @@
                 { return this->parent_; }
 
+            void attachNode(Ogre::SceneNode* node);
+            void detachNode(Ogre::SceneNode* node);
+            void attachToNode(Ogre::SceneNode* node);
+            void detachFromNode(Ogre::SceneNode* node);
+
+            void notifyChildPropsChanged();
+
         protected:
             Ogre::SceneNode* node_;
 
         private:
-            void updateParent();
-
             inline void lookAt_xmlport(const Vector3& target)
                 { this->lookAt(target); }
@@ -155,8 +190,243 @@
                 { this->roll(angle); }
 
+            // network callbacks
+            void parentChanged();
+            inline void scaleChanged()
+                { this->setScale3D(this->getScale3D()); }
+
             WorldEntity* parent_;
             unsigned int parentID_;
             std::set<WorldEntity*> children_;
+
+
+        /////////////
+        // Physics //
+        /////////////
+
+        public:
+            /**
+            @brief
+                Denotes the possible types of physical objects in a Scene.
+
+                Dynamic:   The object is influenced by its physical environment, like for instance little ball.
+                Kinematic: The object can only influence other dynamic objects. It's movement is coordinated by your own saying.
+                Static:    Like kinematic but the object is not allowed to move during the simulation.
+                None:      The object has no physics at all.
+            */
+            enum CollisionType
+            {
+                Dynamic,
+                Kinematic,
+                Static,
+                None
+            };
+
+            //! Tells whether the object has any connection to the Bullet physics engine. If hasPhysics() is false, the object may still have a velocity.
+            bool hasPhysics()       const { return getCollisionType() != None     ; }
+            //! @see CollisionType
+            bool isStatic()         const { return getCollisionType() == Static   ; }
+            //! @see CollisionType
+            bool isKinematic()      const { return getCollisionType() == Kinematic; }
+            //! @see CollisionType
+            bool isDynamic()        const { return getCollisionType() == Dynamic  ; }
+            //! Tells whether physics has been activated (you can temporarily deactivate it)
+            bool isPhysicsActive()  const { return this->bPhysicsActive_; }
+            bool addedToPhysicalWorld() const;
+
+            void activatePhysics();
+            void deactivatePhysics();
+
+            //! Returns the CollisionType. @see CollisionType.
+            inline CollisionType getCollisionType() const
+                { return this->collisionType_; }
+            void setCollisionType(CollisionType type);
+
+            void setCollisionTypeStr(const std::string& type);
+            std::string getCollisionTypeStr() const;
+
+            //! Sets the mass of this object. Note that the total mass may be influenced by attached objects!
+            inline void setMass(float mass)
+                { this->mass_ = mass; recalculateMassProps(); }
+            //! Returns the mass of this object without its children.
+            inline float getMass() const
+                { return this->mass_; }
+
+            //! Returns the total mass of this object with all its attached children.
+            inline float getTotalMass() const
+                { return this->mass_ + this->childrenMass_; }
+
+            /**
+            @brief
+                Returns the diagonal elements of the inertia tensor when calculated in local coordinates.
+            @Note
+                The local inertia tensor cannot be set, but is calculated by Bullet according to the collisionShape.
+                With compound collision shapes, an approximation is used.
+            */
+            inline const btVector3& getLocalInertia() const
+                { return this->localInertia_; }
+
+            /**
+            @brief
+                Sets how much reaction is applied in a collision.
+                
+                Consider two equal spheres colliding with equal velocities:
+                Restitution 1 means that both spheres simply reverse their velocity (no loss of energy)
+                Restitution 0 means that both spheres will immediately stop moving
+                (maximum loss of energy without violating of the preservation of momentum)
+            */
+            inline void setRestitution(float restitution)
+                { this->restitution_ = restitution; internalSetPhysicsProps(); }
+            //! Returns the restitution parameter. @see setRestitution.
+            inline float getRestitution() const
+                { return this->restitution_; }
+
+            /**
+            @brief
+                Sets an artificial parameter that tells how much torque is applied when you apply a non-central force.
+
+                Normally the angular factor is 1, which means it's physically 'correct'. Howerver if you have a player
+                character that should not rotate when hit sideways, you can set the angular factor to 0.
+            */
+            inline void setAngularFactor(float angularFactor)
+                { this->angularFactor_ = angularFactor; internalSetPhysicsProps(); }
+            //! Returns the angular factor. @see setAngularFactor.
+            inline float getAngularFactor() const
+                { return this->angularFactor_; }
+
+            //! Applies a mass independent damping. Velocities will simply diminish exponentially.
+            inline void setLinearDamping(float linearDamping)
+                { this->linearDamping_ = linearDamping; internalSetPhysicsProps(); }
+            //! Returns the linear damping. @see setLinearDamping.
+            inline float getLinearDamping() const
+                { return this->linearDamping_; }
+
+            //! Applies a tensor independent rotation damping. Angular velocities will simply diminish exponentially.
+            inline void setAngularDamping(float angularDamping)
+                { this->angularDamping_ = angularDamping; internalSetPhysicsProps(); }
+            //! Returns the angular damping. @see setAngularDamping.
+            inline float getAngularDamping() const
+                { return this->angularDamping_; }
+
+            //! Applies friction to the object. Friction occurs when two objects collide.
+            inline void setFriction(float friction)
+                { this->friction_ = friction; internalSetPhysicsProps(); }
+            //! Returns the amount of friction applied to the object.
+            inline float getFriction() const
+                { return this->friction_; }
+
+            void attachCollisionShape(CollisionShape* shape);
+            void detachCollisionShape(CollisionShape* shape);
+            CollisionShape* getAttachedCollisionShape(unsigned int index);
+
+            void notifyCollisionShapeChanged();
+            void notifyChildMassChanged();
+
+            /**
+            @brief
+                Virtual function that gets called when this object collides with another.
+            @param otherObject
+                The object this one has collided into.
+            @pram contactPoint
+                Contact point provided by Bullet. Holds more information and can me modified. See return value.
+            @Return
+                Returning false means that no modification to the contactPoint has been made. Return true otherwise!
+            @Note
+                Condition is that enableCollisionCallback() was called.
+            */
+            virtual inline bool collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint)
+                { return false; } /* With false, Bullet assumes no modification to the collision objects. */
+
+            //! Enables the collidesAgainst(.) function. The object doesn't respond to collision otherwise!
+            inline void enableCollisionCallback()
+                { this->bCollisionCallbackActive_ = true; this->collisionCallbackActivityChanged(); }
+            //! Disables the collidesAgainst(.) function. @see enableCollisionCallback()
+            inline void disableCollisionCallback()
+                { this->bCollisionCallbackActive_ = false; this->collisionCallbackActivityChanged(); }
+            //! Tells whether there could be a collision callback via collidesAgainst(.)
+            inline bool isCollisionCallbackActive() const
+                { return this->bCollisionCallbackActive_; }
+
+            //! Enables or disables collision response (default is of course on)
+            inline void setCollisionResponse(bool value)
+                { this->bCollisionResponseActive_ = value; this->collisionResponseActivityChanged(); }
+            //! Tells whether there could be a collision response
+            inline bool hasCollisionResponse()
+                { return this->bCollisionResponseActive_; }
+
+        protected:
+            /**
+            @brief
+                Function checks whether the requested collision type is legal to this object.
+
+                You can override this function in a derived class to constrain the collision to e.g. None or Dynamic.
+                A projectile may not prove very useful if there is no physical body. Simply set the CollisionType
+                in its constructor and override this method. But be careful that a derived classe's virtual functions
+                don't yet exist in the constructor if a base class.
+            */
+            virtual bool isCollisionTypeLegal(CollisionType type) const = 0;
+
+            btRigidBody*  physicalBody_; //!< Bullet rigid body. Everything physical is applied to this instance.
+
+        private:
+            void recalculateMassProps();
+            void internalSetPhysicsProps();
+
+            bool notifyBeingAttached(WorldEntity* newParent);
+            void notifyDetached();
+
+            // network callbacks
+            void collisionTypeChanged();
+            void physicsActivityChanged();
+            void collisionCallbackActivityChanged();
+            void collisionResponseActivityChanged();
+            //! Network callback workaround to call a function when the value changes.
+            inline void massChanged()
+                { this->setMass(this->mass_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void restitutionChanged()
+                { this->setRestitution(this->restitution_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void angularFactorChanged()
+                { this->setAngularFactor(this->angularFactor_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void linearDampingChanged()
+                { this->setLinearDamping(this->linearDamping_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void angularDampingChanged()
+                { this->setAngularDamping(this->angularDamping_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void frictionChanged()
+                { this->setFriction(this->friction_); }
+
+            CollisionType                collisionType_;                 //!< @see setCollisionType
+            CollisionType                collisionTypeSynchronised_;     //!< Network synchronised variable for collisionType_
+            bool                         bPhysicsActive_;                //!< @see isPhysicsActive
+            bool                         bPhysicsActiveSynchronised_;    //!< Network synchronised variable for bPhysicsActive_
+            //! When attaching objects hierarchically this variable tells this object (as child) whether physics was activated before attaching (because the deactivate physics while being attached).
+            bool                         bPhysicsActiveBeforeAttaching_;
+            WorldEntityCollisionShape*   collisionShape_;                //!< Attached collision shapes go here
+            btScalar                     mass_;                          //!< @see setMass
+            btVector3                    localInertia_;                  //!< @see getLocalInertia
+            btScalar                     restitution_;                   //!< @see setRestitution
+            btScalar                     angularFactor_;                 //!< @see setAngularFactor
+            btScalar                     linearDamping_;                 //!< @see setLinearDamping
+            btScalar                     angularDamping_;                //!< @see setAngularDamping
+            btScalar                     friction_;                      //!< @see setFriction
+            btScalar                     childrenMass_;                  //!< Sum of all the children's masses
+            bool                         bCollisionCallbackActive_;      //!< @see enableCollisionCallback
+            bool                         bCollisionResponseActive_;      //!< Tells whether the object should respond to collisions
     };
+
+    // Inline heavily used functions for release builds. In debug, we better avoid including OgreSceneNode here.
+#ifdef _NDEBUG
+    inline const Vector3& WorldEntity::getPosition() const
+        { return this->node_->getPosition(); }
+    inline const Quaternion& WorldEntity::getOrientation() const
+        { return this->node_->getrOrientation(); }
+    inline const Vector3& WorldEntity::getScale3D(void) const
+        { return this->node_->getScale(); }
+#endif
+
+    SUPER_FUNCTION(5, WorldEntity, changedScale, false);
 }
 
Index: code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2662)
@@ -30,10 +30,13 @@
 #include "Pawn.h"
 
+#include "core/Core.h"
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
 #include "util/Math.h"
+#include "PawnManager.h"
 #include "objects/infos/PlayerInfo.h"
 #include "objects/gametypes/Gametype.h"
-#include "objects/weaponSystem/WeaponSystem.h"
+#include "objects/worldentities/ParticleSpawner.h"
+#include "objects/worldentities/ExplosionChunk.h"
 
 namespace orxonox
@@ -45,5 +48,8 @@
         RegisterObject(Pawn);
 
-        this->bAlive_ = false;
+        PawnManager::touch();
+        this->bAlive_ = true;
+        this->fire_ = 0x0;
+        this->firehack_ = 0x0;
 
         this->health_ = 0;
@@ -52,13 +58,19 @@
 
         this->lastHitOriginator_ = 0;
-        this->weaponSystem_ = 0;
-
-        /*
-        //WeaponSystem
-        weaponSystem_ = new WeaponSystem();
-        WeaponSet * weaponSet1 = new WeaponSet(1);
-        this->weaponSystem_->attachWeaponSet(weaponSet1);
-        this->weaponSystem_->getWeaponSetPointer(0)->getWeaponSlotPointer(0)->setAmmoType(true);
-        */
+
+        this->spawnparticleduration_ = 3.0f;
+
+        this->getPickUp().setPlayer(this);
+
+        if (Core::isMaster())
+        {
+            this->weaponSystem_ = new WeaponSystem(this);
+            this->weaponSystem_->setParentPawn(this);
+        }
+        else
+            this->weaponSystem_ = 0;
+
+        this->setRadarObjectColour(ColourValue::Red);
+        this->setRadarObjectShape(RadarViewable::Dot);
 
         this->registerVariables();
@@ -67,4 +79,12 @@
     Pawn::~Pawn()
     {
+        if (this->isInitialized())
+        {
+            for (ObjectList<PawnListener>::iterator it = ObjectList<PawnListener>::begin(); it != ObjectList<PawnListener>::end(); ++it)
+                it->destroyedPawn(this);
+
+            if (this->weaponSystem_)
+                delete this->weaponSystem_;
+        }
     }
 
@@ -73,13 +93,22 @@
         SUPER(Pawn, XMLPort, xmlelement, mode);
 
-        XMLPortParam(Pawn, "health", setHealth, getHealht, xmlelement, mode).defaultValues(100);
+        XMLPortParam(Pawn, "health", setHealth, getHealth, xmlelement, mode).defaultValues(100);
         XMLPortParam(Pawn, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
         XMLPortParam(Pawn, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
+        XMLPortParam(Pawn, "spawnparticlesource", setSpawnParticleSource, getSpawnParticleSource, xmlelement, mode);
+        XMLPortParam(Pawn, "spawnparticleduration", setSpawnParticleDuration, getSpawnParticleDuration, xmlelement, mode).defaultValues(3.0f);
+        XMLPortParam(Pawn, "explosionchunks", setExplosionChunks, getExplosionChunks, xmlelement, mode).defaultValues(7);
+
+        XMLPortObject(Pawn, WeaponSlot, "weaponslots", setWeaponSlot, getWeaponSlot, xmlelement, mode);
+        XMLPortObject(Pawn, WeaponSet, "weaponsets", setWeaponSet, getWeaponSet, xmlelement, mode);
+        XMLPortObject(Pawn, WeaponPack, "weapons", setWeaponPack, getWeaponPack, xmlelement, mode);
     }
 
     void Pawn::registerVariables()
     {
-        REGISTERDATA(this->bAlive_, direction::toclient);
-        REGISTERDATA(this->health_, direction::toclient);
+        registerVariable(this->bAlive_,        variableDirection::toclient);
+        registerVariable(this->health_,        variableDirection::toclient);
+        registerVariable(this->initialHealth_, variableDirection::toclient);
+        registerVariable(this->fire_,          variableDirection::toserver);
     }
 
@@ -87,4 +116,16 @@
     {
         SUPER(Pawn, tick, dt);
+
+        if (this->weaponSystem_)
+        {
+            if (this->fire_ & WeaponMode::fire)
+                this->weaponSystem_->fire(WeaponMode::fire);
+            if (this->fire_ & WeaponMode::altFire)
+                this->weaponSystem_->fire(WeaponMode::altFire);
+            if (this->fire_ & WeaponMode::altFire2)
+                this->weaponSystem_->fire(WeaponMode::altFire2);
+        }
+        this->fire_ = this->firehack_;
+        this->firehack_ = 0x0;
 
         if (this->health_ <= 0)
@@ -119,26 +160,73 @@
     }
 
-    void Pawn::spawn()
+    void Pawn::spawneffect()
     {
         // play spawn effect
+        if (this->spawnparticlesource_ != "")
+        {
+            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
+            effect->setPosition(this->getPosition());
+            effect->setOrientation(this->getOrientation());
+            effect->setDestroyAfterLife(true);
+            effect->setSource(this->spawnparticlesource_);
+            effect->setLifetime(this->spawnparticleduration_);
+        }
     }
 
     void Pawn::death()
     {
+        // Set bAlive_ to false and wait for PawnManager to do the destruction
         this->bAlive_ = false;
+
+        this->setDestroyWhenPlayerLeft(false);
+
         if (this->getGametype())
             this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
+
         if (this->getPlayer())
             this->getPlayer()->stopControl(this);
 
-        delete this;
-
+        if (Core::isMaster())
+            this->deatheffect();
+    }
+
+    void Pawn::deatheffect()
+    {
         // play death effect
-    }
-
-    void Pawn::fire()
-    {
-        if (this->weaponSystem_)
-            this->weaponSystem_->fire();
+        {
+            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
+            effect->setPosition(this->getPosition());
+            effect->setOrientation(this->getOrientation());
+            effect->setDestroyAfterLife(true);
+            effect->setSource("Orxonox/explosion2b");
+            effect->setLifetime(4.0f);
+        }
+        {
+            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
+            effect->setPosition(this->getPosition());
+            effect->setOrientation(this->getOrientation());
+            effect->setDestroyAfterLife(true);
+            effect->setSource("Orxonox/smoke6");
+            effect->setLifetime(4.0f);
+        }
+        {
+            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
+            effect->setPosition(this->getPosition());
+            effect->setOrientation(this->getOrientation());
+            effect->setDestroyAfterLife(true);
+            effect->setSource("Orxonox/sparks");
+            effect->setLifetime(4.0f);
+        }
+        for (unsigned int i = 0; i < this->numexplosionchunks_; ++i)
+        {
+            ExplosionChunk* chunk = new ExplosionChunk(this->getCreator());
+            chunk->setPosition(this->getPosition());
+
+        }
+    }
+
+    void Pawn::fire(WeaponMode::Enum fireMode)
+    {
+        this->firehack_ |= fireMode;
     }
 
@@ -146,5 +234,68 @@
     {
         this->setHealth(this->initialHealth_);
-        this->spawn();
+        if (Core::isMaster())
+            this->spawneffect();
+    }
+
+    void Pawn::dropItems()
+    {
+	pickUp.eraseAll();
+    }
+
+    void Pawn::setWeaponSlot(WeaponSlot * wSlot)
+    {
+        this->attach(wSlot);
+        if (this->weaponSystem_)
+            this->weaponSystem_->attachWeaponSlot(wSlot);
+    }
+
+    WeaponSlot * Pawn::getWeaponSlot(unsigned int index) const
+    {
+        if (this->weaponSystem_)
+            return this->weaponSystem_->getWeaponSlotPointer(index);
+        else
+            return 0;
+    }
+
+    void Pawn::setWeaponPack(WeaponPack * wPack)
+    {
+        if (this->weaponSystem_)
+        {
+            wPack->setParentWeaponSystem(this->weaponSystem_);
+            wPack->setParentWeaponSystemToAllWeapons(this->weaponSystem_);
+            this->weaponSystem_->attachWeaponPack( wPack,wPack->getFireMode() );
+            wPack->attachNeededMunitionToAllWeapons();
+        }
+    }
+
+    WeaponPack * Pawn::getWeaponPack(unsigned int firemode) const
+    {
+        if (this->weaponSystem_)
+            return this->weaponSystem_->getWeaponPackPointer(firemode);
+        else
+            return 0;
+    }
+
+    void Pawn::setWeaponSet(WeaponSet * wSet)
+    {
+        if (this->weaponSystem_)
+            this->weaponSystem_->attachWeaponSet(wSet);
+    }
+
+    WeaponSet * Pawn::getWeaponSet(unsigned int index) const
+    {
+        if (this->weaponSystem_)
+            return this->weaponSystem_->getWeaponSetPointer(index);
+        else
+            return 0;
+    }
+
+
+    ///////////////////
+    // Pawn Listener //
+    ///////////////////
+    PawnListener::PawnListener()
+    {
+        RegisterRootObject(PawnListener);
     }
 }
Index: code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2662)
@@ -31,10 +31,12 @@
 
 #include "OrxonoxPrereqs.h"
-
+#include "objects/pickup/ShipEquipment.h"
 #include "objects/worldentities/ControllableEntity.h"
+#include "objects/RadarViewable.h"
+#include "objects/weaponSystem/WeaponSystem.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Pawn : public ControllableEntity
+    class _OrxonoxExport Pawn : public ControllableEntity, public RadarViewable
     {
         public:
@@ -54,5 +56,5 @@
             inline void removeHealth(float health)
                 { this->setHealth(this->health_ - health); }
-            inline float getHealht() const
+            inline float getHealth() const
                 { return this->health_; }
 
@@ -74,13 +76,45 @@
             virtual void kill();
 
-            virtual void fire();
-
+            virtual void fire(WeaponMode::Enum fireMode);
             virtual void postSpawn();
 
+            void setWeaponSlot(WeaponSlot * wSlot);
+            WeaponSlot * getWeaponSlot(unsigned int index) const;
+            void setWeaponPack(WeaponPack * wPack);
+            WeaponPack * getWeaponPack(unsigned int firemode) const;
+            void setWeaponSet(WeaponSet * wSet);
+            WeaponSet * getWeaponSet(unsigned int index) const;
+
+            inline const WorldEntity* getWorldEntity() const
+                { return const_cast<Pawn*>(this); }
+
+            inline void setSpawnParticleSource(const std::string& source)
+                { this->spawnparticlesource_ = source; }
+            inline const std::string& getSpawnParticleSource() const
+                { return this->spawnparticlesource_; }
+
+            inline void setSpawnParticleDuration(float duration)
+                { this->spawnparticleduration_ = duration; }
+            inline float getSpawnParticleDuration() const
+                { return this->spawnparticleduration_; }
+
+            inline void setExplosionChunks(unsigned int chunks)
+                { this->numexplosionchunks_ = chunks; }
+            inline unsigned int getExplosionChunks() const
+                { return this->numexplosionchunks_; }
+
+            inline ShipEquipment& getPickUp()
+                {return this->pickUp;}
+
+            virtual void dropItems();
+
         protected:
-            virtual void spawn();
             virtual void death();
+            virtual void deatheffect();
+            virtual void spawneffect();
 
+            ShipEquipment pickUp;
             bool bAlive_;
+
 
             float health_;
@@ -91,4 +125,22 @@
 
             WeaponSystem* weaponSystem_;
+            unsigned int fire_;
+            unsigned int firehack_;
+
+            std::string spawnparticlesource_;
+            float spawnparticleduration_;
+            unsigned int numexplosionchunks_;
+    };
+
+    class _OrxonoxExport PawnListener : virtual public OrxonoxClass
+    {
+        friend class Pawn;
+
+        public:
+            PawnListener();
+            virtual ~PawnListener() {}
+
+        protected:
+            virtual void destroyedPawn(Pawn* pawn) = 0;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/pawns/SpaceShip.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/pawns/SpaceShip.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/pawns/SpaceShip.cc	(revision 2662)
@@ -30,11 +30,17 @@
 #include "SpaceShip.h"
 
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
+#include "util/Math.h"
+#include "util/Exception.h"
 #include "core/CoreIncludes.h"
 #include "core/ConfigValueIncludes.h"
+#include "core/Template.h"
 #include "core/XMLPort.h"
-#include "util/Math.h"
+#include "objects/items/Engine.h"
 
 namespace orxonox
 {
+    const float orientationGain = 100;
     CreateFactory(SpaceShip);
 
@@ -43,20 +49,25 @@
         RegisterObject(SpaceShip);
 
-        this->zeroDegree_ = 0;
-
-        this->maxSpeed_ = 0;
-        this->maxSecondarySpeed_ = 0;
-        this->maxRotation_ = 0;
-        this->translationAcceleration_ = 0;
-        this->rotationAcceleration_ = 0;
-        this->translationDamping_ = 0;
-
-        this->yawRotation_ = 0;
-        this->pitchRotation_ = 0;
-        this->rollRotation_ = 0;
+        this->primaryThrust_  = 100;
+        this->auxilaryThrust_ =  30;
+        this->rotationThrust_ =  10;
+
+        this->localLinearAcceleration_.setValue(0, 0, 0);
+        this->localAngularAcceleration_.setValue(0, 0, 0);
+        this->bBoost_ = false;
+        this->bPermanentBoost_ = false;
+        this->steering_ = Vector3::ZERO;
+        this->engine_ = 0;
+
 
         this->bInvertYAxis_ = false;
 
         this->setDestroyWhenPlayerLeft(true);
+
+        // SpaceShip is always a physical object per default
+        // Be aware of this call: The collision type legality check will not reach derived classes!
+        this->setCollisionType(WorldEntity::Dynamic);
+        // Get notification about collisions
+        this->enableCollisionCallback();
 
         this->setConfigValues();
@@ -66,4 +77,6 @@
     SpaceShip::~SpaceShip()
     {
+        if (this->isInitialized() && this->engine_)
+            delete this->engine_;
     }
 
@@ -72,20 +85,15 @@
         SUPER(SpaceShip, XMLPort, xmlelement, mode);
 
-        XMLPortParam(SpaceShip, "maxspeed",          setMaxSpeed,          getMaxSpeed,          xmlelement, mode);
-        XMLPortParam(SpaceShip, "maxsecondaryspeed", setMaxSecondarySpeed, getMaxSecondarySpeed, xmlelement, mode);
-        XMLPortParam(SpaceShip, "maxrotation",       setMaxRotation,       getMaxRotation,       xmlelement, mode);
-        XMLPortParam(SpaceShip, "transacc",          setTransAcc,          getTransAcc,          xmlelement, mode);
-        XMLPortParam(SpaceShip, "rotacc",            setRotAcc,            getRotAcc,            xmlelement, mode);
-        XMLPortParam(SpaceShip, "transdamp",         setTransDamp,         getTransDamp,         xmlelement, mode);
+        XMLPortParam(SpaceShip, "engine",            setEngineTemplate,    getEngineTemplate,    xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "primaryThrust",  primaryThrust_,  xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "auxilaryThrust", auxilaryThrust_, xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "rotationThrust", rotationThrust_, xmlelement, mode);
     }
 
     void SpaceShip::registerVariables()
     {
-        REGISTERDATA(this->maxSpeed_,                direction::toclient);
-        REGISTERDATA(this->maxSecondarySpeed_,       direction::toclient);
-        REGISTERDATA(this->maxRotation_,             direction::toclient);
-        REGISTERDATA(this->translationAcceleration_, direction::toclient);
-        REGISTERDATA(this->rotationAcceleration_,    direction::toclient);
-        REGISTERDATA(this->translationDamping_,      direction::toclient);
+        registerVariable(this->primaryThrust_,  variableDirection::toclient);
+        registerVariable(this->auxilaryThrust_, variableDirection::toclient);
+        registerVariable(this->rotationThrust_, variableDirection::toclient);
     }
 
@@ -95,119 +103,123 @@
     }
 
+    bool SpaceShip::isCollisionTypeLegal(WorldEntity::CollisionType type) const
+    {
+        if (type != WorldEntity::Dynamic)
+        {
+            CCOUT(1) << "Error: Cannot tell a SpaceShip not to be dynamic! Ignoring." << std::endl;
+            assert(false); // Only in debug mode
+            return false;
+        }
+        else
+            return true;
+    }
+
     void SpaceShip::tick(float dt)
     {
-        if (this->isLocallyControlled())
+        SUPER(SpaceShip, tick, dt);
+
+        if (this->hasLocalController())
         {
-            // #####################################
-            // ############# STEERING ##############
-            // #####################################
-
-            Vector3 velocity = this->getVelocity();
-            if (velocity.x > this->maxSecondarySpeed_)
-                velocity.x = this->maxSecondarySpeed_;
-            if (velocity.x < -this->maxSecondarySpeed_)
-                velocity.x = -this->maxSecondarySpeed_;
-            if (velocity.y > this->maxSecondarySpeed_)
-                velocity.y = this->maxSecondarySpeed_;
-            if (velocity.y < -this->maxSecondarySpeed_)
-                velocity.y = -this->maxSecondarySpeed_;
-            if (velocity.z > this->maxSecondarySpeed_)
-                velocity.z = this->maxSecondarySpeed_;
-            if (velocity.z < -this->maxSpeed_)
-                velocity.z = -this->maxSpeed_;
-
-            // normalize velocity and acceleration
-            for (size_t dimension = 0; dimension < 3; ++dimension)
+/*
+            this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() * getMass() * this->auxilaryThrust_);
+            this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() * getMass() * this->auxilaryThrust_);
+            if (this->localLinearAcceleration_.z() > 0)
+                this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->auxilaryThrust_);
+            else
+                this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->primaryThrust_);
+            this->physicalBody_->applyCentralForce(physicalBody_->getWorldTransform().getBasis() * this->localLinearAcceleration_);
+            this->localLinearAcceleration_.setValue(0, 0, 0);
+*/
+            if (!this->isInMouseLook())
             {
-                if (this->acceleration_[dimension] == 0)
+                this->localAngularAcceleration_ *= this->getLocalInertia() * this->rotationThrust_;
+                this->physicalBody_->applyTorque(physicalBody_->getWorldTransform().getBasis() * this->localAngularAcceleration_);
+                this->localAngularAcceleration_.setValue(0, 0, 0);
+            }
+        }
+    }
+
+    void SpaceShip::moveFrontBack(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() - value.x);
+        this->steering_.z = -value.x;
+    }
+
+    void SpaceShip::moveRightLeft(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() + value.x);
+        this->steering_.x = value.x;
+    }
+
+    void SpaceShip::moveUpDown(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() + value.x);
+        this->steering_.y = value.x;
+    }
+
+    void SpaceShip::rotateYaw(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setY(this->localAngularAcceleration_.y() - value.x);
+
+        Pawn::rotateYaw(value);
+    }
+
+    void SpaceShip::rotatePitch(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setX(this->localAngularAcceleration_.x() + value.x);
+
+        Pawn::rotatePitch(value);
+    }
+
+    void SpaceShip::rotateRoll(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setZ(this->localAngularAcceleration_.z() + value.x);
+
+        Pawn::rotateRoll(value);
+    }
+
+    void SpaceShip::fire()
+    {
+    }
+
+    void SpaceShip::boost()
+    {
+        this->bBoost_ = true;
+    }
+
+    void SpaceShip::loadEngineTemplate()
+    {
+        if (this->enginetemplate_ != "")
+        {
+            Template* temp = Template::getTemplate(this->enginetemplate_);
+
+            if (temp)
+            {
+                Identifier* identifier = temp->getBaseclassIdentifier();
+
+                if (identifier)
                 {
-                    if (velocity[dimension] > 0)
+                    BaseObject* object = identifier->fabricate(this);
+                    this->engine_ = dynamic_cast<Engine*>(object);
+
+                    if (this->engine_)
                     {
-                        velocity[dimension] -= (this->translationDamping_ * dt);
-                        if (velocity[dimension] < 0)
-                            velocity[dimension] = 0;
+                        this->engine_->addTemplate(temp);
+                        this->engine_->addToSpaceShip(this);
                     }
-                    else if (velocity[dimension] < 0)
+                    else
                     {
-                        velocity[dimension] += (this->translationDamping_ * dt);
-                        if (velocity[dimension] > 0)
-                            velocity[dimension] = 0;
+                        delete object;
                     }
                 }
             }
-
-            this->setVelocity(velocity);
         }
-
-
-        SUPER(SpaceShip, tick, dt);
-
-
-        if (this->isLocallyControlled())
-        {
-            this->yaw(this->yawRotation_ * dt);
-            if (this->bInvertYAxis_)
-                this->pitch(Degree(-this->pitchRotation_ * dt));
-            else
-                this->pitch(Degree( this->pitchRotation_ * dt));
-            this->roll(this->rollRotation_ * dt);
-
-            this->acceleration_.x = 0;
-            this->acceleration_.y = 0;
-            this->acceleration_.z = 0;
-
-            this->yawRotation_   = this->zeroDegree_;
-            this->pitchRotation_ = this->zeroDegree_;
-            this->rollRotation_  = this->zeroDegree_;
-        }
-    }
-
-    void SpaceShip::moveFrontBack(const Vector2& value)
-    {
-        this->acceleration_.z = -this->translationAcceleration_ * value.x;
-    }
-
-    void SpaceShip::moveRightLeft(const Vector2& value)
-    {
-        this->acceleration_.x = this->translationAcceleration_ * value.x;
-    }
-
-    void SpaceShip::moveUpDown(const Vector2& value)
-    {
-        this->acceleration_.y = this->translationAcceleration_ * value.x;
-    }
-
-    void SpaceShip::rotateYaw(const Vector2& value)
-    {
-        Degree temp = value.x * value.x * sgn(value.x) * this->rotationAcceleration_;
-        if (temp > this->maxRotation_)
-            temp = this->maxRotation_;
-        if (temp < -this->maxRotation_)
-            temp = -this->maxRotation_;
-        this->yawRotation_ = Degree(temp);
-    }
-
-    void SpaceShip::rotatePitch(const Vector2& value)
-    {
-        Degree temp = value.x * value.x * sgn(value.x) * this->rotationAcceleration_;
-        if (temp > this->maxRotation_)
-            temp = this->maxRotation_;
-        if (temp < -this->maxRotation_)
-            temp = -this->maxRotation_;
-        this->pitchRotation_ = Degree(temp);
-    }
-
-    void SpaceShip::rotateRoll(const Vector2& value)
-    {
-        Degree temp = value.x * value.x * sgn(value.x) * this->rotationAcceleration_;
-        if (temp > this->maxRotation_)
-            temp = this->maxRotation_;
-        if (temp < -this->maxRotation_)
-            temp = -this->maxRotation_;
-        this->rollRotation_ = Degree(temp);
-    }
-
-    void SpaceShip::fire()
-    {
+    }
+
+    void SpaceShip::setEngine(Engine* engine)
+    {
+        this->engine_ = engine;
+        if (engine && engine->getShip() != this)
+            engine->addToSpaceShip(this);
     }
 }
Index: code/trunk/src/orxonox/objects/worldentities/pawns/SpaceShip.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/pawns/SpaceShip.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/pawns/SpaceShip.h	(revision 2662)
@@ -32,4 +32,6 @@
 #include "OrxonoxPrereqs.h"
 
+#include "LinearMath/btVector3.h"
+
 #include "Pawn.h"
 
@@ -56,46 +58,50 @@
 
             virtual void fire();
+            virtual void boost();
 
-            void setMaxSpeed(float value)
-                { this->maxSpeed_ = value; }
-            void setMaxSecondarySpeed(float value)
-                { this->maxSecondarySpeed_ = value; }
-            void setMaxRotation(const Degree& value)
-                { this->maxRotation_ = value; }
-            void setTransAcc(float value)
-                { this->translationAcceleration_ = value; }
-            void setRotAcc(const Degree& value)
-                { this->rotationAcceleration_ = value; }
-            void setTransDamp(float value)
-                { this->translationDamping_ = value; }
+            void setEngine(Engine* engine);
+            inline Engine* getEngine() const
+                { return this->engine_; }
 
-            inline float getMaxSpeed() const
-                { return this->maxSpeed_; }
-            inline float getMaxSecondarySpeed() const
-                { return this->maxSecondarySpeed_; }
-            inline float getMaxRotation() const
-                { return this->maxRotation_.valueDegrees(); }
-            inline float getTransAcc() const
-                { return this->translationAcceleration_; }
-            inline float getRotAcc() const
-                { return this->rotationAcceleration_.valueDegrees(); }
-            inline float getTransDamp() const
-                { return this->translationDamping_; }
+            inline void setSteeringDirection(const Vector3& direction)
+                { this->steering_ = direction; }
+            inline const Vector3& getSteeringDirection() const
+                { return this->steering_; }
+
+            inline void setBoost(bool bBoost)
+                { this->bBoost_ = bBoost; }
+            inline bool getBoost() const
+                { return this->bBoost_; }
+
+            inline void setEngineTemplate(const std::string& temp)
+                { this->enginetemplate_ = temp; this->loadEngineTemplate(); }
+            inline const std::string& getEngineTemplate() const
+                { return this->enginetemplate_; }
+
+            inline void setPermanentBoost(bool bPermanent)
+                { this->bPermanentBoost_ = bPermanent; }
+            inline bool getPermanentBoost() const
+                { return this->bPermanentBoost_; }
 
         protected:
             bool bInvertYAxis_;
 
-            float maxSpeed_;
-            float maxSecondarySpeed_;
-            float translationAcceleration_;
-            float translationDamping_;
+            bool bBoost_;
+            bool bPermanentBoost_;
+            Vector3 steering_;
+            float primaryThrust_;
+            float auxilaryThrust_;
+            float rotationThrust_;
+            btVector3 localLinearAcceleration_;
+            btVector3 localAngularAcceleration_;
 
-            Degree maxRotation_;
-            Degree rotationAcceleration_;
+        private:
+            virtual bool isCollisionTypeLegal(WorldEntity::CollisionType type) const;
 
-            Degree zeroDegree_;
-            Degree pitchRotation_;
-            Degree yawRotation_;
-            Degree rollRotation_;
+        private:
+            void loadEngineTemplate();
+
+            std::string enginetemplate_;
+            Engine* engine_;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/pawns/Spectator.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/pawns/Spectator.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/pawns/Spectator.cc	(revision 2662)
@@ -30,5 +30,8 @@
 #include "Spectator.h"
 
+#include <OgreBillboardSet.h>
+
 #include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
 #include "core/Core.h"
 #include "objects/worldentities/Model.h"
@@ -49,23 +52,28 @@
         RegisterObject(Spectator);
 
-        this->speed_ = 100;
-        this->rotationSpeed_ = 3;
+        this->speed_ = 200;
 
         this->yaw_ = 0;
         this->pitch_ = 0;
         this->roll_ = 0;
+        this->localVelocity_ = Vector3::ZERO;
         this->setHudTemplate("spectatorhud");
-        this->hudmode_ = 0;
+        this->greetingFlare_ = 0;
 
         this->setDestroyWhenPlayerLeft(true);
 
-        this->greetingFlare_ = new BillboardSet();
-        this->greetingFlare_->setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 1.0, 0.8), Vector3(0, 20, 0), 1);
-        if (this->greetingFlare_->getBillboardSet())
-            this->getNode()->attachObject(this->greetingFlare_->getBillboardSet());
-        this->greetingFlare_->setVisible(false);
+        if (Core::showsGraphics())
+        {
+            this->greetingFlare_ = new BillboardSet();
+            this->greetingFlare_->setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 1.0, 0.8), Vector3(0, 20, 0), 1);
+            if (this->greetingFlare_->getBillboardSet())
+                this->attachOgreObject(this->greetingFlare_->getBillboardSet());
+            this->greetingFlare_->setVisible(false);
+        }
+
         this->bGreetingFlareVisible_ = false;
         this->bGreeting_ = false;
 
+        this->setConfigValues();
         this->registerVariables();
     }
@@ -78,5 +86,6 @@
             {
                 if (this->greetingFlare_->getBillboardSet())
-                    this->getNode()->detachObject(this->greetingFlare_->getBillboardSet());
+                    this->detachOgreObject(this->greetingFlare_->getBillboardSet());
+
                 delete this->greetingFlare_;
             }
@@ -84,9 +93,13 @@
     }
 
+    void Spectator::setConfigValues()
+    {
+        SetConfigValue(speed_, 200.0f);
+    }
+
     void Spectator::registerVariables()
     {
-        REGISTERDATA(this->bGreetingFlareVisible_, direction::toclient, new NetworkCallback<Spectator>(this, &Spectator::changedFlareVisibility));
-        REGISTERDATA(this->bGreeting_,             direction::toserver, new NetworkCallback<Spectator>(this, &Spectator::changedGreeting));
-        REGISTERDATA(this->hudmode_,               direction::toclient);
+        registerVariable(this->bGreetingFlareVisible_, variableDirection::toclient, new NetworkCallback<Spectator>(this, &Spectator::changedFlareVisibility));
+        registerVariable(this->bGreeting_,             variableDirection::toserver, new NetworkCallback<Spectator>(this, &Spectator::changedGreeting));
     }
 
@@ -99,20 +112,33 @@
     void Spectator::changedFlareVisibility()
     {
-        this->greetingFlare_->setVisible(this->bGreetingFlareVisible_);
+	if ( this->greetingFlare_ )
+            this->greetingFlare_->setVisible(this->bGreetingFlareVisible_);
     }
 
     void Spectator::tick(float dt)
     {
-        this->updateHUD();
-
-        if (this->isLocallyControlled())
-        {
-            Vector3 velocity = this->getVelocity();
-            velocity.normalise();
-            this->setVelocity(velocity * this->speed_);
-
-            this->yaw(Radian(this->yaw_ * this->rotationSpeed_));
-            this->pitch(Radian(this->pitch_ * this->rotationSpeed_));
-            this->roll(Radian(this->roll_ * this->rotationSpeed_));
+        if (this->hasLocalController())
+        {
+            float localSpeedSquared = this->localVelocity_.squaredLength();
+            float localSpeed;
+            if (localSpeedSquared > 1.0)
+                localSpeed = this->speed_ / sqrtf(localSpeedSquared);
+            else
+                localSpeed = this->speed_;
+
+            this->localVelocity_.x *= localSpeed;
+            this->localVelocity_.y *= localSpeed;
+            this->localVelocity_.z *= localSpeed;
+            this->setVelocity(this->getOrientation() * this->localVelocity_);
+            this->localVelocity_.x = 0;
+            this->localVelocity_.y = 0;
+            this->localVelocity_.z = 0;
+
+            if (!this->isInMouseLook())
+            {
+                this->yaw(Radian(this->yaw_ * this->getMouseLookSpeed()));
+                this->pitch(Radian(this->pitch_ * this->getMouseLookSpeed()));
+                this->roll(Radian(this->roll_ * this->getMouseLookSpeed()));
+            }
 
             this->yaw_ = this->pitch_ = this->roll_ = 0;
@@ -120,9 +146,4 @@
 
         SUPER(Spectator, tick, dt);
-
-        if (this->isLocallyControlled())
-        {
-            this->setVelocity(Vector3::ZERO);
-        }
     }
 
@@ -131,45 +152,49 @@
         ControllableEntity::setPlayer(player);
 
-//        this->setObjectMode(direction::toclient);
-    }
-
-    void Spectator::startLocalControl()
-    {
-        ControllableEntity::startLocalControl();
-//        if (this->isLocallyControlled())
-//            this->testmesh_->setVisible(false);
+//        this->setObjectMode(objectDirection::toclient);
+    }
+
+    void Spectator::startLocalHumanControl()
+    {
+        ControllableEntity::startLocalHumanControl();
     }
 
     void Spectator::moveFrontBack(const Vector2& value)
     {
-        this->setVelocity(this->getVelocity() + value.y * this->speed_ * WorldEntity::FRONT);
+        this->localVelocity_.z -= value.x;
     }
 
     void Spectator::moveRightLeft(const Vector2& value)
     {
-        this->setVelocity(this->getVelocity() + value.y * this->speed_ * WorldEntity::RIGHT);
+        this->localVelocity_.x += value.x;
     }
 
     void Spectator::moveUpDown(const Vector2& value)
     {
-        this->setVelocity(this->getVelocity() + value.y * this->speed_ * WorldEntity::UP);
+        this->localVelocity_.y += value.x;
     }
 
     void Spectator::rotateYaw(const Vector2& value)
     {
-        this->yaw_ = value.y;
+        this->yaw_ -= value.y;
+
+        ControllableEntity::rotateYaw(value);
     }
 
     void Spectator::rotatePitch(const Vector2& value)
     {
-        this->pitch_ = value.y;
+        this->pitch_ += value.y;
+
+        ControllableEntity::rotatePitch(value);
     }
 
     void Spectator::rotateRoll(const Vector2& value)
     {
-        this->roll_ = value.y;
-    }
-
-    void Spectator::fire()
+        this->roll_ += value.y;
+
+        ControllableEntity::rotateRoll(value);
+    }
+
+    void Spectator::fire(WeaponMode::Enum fireMode)
     {
         if (this->getPlayer())
@@ -187,71 +212,3 @@
         }
     }
-
-    void Spectator::updateHUD()
-    {
-        // <hack>
-        if (Core::isMaster())
-        {
-            if (this->getPlayer() && this->getGametype())
-            {
-                if (!this->getGametype()->hasStarted() && !this->getGametype()->isStartCountdownRunning())
-                {
-                    if (!this->getPlayer()->isReadyToSpawn())
-                        this->hudmode_ = 0;
-                    else
-                        this->hudmode_ = 1;
-                }
-                else if (!this->getGametype()->hasEnded())
-                {
-                    if (this->getGametype()->isStartCountdownRunning())
-                        this->hudmode_ = 2 + 10*(int)ceil(this->getGametype()->getStartCountdown());
-                    else
-                        this->hudmode_ = 3;
-                }
-                else
-                    this->hudmode_ = 4;
-            }
-            else
-                return;
-        }
-
-        if (this->getHUD())
-        {
-            std::string text;
-            int hudmode = this->hudmode_ % 10;
-
-            switch (hudmode)
-            {
-                case 0:
-                    text = "Press [Fire] to start the match";
-                    break;
-                case 1:
-                    text = "Waiting for other players";
-                    break;
-                case 2:
-                    text = convertToString((this->hudmode_ - 2) / 10);
-                    break;
-                case 3:
-                    text = "Press [Fire] to respawn";
-                    break;
-                case 4:
-                    text = "Game has ended";
-                    break;
-                default:;
-            }
-
-            std::map<std::string, OrxonoxOverlay*>::const_iterator it = this->getHUD()->getOverlays().begin();
-            for (; it != this->getHUD()->getOverlays().end(); ++it)
-            {
-                if (it->second->isA(Class(OverlayText)) && it->second->getName() == "state")
-                {
-                    OverlayText* overlay = dynamic_cast<OverlayText*>(it->second);
-                    if (overlay)
-                        overlay->setCaption(text);
-                    break;
-                }
-            }
-        }
-        // </hack>
-    }
 }
Index: code/trunk/src/orxonox/objects/worldentities/pawns/Spectator.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/pawns/Spectator.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/pawns/Spectator.h	(revision 2662)
@@ -42,9 +42,10 @@
             virtual ~Spectator();
 
+            void setConfigValues();
             void registerVariables();
             virtual void tick(float dt);
 
             virtual void setPlayer(PlayerInfo* player);
-            virtual void startLocalControl();
+            virtual void startLocalHumanControl();
 
             virtual void moveFrontBack(const Vector2& value);
@@ -56,5 +57,5 @@
             virtual void rotateRoll(const Vector2& value);
 
-            virtual void fire();
+            virtual void fire(WeaponMode::Enum fireMode);
             virtual void greet();
 
@@ -62,5 +63,4 @@
             void changedGreeting();
             void changedFlareVisibility();
-            void updateHUD();
 
             BillboardSet* greetingFlare_;
@@ -69,5 +69,4 @@
 
             float speed_;
-            float rotationSpeed_;
 
             float yaw_;
@@ -75,5 +74,5 @@
             float roll_;
 
-            int hudmode_;
+            Vector3 localVelocity_;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/triggers/PlayerTrigger.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/triggers/PlayerTrigger.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/triggers/PlayerTrigger.cc	(revision 2662)
@@ -28,7 +28,7 @@
 
 /**
-    @file PlayerTrigger.cc
+    @file
     @brief
-	Implementation of the PlayerTrigger class.
+    Implementation of the PlayerTrigger class.
 */
 
@@ -38,6 +38,6 @@
 #include "core/CoreIncludes.h"
 
-namespace orxonox {
-
+namespace orxonox
+{
     /**
     @brief
@@ -47,9 +47,9 @@
     {
         RegisterObject(PlayerTrigger);
-        
+
         this->player_ = NULL;
         this->isForPlayer_ = true;
     }
-    
+
     /**
     @brief
@@ -66,6 +66,5 @@
     void PlayerTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
     {
-	SUPER(PlayerTrigger, XMLPort, xmlelement, mode);
+        SUPER(PlayerTrigger, XMLPort, xmlelement, mode);
     }
-
 }
Index: code/trunk/src/orxonox/objects/worldentities/triggers/PlayerTrigger.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/triggers/PlayerTrigger.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/triggers/PlayerTrigger.h	(revision 2662)
@@ -28,7 +28,7 @@
 
 /**
-    @file PlayerTrigger.h
+    @file
     @brief
-	Definition of the PlayerTrigger class.
+    Definition of the PlayerTrigger class.
 */
 
@@ -40,6 +40,6 @@
 #include "Trigger.h"
 
-namespace orxonox {
-    
+namespace orxonox
+{
     /**
     @brief
@@ -50,33 +50,33 @@
     class _OrxonoxExport PlayerTrigger : public Trigger
     {
-	public:
-	    PlayerTrigger(BaseObject* creator);
-	    virtual ~PlayerTrigger();
-	    
-            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a PlayerTrigger object through XML.
+    public:
+        PlayerTrigger(BaseObject* creator);
+        virtual ~PlayerTrigger();
+        
+        virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a PlayerTrigger object through XML.
+        
+        /**
+        @brief Returns the player that triggered the PlayerTrigger.
+        @return Returns a pointer to the ControllableEntity that triggered the PlayerTrigger.
+        */
+        inline ControllableEntity* getTriggeringPlayer(void) const
+            { return this->player_; }
+        
+        /**
+        @brief Checks whether the PlayerTrigger normally returns a ControllableEntity.
+        @return Returns true if the PlayerTrigger normally returns a ControllableEntity.
+        */
+        inline bool isForPlayer(void) const
+           { return this->isForPlayer_; }
             
-            /**
-            @brief Returns the player that triggered the PlayerTrigger.
-            @return Returns a pointer to the ControllableEntity that triggered the PlayerTrigger.
-            */
-            inline ControllableEntity* getTriggeringPlayer(void) const
-                { return this->player_; }
-	    
-	    /**
-	    @brief Checks whether the PlayerTrigger normally returns a ControllableEntity.
-	    @return Returns true if the PlayerTrigger normally returns a ControllableEntity.
-	    */
-	    inline bool isForPlayer(void) const
-	       { return this->isForPlayer_; }
-            
-	protected:
-	    virtual bool isTriggered(TriggerMode mode) = 0;
-	    
-	    /**
-	    @brief Set the player that triggered the PlayerTrigger. This is normally done by classes inheriting vom PlayerTrigger.
-	    @param player A pointer to the ControllableEntity that triggered the PlayerTrigger.
-	    */
-	    inline void setTriggeringPlayer(ControllableEntity* player)
-	       { this->player_ = player; }
+    protected:
+        virtual bool isTriggered(TriggerMode mode) = 0;
+        
+        /**
+        @brief Set the player that triggered the PlayerTrigger. This is normally done by classes inheriting vom PlayerTrigger.
+        @param player A pointer to the ControllableEntity that triggered the PlayerTrigger.
+        */
+        inline void setTriggeringPlayer(ControllableEntity* player)
+           { this->player_ = player; }
 
             /**
@@ -84,11 +84,11 @@
             @param isForPlayer Should be true when the PlayerTrigger schould be set to normally be triggered by ControllableEntities, false if not.
             */
-	    inline void setForPlayer(bool isForPlayer)
-	       { this->isForPlayer_ = isForPlayer; }
-	    
-	private:
-	    ControllableEntity* player_; //!< The player that triggered the PlayerTrigger.
-	    bool isForPlayer_; //!< Is true when the PlayerTrigger schould be set to normally be triggered by ControllableEntities.
-	
+        inline void setForPlayer(bool isForPlayer)
+           { this->isForPlayer_ = isForPlayer; }
+        
+    private:
+        ControllableEntity* player_; //!< The player that triggered the PlayerTrigger.
+        bool isForPlayer_; //!< Is true when the PlayerTrigger schould be set to normally be triggered by ControllableEntities.
+    
     };
 
Index: code/trunk/src/orxonox/objects/worldentities/triggers/Trigger.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/triggers/Trigger.cc	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/triggers/Trigger.cc	(revision 2662)
@@ -31,8 +31,10 @@
 
 #include <OgreBillboard.h>
+#include <OgreBillboardSet.h>
 #include "util/Debug.h"
 #include "core/CoreIncludes.h"
 #include "core/ConsoleCommand.h"
 #include "core/XMLPort.h"
+#include "core/Core.h"
 #include "objects/Scene.h"
 
@@ -44,5 +46,5 @@
   CreateFactory(Trigger);
 
-  Trigger::Trigger(BaseObject* creator) : PositionableEntity(creator)
+  Trigger::Trigger(BaseObject* creator) : StaticEntity(creator)
   {
     RegisterObject(Trigger);
@@ -65,5 +67,5 @@
 //    this->bUpdating_ = false;
 
-    if (this->getScene() && this->getScene()->getSceneManager())
+    if (this->getScene() && Core::showsGraphics())
     {
       this->debugBillboard_.setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
@@ -71,5 +73,5 @@
 
       if (this->debugBillboard_.getBillboardSet())
-        this->getNode()->attachObject(this->debugBillboard_.getBillboardSet());
+          this->attachOgreObject(this->debugBillboard_.getBillboardSet());
     }
 
@@ -106,4 +108,6 @@
     if (!this->BaseObject::isActive())
         return;
+
+    SUPER(Trigger, tick, dt);
 
     bool newTriggered = this->isTriggered() ^ this->bInvertMode_;
Index: code/trunk/src/orxonox/objects/worldentities/triggers/Trigger.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/triggers/Trigger.h	(revision 2262)
+++ code/trunk/src/orxonox/objects/worldentities/triggers/Trigger.h	(revision 2662)
@@ -36,5 +36,5 @@
 
 #include "objects/Tickable.h"
-#include "objects/worldentities/PositionableEntity.h"
+#include "objects/worldentities/StaticEntity.h"
 #include "tools/BillboardSet.h"
 
@@ -48,5 +48,5 @@
   };
 
-  class _OrxonoxExport Trigger : public PositionableEntity, public Tickable
+  class _OrxonoxExport Trigger : public StaticEntity, public Tickable
   {
     public:
