Răsfoiți Sursa

Rotation handle in pivot mode working nicely

Marko Pintera 10 ani în urmă
părinte
comite
b297afa5fb

+ 1 - 1
BansheeCore/Source/BsViewport.cpp

@@ -8,7 +8,7 @@
 
 namespace BansheeEngine 
 {
-	const Color Viewport::DEFAULT_CLEAR_COLOR = Color(143.0f / 255.0f, 111.0f / 255.0f, 0);
+	const Color Viewport::DEFAULT_CLEAR_COLOR = Color(83.0f / 255.0f, 83.0f / 255.0f, 83.0f / 255.0f);
 
 	ViewportBase::ViewportBase(float x, float y, float width, float height)
          :mNormArea(x, y, width, height), mClearColor(DEFAULT_CLEAR_COLOR), mRequiresColorClear(true), 

+ 3 - 1
BansheeEditor/Source/BsHandleSliderDisc.cpp

@@ -164,8 +164,10 @@ namespace BansheeEngine
 		mStartAngle = pointOnCircleToAngle(mNormal, mStartPosition);
 		mStartPosition = getTransform().multiplyAffine(mStartPosition);
 
+		Vector3 worldNormal = getTransform().multiplyAffine(mNormal);
+
 		Vector3 toStart = mStartPosition - getPosition();
-		mDirection = toStart.cross(mNormal);
+		mDirection = worldNormal.cross(toStart);
 		mDirection.normalize();
 	}
 

+ 15 - 15
BansheeEngine/Source/BsShapeMeshes3D.cpp

@@ -531,12 +531,12 @@ namespace BansheeEngine
 		for (UINT32 i = 0; i < numTriangles; i++)
 		{
 			outIndices[i * 6 + 0] = frontSideOffset + 0;
-			outIndices[i * 6 + 1] = frontSideOffset + i;
-			outIndices[i * 6 + 2] = frontSideOffset + i + 1;
+			outIndices[i * 6 + 1] = frontSideOffset + i + 1;
+			outIndices[i * 6 + 2] = frontSideOffset + i;
 
 			outIndices[i * 6 + 3] = backSideOffset + 0;
-			outIndices[i * 6 + 4] = backSideOffset + i + 1;
-			outIndices[i * 6 + 5] = backSideOffset + i;
+			outIndices[i * 6 + 4] = backSideOffset + i;
+			outIndices[i * 6 + 5] = backSideOffset + i + 1;
 		}
 	}
 
@@ -619,15 +619,15 @@ namespace BansheeEngine
 		for (UINT32 i = 0; i < numTriangles - 1; i++)
 		{
 			outIndices[i * 3 + 0] = vertexOffset + baseIdx;
-			outIndices[i * 3 + 1] = vertexOffset + i + 1;
-			outIndices[i * 3 + 2] = vertexOffset + i;
+			outIndices[i * 3 + 1] = vertexOffset + i;
+			outIndices[i * 3 + 2] = vertexOffset + i + 1;
 		}
 
 		{
 			UINT32 i = numTriangles - 1;
 			outIndices[i * 3 + 0] = vertexOffset + baseIdx;
-			outIndices[i * 3 + 1] = vertexOffset + 0;
-			outIndices[i * 3 + 2] = vertexOffset + i;
+			outIndices[i * 3 + 1] = vertexOffset + i;
+			outIndices[i * 3 + 2] = vertexOffset + 0;
 		}
 
 		//// Generate cone
@@ -652,10 +652,10 @@ namespace BansheeEngine
 
 			Vector3 toTop = topVertex - *b;
 
-			Vector3 normalLeft = Vector3::cross(*a - *b, toTop);
+			Vector3 normalLeft = Vector3::cross(toTop, *a - *b);
 			normalLeft.normalize();
 
-			Vector3 normalRight = Vector3::cross(toTop, *c - *b);
+			Vector3 normalRight = Vector3::cross(*c - *b, toTop);
 			normalRight.normalize();
 
 			Vector3 triNormal = Vector3::normalize(normalLeft + normalRight);
