BsHandleSliderLine.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Handles/BsHandleSliderLine.h"
  4. #include "Handles/BsHandleManager.h"
  5. #include "Handles/BsHandleSliderManager.h"
  6. #include "Math/BsCapsule.h"
  7. #include "Math/BsLineSegment3.h"
  8. #include "Math/BsSphere.h"
  9. #include "Math/BsRay.h"
  10. #include "Renderer/BsCamera.h"
  11. namespace bs
  12. {
  13. const float HandleSliderLine::CAPSULE_RADIUS = 0.05f;
  14. const float HandleSliderLine::SPHERE_RADIUS = 0.2f;
  15. HandleSliderLine::HandleSliderLine(const Vector3& direction, float length, bool fixedScale, UINT64 layer)
  16. : HandleSlider(fixedScale, layer), mDirection(Vector3::normalize(direction)), mLength(length), mDelta(0.0f)
  17. , mStartPosition(BsZero)
  18. {
  19. Vector3 start = Vector3::ZERO;
  20. Vector3 end = start + mDirection * length;
  21. Vector3 sphereCenter = start + mDirection * std::max(0.0f, length - SPHERE_RADIUS);
  22. mCapsuleCollider = Capsule(LineSegment3(start, end), CAPSULE_RADIUS);
  23. mSphereCollider = Sphere(sphereCenter, SPHERE_RADIUS);
  24. HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
  25. sliderManager._registerSlider(this);
  26. }
  27. HandleSliderLine::~HandleSliderLine()
  28. {
  29. HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
  30. sliderManager._unregisterSlider(this);
  31. }
  32. bool HandleSliderLine::intersects(const Vector2I& screenPos, const Ray& ray, float& t) const
  33. {
  34. Ray localRay = ray;
  35. localRay.transformAffine(getTransformInv());
  36. auto capsuleIntersect = mCapsuleCollider.intersects(localRay);
  37. auto sphereIntersect = mSphereCollider.intersects(localRay);
  38. t = std::numeric_limits<float>::max();
  39. bool gotIntersect = false;
  40. if (capsuleIntersect.first)
  41. {
  42. t = capsuleIntersect.second;
  43. gotIntersect = true;
  44. }
  45. if (sphereIntersect.first)
  46. {
  47. if (sphereIntersect.second < t)
  48. {
  49. t = sphereIntersect.second;
  50. gotIntersect = true;
  51. }
  52. }
  53. if (gotIntersect)
  54. {
  55. Vector3 intrPoint = localRay.getPoint(t);
  56. intrPoint = getTransform().multiplyAffine(intrPoint);
  57. t = (intrPoint - ray.getOrigin()).length(); // Get distance in world space
  58. }
  59. return gotIntersect;
  60. }
  61. void HandleSliderLine::handleInput(const SPtr<Camera>& camera, const Vector2I& inputDelta)
  62. {
  63. assert(getState() == State::Active);
  64. mCurrentPointerPos += inputDelta;
  65. Vector3 worldDir = getRotation().rotate(mDirection);
  66. mDelta = calcDelta(camera, mStartPosition, worldDir, mStartPointerPos, mCurrentPointerPos);
  67. // Movement in screen space will cover larger range in world space if the camera is further away
  68. float dist = (camera->getTransform().getPosition() - mStartPosition).length();
  69. float arbitraryScale = 1.0f / 5.0f;
  70. mDelta *= dist * arbitraryScale;
  71. }
  72. }