BsHandleSliderPlane.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Handles/BsHandleSliderPlane.h"
  4. #include "Handles/BsHandleManager.h"
  5. #include "Handles/BsHandleSliderManager.h"
  6. #include "Math/BsVector3.h"
  7. #include "Math/BsRay.h"
  8. #include "Math/BsPlane.h"
  9. #include "Renderer/BsCamera.h"
  10. namespace bs
  11. {
  12. HandleSliderPlane::HandleSliderPlane(const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale, UINT64 layer)
  13. : HandleSlider(fixedScale, layer), mDirection1(Vector3::normalize(dir1)), mDirection2(Vector3::normalize(dir2))
  14. , mLength(length), mDelta(BsZero), mStartPlanePosition(BsZero), mStartClickPosition(BsZero)
  15. {
  16. float halfLength = length * 0.5f;
  17. std::array<Vector3, 2> axes = {{ mDirection1, mDirection2 }};
  18. std::array<float, 2> extents = {{ halfLength, halfLength }};
  19. Vector3 center = (dir1 * length + dir2 * length) * 0.5f;
  20. mCollider = Rect3(center, axes, extents);
  21. HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
  22. sliderManager._registerSlider(this);
  23. }
  24. HandleSliderPlane::~HandleSliderPlane()
  25. {
  26. HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
  27. sliderManager._unregisterSlider(this);
  28. }
  29. bool HandleSliderPlane::intersects(const Vector2I& screenPos, const Ray& ray, float& t) const
  30. {
  31. Ray localRay = ray;
  32. localRay.transform(getTransformInv());
  33. auto intersect = mCollider.intersects(localRay);
  34. if (intersect.first)
  35. {
  36. t = intersect.second;
  37. return true;
  38. }
  39. return false;
  40. }
  41. void HandleSliderPlane::activate(const SPtr<Camera>& camera, const Vector2I& pointerPos)
  42. {
  43. mStartPlanePosition = getPosition();
  44. mStartClickPosition = getPositionOnPlane(camera, pointerPos);
  45. }
  46. void HandleSliderPlane::handleInput(const SPtr<Camera>& camera, const Vector2I& inputDelta)
  47. {
  48. assert(getState() == State::Active);
  49. mCurrentPointerPos += inputDelta;
  50. Vector3 worldDir1 = getRotation().rotate(mDirection1);
  51. Vector3 worldDir2 = getRotation().rotate(mDirection2);
  52. Vector3 intersectPosition = getPositionOnPlane(camera, mCurrentPointerPos);
  53. Vector3 positionDelta = intersectPosition - mStartClickPosition;
  54. mDelta.x = positionDelta.dot(worldDir1);
  55. mDelta.y = positionDelta.dot(worldDir2);
  56. }
  57. Vector3 HandleSliderPlane::getPositionOnPlane(const SPtr<Camera>& camera, const Vector2I& pointerPos) const
  58. {
  59. Vector3 worldDir1 = getRotation().rotate(mDirection1);
  60. Vector3 worldDir2 = getRotation().rotate(mDirection2);
  61. Vector3 normal = worldDir1.cross(worldDir2);
  62. float dot = normal.dot(camera->getTransform().getForward());
  63. if (dot > 0)
  64. normal = -normal;
  65. Plane plane(normal, mStartPlanePosition);
  66. Ray clickRay = camera->screenPointToRay(pointerPos);
  67. auto intersectResult = plane.intersects(clickRay);
  68. if (intersectResult.first)
  69. return clickRay.getPoint(intersectResult.second);
  70. return mStartClickPosition;
  71. }
  72. }