Browse Source

Cutoff plane for rotate handle sliders work

Marko Pintera 11 years ago
parent
commit
50e58153be

+ 3 - 0
BansheeEditor/Include/BsHandleSliderDisc.h

@@ -14,6 +14,7 @@ namespace BansheeEngine
 
 		bool intersects(const Ray& ray, float& t) const;
 		void handleInput(const CameraHandlerPtr& camera, const Vector2I& inputDelta);
+		void setCutoffPlane(Degree angle, bool enabled);
 
 		Radian getDelta() const { return mDelta; }
 		Radian getStartAngle() const { return mStartAngle; }
@@ -31,6 +32,8 @@ namespace BansheeEngine
 
 		Vector3 mNormal;
 		float mRadius;
+		bool mHasCutoffPlane;
+		Plane mCutoffPlane;
 
 		Vector3 mDirection;
 		Vector3 mStartPosition;

+ 28 - 1
BansheeEditor/Source/BsHandleSliderDisc.cpp

@@ -14,7 +14,7 @@ namespace BansheeEngine
 	const float HandleSliderDisc::TORUS_RADIUS = 0.1f;
 
 	HandleSliderDisc::HandleSliderDisc(const Vector3& normal, float radius, bool fixedScale)
-		:HandleSlider(fixedScale), mRadius(radius), mNormal(normal), mDelta(0.0f)
+		:HandleSlider(fixedScale), mRadius(radius), mNormal(normal), mDelta(0.0f), mHasCutoffPlane(false)
 	{
 		mCollider = Torus(normal, radius, TORUS_RADIUS);
 
@@ -28,6 +28,26 @@ namespace BansheeEngine
 		sliderManager._unregisterSlider(this);
 	}
 
+	void HandleSliderDisc::setCutoffPlane(Degree angle, bool enabled)
+	{
+		mHasCutoffPlane = enabled;
+
+		if (mHasCutoffPlane)
+		{
+			Vector3 up = mNormal;
+
+			Quaternion alignWithStart = Quaternion(-Vector3::UNIT_Y, angle);
+			Quaternion alignWithUp = Quaternion::getRotationFromTo(Vector3::UNIT_Y, up);
+
+			Vector3 right = alignWithUp.rotate(alignWithStart.rotate(Vector3::UNIT_X));
+			right.normalize();
+
+			Vector3 planeNormal = right.cross(up);
+
+			mCutoffPlane = Plane(planeNormal, 0.0f);
+		}
+	}
+
 	bool HandleSliderDisc::intersects(const Ray& ray, float& t) const
 	{
 		Ray localRay = ray;
@@ -38,6 +58,13 @@ namespace BansheeEngine
 		{
 			t = intersect.second;
 
+			if (mHasCutoffPlane)
+			{
+				auto cutoffIntersect = mCutoffPlane.intersects(localRay);
+				if (cutoffIntersect.first && cutoffIntersect.second < t)
+					return false;
+			}
+
 			return true;
 		}
 

+ 1 - 1
MBansheeEditor/EditorSettings.cs

@@ -31,7 +31,7 @@ namespace BansheeEditor
         public static Degree RotateHandleSnapAmount
         {
             get { return Internal_GetRotateHandleSnapAmount(); }
-            set { Internal_SetRotateHandleSnapAmount(value.GetDegrees()); }
+            set { Internal_SetRotateHandleSnapAmount(value.Degrees); }
         }
 
         public static float DefaultHandleSize

+ 8 - 0
MBansheeEditor/Scene/HandleSliderDisc.cs

@@ -32,6 +32,11 @@ namespace BansheeEditor
             }
         }
 
+        public void SetCutoffPlane(Degree angle, bool enabled)
+        {
+            Internal_SetCutoffPlane(mCachedPtr, angle.Degrees, enabled);
+        }
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CreateInstance(HandleSliderDisc instance, Vector3 normal, float radius, bool fixedScale);
 
