Browse Source

More work scene axis handle GUI

BearishSun 10 years ago
parent
commit
ccbe3fdbb0

+ 11 - 4
BansheeEditor/Source/BsHandleManager.cpp

@@ -67,11 +67,18 @@ namespace BansheeEngine
 
 	float HandleManager::getHandleSize(const CameraPtr& camera, const Vector3& handlePos) const
 	{
-		Vector3 cameraPos = camera->getPosition();
+		if (camera->getProjectionType() == PT_PERSPECTIVE)
+		{
+			Vector3 cameraPos = camera->getPosition();
 
-		Vector3 diff = handlePos - cameraPos;
-		float distAlongViewDir = Math::abs(diff.dot(camera->getRotation().zAxis()));
+			Vector3 diff = handlePos - cameraPos;
+			float distAlongViewDir = Math::abs(diff.dot(camera->getRotation().zAxis()));
 
-		return distAlongViewDir * mDefaultHandleSize;
+			return distAlongViewDir * mDefaultHandleSize;
+		}
+		else
+		{
+			return camera->getOrthoWindowHeight() * mDefaultHandleSize;
+		}
 	}
 }

+ 1 - 1
BansheeEngine/Source/BsCamera.cpp

@@ -19,7 +19,7 @@ namespace BansheeEngine
 
 	CameraBase::CameraBase()
 		:mProjType(PT_PERSPECTIVE), mHorzFOV(Degree(90.0f)), mFarDist(1000.0f),
