Index: /code/branches/objecthierarchy/src/core/ConsoleCommand.cc
===================================================================
--- /code/branches/objecthierarchy/src/core/ConsoleCommand.cc	(revision 2000)
+++ /code/branches/objecthierarchy/src/core/ConsoleCommand.cc	(revision 2001)
@@ -41,6 +41,5 @@
 
         this->keybindMode_ = KeybindMode::OnPress;
-        this->axisParamIndex_ = -1;
-        this->bAxisRelative_ = false;
+        this->inputConfiguredParam_ = -1;
     }
 
Index: /code/branches/objecthierarchy/src/core/ConsoleCommand.h
===================================================================
--- /code/branches/objecthierarchy/src/core/ConsoleCommand.h	(revision 2000)
+++ /code/branches/objecthierarchy/src/core/ConsoleCommand.h	(revision 2001)
@@ -122,4 +122,12 @@
                 { return this->argumentList_.end(); }
 
+            inline ConsoleCommand& setAsInputCommand()
+            {
+                this->keybindMode(KeybindMode::OnHold);
+                this->defaultValue(0, Vector2(0.0f, 0.0f));
+                this->inputConfiguredParam(0);
+                return *this;
+            }
+
             inline ConsoleCommand& keybindMode(KeybindMode::Enum mode)
                 { this->keybindMode_ = mode; return *this; }
@@ -127,13 +135,8 @@
                 { return this->keybindMode_; }
 
-            inline ConsoleCommand& axisParamIndex(int index)
-                { this->axisParamIndex_ = index; return *this; }
-            inline int getAxisParamIndex() const
-                { return this->axisParamIndex_; }
-
-            inline ConsoleCommand& isAxisRelative(bool val)
-                { this->bAxisRelative_ = val; return *this; }
-            inline int getIsAxisRelative() const
-                { return this->bAxisRelative_; }
+            inline ConsoleCommand& inputConfiguredParam(int index)
+                { this->inputConfiguredParam_ = index; return *this; }
+            inline int getInputConfiguredParam_() const
+                { return this->inputConfiguredParam_; }
 
         private:
@@ -143,6 +146,5 @@
 
             KeybindMode::Enum keybindMode_;
-            int axisParamIndex_;
-            bool bAxisRelative_;
+            int inputConfiguredParam_;
     };
 
Index: /code/branches/objecthierarchy/src/core/input/Button.cc
===================================================================
--- /code/branches/objecthierarchy/src/core/input/Button.cc	(revision 2000)
+++ /code/branches/objecthierarchy/src/core/input/Button.cc	(revision 2001)
@@ -175,17 +175,16 @@
 
                 // check for param command