@@ -40,5 +45,8 @@ namespace BansheeEditor
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_GetStartAngle(IntPtr nativeInstance, out float value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetCutoffPlane(IntPtr nativeInstance, float angle, bool enabled);
     }
 }

+ 1 - 1
MBansheeEditor/Scene/Handles.cs

@@ -39,7 +39,7 @@ namespace BansheeEditor
 
         public static Degree SnapValue(Degree value, Degree snapAmount)
         {
-            return SnapValue(value.GetDegrees(), snapAmount.GetDegrees());
+            return SnapValue(value.Degrees, snapAmount.Degrees);
         }
 
         public static float GetHandleSize(Camera camera, Vector3 position)

+ 25 - 12
MBansheeEditor/Scene/RotateHandle.cs

@@ -34,6 +34,10 @@ namespace BansheeEditor
             xAxis.Position = position;
             yAxis.Position = position;
             zAxis.Position = position;
+
+            xAxis.SetCutoffPlane(GetXStartAngle(), true);
+            yAxis.SetCutoffPlane(GetYStartAngle(), true);
+            zAxis.SetCutoffPlane(GetZStartAngle(), true);
         }
 
         protected override void PostInput()
@@ -75,10 +79,7 @@ namespace BansheeEditor
             else
                 HandleDrawing.SetColor(Color.Red);
 
-            Vector3 xStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.sceneObject.Forward, GetXDir());
-            Degree xStartAngle = PointOnCircleToAngle(GetXDir(), xStartDir);
-
-            HandleDrawing.DrawWireArc(Vector3.zero, GetXDir(), 1.0f, xStartAngle, 180.0f, handleSize);
+            HandleDrawing.DrawWireArc(Vector3.zero, GetXDir(), 1.0f, GetXStartAngle(), 180.0f, handleSize);
 
             if (yAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
@@ -87,10 +88,7 @@ namespace BansheeEditor
             else
                 HandleDrawing.SetColor(Color.Green);
 
-            Vector3 yStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.sceneObject.Forward, GetYDir());
-            Degree yStartAngle = PointOnCircleToAngle(GetYDir(), yStartDir);
-
-            HandleDrawing.DrawWireArc(Vector3.zero, GetYDir(), 1.0f, yStartAngle, 180.0f, handleSize);
+            HandleDrawing.DrawWireArc(Vector3.zero, GetYDir(), 1.0f, GetYStartAngle(), 180.0f, handleSize);
 
             if (zAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
@@ -99,10 +97,7 @@ namespace BansheeEditor
             else
                 HandleDrawing.SetColor(Color.Blue);
 
-            Vector3 zStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.sceneObject.Forward, GetZDir());
-            Degree zStartAngle = PointOnCircleToAngle(GetZDir(), zStartDir);
-
-            HandleDrawing.DrawWireArc(Vector3.zero, GetZDir(), 1.0f, zStartAngle, 180.0f, handleSize);
+            HandleDrawing.DrawWireArc(Vector3.zero, GetZDir(), 1.0f, GetZStartAngle(), 180.0f, handleSize);
 
             // Draw active rotation pie
             Color gray = new Color(1.0f, 1.0f, 1.0f, 0.3f);
@@ -118,6 +113,24 @@ namespace BansheeEditor
             // TODO - Free rotate handle
         }
 
+        private Degree GetXStartAngle()
+        {
+            Vector3 xStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.sceneObject.Forward, GetXDir());
+            return PointOnCircleToAngle(GetXDir(), xStartDir);
+        }
+
+        private Degree GetYStartAngle()
+        {
+            Vector3 yStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.sceneObject.Forward, GetYDir());
+            return PointOnCircleToAngle(GetYDir(), yStartDir);
+        }
+
+        private Degree GetZStartAngle()
+        {
+            Vector3 zStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.sceneObject.Forward, GetZDir());
+            return PointOnCircleToAngle(GetZDir(), zStartDir);
+        }
+
         private Vector3 GetXDir()
         {
              return Vector3.xAxis;

+ 1 - 1
MBansheeEditor/Scene/SceneWindow.cs

@@ -288,7 +288,7 @@ namespace BansheeEditor
             else
                 rotateSnapButton.ToggleOff();
 
-            moveSnapInput.Value = Handles.RotateSnapAmount.GetDegrees();
+            moveSnapInput.Value = Handles.RotateSnapAmount.Degrees;
         }
 
         private void UpdateRenderTexture(int width, int height)