-		mNearDist(0.05f), mAspect(1.33333333333333f), mOrthoHeight(1000), mRecalcFrustum(true), mRecalcFrustumPlanes(true),
+		mNearDist(0.05f), mAspect(1.33333333333333f), mOrthoHeight(5), mRecalcFrustum(true), mRecalcFrustumPlanes(true),
 		mCustomViewMatrix(false), mCustomProjMatrix(false), mFrustumExtentsManuallySet(false), mPriority(0), 
 		mLayers(0xFFFFFFFFFFFFFFFF), mRecalcView(true), mCameraFlags(0)
 	{

+ 1 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -131,6 +131,7 @@
     <Compile Include="ProjectSettings.cs" />
     <Compile Include="Library\LibraryWindow.cs" />
     <Compile Include="ProjectWindow.cs" />
+    <Compile Include="Scene\SceneAxesGUI.cs" />
     <Compile Include="Scene\SceneAxesHandle.cs" />
     <Compile Include="Scene\SceneCamera.cs" />
     <Compile Include="Scene\SceneGizmos.cs" />

+ 100 - 93
MBansheeEditor/Scene/Handles.cs

@@ -1,93 +1,100 @@
-using System;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Manages various global values relating to handles.
-    /// </summary>
-    public sealed class Handles
-    {
-        /// <summary>
-        /// Determines if snapping for move handle is active. When active the move handle can only be moved in increments
-        /// specified by <see cref="MoveSnapAmount"/>.
-        /// </summary>
-        public static bool MoveHandleSnapActive
-        {
-            get { return EditorSettings.MoveHandleSnapActive; }
-            set { EditorSettings.MoveHandleSnapActive = value; }
-        }
-
-        /// <summary>
-        /// Determines if snapping for rotate handle is active. When active the rotate handle can only be rotated in 
-        /// increments specified by <see cref="RotateSnapAmount"/>.
-        /// </summary>
-        public static bool RotateHandleSnapActive
-        {
-            get { return EditorSettings.RotateHandleSnapActive; }
-            set { EditorSettings.RotateHandleSnapActive = value; }
-        }
-
-        /// <summary>
-        /// Determines size of the increments the move handle can be moved when <see cref="MoveHandleSnapActive"/> is
-        /// active.
-        /// </summary>
-        public static float MoveSnapAmount
-        {
-            get { return EditorSettings.MoveHandleSnapAmount; }
-            set { EditorSettings.MoveHandleSnapAmount = value; }
-        }
-
-        /// <summary>
-        /// Determines size of the increments the rotate handle can be moved when <see cref="RotateHandleSnapActive"/> is
-        /// active.
-        /// </summary>
-        public static Degree RotateSnapAmount
-        {
-            get { return EditorSettings.RotateHandleSnapAmount; }
-            set { EditorSettings.RotateHandleSnapAmount = value; }
-        }
-
-        /// <summary>
-        /// Snaps a value to the specified increments.
-        /// </summary>
-        /// <param name="value">Value to snap.</param>
-        /// <param name="snapAmount">Increment to which to snap the value to.</param>
-        /// <returns>Value snapped to the provided increments.</returns>
-        public static float SnapValue(float value, float snapAmount)
-        {
-            if (snapAmount > 0)
-                return MathEx.RoundToInt(value / snapAmount) * snapAmount;
-
-            return value;
-        }
-
-        /// <summary>
-        /// Snaps an angle value to the specified increments.
-        /// </summary>
-        /// <param name="value">Value to snap.</param>
-        /// <param name="snapAmount">Increment to which to snap the value to.</param>
-        /// <returns>Value snapped to the provided increments.</returns>
-        public static Degree SnapValue(Degree value, Degree snapAmount)
-        {
-            return SnapValue(value.Degrees, snapAmount.Degrees);
-        }
-
-        /// <summary>
-        /// Returns a scale that can be applied to a handle in order to keep it at constant size regardless of distance
-        /// from the provided camera.
-        /// </summary>
-        /// <param name="camera">Camera through which the handle is being viewed.</param>
-        /// <param name="position">Center of the handle.</param>
-        /// <returns>Uniform scale to apply to the handle.</returns>
-        public static float GetHandleSize(Camera camera, Vector3 position)
-        {
-            Vector3 cameraPos = camera.SceneObject.Position;
-
-		    Vector3 diff = position - cameraPos;
-		    float distAlongViewDir = Math.Abs(Vector3.Dot(diff, camera.SceneObject.Rotation.Forward));
-
-            return distAlongViewDir * EditorSettings.DefaultHandleSize;
-        }
-    }
-}
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Manages various global values relating to handles.
+    /// </summary>
+    public sealed class Handles
+    {
+        /// <summary>
+        /// Determines if snapping for move handle is active. When active the move handle can only be moved in increments
+        /// specified by <see cref="MoveSnapAmount"/>.
+        /// </summary>
+        public static bool MoveHandleSnapActive
+        {
+            get { return EditorSettings.MoveHandleSnapActive; }
+            set { EditorSettings.MoveHandleSnapActive = value; }
+        }
+
+        /// <summary>
+        /// Determines if snapping for rotate handle is active. When active the rotate handle can only be rotated in 
+        /// increments specified by <see cref="RotateSnapAmount"/>.
+        /// </summary>
+        public static bool RotateHandleSnapActive
+        {
+            get { return EditorSettings.RotateHandleSnapActive; }
+            set { EditorSettings.RotateHandleSnapActive = value; }
+        }
+
+        /// <summary>
+        /// Determines size of the increments the move handle can be moved when <see cref="MoveHandleSnapActive"/> is
+        /// active.
+        /// </summary>
+        public static float MoveSnapAmount
+        {
+            get { return EditorSettings.MoveHandleSnapAmount; }
+            set { EditorSettings.MoveHandleSnapAmount = value; }
+        }
+
+        /// <summary>
+        /// Determines size of the increments the rotate handle can be moved when <see cref="RotateHandleSnapActive"/> is
+        /// active.
+        /// </summary>
+        public static Degree RotateSnapAmount
+        {
+            get { return EditorSettings.RotateHandleSnapAmount; }
+            set { EditorSettings.RotateHandleSnapAmount = value; }
+        }
+
+        /// <summary>
+        /// Snaps a value to the specified increments.
+        /// </summary>
+        /// <param name="value">Value to snap.</param>
+        /// <param name="snapAmount">Increment to which to snap the value to.</param>
+        /// <returns>Value snapped to the provided increments.</returns>
+        public static float SnapValue(float value, float snapAmount)
+        {
+            if (snapAmount > 0)
+                return MathEx.RoundToInt(value / snapAmount) * snapAmount;
+
+            return value;
+        }
+
+        /// <summary>
+        /// Snaps an angle value to the specified increments.
+        /// </summary>
+        /// <param name="value">Value to snap.</param>
+        /// <param name="snapAmount">Increment to which to snap the value to.</param>
+        /// <returns>Value snapped to the provided increments.</returns>
+        public static Degree SnapValue(Degree value, Degree snapAmount)
+        {
+            return SnapValue(value.Degrees, snapAmount.Degrees);
+        }
+
+        /// <summary>
+        /// Returns a scale that can be applied to a handle in order to keep it at constant size regardless of distance
+        /// from the provided camera.
+        /// </summary>
+        /// <param name="camera">Camera through which the handle is being viewed.</param>
+        /// <param name="position">Center of the handle.</param>
+        /// <returns>Uniform scale to apply to the handle.</returns>
+        public static float GetHandleSize(Camera camera, Vector3 position)
+        {
+            if (camera.ProjectionType == ProjectionType.Perspective)
+            {
+                Vector3 cameraPos = camera.SceneObject.Position;
+
+                Vector3 diff = position - cameraPos;
+                float distAlongViewDir = Math.Abs(Vector3.Dot(diff, camera.SceneObject.Rotation.Forward));
+
+                return distAlongViewDir*EditorSettings.DefaultHandleSize;
+            }
+            else
+            {
+                return camera.OrthoHeight*EditorSettings.DefaultHandleSize;
+            }
+        }
+    }
+}

