CmInput.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "CmInput.h"
  2. #include "CmTime.h"
  3. #include "CmMath.h"
  4. #include "CmRect.h"
  5. #include <boost/bind.hpp>
  6. namespace CamelotEngine
  7. {
  8. const int Input::HISTORY_BUFFER_SIZE = 10; // Size of buffer used for input smoothing
  9. const float Input::WEIGHT_MODIFIER = 0.5f;
  10. Input::Input()
  11. :mSmoothHorizontalAxis(0.0f), mSmoothVerticalAxis(0.0f), mCurrentBufferIdx(0), mMouseLastRel(0, 0),
  12. mUsingClipRect(false), mClipRect(0, 0, 0, 0)
  13. {
  14. mHorizontalHistoryBuffer = new float[HISTORY_BUFFER_SIZE];
  15. mVerticalHistoryBuffer = new float[HISTORY_BUFFER_SIZE];
  16. mTimesHistoryBuffer = new 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. }
  24. Input::~Input()
  25. {
  26. delete[] mHorizontalHistoryBuffer;
  27. delete[] mVerticalHistoryBuffer;
  28. delete[] mTimesHistoryBuffer;
  29. }
  30. void Input::init(std::shared_ptr<InputHandler> inputHandler, Rect& clipRect)
  31. {
  32. mInputHandler = inputHandler;
  33. mClipRect = clipRect;
  34. mUsingClipRect = (clipRect.width > 0 && clipRect.height > 0);
  35. mInputHandler->onKeyDown.connect(boost::bind(&Input::keyDown, this, _1));
  36. mInputHandler->onKeyUp.connect(boost::bind(&Input::keyUp, this, _1));
  37. mInputHandler->onMouseMoved.connect(boost::bind(&Input::mouseMoved, this, _1));
  38. mInputHandler->onMouseDown.connect(boost::bind(&Input::mouseDown, this, _1, _2));
  39. mInputHandler->onMouseUp.connect(boost::bind(&Input::mouseUp, this, _1, _2));
  40. }
  41. void Input::update()
  42. {
  43. mInputHandler->update();
  44. updateSmoothInput();
  45. }
  46. void Input::keyDown(KeyCode keyCode)
  47. {
  48. onKeyDown(keyCode);
  49. }
  50. void Input::keyUp(KeyCode keyCode)
  51. {
  52. onKeyUp(keyCode);
  53. }
  54. void Input::mouseMoved(const MouseEvent& event)
  55. {
  56. if(mUsingClipRect)
  57. {
  58. if(!mClipRect.contains(event.coords))
  59. return;
  60. }
  61. onMouseMoved(event);
  62. mMouseLastRel = Point(-event.relCoords.x, -event.relCoords.y);
  63. }
  64. void Input::mouseDown(const MouseEvent& event, MouseButton buttonID)
  65. {
  66. if(mUsingClipRect)
  67. {
  68. if(!mClipRect.contains(event.coords))
  69. return;
  70. }
  71. onMouseDown(event, buttonID);
  72. }
  73. void Input::mouseUp(const MouseEvent& event, MouseButton buttonID)
  74. {
  75. if(mUsingClipRect)
  76. {
  77. if(!mClipRect.contains(event.coords))
  78. return;
  79. }
  80. onMouseUp(event, buttonID);
  81. }
  82. float Input::getHorizontalAxis() const
  83. {
  84. return mSmoothHorizontalAxis;
  85. }
  86. float Input::getVerticalAxis() const
  87. {
  88. return mSmoothVerticalAxis;
  89. }
  90. void Input::updateSmoothInput()
  91. {
  92. float currentTime = gTime().getTimeSinceApplicationStart();
  93. mHorizontalHistoryBuffer[mCurrentBufferIdx] = (float)mMouseLastRel.x;
  94. mVerticalHistoryBuffer[mCurrentBufferIdx] = (float)mMouseLastRel.y;
  95. mTimesHistoryBuffer[mCurrentBufferIdx] = currentTime;
  96. int i = 0;
  97. int idx = mCurrentBufferIdx;
  98. float currentWeight = 1.0f;
  99. float horizontalTotal = 0.0f;
  100. float verticalTotal = 0.0f;
  101. while(i < HISTORY_BUFFER_SIZE)
  102. {
  103. float timeWeight = 1.0f - (currentTime - mTimesHistoryBuffer[idx]) * 10.0f;
  104. if(timeWeight < 0.0f)
  105. timeWeight = 0.0f;
  106. horizontalTotal += mHorizontalHistoryBuffer[idx] * currentWeight * timeWeight;
  107. verticalTotal += mVerticalHistoryBuffer[idx] * currentWeight * timeWeight;
  108. currentWeight *= WEIGHT_MODIFIER;
  109. idx = (idx + 1) % HISTORY_BUFFER_SIZE;
  110. i++;
  111. }
  112. mCurrentBufferIdx = (mCurrentBufferIdx + 1) % HISTORY_BUFFER_SIZE;
  113. mSmoothHorizontalAxis = Math::Clamp(horizontalTotal / HISTORY_BUFFER_SIZE, -1.0f, 1.0f);
  114. mSmoothVerticalAxis = Math::Clamp(verticalTotal / HISTORY_BUFFER_SIZE, -1.0f, 1.0f);
  115. mMouseLastRel = Point(0, 0);
  116. }
  117. Input& gInput()
  118. {
  119. return Input::instance();
  120. }
  121. }