Browse Source

Added free rotate and free scale handles (WIP)

Marko Pintera 11 years ago
parent
commit
9fbd25a56f

+ 1 - 0
BansheeEditor/Source/BsEditorApplication.cpp

@@ -311,6 +311,7 @@ namespace BansheeEngine
 
 		HSceneObject clone = testModelGO->clone();
 		GameObjectHandle<DbgTestGameObjectRef> clonedDbgTestGameObjectRef = clone->getComponent<DbgTestGameObjectRef>();
+		clone->setScale(Vector3::ONE * 0.01f);
 
 		testModelGO->destroy();
 

+ 1 - 0
BansheeUtility/Source/BsRect3.cpp

@@ -1,6 +1,7 @@
 #include "BsRect3.h"
 #include "BsRay.h"
 #include "BsLineSegment3.h"
+#include "BsDebug.h"
 
 namespace BansheeEngine
 {

+ 13 - 2
MBansheeEditor/Scene/DefaultHandleManager.cs

@@ -145,8 +145,19 @@ namespace BansheeEditor
                         {
                             ScaleHandle scaleHandle = (ScaleHandle) activeHandle;
 
-                            foreach (var selectedObj in activeSelection)
-                                selectedObj.so.LocalScale = selectedObj.initialScale + scaleHandle.Delta;
+                            if (EditorApplication.ActivePivotMode == HandlePivotMode.Pivot)
+                            {
+                                foreach (var selectedObj in activeSelection)
+                                    selectedObj.so.LocalScale = selectedObj.initialScale + scaleHandle.Delta;
+                            }
+                            else
+                            {
+                                foreach (var selectedObj in activeSelection)
+                                {
+                                    selectedObj.so.LocalScale = selectedObj.initialScale + scaleHandle.Delta;
+                                    // TODO
+                                }
+                            }
                         }
                             break;
                     }

+ 27 - 2
MBansheeEditor/Scene/RotateHandle.cs

@@ -10,6 +10,8 @@ namespace BansheeEditor
         private HandleSliderDisc yAxis;
         private HandleSliderDisc zAxis;
 
+        private HandleSliderDisc freeAxis;
+
         public Quaternion Delta
         {
             get { return delta; }
@@ -19,7 +21,8 @@ namespace BansheeEditor
         {
             return xAxis.State == HandleSlider.StateType.Active ||
                     yAxis.State == HandleSlider.StateType.Active ||
-                    zAxis.State == HandleSlider.StateType.Active;
+                    zAxis.State == HandleSlider.StateType.Active ||
+                    freeAxis.State == HandleSlider.StateType.Active;
         }
 
         public RotateHandle()
@@ -27,6 +30,7 @@ namespace BansheeEditor
             xAxis = new HandleSliderDisc(this, Vector3.xAxis, 1.0f);
             yAxis = new HandleSliderDisc(this, Vector3.yAxis, 1.0f);
             zAxis = new HandleSliderDisc(this, Vector3.zAxis, 1.0f);
+            freeAxis = new HandleSliderDisc(this, Vector3.zAxis, 1.0f);
         }
 
         protected override void PreInput()
@@ -35,9 +39,13 @@ namespace BansheeEditor
             yAxis.Position = position;
             zAxis.Position = position;
 
+            freeAxis.Position = position;
+            freeAxis.Rotation = EditorApplication.SceneViewCamera.sceneObject.Rotation;
+
             xAxis.SetCutoffPlane(GetXStartAngle(), true);
             yAxis.SetCutoffPlane(GetYStartAngle(), true);
             zAxis.SetCutoffPlane(GetZStartAngle(), true);
+            freeAxis.SetCutoffPlane(0.0f, false);
         }
 
         protected override void PostInput()
@@ -64,6 +72,11 @@ namespace BansheeEditor
             delta = Quaternion.FromAxisAngle(GetXDir(), xValue) * delta;
             delta = Quaternion.FromAxisAngle(GetYDir(), yValue) * delta;
             delta = Quaternion.FromAxisAngle(GetZDir(), zValue) * delta;
+
+            Matrix4 cameraToWorld = EditorApplication.SceneViewCamera.ViewMatrixInverse;
+
+            Vector3 rotDir = cameraToWorld.MultiplyAffine(new Vector3(-Input.PointerDelta.y, -Input.PointerDelta.x, 0));
+            delta = Quaternion.FromAxisAngle(rotDir.Normalized, Input.PointerDelta.Magnitude) * delta;
         }
 
         protected override void Draw()
