Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 23, 2008, 12:15:09 AM (16 years ago)
Author:
rgrieder
Message:
  • Fixed issue with relative mouse movements.
  • Fixed bug when parsing commands in keybindings.ini
  • Fixed potential framerate dependency with relative movements
  • Simplified the use of a configured input command
  • Changed how parametrised input is handled (superposition and [-1,1]-clamp instead of average).
Location:
code/branches/objecthierarchy/src/core
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • code/branches/objecthierarchy/src/core/ConsoleCommand.cc

    r1755 r2001  
    4141
    4242        this->keybindMode_ = KeybindMode::OnPress;
    43         this->axisParamIndex_ = -1;
    44         this->bAxisRelative_ = false;
     43        this->inputConfiguredParam_ = -1;
    4544    }
    4645
  • code/branches/objecthierarchy/src/core/ConsoleCommand.h

    r1755 r2001  
    122122                { return this->argumentList_.end(); }
    123123
     124            inline ConsoleCommand& setAsInputCommand()
     125            {
     126                this->keybindMode(KeybindMode::OnHold);
     127                this->defaultValue(0, Vector2(0.0f, 0.0f));
     128                this->inputConfiguredParam(0);
     129                return *this;
     130            }
     131
    124132            inline ConsoleCommand& keybindMode(KeybindMode::Enum mode)
    125133                { this->keybindMode_ = mode; return *this; }
     
    127135                { return this->keybindMode_; }
    128136
    129             inline ConsoleCommand& axisParamIndex(int index)
    130                 { this->axisParamIndex_ = index; return *this; }
    131             inline int getAxisParamIndex() const
    132                 { return this->axisParamIndex_; }
    133 
    134             inline ConsoleCommand& isAxisRelative(bool val)
    135                 { this->bAxisRelative_ = val; return *this; }
    136             inline int getIsAxisRelative() const
    137                 { return this->bAxisRelative_; }
     137            inline ConsoleCommand& inputConfiguredParam(int index)
     138                { this->inputConfiguredParam_ = index; return *this; }
     139            inline int getInputConfiguredParam_() const
     140                { return this->inputConfiguredParam_; }
    138141
    139142        private:
     
    143146
    144147            KeybindMode::Enum keybindMode_;
    145             int axisParamIndex_;
    146             bool bAxisRelative_;
     148            int inputConfiguredParam_;
    147149    };
    148150
  • code/branches/objecthierarchy/src/core/input/Button.cc

    r1887 r2001  
    175175
    176176                // check for param command
    177                 int paramIndex = eval.getConsoleCommand()->getAxisParamIndex();
     177                int paramIndex = eval.getConsoleCommand()->getInputConfiguredParam_();
    178178                if (paramIndex >= 0)
    179179                {
    180180                    // parameter supported command
    181181                    ParamCommand* cmd = new ParamCommand();
    182                     cmd->paramModifier_ = paramModifier;
    183                     cmd->bRelative_ = eval.getConsoleCommand()->getIsAxisRelative();
     182                    cmd->scale_ = paramModifier;
    184183
    185184                    // add command to the buffer if not yet existing
    186185                    for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer_->size(); iParamCmd++)
    187186                    {
    188                         if (getLowercase((*paramCommandBuffer_)[iParamCmd]->evaluation_.getOriginalCommand())
    189                             == getLowercase(commandStr))
     187                        if ((*paramCommandBuffer_)[iParamCmd]->evaluation_.getConsoleCommand()
     188                            == eval.getConsoleCommand())
    190189                        {
    191190                            // already in list
  • code/branches/objecthierarchy/src/core/input/HalfAxis.h

    r1887 r2001  
    5050            , paramCommands_(0)
    5151            , nParamCommands_(0)
    52             , wasDown_(false)
     52            , pressed_(false)
    5353            , hasChanged_(false)
    5454        { }
     
    6565
    6666        // button related
    67         bool wasDown_;
     67        bool pressed_;
    6868        bool hasChanged_;
    6969    };
  • code/branches/objecthierarchy/src/core/input/InputCommands.cc

    r1887 r2001  
    3434
    3535#include "InputCommands.h"
     36#include "util/Math.h"
    3637#include "core/CommandExecutor.h"
    3738
     
    5152    bool BufferedParamCommand::execute()
    5253    {
    53         if (nValuesAdded_)
     54        if (this->abs_ != 0.0f || this->rel_ != 0.0f)
    5455        {
    55             BufferedParamCommand& cmd = *this;
    56             cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_);
     56            evaluation_.setEvaluatedParameter(paramIndex_, Vector2(abs_, rel_));
    5757            // reset
    58             cmd.nValuesAdded_ = 0;
    59             cmd.value_ = 0;
    60             return cmd.evaluation_.execute();
     58            rel_ = 0.0;
     59            abs_ = 0.0;
     60            return evaluation_.execute();
    6161        }
    6262        else
     
    7979        BufferedParamCommand& cmd = *paramCommand_;
    8080        // command has an additional parameter
    81         if (bRelative_)
     81        if (rel != 0.0f)
    8282        {
    83             if (rel != 0.0f)
    84             {
    85                 // we have to calculate a relative movement.
    86                 // paramModifier_ says how much one keystroke is
    87                 cmd.value_ += paramModifier_ * rel;
    88             }
     83            // calculate relative movement.
     84            // scale_ says how much one keystroke is
     85            cmd.rel_ += scale_ * rel;
    8986        }
    90         else if (abs != 0.0f)
     87
     88        if (abs != 0.0f)
    9189        {
    92             // Usually, joy sticks create 'noise' (they return values if they're in 0 position)
    93             // and normally this is caught in tickInput(), but that threshold cannot be to high
    94             // in order to preserve accuracy. Instead, we have to catch the problem here. An example:
    95             // Someone only uses buttons with an active joystick. The joy stick value could then
    96             // be 0.05 for instance and the the key value 1. Without handling the problem, the final
    97             // value would be computed to (1+0.05)/2=0.5025 which is not what the user expects.
    98             float absQ = abs * abs;
    99             float valueQ = cmd.value_ * cmd.value_;
    100             if (absQ > 50.0f * valueQ) // ease up comparison by using quadratics
    101             {
    102                 cmd.value_ = abs * paramModifier_;
    103                 cmd.nValuesAdded_ = 1;
    104             }
    105             else if (absQ * 50.0f < valueQ)
    106             {
    107                 // abs is too small, we just don't do anything
    108             }
    109             else
    110             {
    111                 // we have to calculate the absolute position of the axis.
    112                 // Since there might be another axis that is affected, we have to wait and
    113                 // store the result in a temporary place
    114                 cmd.value_ = (cmd.value_ * cmd.nValuesAdded_ + paramModifier_ * abs) / ++cmd.nValuesAdded_;
    115             }
     90            cmd.abs_ += scale_ * abs;
     91            if (cmd.abs_ > 1.0)
     92                cmd.abs_ = 1.0;
     93            if (cmd.abs_ < -1.0)
     94                cmd.abs_ = -1.0;
    11695        }
    11796        return true;
  • code/branches/objecthierarchy/src/core/input/InputCommands.h

    r1887 r2001  
    4444    {
    4545    public:
    46         BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { }
     46        BufferedParamCommand() : abs_(0.0f), rel_(0.0), paramIndex_(-1) { }
    4747        bool execute();
    4848
    49         float value_;
    50         unsigned int nValuesAdded_;
     49        float abs_;
     50        float rel_;
    5151        int paramIndex_;
    5252        CommandEvaluation evaluation_;
     
    8282    {
    8383    public:
    84         ParamCommand() : bRelative_(false), paramModifier_(1.0f), paramCommand_(0) { }
     84        ParamCommand() : scale_(1.0f), paramCommand_(0) { }
    8585        bool execute(float abs = 1.0f, float rel = 1.0f);
    8686
    87         bool bRelative_;
    88         float paramModifier_;
     87        float scale_;
    8988        BufferedParamCommand* paramCommand_;
    9089    };
  • code/branches/objecthierarchy/src/core/input/KeyBinder.cc

    r1887 r2001  
    137137        SetConfigValue(analogThreshold_, 0.05f)
    138138            .description("Threshold for analog axes until which the state is 0.");
     139        SetConfigValue(bFilterAnalogNoise_, false)
     140            .description("Specifies whether to filter small analog values like joy stick fluctuations.");
    139141        SetConfigValue(mouseSensitivity_, 1.0f)
    140142            .description("Mouse sensitivity.");
     
    145147        SetConfigValue(mouseSensitivityDerived_, 1.0f)
    146148            .description("Mouse sensitivity if mouse input is derived.");
    147         SetConfigValue(mouseWheelStepSize_, 120.0f)
     149        SetConfigValue(mouseWheelStepSize_, 120)
    148150            .description("Equals one step of the mousewheel.");
    149151        SetConfigValue(buttonThreshold_, 0.80f)
     
    323325    void KeyBinder::tickMouse(float dt)
    324326    {
    325         tickDevices(mouseAxes_, mouseAxes_ + MouseAxisCode::numberOfAxes * 2);
    326 
    327327        if (bDeriveMouseInput_)
    328328        {
     329            // only update when derive dt has passed
    329330            if (deriveTime_ > derivePeriod_)
    330331            {
     
    357358                deriveTime_ += dt;
    358359        }
    359     }
    360 
    361     void KeyBinder::tickDevices(HalfAxis* begin, HalfAxis* end)
    362     {
    363         for (HalfAxis* current = begin; current < end; ++current) // pointer arithmetic
    364         {
    365             // button mode
    366             // TODO: optimize out all the half axes that don't act as a button at the moment
    367             if (current->hasChanged_)
    368             {
    369                 if (!current->wasDown_ && current->absVal_ > current->buttonThreshold_)
    370                 {
    371                     current->wasDown_ = true;
    372                     if (current->nCommands_[KeybindMode::OnPress])
    373                         current->execute(KeybindMode::OnPress);
    374                 }
    375                 else if (current->wasDown_ && current->absVal_ < current->buttonThreshold_)
    376                 {
    377                     current->wasDown_ = false;
    378                     if (current->nCommands_[KeybindMode::OnRelease])
    379                         current->execute(KeybindMode::OnRelease);
    380                 }
    381                 current->hasChanged_ = false;
    382             }
    383 
    384             if (current->wasDown_)
    385             {
    386                 if (current->nCommands_[KeybindMode::OnHold])
    387                     current->execute(KeybindMode::OnHold);
    388             }
    389 
    390             // these are the actually useful axis bindings for analog input
    391             if (current->relVal_ > analogThreshold_ || current->absVal_ > analogThreshold_)
    392             {
    393                 current->execute();
    394             }
     360
     361        for (int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
     362        {
     363            // Why dividing relative value by dt? The reason lies in the simple fact, that when you
     364            // press a button that has relative movement, that value has to be multiplied by dt to be
     365            // frame rate independant. This can easily (and only) be done in tickInput(float).
     366            // Hence we need to divide by dt here for the mouse to compensate, because the relative
     367            // move movements have nothing to do with dt.
     368            if (dt != 0.0f)
     369            {
     370                // just ignore if dt == 0.0 because we have multiplied by 0.0 anyway..
     371                mouseAxes_[i].relVal_ /= dt;
     372            }
     373
     374            tickHalfAxis(mouseAxes_[i]);
     375        }
     376    }
     377
     378    void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
     379    {
     380        for (int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
     381        {
     382            tickHalfAxis(joyStickAxes_[joyStick][i]);
     383        }
     384    }
     385
     386    void KeyBinder::tickHalfAxis(HalfAxis& halfAxis)
     387    {
     388        // button mode
     389        // TODO: optimize out all the half axes that don't act as a button at the moment
     390        if (halfAxis.hasChanged_)
     391        {
     392            if (!halfAxis.pressed_ && halfAxis.absVal_ > halfAxis.buttonThreshold_)
     393            {
     394                // key pressed event
     395                halfAxis.pressed_ = true;
     396                if (halfAxis.nCommands_[KeybindMode::OnPress])
     397                    halfAxis.execute(KeybindMode::OnPress);
     398            }
     399            else if (halfAxis.pressed_ && halfAxis.absVal_ < halfAxis.buttonThreshold_)
     400            {
     401                // key released event
     402                halfAxis.pressed_ = false;
     403                if (halfAxis.nCommands_[KeybindMode::OnRelease])
     404                    halfAxis.execute(KeybindMode::OnRelease);
     405            }
     406            halfAxis.hasChanged_ = false;
     407        }
     408
     409        if (halfAxis.pressed_)
     410        {
     411            // key held event
     412            if (halfAxis.nCommands_[KeybindMode::OnHold])
     413                halfAxis.execute(KeybindMode::OnHold);
     414        }
     415
     416        // these are the actually useful axis bindings for analog input
     417        if (!bFilterAnalogNoise_ || halfAxis.relVal_ > analogThreshold_ || halfAxis.absVal_ > analogThreshold_)
     418        {
     419            halfAxis.execute();
    395420        }
    396421    }
     
    407432        int rel[] = { rel_.x, -rel_.y };
    408433
    409         if (!bDeriveMouseInput_)
     434        if (bDeriveMouseInput_)
     435        {
     436            mouseRelative_[0] += rel[0];
     437            mouseRelative_[1] += rel[1];
     438        }
     439        else
    410440        {
    411441            for (int i = 0; i < 2; i++)
     
    437467            }
    438468        }
    439         else
    440         {
    441             mouseRelative_[0] += rel[0];
    442             mouseRelative_[1] += rel[1];
    443         }
    444469
    445470        // relative
  • code/branches/objecthierarchy/src/core/input/KeyBinder.h

    r1888 r2001  
    7171        void tickJoyStick(float dt, unsigned int joyStick);
    7272        // internal
    73         void tickDevices(HalfAxis* begin, HalfAxis* end);
     73        void tickHalfAxis(HalfAxis& halfAxis);
    7474
    7575        void buttonThresholdChanged();
     
    149149        //! Filename of default keybindings.
    150150        std::string defaultKeybindings_;
     151        //! Whether to filter small value analog input
     152        bool bFilterAnalogNoise_;
    151153        //! Threshold for analog triggers until which the state is 0.
    152154        float analogThreshold_;
     
    162164        float mouseSensitivityDerived_;
    163165        //! Equals one step of the mousewheel
    164         float mouseWheelStepSize_;
     166        int mouseWheelStepSize_;
    165167
    166168        //##### Constant config variables #####
     
    198200    { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnHold); }
    199201
    200     inline void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
    201     {
    202         tickDevices(&joyStickAxes_[joyStick][0], &joyStickAxes_[joyStick][JoyStickAxisCode::numberOfAxes * 2]);
    203     }
    204 
    205202    inline void KeyBinder::tickInput(float dt)
    206203    {
    207204        // execute all buffered bindings (additional parameter)
    208205        for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
     206        {
     207            paramCommandBuffer_[i]->rel_ *= dt;
    209208            paramCommandBuffer_[i]->execute();
     209        }
    210210
    211211        // always reset the relative movement of the mouse
Note: See TracChangeset for help on using the changeset viewer.