+ 118 - 0
MBansheeEditor/Scene/SceneAxesGUI.cs

@@ -0,0 +1,118 @@
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Handles rendering of scene axis handles into a GUI element.
+    /// </summary>
+    internal class SceneAxesGUI
+    {
+        private RenderTexture2D renderTexture;
+        private Camera camera;
+        private SceneHandles sceneHandles;
+
+        private GUIRenderTexture renderTextureGUI;
+        private Rect2I bounds;
+
+        /// <summary>
+        /// Creates a new scene axes GUI.
+        /// </summary>
+        /// <param name="window">Window in which the GUI is located in.</param>
+        /// <param name="panel">Panel onto which to place the GUI element.</param>
+        /// <param name="width">Width of the GUI element.</param>
+        /// <param name="height">Height of the GUI element.</param>
+        public SceneAxesGUI(EditorWindow window, GUIPanel panel, int width, int height)
+        {
+            renderTexture = new RenderTexture2D(PixelFormat.R8G8B8A8, width, height);
+            renderTexture.Priority = 1;
+
+            SceneObject cameraSO = new SceneObject("SceneAxesCamera", true);
+            camera = cameraSO.AddComponent<Camera>();
+            camera.Target = renderTexture;
+            camera.ViewportRect = new Rect2(0.0f, 0.0f, 1.0f, 1.0f);
+
+            cameraSO.Position = new Vector3(0, 0, 5);
+            cameraSO.LookAt(new Vector3(0, 0, 0));
+
+            camera.Priority = 2;
+            camera.NearClipPlane = 0.05f;
+            camera.FarClipPlane = 1000.0f;
+            camera.ClearColor = new Color(0.0f, 0.0f, 0.0f, 0.0f);
+            camera.ProjectionType = ProjectionType.Orthographic;
+            camera.Layers = SceneAxesHandle.LAYER;
+            camera.AspectRatio = 1.0f;
+            camera.OrthoHeight = 2.0f;
+
+            renderTextureGUI = new GUIRenderTexture(renderTexture);
+            panel.AddElement(renderTextureGUI);
+
+            Rect2I bounds = new Rect2I(0, 0, width, height);
+            sceneHandles = new SceneHandles(window, camera);
+            renderTextureGUI.Bounds = bounds;
+
+            this.bounds = bounds;
+        }
+
+        /// <summary>
+        /// Selects a handle under the pointer position.
+        /// </summary>
+        /// <param name="pointerPos">Position of the pointer relative to the parent GUI panel.</param>
+        public void TrySelect(Vector2I pointerPos)
+        {
+            if (!bounds.Contains(pointerPos))
+                return;
+
+            pointerPos.x -= bounds.x;
+            pointerPos.y -= bounds.y;
+            sceneHandles.TrySelect(pointerPos);
+        }
+
+        /// <summary>
+        /// Checks is any handle currently active.
+        /// </summary>
+        /// <returns>True if a handle is active.</returns>
+        internal bool IsActive()
+        {
+            return sceneHandles.IsActive();
+        }
+
+        /// <summary>
+        /// Deselects any currently active handles.
+        /// </summary>
+        public void ClearSelection()
+        {
+            sceneHandles.ClearSelection();
+        }
+
+        /// <summary>
+        /// Updates active handles by moving them as a result of any input.
+        /// </summary>
+        /// <param name="pointerPos">Position of the pointer relative to the parent GUI panel</param>
+        public void UpdateInput(Vector2I pointerPos)
+        {
+            pointerPos.x -= bounds.x;
+            pointerPos.y -= bounds.y;
+            sceneHandles.UpdateInput(pointerPos, Input.PointerDelta);
+        }
+
+        /// <summary>
+        /// Draws the scene axes onto the underlying camera.
+        /// </summary>
+        public void Draw()
+        {
+            sceneHandles.Draw();
+        }
+
+        /// <summary>
+        /// Moves the GUI element to the specified position.
+        /// </summary>
+        /// <param name="x">Horizontal position of the GUI element relative to the parent panel.</param>
+        /// <param name="y">Vertical position of the GUI element relative to the parent panel.</param>
+        public void SetPosition(int x, int y)
+        {
+            bounds.x = x;
+            bounds.y = y;
+            renderTextureGUI.Bounds = bounds;
+        }
+    }
+}