@@ -676,15 +676,15 @@ namespace BansheeEngine
 		for (UINT32 i = 0; i < numTriangles - 1; i++)
 		{
 			outIndices[i * 3 + 0] = curVertTopOffset + i;
-			outIndices[i * 3 + 1] = curVertBaseOffset + i;
-			outIndices[i * 3 + 2] = curVertBaseOffset + i + 1;
+			outIndices[i * 3 + 1] = curVertBaseOffset + i + 1;
+			outIndices[i * 3 + 2] = curVertBaseOffset + i;
 		}
 
 		{
 			UINT32 i = numTriangles - 1;
 			outIndices[i * 3 + 0] = curVertTopOffset + i;
-			outIndices[i * 3 + 1] = curVertBaseOffset + i;
-			outIndices[i * 3 + 2] = curVertBaseOffset + 0;
+			outIndices[i * 3 + 1] = curVertBaseOffset + 0;
+			outIndices[i * 3 + 2] = curVertBaseOffset + i;
 		}
 	}
 
@@ -986,7 +986,7 @@ namespace BansheeEngine
 		Vector3 right = alignWithUp.rotate(alignWithStart.rotate(Vector3::UNIT_X));
 		right.normalize();
 
-		Quaternion increment(-up, angleAmount / (float)(numVertices - 1));
+		Quaternion increment(up, angleAmount / (float)(numVertices - 1));
 
 		outVertices += vertexOffset * vertexStride;
 		Vector3 curDirection = right * radius;

+ 0 - 1
MBansheeEditor/EditorApplication.cs

@@ -113,7 +113,6 @@ namespace BansheeEditor
 
             SceneObject gizmoDbgObject = new SceneObject("GizmoDebug");
             gizmoDbgObject.AddComponent<DbgGizmoComponent>();
-
             //ProgressBar.Show("Test", 0.5f);
             //ColorPicker.Show();
 

+ 23 - 17
MBansheeEditor/Scene/DefaultHandleManager.cs

@@ -81,9 +81,7 @@ namespace BansheeEditor
                 {
                     List<SceneObject> flatenedHierarchy = new List<SceneObject>();
                     foreach (var so in selectedSceneObjects)
-                    {
                         flatenedHierarchy.AddRange(EditorUtility.FlattenHierarchy(so));
-                    }
 
                     AABox selectionBounds = EditorUtility.CalculateBounds(flatenedHierarchy.ToArray());
                     position = selectionBounds.center;
@@ -125,40 +123,48 @@ namespace BansheeEditor
                     switch (activeHandleType)
                     {
                         case SceneViewTool.Move:
-                        {
                             MoveHandle moveHandle = (MoveHandle) activeHandle;
 
                             foreach (var selectedObj in activeSelection)
                                 selectedObj.so.Position = selectedObj.initialPosition + moveHandle.Delta;
-                        }
 
                             break;
                         case SceneViewTool.Rotate:
-                        {
                             RotateHandle rotateHandle = (RotateHandle) activeHandle;
 
                             foreach (var selectedObj in activeSelection)
                                 selectedObj.so.Rotation = selectedObj.initialRotation * rotateHandle.Delta;
-                        }
+
                             break;
                         case SceneViewTool.Scale:
-                        {
                             ScaleHandle scaleHandle = (ScaleHandle) activeHandle;
 
-                            if (EditorApplication.ActivePivotMode == HandlePivotMode.Pivot)
+                            // Make sure we transform relative to the handle position
+                            SceneObject temporarySO = new SceneObject("Temp");
+                            temporarySO.Position = activeHandle.Position;
+
+                            SceneObject[] originalParents = new SceneObject[activeSelection.Length];
+                            for (int i = 0; i < activeSelection.Length; i++)
                             {
-                                foreach (var selectedObj in activeSelection)
-                                    selectedObj.so.LocalScale = selectedObj.initialScale + scaleHandle.Delta;
+                                originalParents[i] = activeSelection[i].so.Parent;
+                                activeSelection[i].so.LocalScale = activeSelection[i].initialScale;
+                                activeSelection[i].so.Parent = temporarySO;
                             }
-                            else
+
+                            //temporarySO.LocalScale = Vector3.one + scaleHandle.Delta;
+                            temporarySO.LocalScale = Vector3.one*0.5f;
+                            Debug.Log("SCALE " + temporarySO.LocalScale + " - " + scaleHandle.Delta);
+
+                            for (int i = 0; i < activeSelection.Length; i++)
                             {
-                                foreach (var selectedObj in activeSelection)
-                                {
-                                    selectedObj.so.LocalScale = selectedObj.initialScale + scaleHandle.Delta;
-                                    // TODO
-                                }
+                                Debug.Log("POSITION A: " + activeSelection[i].so.Position);
+                                activeSelection[i].so.Parent = originalParents[i];
+                                Debug.Log("TFRM " + activeSelection[i].so.LocalScale + " - " + activeSelection[i].so.Position);
                             }
-                        }
+
+                            
+                            temporarySO.Destroy();
+
                             break;
                     }
                 }