+ 11 - 11
MBansheeEngine/Math/Degree.cs

@@ -18,7 +18,7 @@ namespace BansheeEngine
 
         public Degree(Radian r)
         {
-            this.value = r.GetDegrees();
+            this.value = r.Degrees;
         }
 
         public static implicit operator Degree(float value)
@@ -28,7 +28,7 @@ namespace BansheeEngine
 
         public static implicit operator Degree(Radian r)
         {
-            return new Degree(r.GetDegrees());
+            return new Degree(r.Degrees);
         }
 
 	    public static explicit operator float(Degree d)
@@ -36,17 +36,17 @@ namespace BansheeEngine
             return d.value;
 	    }
 
-	    public float GetDegrees()
-	    {
-	        return value;
-	    }
+        public float Degrees
+        {
+            get { return value; }
+        }
 
-        public float GetRadians()
+        public float Radians
         {
-            return value * MathEx.Deg2Rad;
+            get { return value*MathEx.Deg2Rad; }
         }
 
-	    public static Degree operator+(Degree a)
+        public static Degree operator+(Degree a)
 	    {
 	        return a;
 	    }
@@ -58,7 +58,7 @@ namespace BansheeEngine
 
         public static Degree operator+(Degree a, Radian r) 
         { 
-            return new Degree (a.value + r.GetDegrees()); 
+            return new Degree (a.value + r.Degrees); 
         }
 
 	    public static Degree operator-(Degree a)
@@ -73,7 +73,7 @@ namespace BansheeEngine
 
         public static Degree operator-(Degree a, Radian r) 
         { 
-            return new Degree (a.value - r.GetDegrees()); 
+            return new Degree (a.value - r.Degrees); 
         }
 
         public static Degree operator*(Degree a, float s)

+ 1 - 1
MBansheeEngine/Math/MathEx.cs