+ 16 - 28
MBansheeEditor/Scene/SceneAxesHandle.cs

@@ -30,11 +30,11 @@ namespace BansheeEditor
         /// </summary>
         public SceneAxesHandle()
         {
-            xAxis = new HandleSliderLine(this, Vector3.XAxis, 1.0f, true, LAYER);
-            yAxis = new HandleSliderLine(this, Vector3.YAxis, 1.0f, true, LAYER);
-            zAxis = new HandleSliderLine(this, Vector3.ZAxis, 1.0f, true, LAYER);
+            xAxis = new HandleSliderLine(this, Vector3.XAxis, 1.0f, false, LAYER);
+            yAxis = new HandleSliderLine(this, Vector3.YAxis, 1.0f, false, LAYER);
+            zAxis = new HandleSliderLine(this, Vector3.ZAxis, 1.0f, false, LAYER);
 
-            projTypePlane = new HandleSliderPlane(this, Vector3.XAxis, Vector3.YAxis, 0.4f);
+            projTypePlane = new HandleSliderPlane(this, Vector3.XAxis, Vector3.YAxis, 0.4f, false, LAYER);
         }
 
         /// <inheritdoc/>
@@ -44,17 +44,8 @@ namespace BansheeEditor
             if (cam == null)
                 return;
 
-            float distFromCamera = 500.0f;
-            float x = cam.GetFrustumWidth(distFromCamera) * 0.5f;
-            float y = x / cam.AspectRatio;
-
-            Vector3 localPosition = new Vector3(0, 0, -distFromCamera);
-            float appoxHandleSize = EditorSettings.DefaultHandleSize * distFromCamera;
-            localPosition.x = x - appoxHandleSize * 1.2f;
-            localPosition.y = y - appoxHandleSize * 1.2f;
-
-            position = cam.SceneObject.WorldTransform.MultiplyAffine(localPosition);
-            rotation = Quaternion.Identity;
+            position = new Vector3(0, 0, -5.0f);
+            rotation = cam.SceneObject.Rotation;
 
             xAxis.Position = position;
             yAxis.Position = position;
@@ -64,10 +55,9 @@ namespace BansheeEditor
             yAxis.Rotation = rotation;
             zAxis.Rotation = rotation;
 
-            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
-            Vector3 freeAxisOffset = (Vector3.XAxis * -0.2f + Vector3.YAxis * -0.2f) * handleSize;
-            projTypePlane.Rotation = EditorApplication.SceneViewCamera.SceneObject.Rotation;
-            projTypePlane.Position = position + projTypePlane.Rotation.Rotate(freeAxisOffset);
+            Vector3 freeAxisOffset = new Vector3(-0.2f, -0.2f, 0.2f);
+            projTypePlane.Rotation = Quaternion.Identity;
+            projTypePlane.Position = position + freeAxisOffset;
         }
 
         /// <inheritdoc/>