+ 53 - 37
MBansheeEditor/Scene/RotateHandle.cs

@@ -10,6 +10,9 @@ namespace BansheeEditor
         private HandleSliderDisc yAxis;
         private HandleSliderDisc zAxis;
 
+        private bool isDragged;
+        private Quaternion dragStartRotation;
+
         public Quaternion Delta
         {
             get { return delta; }
@@ -35,14 +38,31 @@ namespace BansheeEditor
             yAxis.Position = position;
             zAxis.Position = position;
 
-            xAxis.SetCutoffPlane(GetXStartAngle(), true);
-            yAxis.SetCutoffPlane(GetYStartAngle(), true);
-            zAxis.SetCutoffPlane(GetZStartAngle(), true);
+            Quaternion handleRotation = isDragged ? dragStartRotation : Rotation;
+            xAxis.Rotation = handleRotation;
+            yAxis.Rotation = handleRotation;
+            zAxis.Rotation = handleRotation;
+
+            xAxis.SetCutoffPlane(GetXStartAngle(isDragged), true);
+            yAxis.SetCutoffPlane(GetYStartAngle(isDragged), true);
+            zAxis.SetCutoffPlane(GetZStartAngle(isDragged), true);
         }
 
         protected override void PostInput()
         {
-            delta = Quaternion.identity;
+            if (IsDragged())
+            {
+                if (!isDragged)
+                {
+                    isDragged = true;
+                    dragStartRotation = Rotation;
+                }
+            }
+            else
+            {
+                isDragged = false;
+                dragStartRotation = Quaternion.identity;
+            }
 
             Degree xValue = 0.0f;
             Degree yValue = 0.0f;
@@ -61,14 +81,13 @@ namespace BansheeEditor
                 zValue = zAxis.Delta;
             }
 