-                int paramIndex = eval.getConsoleCommand()->getAxisParamIndex();
+                int paramIndex = eval.getConsoleCommand()->getInputConfiguredParam_();
                 if (paramIndex >= 0)
                 {
                     // parameter supported command
                     ParamCommand* cmd = new ParamCommand();
-                    cmd->paramModifier_ = paramModifier;
-                    cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative();
+                    cmd->scale_ = paramModifier;
 
                     // add command to the buffer if not yet existing
                     for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer_->size(); iParamCmd++)
                     {
-                        if (getLowercase((*paramCommandBuffer_)[iParamCmd]->evaluation_.getOriginalCommand())
-                            == getLowercase(commandStr))
+                        if ((*paramCommandBuffer_)[iParamCmd]->evaluation_.getConsoleCommand()
+                            == eval.getConsoleCommand())
                         {
                             // already in list
Index: /code/branches/objecthierarchy/src/core/input/HalfAxis.h
===================================================================
--- /code/branches/objecthierarchy/src/core/input/HalfAxis.h	(revision 2000)
+++ /code/branches/objecthierarchy/src/core/input/HalfAxis.h	(revision 2001)
@@ -50,5 +50,5 @@
             , paramCommands_(0)
             , nParamCommands_(0)
-            , wasDown_(false)
+            , pressed_(false)
             , hasChanged_(false)
         { }
@@ -65,5 +65,5 @@
 
         // button related
-        bool wasDown_;
+        bool pressed_;
         bool hasChanged_;
     };
Index: /code/branches/objecthierarchy/src/core/input/InputCommands.cc
===================================================================
--- /code/branches/objecthierarchy/src/core/input/InputCommands.cc	(revision 2000)
+++ /code/branches/objecthierarchy/src/core/input/InputCommands.cc	(revision 2001)
@@ -34,4 +34,5 @@
 
 #include "InputCommands.h"
+#include "util/Math.h"
 #include "core/CommandExecutor.h"
 
@@ -51,12 +52,11 @@
     bool BufferedParamCommand::execute()
     {
-        if (nValuesAdded_)
+        if (this->abs_ != 0.0f || this->rel_ != 0.0f)
         {
-            BufferedParamCommand& cmd = *this;
-            cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_);
+            evaluation_.setEvaluatedParameter(paramIndex_, Vector2(abs_, rel_));
             // reset
-            cmd.nValuesAdded_ = 0;
-            cmd.value_ = 0;
-            return cmd.evaluation_.execute();
+            rel_ = 0.0;
+            abs_ = 0.0;
+            return evaluation_.execute();
         }
         else
@@ -79,39 +79,18 @@
         BufferedParamCommand& cmd = *paramCommand_;
         // command has an additional parameter
-        if (bRelative_)
+        if (rel != 0.0f)
         {
-            if (rel != 0.0f)
-            {
-                // we have to calculate a relative movement.
-                // paramModifier_ says how much one keystroke is
-                cmd.value_ += paramModifier_ * rel;
-            }
+            // calculate relative movement.
+            // scale_ says how much one keystroke is
+            cmd.rel_ += scale_ * rel;
         }
-        else if (abs != 0.0f)
+
+        if (abs != 0.0f)
         {
-            // Usually, joy sticks create 'noise' (they return values if they're in 0 position)
-            // and normally this is caught in tickInput(), but that threshold cannot be to high
-            // in order to preserve accuracy. Instead, we have to catch the problem here. An example:
-            // Someone only uses buttons with an active joystick. The joy stick value could then
-            // be 0.05 for instance and the the key value 1. Without handling the problem, the final
-            // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects.
-            float absQ = abs * abs;
-            float valueQ = cmd.value_ * cmd.value_;
-            if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics
-            {
-                cmd.value_ = abs * paramModifier_;
-                cmd.nValuesAdded_ = 1;
-            }
-            else if (absQ * 50.0f < valueQ)
-            {
-                // abs is too small, we just don't do anything
-            }
-            else
-            {
-                // we have to calculate the absolute position of the axis.
-                // Since there might be another axis that is affected, we have to wait and
-                // store the result in a temporary place
-                cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_;
-            }
+            cmd.abs_ += scale_ * abs;
+            if (cmd.abs_ > 1.0)
+                cmd.abs_ = 1.0;
+            if (cmd.abs_ < -1.0)
+                cmd.abs_ = -1.0;
         }
         return true;
Index: /code/branches/objecthierarchy/src/core/input/InputCommands.h
===================================================================
--- /code/branches/objecthierarchy/src/core/input/InputCommands.h	(revision 2000)
+++ /code/branches/objecthierarchy/src/core/input/InputCommands.h	(revision 2001)
@@ -44,9 +44,9 @@
     {
     public:
-        BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { }
+        BufferedParamCommand() : abs_(0.0f), rel_(0.0), paramIndex_(-1) { }
         bool execute();
 
-        float value_;
-        unsigned int nValuesAdded_;
+        float abs_;
+        float rel_;
         int paramIndex_;
         CommandEvaluation evaluation_;
@@ -82,9 +82,8 @@
     {
     public:
-        ParamCommand() : bRelative_(false), paramModifier_(1.0f), paramCommand_(0) { }
+        ParamCommand() : scale_(1.0f), paramCommand_(0) { }
         bool execute(float abs = 1.0f, float rel = 1.0f);
 
-        bool bRelative_;
-        float paramModifier_;
+        float scale_;
         BufferedParamCommand* paramCommand_;
     };
Index: /code/branches/objecthierarchy/src/core/input/KeyBinder.cc
===================================================================
--- /code/branches/objecthierarchy/src/core/input/KeyBinder.cc	(revision 2000)
+++ /code/branches/objecthierarchy/src/core/input/KeyBinder.cc	(revision 2001)
@@ -137,4 +137,6 @@
         SetConfigValue(analogThreshold_, 0.05f)
             .description("Threshold for analog axes until which the state is 0.");
+        SetConfigValue(bFilterAnalogNoise_, false)
+            .description("Specifies whether to filter small analog values like joy stick fluctuations.");
         SetConfigValue(mouseSensitivity_, 1.0f)
             .description("Mouse sensitivity.");
@@ -145,5 +147,5 @@
         SetConfigValue(mouseSensitivityDerived_, 1.0f)
             .description("Mouse sensitivity if mouse input is derived.");
-        SetConfigValue(mouseWheelStepSize_, 120.0f)
+        SetConfigValue(mouseWheelStepSize_, 120)
             .description("Equals one step of the mousewheel.");
         SetConfigValue(buttonThreshold_, 0.80f)
@@ -323,8 +325,7 @@
     void KeyBinder::tickMouse(float dt)
     {
-        tickDevices(mouseAxes_, mouseAxes_ + MouseAxisCode::numberOfAxes * 2);
-
         if (bDeriveMouseInput_)
         {
+            // only update when derive dt has passed
             if (deriveTime_ > derivePeriod_)
             {
@@ -357,40 +358,64 @@
                 deriveTime_ += dt;
         }
-    }
-
-    void KeyBinder::tickDevices(HalfAxis* begin, HalfAxis* end)
-    {
-        for (HalfAxis* current = begin; current < end; ++current) // pointer arithmetic
-        {
-            // button mode
-            // TODO: optimize out all the half axes that don't act as a button at the moment
-            if (current->hasChanged_)
-            {
-                if (!current->wasDown_ && current->absVal_ > current->buttonThreshold_)
-                {
-                    current->wasDown_ = true;
-                    if (current->nCommands_[KeybindMode::OnPress])
-                        current->execute(KeybindMode::OnPress);
-                }
-                else if (current->wasDown_ && current->absVal_ < current->buttonThreshold_)
-                {
-                    current->wasDown_ = false;
-                    if (current->nCommands_[KeybindMode::OnRelease])
-                        current->execute(KeybindMode::OnRelease);
-                }
-                current->hasChanged_ = false;
-            }
-
-            if (current->wasDown_)
-            {
-                if (current->nCommands_[KeybindMode::OnHold])
-                    current->execute(KeybindMode::OnHold);
-            }
-
-            // these are the actually useful axis bindings for analog input
-            if (current->relVal_ > analogThreshold_ || current->absVal_ > analogThreshold_)
-            {
-                current->execute();
-            }
+
+        for (int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            // Why dividing relative value by dt? The reason lies in the simple fact, that when you
+            // press a button that has relative movement, that value has to be multiplied by dt to be
+            // frame rate independant. This can easily (and only) be done in tickInput(float).
+            // Hence we need to divide by dt here for the mouse to compensate, because the relative
+            // move movements have nothing to do with dt.
+            if (dt != 0.0f)
+            {
+                // just ignore if dt == 0.0 because we have multiplied by 0.0 anyway..
+                mouseAxes_[i].relVal_ /= dt;
+            }
+
+            tickHalfAxis(mouseAxes_[i]);
+        }
+    }
+
+    void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
+    {
+        for (int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+        {
+            tickHalfAxis(joyStickAxes_[joyStick][i]);
+        }
+    }
+
+    void KeyBinder::tickHalfAxis(HalfAxis& halfAxis)
+    {
+        // button mode
+        // TODO: optimize out all the half axes that don't act as a button at the moment
+        if (halfAxis.hasChanged_)
+        {
+            if (!halfAxis.pressed_ && halfAxis.absVal_ > halfAxis.buttonThreshold_)
+            {
+                // key pressed event
+                halfAxis.pressed_ = true;
+                if (halfAxis.nCommands_[KeybindMode::OnPress])
+                    halfAxis.execute(KeybindMode::OnPress);
+            }
+            else if (halfAxis.pressed_ && halfAxis.absVal_ < halfAxis.buttonThreshold_)
+            {
+                // key released event
+                halfAxis.pressed_ = false;
+                if (halfAxis.nCommands_[KeybindMode::OnRelease])
+                    halfAxis.execute(KeybindMode::OnRelease);
+            }
+            halfAxis.hasChanged_ = false;
+        }
+
+        if (halfAxis.pressed_)
+        {
+            // key held event
+            if (halfAxis.nCommands_[KeybindMode::OnHold])
+                halfAxis.execute(KeybindMode::OnHold);
+        }
+
+        // these are the actually useful axis bindings for analog input
+        if (!bFilterAnalogNoise_ || halfAxis.relVal_ > analogThreshold_ || halfAxis.absVal_ > analogThreshold_)
+        {
+            halfAxis.execute();
         }
     }
@@ -407,5 +432,10 @@
         int rel[] = { rel_.x, -rel_.y };
 
-        if (!bDeriveMouseInput_)
+        if (bDeriveMouseInput_)
+        {
+            mouseRelative_[0] += rel[0];
+            mouseRelative_[1] += rel[1];
+        }
+        else
         {
             for (int i = 0; i < 2; i++)
@@ -437,9 +467,4 @@
             }
         }
-        else
-        {
-            mouseRelative_[0] += rel[0];
-            mouseRelative_[1] += rel[1];
-        }
 
         // relative
Index: /code/branches/objecthierarchy/src/core/input/KeyBinder.h
===================================================================
--- /code/branches/objecthierarchy/src/core/input/KeyBinder.h	(revision 2000)
+++ /code/branches/objecthierarchy/src/core/input/KeyBinder.h	(revision 2001)
@@ -71,5 +71,5 @@
         void tickJoyStick(float dt, unsigned int joyStick);
         // internal
-        void tickDevices(HalfAxis* begin, HalfAxis* end);
+        void tickHalfAxis(HalfAxis& halfAxis);
 
         void buttonThresholdChanged();
@@ -149,4 +149,6 @@
         //! Filename of default keybindings.
         std::string defaultKeybindings_;
+        //! Whether to filter small value analog input
+        bool bFilterAnalogNoise_;
         //! Threshold for analog triggers until which the state is 0.
         float analogThreshold_;
@@ -162,5 +164,5 @@
         float mouseSensitivityDerived_;
         //! Equals one step of the mousewheel
-        float mouseWheelStepSize_;
+        int mouseWheelStepSize_;
 
         //##### Constant config variables #####
@@ -198,14 +200,12 @@
     { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnHold); }
 
-    inline void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
-    {
-        tickDevices(&joyStickAxes_[joyStick][0], &joyStickAxes_[joyStick][JoyStickAxisCode::numberOfAxes * 2]);
-    }
-
     inline void KeyBinder::tickInput(float dt)
     {
         // execute all buffered bindings (additional parameter)
         for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
+        {
+            paramCommandBuffer_[i]->rel_ *= dt;
             paramCommandBuffer_[i]->execute();
+        }
 
         // always reset the relative movement of the mouse
Index: /code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.cc
===================================================================
--- /code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.cc	(revision 2000)
+++ /code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.cc	(revision 2001)
@@ -36,12 +36,12 @@
 namespace orxonox
 {
-    SetConsoleCommand(HumanController, moveFrontBack, true).defaultValue(0, 1.0f).axisParamIndex(0).keybindMode(KeybindMode::OnHold);
-    SetConsoleCommand(HumanController, moveRightLeft, true).defaultValue(0, 1.0f).axisParamIndex(0).keybindMode(KeybindMode::OnHold);
-    SetConsoleCommand(HumanController, moveUpDown,    true).defaultValue(0, 1.0f).axisParamIndex(0).keybindMode(KeybindMode::OnHold);
-    SetConsoleCommand(HumanController, rotateYaw,     true).defaultValue(0, 1.0f).axisParamIndex(0).keybindMode(KeybindMode::OnHold);
-    SetConsoleCommand(HumanController, rotatePitch,   true).defaultValue(0, 1.0f).axisParamIndex(0).keybindMode(KeybindMode::OnHold);
-    SetConsoleCommand(HumanController, rotateRoll,    true).defaultValue(0, 1.0f).axisParamIndex(0).keybindMode(KeybindMode::OnHold);
-    SetConsoleCommand(HumanController, fire,          true).axisParamIndex(0).keybindMode(KeybindMode::OnHold);
-    SetConsoleCommand(HumanController, altFire,       true).axisParamIndex(0).keybindMode(KeybindMode::OnHold);
+    SetConsoleCommand(HumanController, moveFrontBack, true).setAsInputCommand();
+    SetConsoleCommand(HumanController, moveRightLeft, true).setAsInputCommand();
+    SetConsoleCommand(HumanController, moveUpDown,    true).setAsInputCommand();
+    SetConsoleCommand(HumanController, rotateYaw,     true).setAsInputCommand();
+    SetConsoleCommand(HumanController, rotatePitch,   true).setAsInputCommand();
+    SetConsoleCommand(HumanController, rotateRoll,    true).setAsInputCommand();
+    SetConsoleCommand(HumanController, fire,          true).keybindMode(KeybindMode::OnHold);
+    SetConsoleCommand(HumanController, altFire,       true).keybindMode(KeybindMode::OnHold);
     SetConsoleCommand(HumanController, greet,         true);
     SetConsoleCommand(HumanController, use,           true);
@@ -64,38 +64,38 @@
     }
 
-    void HumanController::moveFrontBack(float value)
+    void HumanController::moveFrontBack(const Vector2& value)
     {
         if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->moveFrontBack(value);
+            HumanController::localController_s->pawn_->moveFrontBack(value.y);
     }
 
-    void HumanController::moveRightLeft(float value)
+    void HumanController::moveRightLeft(const Vector2& value)
     {
         if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->moveRightLeft(value);
+            HumanController::localController_s->pawn_->moveRightLeft(value.y);
     }
 
-    void HumanController::moveUpDown(float value)
+    void HumanController::moveUpDown(const Vector2& value)
     {
         if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->moveUpDown(value);
+            HumanController::localController_s->pawn_->moveUpDown(value.y);
     }
 
-    void HumanController::rotateYaw(float value)
+    void HumanController::rotateYaw(const Vector2& value)
     {
         if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->rotateYaw(value);
+            HumanController::localController_s->pawn_->rotateYaw(value.y);
     }
 
-    void HumanController::rotatePitch(float value)
+    void HumanController::rotatePitch(const Vector2& value)
     {
         if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->rotatePitch(value);
+            HumanController::localController_s->pawn_->rotatePitch(value.y);
     }
 
-    void HumanController::rotateRoll(float value)
+    void HumanController::rotateRoll(const Vector2& value)
     {
         if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->rotateRoll(value);
+            HumanController::localController_s->pawn_->rotateRoll(value.y);
     }
 
Index: /code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.h
===================================================================
--- /code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.h	(revision 2000)
+++ /code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.h	(revision 2001)
@@ -32,4 +32,5 @@
 #include "OrxonoxPrereqs.h"
 
+#include "util/Math.h"
 #include "Controller.h"
 
@@ -42,11 +43,11 @@
             virtual ~HumanController();
 
-            static void moveFrontBack(float value);
-            static void moveRightLeft(float value);
-            static void moveUpDown(float value);
+            static void moveFrontBack(const Vector2& value);
+            static void moveRightLeft(const Vector2& value);
+            static void moveUpDown(const Vector2& value);
 
-            static void rotateYaw(float value);
-            static void rotatePitch(float value);
-            static void rotateRoll(float value);
+            static void rotateYaw(const Vector2& value);
+            static void rotatePitch(const Vector2& value);
+            static void rotateRoll(const Vector2& value);
 
             static void fire();
Index: /code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.cc
===================================================================
--- /code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.cc	(revision 2000)
+++ /code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.cc	(revision 2001)
@@ -66,7 +66,8 @@
         this->setVelocity(velocity * this->speed_);
 
-        this->yaw(Radian(this->yaw_ * dt * this->rotationSpeed_));
-        this->pitch(Radian(this->pitch_ * dt * this->rotationSpeed_));
-        this->roll(Radian(this->roll_ * dt * this->rotationSpeed_));
+        // TODO: Check why I have removed *dt (1337)
+        this->yaw(Radian(this->yaw_ * this->rotationSpeed_));
+        this->pitch(Radian(this->pitch_ * this->rotationSpeed_));
+        this->roll(Radian(this->roll_ * this->rotationSpeed_));
 
         this->yaw_ = this->pitch_ = this->roll_ = 0;