@@ -104,9 +94,7 @@ namespace BansheeEditor
             HandleDrawing.Layer = LAYER;
             HandleDrawing.Transform = Matrix4.TRS(position, rotation, Vector3.One);
             Vector3 cameraForward = EditorApplication.SceneViewCamera.SceneObject.Forward;
-            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
 
-           
             // Draw 1D arrows
             Color xColor = Color.Red;
             if (xAxis.State == HandleSlider.StateType.Active)
@@ -118,8 +106,8 @@ namespace BansheeEditor
             HandleDrawing.Color = xColor;
 
             Vector3 xConeStart = Vector3.XAxis * (1.0f - CONE_HEIGHT);
-            HandleDrawing.DrawLine(Vector3.Zero, xConeStart, handleSize);
-            HandleDrawing.DrawCone(xConeStart, Vector3.XAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
+            HandleDrawing.DrawLine(Vector3.Zero, xConeStart);
+            HandleDrawing.DrawCone(xConeStart, Vector3.XAxis, CONE_HEIGHT, CONE_RADIUS);
 
             Color yColor = Color.Green;
             if (yAxis.State == HandleSlider.StateType.Active)
@@ -131,8 +119,8 @@ namespace BansheeEditor
             HandleDrawing.Color = yColor;
 
             Vector3 yConeStart = Vector3.YAxis * (1.0f - CONE_HEIGHT);
-            HandleDrawing.DrawLine(Vector3.Zero, yConeStart, handleSize);
-            HandleDrawing.DrawCone(yConeStart, Vector3.YAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
+            HandleDrawing.DrawLine(Vector3.Zero, yConeStart);
+            HandleDrawing.DrawCone(yConeStart, Vector3.YAxis, CONE_HEIGHT, CONE_RADIUS);
 
             Color zColor = Color.Blue;
             if (zAxis.State == HandleSlider.StateType.Active)
@@ -144,8 +132,8 @@ namespace BansheeEditor
             HandleDrawing.Color = zColor;
 
             Vector3 zConeStart = Vector3.ZAxis * (1.0f - CONE_HEIGHT);
-            HandleDrawing.DrawLine(Vector3.Zero, zConeStart, handleSize);
-            HandleDrawing.DrawCone(zConeStart, Vector3.ZAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
+            HandleDrawing.DrawLine(Vector3.Zero, zConeStart);
+            HandleDrawing.DrawCone(zConeStart, Vector3.ZAxis, CONE_HEIGHT, CONE_RADIUS);
 
             // Draw projection type handle
             if (projTypePlane.State == HandleSlider.StateType.Active)
@@ -155,7 +143,7 @@ namespace BansheeEditor
             else
                 HandleDrawing.Color = Color.White;
 
-            HandleDrawing.DrawCube(Vector3.Zero, new Vector3(0.2f, 0.2f, 0.2f), handleSize);
+            HandleDrawing.DrawCube(Vector3.Zero, new Vector3(0.2f, 0.2f, 0.2f));
 
             // TODO - Add a text notifying the user whether ortho/proj is active
         }

+ 31 - 12
MBansheeEditor/Scene/SceneCamera.cs

@@ -22,6 +22,7 @@ namespace BansheeEditor
 	    private const float Acceleration = 1.0f;
 	    private const float FastModeMultiplier = 2.0f;
 	    private const float RotationalSpeed = 360.0f; // Degrees/second
+        private readonly Degree FieldOfView = 90.0f;
 
         private VirtualButton moveForwardBtn;
         private VirtualButton moveLeftBtn;
@@ -41,7 +42,7 @@ namespace BansheeEditor
 
         // Animating camera transitions
         private CameraAnimation animation = new CameraAnimation();
-        private float currentSize = 50.0f;
+        private float frustumWidth = 50.0f;
         private float lerp;
         private bool isAnimating;
 
@@ -198,7 +199,7 @@ namespace BansheeEditor
             state.Position = bounds.Center - forward * distance;
             state.Rotation = Quaternion.LookRotation(forward, Vector3.YAxis);
             state.Ortographic = camera.ProjectionType == ProjectionType.Orthographic;
-            state.Size = distance;
+            state.FrustumWidth = frustumWidth;
 
             SetState(state);
         }
@@ -216,7 +217,7 @@ namespace BansheeEditor
             startState.Position = SceneObject.Position;
             startState.Rotation = SceneObject.Rotation;
             startState.Ortographic = camera.ProjectionType == ProjectionType.Orthographic;
-            startState.Size = currentSize;
+            startState.FrustumWidth = frustumWidth;
 
             animation.Start(startState, state);
             if (!animated)
@@ -243,25 +244,37 @@ namespace BansheeEditor
 
             SceneObject.Position = animation.State.Position;
             SceneObject.Rotation = animation.State.Rotation;
-            camera.ProjectionType = animation.State.Ortographic ? ProjectionType.Orthographic : ProjectionType.Perspective;
-            currentSize = animation.State.Size;
+            frustumWidth = animation.State.FrustumWidth;
 
             Vector3 eulerAngles = SceneObject.Rotation.ToEuler();
             pitch = eulerAngles.x;
             yaw = eulerAngles.y;
 
+            Degree FOV = (1.0f - animation.State.OrtographicPct)*FieldOfView;
+            if (FOV < 5.0f)
+            {
+                camera.ProjectionType = ProjectionType.Orthographic;
+                camera.OrthoHeight = frustumWidth * 0.5f / camera.AspectRatio;
+            }
+            else
+            {
+                camera.ProjectionType = ProjectionType.Perspective;
+                camera.FieldOfView = FOV;
+            }
+
             // Note: Consider having a global setting for near/far planes as changing it here might confuse the user
-            if (currentSize < 1)
+            float distance = CalcDistanceForFrustumWidth(frustumWidth);
+            if (distance < 1)
             {
                 camera.NearClipPlane = 0.005f;
                 camera.FarClipPlane = 1000f;
             }
-            if (currentSize < 100)
+            if (distance < 100)
             {
                 camera.NearClipPlane = 0.05f;
                 camera.FarClipPlane = 2500f;
             }
-            else if (currentSize < 1000)
+            else if (distance < 1000)
             {
                 camera.NearClipPlane = 0.5f;
                 camera.FarClipPlane = 10000f;
@@ -311,17 +324,23 @@ namespace BansheeEditor
         /// </summary>
         private struct CameraState
         {
-            internal float _ortographic;
+            private float _ortographic;
 
             public Vector3 Position { get; set; }
             public Quaternion Rotation { get; set; }
-            public float Size { get; set; }
+            public float FrustumWidth { get; set; }
 
             public bool Ortographic
             {
                 get { return _ortographic > 0.5; }
                 set { _ortographic = value ? 1.0f : 0.0f; }
             }
+
+            public float OrtographicPct
+            {
+                get { return _ortographic; }
+                set { _ortographic = value; }
+            }
         }
 
         /// <summary>
@@ -361,9 +380,9 @@ namespace BansheeEditor
             {
                 interpolated.Position = start.Position * (1.0f - t) + target.Position * t;
                 interpolated.Rotation = Quaternion.Slerp(start.Rotation, target.Rotation, t);
-                interpolated._ortographic = start._ortographic * (1.0f - t) + target._ortographic * t;
+                interpolated.OrtographicPct = start.OrtographicPct * (1.0f - t) + target.OrtographicPct * t;
 
-                interpolated.Size = start.Size * (1.0f - t) + target.Size * t;
+                interpolated.FrustumWidth = start.FrustumWidth * (1.0f - t) + target.FrustumWidth * t;
             }
         };
     }