@@ -265,7 +265,7 @@ namespace BansheeEngine
         public static Degree WrapAngle(Degree angle)
         {
             const float inv360 = 1.0f/360.0f;
-            float angleVal = angle.GetDegrees();
+            float angleVal = angle.Degrees;
             float wrapCount = (float)MathEx.Floor(MathEx.Abs(angleVal * inv360));
 
             if (angleVal > 0.0f)

+ 3 - 3
MBansheeEngine/Math/Matrix3.cs

@@ -371,7 +371,7 @@ namespace BansheeEngine
             float trace = m00 + m11 + m22;
             float cos = 0.5f*(trace-1.0f);
             Radian radians = MathEx.Acos(cos);  // In [0, PI]
-            angle = radians.GetDegrees();
+            angle = radians.Degrees;
 
             if (radians > 0.0f)
             {
@@ -479,8 +479,8 @@ namespace BansheeEngine
         {
             Matrix3 mat;
 
-            float cos = MathEx.Cos(angle.GetRadians());
-            float sin = MathEx.Sin(angle.GetRadians());
+            float cos = MathEx.Cos(angle.Radians);
+            float sin = MathEx.Sin(angle.Radians);
             float oneMinusCos = 1.0f - cos;
             float x2 = axis.x * axis.x;
             float y2 = axis.y * axis.y;

+ 10 - 10
MBansheeEngine/Math/Radian.cs

@@ -18,7 +18,7 @@ namespace BansheeEngine
 
         public Radian(Degree d)
         {
-            this.value = d.GetRadians();
+            this.value = d.Radians;
         }
 
         public static implicit operator Radian(float value)
@@ -28,7 +28,7 @@ namespace BansheeEngine
 
         public static implicit operator Radian(Degree d)
         {
-            return new Radian(d.GetRadians());
+            return new Radian(d.Radians);
         }
 
         public static explicit operator float(Radian d)
@@ -36,14 +36,14 @@ namespace BansheeEngine
             return d.value;
         }
 
-	    public float GetDegrees()
-	    {
-	        return value * MathEx.Rad2Deg;
-	    }
+        public float Degrees
+        {
+            get { return value*MathEx.Rad2Deg; }
+        }
 
-        public float GetRadians()
+        public float Radians
         {
-            return value;
+            get { return value; }
         }
 
         public static Radian operator +(Radian a)
@@ -58,7 +58,7 @@ namespace BansheeEngine
 
         public static Radian operator +(Radian a, Degree d) 
         {
-            return new Radian(a.value + d.GetRadians()); 
+            return new Radian(a.value + d.Radians); 
         }
 
         public static Radian operator -(Radian a)
@@ -73,7 +73,7 @@ namespace BansheeEngine
 
         public static Radian operator -(Radian a, Degree d) 
         {
-            return new Radian(a.value - d.GetRadians()); 
+            return new Radian(a.value - d.Radians); 
         }
 
         public static Radian operator *(Radian a, float s)

+ 1 - 0
SBansheeEditor/Include/BsScriptHandleSliderDisc.h

@@ -21,6 +21,7 @@ namespace BansheeEngine
 		static void internal_CreateInstance(MonoObject* instance, Vector3 normal, float radius, bool fixedScale);
 		static void internal_GetDelta(ScriptHandleSliderDisc* nativeInstance, float* value);
 		static void internal_GetStartAngle(ScriptHandleSliderDisc* nativeInstance, float* value);
+		static void internal_SetCutoffPlane(ScriptHandleSliderDisc* nativeInstance, float value, bool enabled);
 
 		ScriptHandleSliderDisc(MonoObject* instance, const Vector3& normal, float radius, bool fixedScale);
 		~ScriptHandleSliderDisc();

+ 6 - 0
SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp

@@ -31,6 +31,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptHandleSliderDisc::internal_CreateInstance);
 		metaData.scriptClass->addInternalCall("Internal_GetDelta", &ScriptHandleSliderDisc::internal_GetDelta);
 		metaData.scriptClass->addInternalCall("Internal_GetStartAngle", &ScriptHandleSliderDisc::internal_GetStartAngle);
+		metaData.scriptClass->addInternalCall("Internal_SetCutoffPlane", &ScriptHandleSliderDisc::internal_SetCutoffPlane);
 	}
 
 	void ScriptHandleSliderDisc::internal_CreateInstance(MonoObject* instance, Vector3 normal, float radius, bool fixedScale)
@@ -48,4 +49,9 @@ namespace BansheeEngine
 	{
 		*value = nativeInstance->mSlider->getStartAngle().valueDegrees();
 	}
+
+	void ScriptHandleSliderDisc::internal_SetCutoffPlane(ScriptHandleSliderDisc* nativeInstance, float value, bool enabled)
+	{
+		nativeInstance->mSlider->setCutoffPlane(Degree(value), enabled);
+	}
 }

+ 2 - 1
TODO.txt

@@ -14,9 +14,10 @@ Possibly set up automatic refresh in debug mode after initialization? As an ad-h
 Add free scale handle
 
 Rotate handle:
- - Selecting the top right quadrant of the blue disc doesn't seem to work
  - Missing two free rotate arcs
  - How to handle local/global with rotate handle?
+   - This maybe just determines initial rotation of the handle?
+   - I don't think my code properly handles rotation handle transforms (e.g. arc drawing)
  - Backside of handle disc sliders shouldn't be interactable
    - Add an "cutoffPlane" parameter to block intersection with backside if enabled