-            delta = Quaternion.FromAxisAngle(GetXDir(), xValue) * delta;
-            delta = Quaternion.FromAxisAngle(GetYDir(), yValue) * delta;
-            delta = Quaternion.FromAxisAngle(GetZDir(), zValue) * delta;
+            delta = Quaternion.FromEuler(xValue, yValue, zValue);
         }
 
         protected override void Draw()
         {
-            HandleDrawing.SetTransform(Matrix4.TRS(Position, Quaternion.identity, Vector3.one));
+            //HandleDrawing.SetTransform(Matrix4.TRS(Position, Quaternion.identity, Vector3.one));
+            HandleDrawing.SetTransform(Matrix4.TRS(Position, Rotation, Vector3.one));
             float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
 
             // Draw arcs
@@ -79,7 +98,8 @@ namespace BansheeEditor
             else
                 HandleDrawing.SetColor(Color.Red);
 
-            HandleDrawing.DrawWireArc(Vector3.zero, GetXDir(), 1.0f, GetXStartAngle(), 180.0f, handleSize);
+            //HandleDrawing.DrawWireArc(Vector3.zero, Rotation.Rotate(Vector3.xAxis), 1.0f, GetXStartAngle(false), -180.0f, handleSize);
+            HandleDrawing.DrawWireArc(Vector3.zero, Vector3.xAxis, 1.0f, GetXStartAngle(false), -180.0f, handleSize);
 
             if (yAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
@@ -88,7 +108,8 @@ namespace BansheeEditor
             else
                 HandleDrawing.SetColor(Color.Green);
 
-            HandleDrawing.DrawWireArc(Vector3.zero, GetYDir(), 1.0f, GetYStartAngle(), 180.0f, handleSize);
+            //HandleDrawing.DrawWireArc(Vector3.zero, Rotation.Rotate(Vector3.yAxis), 1.0f, GetYStartAngle(false), -180.0f, handleSize);
+            HandleDrawing.DrawWireArc(Vector3.zero, Vector3.yAxis, 1.0f, GetYStartAngle(false), -180.0f, handleSize);
 
             if (zAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
@@ -97,58 +118,53 @@ namespace BansheeEditor
             else
                 HandleDrawing.SetColor(Color.Blue);
 
-            HandleDrawing.DrawWireArc(Vector3.zero, GetZDir(), 1.0f, GetZStartAngle(), 180.0f, handleSize);
+            //HandleDrawing.DrawWireArc(Vector3.zero, Rotation.Rotate(Vector3.zAxis), 1.0f, GetZStartAngle(false), -180.0f, handleSize);
+            HandleDrawing.DrawWireArc(Vector3.zero, Vector3.zAxis, 1.0f, GetZStartAngle(false), -180.0f, handleSize);
 
             // Draw active rotation pie
             Color gray = new Color(1.0f, 1.0f, 1.0f, 0.3f);
             HandleDrawing.SetColor(gray);
+            HandleDrawing.SetTransform(Matrix4.TRS(Position, dragStartRotation, Vector3.one));
 
             if (xAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.DrawArc(Vector3.zero, GetXDir(), 1.0f, xAxis.StartAngle, xAxis.Delta, handleSize);
+                HandleDrawing.DrawArc(Vector3.zero, Vector3.xAxis, 1.0f, xAxis.StartAngle, xAxis.Delta, handleSize);
             else if (yAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.DrawArc(Vector3.zero, GetYDir(), 1.0f, yAxis.StartAngle, yAxis.Delta, handleSize);
+                HandleDrawing.DrawArc(Vector3.zero, Vector3.yAxis, 1.0f, yAxis.StartAngle, yAxis.Delta, handleSize);
             else if (zAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.DrawArc(Vector3.zero, GetZDir(), 1.0f, zAxis.StartAngle, zAxis.Delta, handleSize);
+                HandleDrawing.DrawArc(Vector3.zero, Vector3.zAxis, 1.0f, zAxis.StartAngle, zAxis.Delta, handleSize);
 
             // Draw free rotate handle
+            HandleDrawing.SetTransform(Matrix4.TRS(Position, Quaternion.identity, Vector3.one));
+            
             //// 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;
+            Vector3 freeHandleNormal = EditorApplication.SceneViewCamera.SceneObject.Rotation.Rotate(Vector3.zAxis);
+            Vector3 offset = freeHandleNormal * 0.1f;
 
             HandleDrawing.DrawWireDisc(offset, freeHandleNormal, 1.0f, handleSize);
         }
 
-        private Degree GetXStartAngle()
+        private Degree GetXStartAngle(bool frozen)
         {
-            Vector3 xStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.SceneObject.Forward, GetXDir());
-            return PointOnCircleToAngle(GetXDir(), xStartDir);
-        }
+            Quaternion handleRotation = frozen ? dragStartRotation : Rotation;
 
-        private Degree GetYStartAngle()
-        {
-            Vector3 yStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.SceneObject.Forward, GetYDir());
-            return PointOnCircleToAngle(GetYDir(), yStartDir);
+            Vector3 xStartDir = Vector3.Cross(handleRotation.Inverse.Rotate(EditorApplication.SceneViewCamera.SceneObject.Forward), Vector3.xAxis);
+            return PointOnCircleToAngle(Vector3.xAxis, xStartDir);
         }
 
-        private Degree GetZStartAngle()
+        private Degree GetYStartAngle(bool frozen)
         {
-            Vector3 zStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.SceneObject.Forward, GetZDir());
-            return PointOnCircleToAngle(GetZDir(), zStartDir);
-        }
+            Quaternion handleRotation = frozen ? dragStartRotation : Rotation;
 
-        private Vector3 GetXDir()
-        {
-             return Vector3.xAxis;
+            Vector3 yStartDir = Vector3.Cross(handleRotation.Inverse.Rotate(EditorApplication.SceneViewCamera.SceneObject.Forward), Vector3.yAxis);
+            return PointOnCircleToAngle(Vector3.yAxis, yStartDir);
         }
 
-        private Vector3 GetYDir()
+        private Degree GetZStartAngle(bool frozen)
         {
-            return Vector3.yAxis;
-        }
+            Quaternion handleRotation = frozen ? dragStartRotation : Rotation;
 
-        private Vector3 GetZDir()
-        {
-            return Vector3.zAxis;
+            Vector3 zStartDir = Vector3.Cross(handleRotation.Inverse.Rotate(EditorApplication.SceneViewCamera.SceneObject.Forward), Vector3.zAxis);
+            return PointOnCircleToAngle(Vector3.zAxis, zStartDir);
         }
 
         private Degree PointOnCircleToAngle(Vector3 up, Vector3 point)

+ 2 - 0
MBansheeEditor/Scene/SceneWindow.cs

@@ -12,6 +12,7 @@ namespace BansheeEditor
     {
         private const int HeaderHeight = 20;
         private const float DefaultPlacementDepth = 5.0f;
+        private static readonly Color ClearColor = new Color(83.0f/255.0f, 83.0f/255.0f, 83.0f/255.0f);
 
         private Camera camera;
         private SceneCamera cameraController;
@@ -409,6 +410,7 @@ namespace BansheeEditor
                 camera.Priority = 1;
                 camera.NearClipPlane = 0.005f;
                 camera.FarClipPlane = 1000.0f;
+                camera.ClearColor = ClearColor;
 
                 cameraController = sceneCameraSO.AddComponent<SceneCamera>();
 

+ 4 - 4
MBansheeEngine/Math/Quaternion.cs

@@ -178,7 +178,7 @@ namespace BansheeEngine
 
         public static Quaternion operator- (Quaternion quat)
         {
-            return new Quaternion(-quat.w, -quat.x, -quat.y, -quat.z);
+            return new Quaternion(-quat.x, -quat.y, -quat.z, -quat.w);
         }
 
         public static bool operator== (Quaternion lhs, Quaternion rhs)
@@ -537,9 +537,9 @@ namespace BansheeEngine
 		    float sz = MathEx.Sin(halfZAngle);
 
 		    Quaternion[] quats = new Quaternion[3];
-		    quats[0] = new Quaternion(cx, sx, 0.0f, 0.0f);
-		    quats[1] = new Quaternion(cy, 0.0f, sy, 0.0f);
-		    quats[2] = new Quaternion(cz, 0.0f, 0.0f, sz);
+		    quats[0] = new Quaternion(sx, 0.0f, 0.0f, cx);
+		    quats[1] = new Quaternion(0.0f, sy, 0.0f, cy);
+		    quats[2] = new Quaternion(0.0f, 0.0f, sz, cz);
 
 		    return (quats[l.a] * quats[l.b]) * quats[l.c];
         }

+ 5 - 0
TODO.txt

@@ -58,6 +58,8 @@ Polish stage 1
 
 Handles:
 Move plane handles could be more precise
+Cut-off angle for rotation discs is wrong after they rotate
+Rotation disc normals are wrong on one side (likely it's double-sided)
 Once rotated further rotations seem to be going in wrong direction and gizmo is messed up
 Rotations seems to be going in the wrong direction
 Rotations around center incorrectly move and rotate the rotation gizmos
@@ -90,6 +92,9 @@ Need a way to add scene objects and components (and remove them)
  - Adding scene objects should be doable from context menu in Hierarchy, by dropping a Prefab or by main Menu (undoable)
  - Deleting them should be doable by context menu in Hierarchy and Del keystroke (undoable)
 
+Add shortcut keys for view/move/rotate/scale
+Add "focus on object" key (F)
+
 For later: I could record undo/redo per-property using the new diff system
 Remember: Record all portions where objects & components get modified so I can mark them dirty, will likely need
  to use those some points for undo/redo