Browse Source

Improvements to SceneObject transform

Marko Pintera 11 years ago
parent
commit
2f7095dbd2

+ 8 - 0
BansheeCore/Include/BsSceneObject.h

@@ -132,6 +132,14 @@ namespace BansheeEngine
 		 */
 		 */
 		const Vector3& getScale() const { return mScale; }
 		const Vector3& getScale() const { return mScale; }
 
 
+		/**
+		 * @brief	Sets the world scale of the object.
+		 *
+		 * @note	This will not work properly if this object or any of its parents
+		 *			have non-affine transform matrices.
+		 */
+		void setWorldScale(const Vector3& scale);
+
 		/**
 		/**
 		 * @brief	Gets world scale of the object.
 		 * @brief	Gets world scale of the object.
 		 *
 		 *

+ 25 - 0
BansheeCore/Source/BsSceneObject.cpp

@@ -155,6 +155,21 @@ namespace BansheeEngine
 		markTfrmDirty();
 		markTfrmDirty();
 	}
 	}
 
 
+	void SceneObject::setWorldScale(const Vector3& scale)
+	{
+		if (mParent != nullptr)
+		{
+			Matrix4 parentTfrm = mParent->getWorldTfrm();
+			parentTfrm.inverseAffine();
+
+			mScale = parentTfrm.multiplyDirection(scale);
+		}
+		else
+			mScale = scale;
+
+		markTfrmDirty();
+	}
+
 	const Vector3& SceneObject::getWorldPosition() const
 	const Vector3& SceneObject::getWorldPosition() const
 	{ 
 	{ 
 		if (!isCachedWorldTfrmUpToDate())
 		if (!isCachedWorldTfrmUpToDate())
@@ -357,6 +372,11 @@ namespace BansheeEngine
 
 
 		if(mParent == nullptr || mParent != parent)
 		if(mParent == nullptr || mParent != parent)
 		{
 		{
+			// Make sure the object keeps its world coordinates
+			Vector3 worldPos = getWorldPosition();
+			Quaternion worldRot = getWorldRotation();
+			Vector3 worldScale = getWorldScale();
+
 			if(mParent != nullptr)
 			if(mParent != nullptr)
 				mParent->removeChild(mThisHandle);
 				mParent->removeChild(mThisHandle);
 
 
@@ -364,6 +384,11 @@ namespace BansheeEngine
 				parent->addChild(mThisHandle);
 				parent->addChild(mThisHandle);
 
 
 			mParent = parent;
 			mParent = parent;
+
+			setWorldPosition(worldPos);
+			setWorldRotation(worldRot);
+			setWorldScale(worldScale);
+
 			markTfrmDirty();
 			markTfrmDirty();
 		}
 		}
 	}
 	}

+ 1 - 1
BansheeEditor/Source/BsSceneViewHandler.cpp

@@ -134,7 +134,7 @@ namespace BansheeEngine
 			offset.y = -maxHeight;
 			offset.y = -maxHeight;
 
 
 		windowPos += offset;
 		windowPos += offset;
-		
+
 		Vector2I wrappedScreenPos = parentWindow->windowToScreenPos(windowPos);
 		Vector2I wrappedScreenPos = parentWindow->windowToScreenPos(windowPos);
 		Cursor::instance().setScreenPosition(wrappedScreenPos);
 		Cursor::instance().setScreenPosition(wrappedScreenPos);
 
 

+ 13 - 2
BansheeUtility/Include/BsMatrix4.h

@@ -345,7 +345,7 @@ namespace BansheeEngine
         }
         }
 
 
         /**
         /**
-         * @brief	Transform a 3D vector by this matrix.
+         * @brief	Transform a 3D point by this matrix.
          * 			
          * 			
          * @note	Matrix must be affine, if it is not use "multiply" method.
          * @note	Matrix must be affine, if it is not use "multiply" method.
          */
          */