+ 32 - 6
MBansheeEditor/Scene/SceneWindow.cs

@@ -26,6 +26,8 @@ namespace BansheeEditor
         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 const string ProfilerOverlayActiveKey = "_Internal_ProfilerOverlayActive";
+        private const int HandleAxesGUISize = 50;
+        private const int HandleAxesGUIPadding = 5;
 
         private Camera camera;
         private SceneCamera cameraController;
@@ -56,6 +58,8 @@ namespace BansheeEditor
         private GUIToggle rotateSnapButton;
         private GUIFloatField rotateSnapInput;
 
+        private SceneAxesGUI sceneAxesGUI;
+
         private int editorSettingsHash = int.MaxValue;
 
         private VirtualButton duplicateKey;
@@ -244,7 +248,11 @@ namespace BansheeEditor
             handlesLayout.AddElement(rotateSnapButton);
             handlesLayout.AddElement(rotateSnapInput);
 
-            rtPanel = mainLayout.AddPanel();
+            GUIPanel mainPanel = mainLayout.AddPanel();
+            rtPanel = mainPanel.AddPanel();
+
+            GUIPanel sceneAxesPanel = mainPanel.AddPanel(-1);
+            sceneAxesGUI = new SceneAxesGUI(this, sceneAxesPanel, HandleAxesGUISize, HandleAxesGUISize);
 
             toggleProfilerOverlayKey = new VirtualButton(ToggleProfilerOverlayBinding);
             viewToolKey = new VirtualButton(ViewToolBinding);
