CmInput.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "CmInput.h"
  2. #include "CmTime.h"
  3. #include "CmMath.h"
  4. #include "CmRect.h"
  5. #include "CmDebug.h"
  6. #include <boost/bind.hpp>
  7. namespace CamelotFramework
  8. {
  9. const int Input::HISTORY_BUFFER_SIZE = 10; // Size of buffer used for input smoothing
  10. const float Input::WEIGHT_MODIFIER = 0.5f;
  11. Input::Input()
  12. :mSmoothHorizontalAxis(0.0f), mSmoothVerticalAxis(0.0f), mCurrentBufferIdx(0), mMouseLastRel(0, 0), mInputHandler(nullptr)
  13. {
  14. mHorizontalHistoryBuffer = cm_newN<float>(HISTORY_BUFFER_SIZE);
  15. mVerticalHistoryBuffer = cm_newN<float>(HISTORY_BUFFER_SIZE);
  16. mTimesHistoryBuffer = cm_newN<float>(HISTORY_BUFFER_SIZE);
  17. for(int i = 0; i < HISTORY_BUFFER_SIZE; i++)
  18. {
  19. mHorizontalHistoryBuffer[i] = 0.0f;
  20. mVerticalHistoryBuffer[i] = 0.0f;
  21. mTimesHistoryBuffer[i] = 0.0f;
  22. }
  23. for(int i = 0; i < MB_Count; i++)
  24. mMouseButtonState[i] = false;
  25. for(int i = 0; i < KC_Count; i++)
  26. mKeyState[i] = false;
  27. }
  28. Input::~Input()
  29. {
  30. cm_deleteN(mHorizontalHistoryBuffer, HISTORY_BUFFER_SIZE);
  31. cm_deleteN(mVerticalHistoryBuffer, HISTORY_BUFFER_SIZE);
  32. cm_deleteN(mTimesHistoryBuffer, HISTORY_BUFFER_SIZE);
  33. }
  34. void Input::registerInputHandler(InputHandlerPtr inputHandler)
  35. {
  36. if(mInputHandler != inputHandler)
  37. {
  38. mInputHandler = inputHandler;
  39. if(mInputHandler != nullptr)
  40. {
  41. mInputHandler->onKeyDown.connect(boost::bind(&Input::keyDown, this, _1));
  42. mInputHandler->onKeyUp.connect(boost::bind(&Input::keyUp, this, _1));
  43. mInputHandler->onMouseMoved.connect(boost::bind(&Input::mouseMoved, this, _1));
  44. mInputHandler->onMouseDown.connect(boost::bind(&Input::mouseDown, this, _1, _2));
  45. mInputHandler->onMouseUp.connect(boost::bind(&Input::mouseUp, this, _1, _2));
  46. }
  47. }
  48. }
  49. void Input::update()
  50. {
  51. if(mInputHandler == nullptr)
  52. {
  53. LOGERR("Input handler not initialized!");
  54. return;
  55. }
  56. mInputHandler->update();
  57. updateSmoothInput();
  58. }
  59. void Input::inputWindowChanged(const RenderWindow& win)
  60. {
  61. if(mInputHandler != nullptr)
  62. mInputHandler->inputWindowChanged(win);
  63. }
  64. void Input::keyDown(const KeyEvent& event)
  65. {
  66. mKeyState[event.keyCode] = true;
  67. onKeyDown(event);
  68. }
  69. void Input::keyUp(const KeyEvent& event)
  70. {
  71. mKeyState[event.keyCode] = false;
  72. onKeyUp(event);
  73. }
  74. void Input::mouseMoved(const MouseEvent& event)
  75. {
  76. onMouseMoved(event);
  77. mMouseLastRel = Int2(-event.relCoords.x, -event.relCoords.y);
  78. }
  79. void Input::mouseDown(const MouseEvent& event, MouseButton buttonID)
  80. {
  81. mMouseButtonState[buttonID] = true;
  82. onMouseDown(event, buttonID);
  83. }
  84. void Input::mouseUp(const MouseEvent& event, MouseButton buttonID)
  85. {
  86. mMouseButtonState[buttonID] = false;
  87. onMouseUp(event, buttonID);
  88. }
  89. float Input::getHorizontalAxis() const
  90. {
  91. return mSmoothHorizontalAxis;
  92. }
  93. float Input::getVerticalAxis() const
  94. {
  95. return mSmoothVerticalAxis;
  96. }
  97. bool Input::isButtonDown(MouseButton button) const
  98. {
  99. return mMouseButtonState[button];
  100. }
  101. bool Input::isKeyDown(KeyCode keyCode) const
  102. {
  103. return mKeyState[keyCode];
  104. }
  105. void Input::updateSmoothInput()
  106. {
  107. float currentTime = gTime().getTime();
  108. mHorizontalHistoryBuffer[mCurrentBufferIdx] = (float)mMouseLastRel.x;
  109. mVerticalHistoryBuffer[mCurrentBufferIdx] = (float)mMouseLastRel.y;
  110. mTimesHistoryBuffer[mCurrentBufferIdx] = currentTime;
  111. int i = 0;
  112. int idx = mCurrentBufferIdx;
  113. float currentWeight = 1.0f;
  114. float horizontalTotal = 0.0f;
  115. float verticalTotal = 0.0f;
  116. while(i < HISTORY_BUFFER_SIZE)
  117. {
  118. float timeWeight = 1.0f - (currentTime - mTimesHistoryBuffer[idx]) * 10.0f;
  119. if(timeWeight < 0.0f)
  120. timeWeight = 0.0f;
  121. horizontalTotal += mHorizontalHistoryBuffer[idx] * currentWeight * timeWeight;
  122. verticalTotal += mVerticalHistoryBuffer[idx] * currentWeight * timeWeight;
  123. currentWeight *= WEIGHT_MODIFIER;
  124. idx = (idx + 1) % HISTORY_BUFFER_SIZE;
  125. i++;
  126. }
  127. mCurrentBufferIdx = (mCurrentBufferIdx + 1) % HISTORY_BUFFER_SIZE;
  128. mSmoothHorizontalAxis = Math::Clamp(horizontalTotal / HISTORY_BUFFER_SIZE, -1.0f, 1.0f);
  129. mSmoothVerticalAxis = Math::Clamp(verticalTotal / HISTORY_BUFFER_SIZE, -1.0f, 1.0f);
  130. mMouseLastRel = Int2(0, 0);
  131. }
  132. Input& gInput()
  133. {
  134. return Input::instance();
  135. }
  136. }