@@ -392,7 +392,7 @@ namespace BansheeEngine
         }
         }
 
 
         /**
         /**
-         * @brief	Transform a 3D vector by this matrix.  
+         * @brief	Transform a 3D point by this matrix.  
          *
          *
          * @note	w component of the vector is assumed to be 1. After transformation all components
          * @note	w component of the vector is assumed to be 1. After transformation all components
          * 			are projected back so that w remains 1.
          * 			are projected back so that w remains 1.
@@ -412,6 +412,17 @@ namespace BansheeEngine
             return r;
             return r;
         }
         }
 
 
+		/**
+         * @brief	Transform a 3D direction by this matrix.
+         */
+        Vector3 multiplyDirection(const Vector3& v) const
+        {
+            return Vector3(
+                    m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z, 
+                    m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z,
+                    m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z);
+        }
+
         /**
         /**
          * @brief	Transform a 4D vector by this matrix.  
          * @brief	Transform a 4D vector by this matrix.  
          *
          *

+ 3 - 5
MBansheeEditor/Scene/MoveHandle.cs

@@ -100,12 +100,10 @@ namespace BansheeEditor
             float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
             float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
 
 
             // Draw 1D arrows
             // Draw 1D arrows
-            Color axisHover = new Color(0.8f, 0.8f, 0.8f, 1.0f);
-
             if (xAxis.State == HandleSlider.StateType.Active)
             if (xAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
                 HandleDrawing.SetColor(Color.White);
             else if(xAxis.State == HandleSlider.StateType.Hover)
             else if(xAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.SetColor(Color.Red * axisHover);
+                HandleDrawing.SetColor(Color.BansheeOrange);
             else
             else
                 HandleDrawing.SetColor(Color.Red);
                 HandleDrawing.SetColor(Color.Red);
 
 
@@ -116,7 +114,7 @@ namespace BansheeEditor
             if (yAxis.State == HandleSlider.StateType.Active)
             if (yAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
                 HandleDrawing.SetColor(Color.White);
             else if (yAxis.State == HandleSlider.StateType.Hover)
             else if (yAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.SetColor(Color.Green * axisHover);
+                HandleDrawing.SetColor(Color.BansheeOrange);
             else
             else
                 HandleDrawing.SetColor(Color.Green);
                 HandleDrawing.SetColor(Color.Green);
 
 
@@ -127,7 +125,7 @@ namespace BansheeEditor
             if (zAxis.State == HandleSlider.StateType.Active)
             if (zAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.White);
                 HandleDrawing.SetColor(Color.White);
             else if (zAxis.State == HandleSlider.StateType.Hover)
             else if (zAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.SetColor(Color.Blue * axisHover);
+                HandleDrawing.SetColor(Color.BansheeOrange);
             else
             else
                 HandleDrawing.SetColor(Color.Blue);
                 HandleDrawing.SetColor(Color.Blue);
 
 

+ 1 - 24
MBansheeEditor/Scene/RotateHandle.cs

@@ -10,8 +10,6 @@ namespace BansheeEditor
         private HandleSliderDisc yAxis;
         private HandleSliderDisc yAxis;
         private HandleSliderDisc zAxis;
         private HandleSliderDisc zAxis;
 
 
-        private HandleSliderDisc freeAxis;
-
         public Quaternion Delta
         public Quaternion Delta
         {
         {
             get { return delta; }
             get { return delta; }
@@ -21,8 +19,7 @@ namespace BansheeEditor
         {
         {
             return xAxis.State == HandleSlider.StateType.Active ||
             return xAxis.State == HandleSlider.StateType.Active ||
                     yAxis.State == HandleSlider.StateType.Active ||
                     yAxis.State == HandleSlider.StateType.Active ||
-                    zAxis.State == HandleSlider.StateType.Active ||
-                    freeAxis.State == HandleSlider.StateType.Active;
+                    zAxis.State == HandleSlider.StateType.Active;
         }
         }
 
 
         public RotateHandle()
         public RotateHandle()
@@ -30,7 +27,6 @@ namespace BansheeEditor
             xAxis = new HandleSliderDisc(this, Vector3.xAxis, 1.0f);
             xAxis = new HandleSliderDisc(this, Vector3.xAxis, 1.0f);
             yAxis = new HandleSliderDisc(this, Vector3.yAxis, 1.0f);
             yAxis = new HandleSliderDisc(this, Vector3.yAxis, 1.0f);
             zAxis = new HandleSliderDisc(this, Vector3.zAxis, 1.0f);
             zAxis = new HandleSliderDisc(this, Vector3.zAxis, 1.0f);
-            freeAxis = new HandleSliderDisc(this, Vector3.zAxis, 1.0f);
         }
         }
 
 
         protected override void PreInput()
         protected override void PreInput()
@@ -39,13 +35,9 @@ namespace BansheeEditor
             yAxis.Position = position;
             yAxis.Position = position;
             zAxis.Position = position;
             zAxis.Position = position;
 
 
-            freeAxis.Position = position;
-            freeAxis.Rotation = EditorApplication.SceneViewCamera.sceneObject.Rotation;
-
             xAxis.SetCutoffPlane(GetXStartAngle(), true);
             xAxis.SetCutoffPlane(GetXStartAngle(), true);
             yAxis.SetCutoffPlane(GetYStartAngle(), true);
             yAxis.SetCutoffPlane(GetYStartAngle(), true);
             zAxis.SetCutoffPlane(GetZStartAngle(), true);
             zAxis.SetCutoffPlane(GetZStartAngle(), true);
-            freeAxis.SetCutoffPlane(0.0f, false);
         }
         }
 
 
         protected override void PostInput()
         protected override void PostInput()
@@ -72,14 +64,6 @@ namespace BansheeEditor
             delta = Quaternion.FromAxisAngle(GetXDir(), xValue) * delta;
             delta = Quaternion.FromAxisAngle(GetXDir(), xValue) * delta;
             delta = Quaternion.FromAxisAngle(GetYDir(), yValue) * delta;
             delta = Quaternion.FromAxisAngle(GetYDir(), yValue) * delta;
             delta = Quaternion.FromAxisAngle(GetZDir(), zValue) * delta;
             delta = Quaternion.FromAxisAngle(GetZDir(), zValue) * delta;
-
-            if (freeAxis.State == HandleSlider.StateType.Active)
-            {
-                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()
         protected override void Draw()
@@ -127,13 +111,6 @@ namespace BansheeEditor
                 HandleDrawing.DrawArc(Vector3.zero, GetZDir(), 1.0f, zAxis.StartAngle, zAxis.Delta, handleSize);
                 HandleDrawing.DrawArc(Vector3.zero, GetZDir(), 1.0f, zAxis.StartAngle, zAxis.Delta, handleSize);
 
 
             // Draw 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
             //// 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 freeHandleNormal = EditorApplication.SceneViewCamera.sceneObject.Rotation.Rotate(GetZDir());
             Vector3 offset = freeHandleNormal*0.1f;
             Vector3 offset = freeHandleNormal*0.1f;

+ 2 - 56
TODO.txt

@@ -7,8 +7,8 @@ Possibly set up automatic refresh in debug mode after initialization? As an ad-h
 
 
 <<<<<<Handles>>>>>>>>
 <<<<<<Handles>>>>>>>>
 
 
-Free rotate doesn't really work
 When scaling using center make sure to offset the object before scale
 When scaling using center make sure to offset the object before scale
+Handles should probably not having shading, or have better shading.
 
 
 Rotate handle:
 Rotate handle:
  - How to handle local/global with rotate handle?
  - How to handle local/global with rotate handle?
@@ -17,9 +17,6 @@ Rotate handle:
 
 
 Ideally free scale handle indicator should always render and be interactable and never be hidden by axis scale indicators (Not high priority)
 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
-
 <<<<Multi-resource saving>>>>:
 <<<<Multi-resource saving>>>>:
  - Modify Font so it doesn't contain a texture, but instead keeps a handle to it
  - Modify Font so it doesn't contain a texture, but instead keeps a handle to it
  - Register it in its meta file
  - Register it in its meta file
@@ -29,8 +26,6 @@ When changing handle types they do not refresh until you click on the scene view
 
 
 Other:
 Other:
 Window resize end callback
 Window resize end callback
-Add cutoff plane when rendering discs for rotation handle.
-There seems to be a delay when changing GUI element sprite textures (like 1 frame there is no texture at all)
 
 
 I can get mono errors by checking g_print calls in goutput.c
 I can get mono errors by checking g_print calls in goutput.c
  - Calling thunks incorrectly can cause those weird errors with no real callstack
  - Calling thunks incorrectly can cause those weird errors with no real callstack
@@ -53,64 +48,15 @@ Set up a default layout and save it
 Need a way to drag and drop items from Scene tree view to Scene view
 Need a way to drag and drop items from Scene tree view to Scene view
 
 
 AFTER I have scene widget in C#:
 AFTER I have scene widget in C#:
- - Implement free move handle and remaining handles
  - Test custom handles from C#
  - Test custom handles from C#
  - Test handle snapping
  - Test handle snapping
 
 
-IMPLEMENT SELECTION RENDERING
-
 IMPROVE SceneGrid LOOK - Use the shader created in Unity
 IMPROVE SceneGrid LOOK - Use the shader created in Unity
 
 
-----------------------------------------------------------------------
-Handles
-
-SliderLine - position, direction, length
-  - When initially activated it records position nearest so the line as the starting point
-  - Further mouse dragging also finds nearest position to the line
-  - Difference between those two results in a float value (how much to move along direction from position to reach new position)
-  - Slider line has a capsule + sphere collider size of which can be set manually
-
-SliderPlane - position, normal, size
-  - Similar to line slider only the direction is determined dynamically as well as distance
-  - Outputs a Vector2 (direction * distance moved)
-  - A OOB is used as a collider
-
-SliderDisc - position, normal, radius
-  - When initially activated it records position nearest so the disc as the starting point
-  - Further movement calculates the dynamic direction from the starting point to the current point on the plane the disc lies on
-  - Distance along that direction is returned as amount of movement (similar to line slider)
-  - Outputs a single float
-  - A torus is used as a collider
-
-Free move/rotate/scale handles need to exist as well
- - Scale is easy, just perform uniform scale. Use SliderPlane oriented towards camera
- - Move also use SliderPlane oriented towards camera
- - Rotation use SliderDisc oriented towards camera
-
-----------------------------------------------------
-STAGE 1
-
-CONCRETE TODO:
-HandleSliderPlane/HandleSliderDisc
- - update() implementation
-
-----------------------------------------------------
-STAGE 2
-Implement RotateHandle & ScaleHandle in C#
- - Nearest point to disc/arc code
-Add 2D move and scale
-Add free move, free rotate, free scale functionality
-Handles that remain the same size regardless of distance from camera
- - For both drawing and collision
-
- More complex types for drawing like DrawArrow in HandleDrawManager
-
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 SelectionRenderer
 SelectionRenderer
 
 
 Retrieve a list of selected objects from SelectionManager
 Retrieve a list of selected objects from SelectionManager
 Find ones with Renderable components
 Find ones with Renderable components
 Retrieve Meshes, and world transforms from them
 Retrieve Meshes, and world transforms from them
-Draw that same mesh with either a wireframe or a grayed out shader with a slight depth bias
-
----------------------------------------------------------------------
+Draw that same mesh with either a wireframe or a grayed out shader with a slight depth bias