@@ -369,6 +377,12 @@ namespace BansheeEditor
                     sceneHandles.ClearSelection();
                     handleActive = true;
                 }
+
+                if (sceneAxesGUI.IsActive())
+                {
+                    sceneAxesGUI.ClearSelection();
+                    handleActive = true;
+                }
             }
 
             Vector2I scenePos;
@@ -467,7 +481,13 @@ namespace BansheeEditor
                 {
                     if (Input.IsPointerButtonDown(PointerButton.Left))
                     {
-                        sceneHandles.TrySelect(scenePos);
+                        Rect2I sceneAxesGUIBounds = new Rect2I(Width - HandleAxesGUISize - HandleAxesGUIPadding, 
+                            HandleAxesGUIPadding, HandleAxesGUISize, HandleAxesGUISize);
+
+                        if (sceneAxesGUIBounds.Contains(scenePos))
+                            sceneAxesGUI.TrySelect(scenePos);
+                        else
+                            sceneHandles.TrySelect(scenePos);
                     }
                     else if (Input.IsPointerButtonUp(PointerButton.Left))
                     {
@@ -486,6 +506,10 @@ namespace BansheeEditor
 
             sceneHandles.UpdateInput(scenePos, Input.PointerDelta);
             sceneHandles.Draw();
+
+            sceneAxesGUI.UpdateInput(scenePos);
+            sceneAxesGUI.Draw();
+
             sceneSelection.Draw();
 
             if (VirtualInput.IsButtonDown(frameKey))
@@ -696,7 +720,7 @@ namespace BansheeEditor
                 camera.NearClipPlane = 0.05f;
                 camera.FarClipPlane = 2500.0f;
                 camera.ClearColor = ClearColor;
-		        camera.Layers = UInt64.MaxValue & ~SceneAxesHandle.LAYER; // Don't draw scene axes in this camera
+                camera.Layers = UInt64.MaxValue & ~SceneAxesHandle.LAYER; // Don't draw scene axes in this camera
 
                 cameraController = sceneCameraSO.AddComponent<SceneCamera>();
 
@@ -717,10 +741,12 @@ namespace BansheeEditor
             Rect2I rtBounds = new Rect2I(0, 0, width, height);
             renderTextureGUI.Bounds = rtBounds;
 
-		    // 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.
+            sceneAxesGUI.SetPosition(width - HandleAxesGUISize - HandleAxesGUIPadding, HandleAxesGUIPadding);
+
+            // 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;
 
             if (profilerCamera != null)
                 profilerCamera.Target = renderTexture;

+ 1 - 1
MBansheeEngine/Camera.cs

@@ -412,7 +412,7 @@ namespace BansheeEngine
             public Degree fieldOfView = new Degree(90);
             public Rect2 viewportRect = new Rect2(0, 0, 1, 1);
             public ProjectionType projectionType = ProjectionType.Perspective;
-            public float orthoHeight;
+            public float orthoHeight = 5.0f;
             public Color clearColor = new Color(83.0f / 255.0f, 83.0f / 255.0f, 83.0f / 255.0f);
             public float clearDepth = 1.0f;
             public UInt16 clearStencil;