@@ -110,7 +123,19 @@ namespace BansheeEditor
             else if (zAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.DrawArc(Vector3.zero, GetZDir(), 1.0f, zAxis.StartAngle, zAxis.Delta, handleSize);
 
-            // TODO - Free rotate handle
+            // Draw free rotate handle
+            if (freeAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.SetColor(Color.White);
+            else if (freeAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.SetColor(Color.BansheeOrange);
+            else
+                HandleDrawing.SetColor(Color.White);
+
+            //// Rotate it so it always faces the camera, and move it forward a bit to always render in front
+            Vector3 freeHandleNormal = EditorApplication.SceneViewCamera.sceneObject.Rotation.Rotate(GetZDir());
+            Vector3 offset = freeHandleNormal*0.1f;
+
+            HandleDrawing.DrawWireDisc(offset, freeHandleNormal, 1.0f, handleSize);
         }
 
         private Degree GetXStartAngle()

+ 44 - 9
MBansheeEditor/Scene/ScaleHandle.cs

@@ -13,6 +13,8 @@ namespace BansheeEditor
         private HandleSliderLine yAxis;
         private HandleSliderLine zAxis;
 
+        private HandleSliderPlane freeAxis;
+
         public Vector3 Delta
         {
             get { return delta; }
@@ -22,7 +24,8 @@ namespace BansheeEditor
         {
             return xAxis.State == HandleSlider.StateType.Active ||
                     yAxis.State == HandleSlider.StateType.Active ||
-                    zAxis.State == HandleSlider.StateType.Active;
+                    zAxis.State == HandleSlider.StateType.Active ||
+                    freeAxis.State == HandleSlider.StateType.Active;
         }
 
         public ScaleHandle()
@@ -30,6 +33,8 @@ namespace BansheeEditor
             xAxis = new HandleSliderLine(this, Vector3.xAxis, 1.0f);
             yAxis = new HandleSliderLine(this, Vector3.yAxis, 1.0f);
             zAxis = new HandleSliderLine(this, Vector3.zAxis, 1.0f);
+
+            freeAxis = new HandleSliderPlane(this, Vector3.xAxis, Vector3.yAxis, 0.6f);
         }
 
         protected override void PreInput()
@@ -41,15 +46,21 @@ namespace BansheeEditor
             xAxis.Rotation = rotation;
             yAxis.Rotation = rotation;
             zAxis.Rotation = rotation;
+
+            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
+            Vector3 freeAxisOffset = (Vector3.xAxis * -0.3f + Vector3.yAxis * -0.3f) * handleSize;
+            freeAxis.Rotation = EditorApplication.SceneViewCamera.sceneObject.Rotation;
+            freeAxis.Position = position + freeAxis.Rotation.Rotate(freeAxisOffset);
         }
 
         protected override void PostInput()
         {
             delta = Vector3.zero;
 
-            delta += xAxis.Delta * GetXDir();
-            delta += yAxis.Delta * GetYDir();
-            delta += zAxis.Delta * GetZDir();
+            delta += xAxis.Delta * GetXDir() * 0.01f;
+            delta += yAxis.Delta * GetYDir() * 0.01f;
+            delta += zAxis.Delta * GetZDir() * 0.01f;
+            delta += (freeAxis.Delta.x + freeAxis.Delta.y) * Vector3.one * 0.01f;
         }
 
         protected override void Draw()
@@ -59,12 +70,11 @@ namespace BansheeEditor
 
             // Draw 1D sliders
             Vector3 smallCubeExtents = new Vector3(SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f);
-            Color axisHover = new Color(0.8f, 0.8f, 0.8f, 1.0f);
 
             if (xAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
             else if (xAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.SetColor(Color.Red * axisHover);
+                HandleDrawing.SetColor(Color.BansheeOrange);
             else
                 HandleDrawing.SetColor(Color.Red);
 
@@ -77,7 +87,7 @@ namespace BansheeEditor
             if (yAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
             else if (yAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.SetColor(Color.Green * axisHover);
+                HandleDrawing.SetColor(Color.BansheeOrange);
             else
                 HandleDrawing.SetColor(Color.Green);
 
@@ -90,7 +100,7 @@ namespace BansheeEditor
             if (zAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
             else if (zAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.SetColor(Color.Blue * axisHover);
+                HandleDrawing.SetColor(Color.BansheeOrange);
             else
                 HandleDrawing.SetColor(Color.Blue);
 
@@ -100,7 +110,32 @@ namespace BansheeEditor
             HandleDrawing.DrawLine(Vector3.zero, zCubeStart, handleSize);
             HandleDrawing.DrawCube(zCubeStart + zCubeOffset, smallCubeExtents, handleSize);
 
-            // TODO - Draw free scale handle
+            // Draw free scale handle
+            if (freeAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.SetColor(Color.White);
+            else if (freeAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.SetColor(Color.BansheeOrange);
+            else
+                HandleDrawing.SetColor(Color.White);
+
+            //// Rotate it so it always faces the camera, and move it forward a bit to always render in front
+            Vector3 bottomLeft = -Vector3.xAxis * 0.3f - Vector3.yAxis * 0.3f;
+            Vector3 topLeft = -Vector3.xAxis * 0.3f + Vector3.yAxis * 0.3f;
+            Vector3 topRight = Vector3.xAxis * 0.3f + Vector3.yAxis * 0.3f;
+            Vector3 bottomRight = Vector3.xAxis * 0.3f - Vector3.yAxis * 0.3f;
+
+            Vector3 offset = Vector3.zAxis*0.1f;
+
+            Quaternion cameraRot = EditorApplication.SceneViewCamera.sceneObject.Rotation;
+            bottomLeft = cameraRot.Rotate(bottomLeft + offset);
+            topLeft = cameraRot.Rotate(topLeft + offset);
+            topRight = cameraRot.Rotate(topRight + offset);
+            bottomRight = cameraRot.Rotate(bottomRight + offset);
+
+            HandleDrawing.DrawLine(bottomLeft, bottomRight, handleSize);
+            HandleDrawing.DrawLine(bottomLeft, topLeft, handleSize);
+            HandleDrawing.DrawLine(topLeft, topRight, handleSize);
+            HandleDrawing.DrawLine(bottomRight, topRight, handleSize);
         }
 
         private Vector3 GetXDir()

+ 1 - 1
MBansheeEditor/Scene/SceneCamera.cs

@@ -98,7 +98,7 @@ namespace BansheeEditor
             if (goingRight) direction += sceneObject.Right;
             if (goingLeft) direction -= sceneObject.Right;
 
-            if (direction.sqrdMagnitude != 0)
+            if (direction.SqrdMagnitude != 0)
             {
                 direction.Normalize();
 

+ 7 - 7
MBansheeEditor/Scene/SceneWindow.cs

@@ -303,15 +303,15 @@ namespace BansheeEditor
 		    {
                 SceneObject sceneCameraSO = new SceneObject("SceneCamera");
                 camera = sceneCameraSO.AddComponent<Camera>();
-                camera.target = renderTexture;
-                camera.viewportRect = new Rect2(0.0f, 0.0f, 1.0f, 1.0f);
+                camera.Target = renderTexture;
+                camera.ViewportRect = new Rect2(0.0f, 0.0f, 1.0f, 1.0f);
 
                 sceneCameraSO.Position = new Vector3(0, 0.5f, 1);
                 sceneCameraSO.LookAt(new Vector3(0, 0, 0));
 
-                camera.priority = 1;
-                camera.nearClipPlane = 0.005f;
-                camera.farClipPlane = 1000.0f;
+                camera.Priority = 1;
+                camera.NearClipPlane = 0.005f;
+                camera.FarClipPlane = 1000.0f;
 
                 cameraController = sceneCameraSO.AddComponent<SceneCamera>();
 
@@ -322,14 +322,14 @@ namespace BansheeEditor
 		    }
 		    else
 		    {
-		        camera.target = renderTexture;
+		        camera.Target = renderTexture;
 		        renderTextureGUI.RenderTexture = renderTexture;
 		    }
 
 		    // TODO - Consider only doing the resize once user stops resizing the widget in order to reduce constant
 		    // render target destroy/create cycle for every single pixel.
 
-		    camera.aspectRatio = width / (float)height;
+		    camera.AspectRatio = width / (float)height;
 	    }
     }
 }

+ 21 - 21
MBansheeEngine/Camera.cs

@@ -18,120 +18,120 @@ namespace BansheeEngine
             get { return handler; }
         }
 
-        public float aspectRatio
+        public float AspectRatio
         {
             get { return handler.aspectRatio; }
             set { handler.aspectRatio = value; serializableData.aspectRatio = value; }
         }
 
-        public float nearClipPlane
+        public float NearClipPlane
         {
             get { return handler.nearClipPlane; }
             set { handler.nearClipPlane = value; serializableData.nearClipPlane = value; }
         }
 
-        public float farClipPlane
+        public float FarClipPlane
         {
             get { return handler.farClipPlane; }
             set { handler.farClipPlane = value; serializableData.farClipPlane = value; }
         }
 
-        public Degree fieldOfView
+        public Degree FieldOfView
         {
             get { return handler.fieldOfView; }
             set { handler.fieldOfView = value; serializableData.fieldOfView = value; }
         }
 
-        public Rect2 viewportRect
+        public Rect2 ViewportRect
         {
             get { return handler.viewportRect; }
             set { handler.viewportRect = value; serializableData.viewportRect = value; }
         }
 
-        public ProjectionType projectionType
+        public ProjectionType ProjectionType
         {
             get { return handler.projectionType; }
             set { handler.projectionType = value; serializableData.projectionType = value; }
         }
 
-        public float orthoHeight
+        public float OrthoHeight
         {
             get { return handler.orthoHeight; }
             set { handler.orthoHeight = value; serializableData.orthoHeight = value; }
         }
 
-        public float orthoWidth
+        public float OrthoWidth
         {
             get { return handler.orthoWidth; }
         }
 
-        public Color clearColor
+        public Color ClearColor
         {
             get { return handler.clearColor; }
             set { handler.clearColor = value; serializableData.clearColor = value; }
         }
 
-        public float clearDepth
+        public float ClearDepth
         {
             get { return handler.clearDepth; }
             set { handler.clearDepth = value; serializableData.clearDepth = value; }
         }
 
-        public UInt16 clearStencil
+        public UInt16 ClearStencil
         {
             get { return handler.clearStencil; }
             set { handler.clearStencil = value; serializableData.clearStencil = value; }
         }
 
-        public ClearFlags clearFlags
+        public ClearFlags ClearFlags
         {
             get { return handler.clearFlags; }
             set { handler.clearFlags = value; serializableData.clearFlags = value; }
         }
 
-        public int priority
+        public int Priority
         {
             get { return handler.priority; }
             set { handler.priority = value; serializableData.priority = value; }
         }
 
-        public UInt64 layers
+        public UInt64 Layers
         {
             get { return handler.layers; }
             set { handler.layers = value; serializableData.layers = value; }
         }
 
-        public Matrix4 projMatrix
+        public Matrix4 ProjMatrix
         {
             get { return handler.projMatrix; }
         }
 
-        public Matrix4 projMatrixInv
+        public Matrix4 ProjMatrixInverse
         {
             get { return handler.projMatrixInv; }
         }
 
-        public Matrix4 viewMatrix
+        public Matrix4 ViewMatrix
         {
             get { return handler.viewMatrix; }
         }
 
-        public Matrix4 viewMatrixInv
+        public Matrix4 ViewMatrixInverse
         {
             get { return handler.viewMatrixInv; }
         }
 
-        public int widthPixels
+        public int WidthPixels
         {
             get { return handler.widthPixels; }
         }
 
-        public int heightPixels
+        public int HeightPixels
         {
             get { return handler.heightPixels; }
         }
 
-        public RenderTarget target
+        public RenderTarget Target
         {
             get { return handler.target; }
             set { handler.target = value; }

+ 22 - 2
MBansheeEngine/Math/Matrix4.cs

@@ -160,6 +160,26 @@ namespace BansheeEngine
             }
         }
 
+        public Matrix4 Inverse
+        {
+            get
+            {
+                Matrix4 value = this;
+                value.Invert();
+                return value;
+            }
+        }
+
+        public Matrix4 InverseAffine
+        {
+            get
+            {
+                Matrix4 value = this;
+                value.InvertAffine();
+                return value;
+            }
+        }
+
         public static Matrix4 operator *(Matrix4 lhs, Matrix4 rhs)
         {
             return new Matrix4()
@@ -478,14 +498,14 @@ namespace BansheeEngine
                 mat.m20, mat.m21, mat.m22);
         }
 
-        public static Matrix4 Inverse(Matrix4 mat)
+        public static Matrix4 Invert(Matrix4 mat)
         {
             Matrix4 copy = mat;
             copy.Invert();
             return copy;
         }
 
-        public static Matrix4 InverseAffine(Matrix4 mat)
+        public static Matrix4 InvertAffine(Matrix4 mat)
         {
             Matrix4 copy = mat;
             copy.InvertAffine();

+ 1 - 1
MBansheeEngine/Math/Quaternion.cs

@@ -211,7 +211,7 @@ namespace BansheeEngine
 			    {
 				    // Generate an axis
 				    Vector3 axis = Vector3.Cross(Vector3.xAxis, fromDirection);
-                    if (axis.sqrdMagnitude < ((1e-06f * 1e-06f))) // Pick another if collinear
+                    if (axis.SqrdMagnitude < ((1e-06f * 1e-06f))) // Pick another if collinear
 					    axis = Vector3.Cross(Vector3.yAxis, fromDirection);
 				    axis.Normalize();
                     this = FromAxisAngle(axis, MathEx.Pi * MathEx.Rad2Deg);

+ 16 - 0
MBansheeEngine/Math/Vector2I.cs

@@ -46,6 +46,22 @@ namespace BansheeEngine
             this.y = y;
         }
 
+        public float Magnitude
+        {
+            get
+            {
+                return (float)MathEx.Sqrt(x * x + y * y);
+            }
+        }
+
+        public float SqrdMagnitude
+        {
+            get
+            {
+                return (x * x + y * y);
+            }
+        }
+
         public static Vector2I operator +(Vector2I a, Vector2I b)
         {
             return new Vector2I(a.x + b.x, a.y + b.y);

+ 5 - 15
MBansheeEngine/Math/Vector3.cs

@@ -52,7 +52,7 @@ namespace BansheeEngine
             }
         }
 
-        public Vector3 normalized
+        public Vector3 Normalized
         {
             get
             {
@@ -60,7 +60,7 @@ namespace BansheeEngine
             }
         }
 
-        public float magnitude
+        public float Magnitude
         {
             get
             {
@@ -68,7 +68,7 @@ namespace BansheeEngine
             }
         }
 
-        public float sqrdMagnitude
+        public float SqrdMagnitude
         {
             get
             {
@@ -140,7 +140,7 @@ namespace BansheeEngine
 
         public static Vector3 Normalize(Vector3 value)
         {
-            float num = Magnitude(value);
+            float num = value.Magnitude;
             if (num > 9.999999E-06)
                 return value / num;
             
@@ -158,16 +158,6 @@ namespace BansheeEngine
             return MathEx.Sqrt(vector3.x * vector3.x + vector3.y * vector3.y + vector3.z * vector3.z);
         }
 
-        public static float Magnitude(Vector3 v)
-        {
-            return (float)MathEx.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
-        }
-
-        public static float SqrMagnitude(Vector3 v)
-        {
-            return (v.x * v.x + v.y * v.y + v.z * v.z);
-        }
-
         public void Scale(Vector3 scale)
         {
             x *= scale.x;
@@ -177,7 +167,7 @@ namespace BansheeEngine
 
         public void Normalize()
         {
-            float num = Magnitude(this);
+            float num = Magnitude;
             if (num > 9.999999E-06)
                 this /= num;
             else

+ 5 - 8
TODO.txt

@@ -1,9 +1,5 @@
 --------- ALL LONG TERM TASKS / FIXES BELONG TO GOOGLE DOCS: ImplementationTODO OR PossibleImprovements ----------
 
-Do a cleanup pass on the editor? Fix the annoying little issues:
- - Switching between button states seem to cause 1 frame of no texture for the gui element
- - Much more I can't think of right now
-
 <<<<<Assembly refresh>>>>>
 
 When serializing Camera I cannot save the reference to RenderTexture. Make it a Resource?
@@ -11,15 +7,16 @@ Possibly set up automatic refresh in debug mode after initialization? As an ad-h
 
 <<<<<<Handles>>>>>>>>
 
-Add free scale handle
+Rotation is really really jerky
+Free rotate doesn't really work
+When scaling using center make sure to offset the object before scale
 
 Rotate handle:
- - 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
+
+Ideally free scale handle indicator should always render and be interactable and never be hidden by axis scale indicators (Not high priority)
 
 Cursor wrap only works when cursor moves really slowly over the border, and even then it's spotty
 When changing handle types they do not refresh until you click on the scene view