Browse Source

Better slider plane handling

Marko Pintera 10 years ago
parent
commit
9fea88e795

+ 8 - 5
BansheeEditor/Include/BsHandleSliderPlane.h

@@ -13,13 +13,15 @@ namespace BansheeEngine
 		HandleSliderPlane(const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale);
 		~HandleSliderPlane();
 
-		bool intersects(const Ray& ray, float& t) const;
-		void handleInput(const CameraHandlerPtr& camera, const Vector2I& inputDelta);
+		bool intersects(const Ray& ray, float& t) const override;
+		void handleInput(const CameraHandlerPtr& camera, const Vector2I& inputDelta) override;
 
 		Vector2 getDelta() const { return mDelta; }
 	protected:
-		void activate(const CameraHandlerPtr& camera, const Vector2I& pointerPos) { mStartPosition = getPosition(); }
-		void reset() { mDelta = Vector2::ZERO; }
+		void activate(const CameraHandlerPtr& camera, const Vector2I& pointerPos) override;
+		void reset() override { mDelta = Vector2::ZERO; }
+
+		Vector3 getClickPosition(const CameraHandlerPtr& camera, const Vector2I& pointerPos) const;
 
 		Vector3 mDirection1;
 		Vector3 mDirection2;
@@ -28,6 +30,7 @@ namespace BansheeEngine
 		Rect3 mCollider;
 
 		Vector2 mDelta;
-		Vector3 mStartPosition;
+		Vector3 mStartPlanePosition;
+		Vector3 mStartClickPosition;
 	};
 }

+ 36 - 3
BansheeEditor/Source/BsHandleSliderPlane.cpp

@@ -3,6 +3,11 @@
 #include "BsHandleSliderManager.h"
 #include "BsVector3.h"
 #include "BsRay.h"
+#include "BsPlane.h"
+#include "BsCameraHandler.h"
+
+// DEBUG ONLY
+#include "BsDebug.h"
 
 namespace BansheeEngine
 {
@@ -29,7 +34,6 @@ namespace BansheeEngine
 		sliderManager._unregisterSlider(this);
 	}
 
-
 	bool HandleSliderPlane::intersects(const Ray& ray, float& t) const
 	{
 		Ray localRay = ray;
@@ -47,6 +51,12 @@ namespace BansheeEngine
 		return false;
 	}
 
+	void HandleSliderPlane::activate(const CameraHandlerPtr& camera, const Vector2I& pointerPos)
+	{
+		mStartPlanePosition = getPosition();
+		mStartClickPosition = getClickPosition(camera, pointerPos);
+	}
+
 	void HandleSliderPlane::handleInput(const CameraHandlerPtr& camera, const Vector2I& inputDelta)
 	{
 		assert(getState() == State::Active);
@@ -56,7 +66,30 @@ namespace BansheeEngine
 		Vector3 worldDir1 = getRotation().rotate(mDirection1);
 		Vector3 worldDir2 = getRotation().rotate(mDirection2);
 
-		mDelta.x = calcDelta(camera, mStartPosition, worldDir1, mStartPointerPos, mCurrentPointerPos);
-		mDelta.y = calcDelta(camera, mStartPosition, worldDir2, mStartPointerPos, mCurrentPointerPos);
+		Vector3 intersectPosition = getClickPosition(camera, mCurrentPointerPos);
+		Vector3 positionDelta = intersectPosition - mStartClickPosition;
+
+		mDelta.x = positionDelta.dot(worldDir1);
+		mDelta.y = positionDelta.dot(worldDir2);
+	}
+
+	Vector3 HandleSliderPlane::getClickPosition(const CameraHandlerPtr& camera, const Vector2I& pointerPos) const
+	{
+		Vector3 worldDir1 = getRotation().rotate(mDirection1);
+		Vector3 worldDir2 = getRotation().rotate(mDirection2);
+
+		Vector3 normal = worldDir1.cross(worldDir2);
+		float dot = normal.dot(camera->getForward());
+		if (dot > 0)
+			normal = -normal;
+
+		Plane plane(normal, mStartPlanePosition);
+
+		Ray clickRay = camera->screenPointToRay(pointerPos);
+		auto intersectResult = plane.intersects(clickRay);
+		if (intersectResult.first)
+			return clickRay.getPoint(intersectResult.second);
+
+		return mStartClickPosition;
 	}
 }