Browse Source

Scene handle rendering & interaction can now be separated per layer

BearishSun 10 năm trước cách đây
mục cha
commit
5ab1368c9e
30 tập tin đã thay đổi với 2488 bổ sung2328 xóa
  1. 263 257
      BansheeEditor/Include/BsHandleDrawManager.h
  2. 183 178
      BansheeEditor/Include/BsHandleSlider.h
  3. 112 111
      BansheeEditor/Include/BsHandleSliderDisc.h
  4. 69 68
      BansheeEditor/Include/BsHandleSliderLine.h
  5. 79 78
      BansheeEditor/Include/BsHandleSliderPlane.h
  6. 284 279
      BansheeEditor/Source/BsHandleDrawManager.cpp
  7. 124 124
      BansheeEditor/Source/BsHandleSlider.cpp
  8. 182 182
      BansheeEditor/Source/BsHandleSliderDisc.cpp
  9. 83 83
      BansheeEditor/Source/BsHandleSliderLine.cpp
  10. 131 129
      BansheeEditor/Source/BsHandleSliderManager.cpp
  11. 91 91
      BansheeEditor/Source/BsHandleSliderPlane.cpp
  12. 15 5
      BansheeEngine/Include/BsDrawHelper.h
  13. 130 41
      BansheeEngine/Source/BsDrawHelper.cpp
  14. 13 0
      MBansheeEditor/Scene/HandleDrawing.cs
  15. 5 3
      MBansheeEditor/Scene/HandleSliderDisc.cs
  16. 5 3
      MBansheeEditor/Scene/HandleSliderLine.cs
  17. 6 4
      MBansheeEditor/Scene/HandleSliderPlane.cs
  18. 245 244
      MBansheeEditor/Scene/MoveHandle.cs
  19. 245 244
      MBansheeEditor/Scene/RotateHandle.cs
  20. 183 182
      MBansheeEditor/Scene/ScaleHandle.cs
  21. 8 4
      MBansheeEditor/Scene/SceneAxesHandle.cs
  22. 1 0
      MBansheeEditor/Scene/SceneWindow.cs
  23. 1 0
      SBansheeEditor/Include/BsScriptHandleDrawing.h
  24. 2 2
      SBansheeEditor/Include/BsScriptHandleSliderDisc.h
  25. 2 2
      SBansheeEditor/Include/BsScriptHandleSliderLine.h
  26. 4 2
      SBansheeEditor/Include/BsScriptHandleSliderPlane.h
  27. 6 0
      SBansheeEditor/Source/BsScriptHandleDrawing.cpp
  28. 4 4
      SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp
  29. 6 4
      SBansheeEditor/Source/BsScriptHandleSliderLine.cpp
  30. 6 4
      SBansheeEditor/Source/BsScriptHandleSliderPlane.cpp

+ 263 - 257
BansheeEditor/Include/BsHandleDrawManager.h

@@ -1,258 +1,264 @@
-#pragma once
-
-#include "BsEditorPrerequisites.h"
-#include "BsGpuParams.h"
-
-namespace BansheeEngine
-{
-	class HandleDrawManagerCore;
-
-	/**
-	 * @brief	Allows you to easily draw various kinds of simple shapes, primarily
-	 *			used for drawing handles in the scene view.
-	 *
-	 *			Drawn elements only persist for a single draw call and need to be re-queued
-	 *			after.
-	 */
-	class BS_ED_EXPORT HandleDrawManager
-	{
-	public:
-		HandleDrawManager();
-		~HandleDrawManager();
-
-		/**
-		 * @brief	Sets the color of all the following draw* calls.
-		 */
-		void setColor(const Color& color);
-
-		/**
-		 * @brief	Sets the transform matrix that will be applied to all
-		 *			following draw* calls.
-		 */
-		void setTransform(const Matrix4& transform);
-
-		/**
-		 * @brief	Draws a solid cuboid.
-		 *
-		 * @param	position	Center of the cuboid.
-		 * @param	extents		Radius of the cuboid in all directions.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawCube(const Vector3& position, const Vector3& extents, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a solid sphere.
-		 *
-		 * @param	position	Center of the sphere.
-		 * @param	radius		Radius of the sphere.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawSphere(const Vector3& position, float radius, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a wireframe cuboid.
-		 *
-		 * @param	position	Center of the cuboid.
-		 * @param	extents		Radius of the cuboid in all directions.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawWireCube(const Vector3& position, const Vector3& extents, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a wireframe sphere.
-		 *
-		 * @param	position	Center of the sphere.
-		 * @param	radius		Radius of the sphere.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawWireSphere(const Vector3& position, float radius, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a solid cone.
-		 *
-		 * @param	base		Position of the center of the base of the cone.
-		 * @param	normal		Orientation of the cone, pointing from center base to the tip of the cone.
-		 * @param	height		Height of the cone (along the normal).
-		 * @param	radius		Radius of the base of the cone.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawCone(const Vector3& base, const Vector3& normal, float height, float radius, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a line.
-		 *
-		 * @param	start		Starting point for the line.
-		 * @param	end			Ending point for the line.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawLine(const Vector3& start, const Vector3& end, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a double-sided solid disc.
-		 *
-		 * @param	position	Center of the disc.
-		 * @param	normal		Orientation of the disc, pointing in the direction the disc is visible in.
-		 * @param	radius		Radius of the disc.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawDisc(const Vector3& position, const Vector3& normal, float radius, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a wireframe disc.
-		 *
-		 * @param	position	Center of the disc.
-		 * @param	normal		Orientation of the disc, pointing in the direction the disc is visible in.
-		 * @param	radius		Radius of the disc.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawWireDisc(const Vector3& position, const Vector3& normal, float radius, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a double-sided solid arc.
-		 *
-		 * @param	position	Center of the arc.
-		 * @param	normal		Orientation of the arc, pointing in the direction the arc is visible in.
-		 * @param	radius		Radius of the arc.
-		 * @param	startAngle	Angle at which to start the arc.
-		 * @param	amountAngle	Length of the arc.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a wireframe arc.
-		 *
-		 * @param	position	Center of the arc.
-		 * @param	normal		Orientation of the arc, pointing in the direction the arc is visible in.
-		 * @param	radius		Radius of the arc.
-		 * @param	startAngle	Angle at which to start the arc.
-		 * @param	amountAngle	Length of the arc.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size = 1.0f);
-
-		/**
-		 * @brief	Draws a double-sided solid rectangle.
-		 *
-		 * @param	area		Position and size of the rectangle.
-		 * @param	size		Uniform scale of the object.
-		 */
-		void drawRect(const Rect3& area, float size = 1.0f);
-
-		/**
-		 * @brief	Queues all the handle draw commands executed so far for rendering. All commands
-		 *			are cleared and will need to be called again to draw them again.
-		 */
-		void draw(const CameraPtr& camera);
-
-	private:
-		friend class HandleDrawManagerCore;
-
-		/**
-		 * @brief	Initializes the core thread portion of the draw manager.
-		 *
-		 * @param	wireMat		Material used for drawing the wireframe objects.
-		 * @param	solidMat	Material used for drawing the solid objects.
-		 */
-		void initializeCore(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat);
-
-		/**
-		 * @brief	Destroys the core thread portion of the draw manager.
-		 */
-		void destroyCore(HandleDrawManagerCore* core);
-
-		static const UINT32 SPHERE_QUALITY;
-		static const UINT32 WIRE_SPHERE_QUALITY;
-		static const UINT32 ARC_QUALITY;
-
-		Matrix4 mTransform;
-		std::atomic<HandleDrawManagerCore*> mCore;
-		DrawHelper* mDrawHelper;
-	};
-
-	/**
-	 * @brief	Core thread specific portion of the HandleDrawManager that
-	 *			handles actual rendering.
-	 */
-	class BS_ED_EXPORT HandleDrawManagerCore
-	{
-		/**
-		 * @brief	Contains information about the material used for 
-		 *			drawing solid objects and its parameters.
-		 */
-		struct SolidMaterialData
-		{
-			SPtr<MaterialCore> mat;
-			GpuParamMat4Core mViewProj;
-			GpuParamVec4Core mViewDir;
-		};
-
-		/**
-		 * @brief	Contains information about the material used for 
-		 *			drawing wireframe objects and its parameters.
-		 */
-		struct WireMaterialData
-		{
-			SPtr<MaterialCore> mat;
-			GpuParamMat4Core mViewProj;
-		};
-
-		/**
-		 * @brief	Type of mesh that can be drawn.
-		 */
-		enum class MeshType
-		{
-			Solid, Wire
-		};
-
-		/**
-		 * @brief	Contains data about a render mesh.
-		 */
-		struct MeshData
-		{
-			MeshData(const SPtr<MeshCoreBase>& mesh, MeshType type)
-				:mesh(mesh), type(type)
-			{ }
-
-			SPtr<MeshCoreBase> mesh;
-			MeshType type;
-		};
-
-		struct PrivatelyConstruct { };
-
-	public:
-		HandleDrawManagerCore(const PrivatelyConstruct& dummy) { }
-		~HandleDrawManagerCore();
-
-	private:
-		friend class HandleDrawManager;
-
-		/**
-		 * @brief	Initializes the object. Must be called right after construction.
-		 *
-		 * @param	wireMat		Material used for drawing the wireframe objects.
-		 * @param	solidMat	Material used for drawing the solid objects.
-		 */
-		void initialize(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat);
-
-		/**
-		 * @brief	Updates the data that will be used for rendering the new frame.
-		 *
-		 * @param	camera	Camera to render to.
-		 * @param	meshes	Meshes to render.
-		 */
-		void updateData(const SPtr<CameraCore>& camera, const Vector<MeshData>& meshes);
-
-		/**
-		 * @brief	Callback triggered by the renderer. Draws the stored meshes.
-		 */
-		void render();
-
-		SPtr<CameraCore> mCamera;
-		Vector<MeshData> mMeshes;
-
-		// Immutable
-		SolidMaterialData mSolidMaterial;
-		WireMaterialData mWireMaterial;
-	};
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+#include "BsGpuParams.h"
+
+namespace BansheeEngine
+{
+	class HandleDrawManagerCore;
+
+	/**
+	 * @brief	Allows you to easily draw various kinds of simple shapes, primarily
+	 *			used for drawing handles in the scene view.
+	 *
+	 *			Drawn elements only persist for a single draw call and need to be re-queued
+	 *			after.
+	 */
+	class BS_ED_EXPORT HandleDrawManager
+	{
+	public:
+		HandleDrawManager();
+		~HandleDrawManager();
+
+		/**
+		 * @brief	Sets the color of all the following draw* calls.
+		 */
+		void setColor(const Color& color);
+
+		/**
+		 * @brief	Sets the transform matrix that will be applied to all
+		 *			following draw* calls.
+		 */
+		void setTransform(const Matrix4& transform);
+
+		/**
+		 * Sets the layer bitfield that controls whether a handle is considered visible in a specific camera. Handle layer 
+		 * must match camera layer in order for the camera to render it
+		 */
+		void setLayer(UINT64 layer);
+
+		/**
+		 * @brief	Draws a solid cuboid.
+		 *
+		 * @param	position	Center of the cuboid.
+		 * @param	extents		Radius of the cuboid in all directions.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawCube(const Vector3& position, const Vector3& extents, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a solid sphere.
+		 *
+		 * @param	position	Center of the sphere.
+		 * @param	radius		Radius of the sphere.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawSphere(const Vector3& position, float radius, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a wireframe cuboid.
+		 *
+		 * @param	position	Center of the cuboid.
+		 * @param	extents		Radius of the cuboid in all directions.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawWireCube(const Vector3& position, const Vector3& extents, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a wireframe sphere.
+		 *
+		 * @param	position	Center of the sphere.
+		 * @param	radius		Radius of the sphere.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawWireSphere(const Vector3& position, float radius, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a solid cone.
+		 *
+		 * @param	base		Position of the center of the base of the cone.
+		 * @param	normal		Orientation of the cone, pointing from center base to the tip of the cone.
+		 * @param	height		Height of the cone (along the normal).
+		 * @param	radius		Radius of the base of the cone.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawCone(const Vector3& base, const Vector3& normal, float height, float radius, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a line.
+		 *
+		 * @param	start		Starting point for the line.
+		 * @param	end			Ending point for the line.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawLine(const Vector3& start, const Vector3& end, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a double-sided solid disc.
+		 *
+		 * @param	position	Center of the disc.
+		 * @param	normal		Orientation of the disc, pointing in the direction the disc is visible in.
+		 * @param	radius		Radius of the disc.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawDisc(const Vector3& position, const Vector3& normal, float radius, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a wireframe disc.
+		 *
+		 * @param	position	Center of the disc.
+		 * @param	normal		Orientation of the disc, pointing in the direction the disc is visible in.
+		 * @param	radius		Radius of the disc.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawWireDisc(const Vector3& position, const Vector3& normal, float radius, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a double-sided solid arc.
+		 *
+		 * @param	position	Center of the arc.
+		 * @param	normal		Orientation of the arc, pointing in the direction the arc is visible in.
+		 * @param	radius		Radius of the arc.
+		 * @param	startAngle	Angle at which to start the arc.
+		 * @param	amountAngle	Length of the arc.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a wireframe arc.
+		 *
+		 * @param	position	Center of the arc.
+		 * @param	normal		Orientation of the arc, pointing in the direction the arc is visible in.
+		 * @param	radius		Radius of the arc.
+		 * @param	startAngle	Angle at which to start the arc.
+		 * @param	amountAngle	Length of the arc.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size = 1.0f);
+
+		/**
+		 * @brief	Draws a double-sided solid rectangle.
+		 *
+		 * @param	area		Position and size of the rectangle.
+		 * @param	size		Uniform scale of the object.
+		 */
+		void drawRect(const Rect3& area, float size = 1.0f);
+
+		/**
+		 * @brief	Queues all the handle draw commands executed so far for rendering. All commands
+		 *			are cleared and will need to be called again to draw them again.
+		 */
+		void draw(const CameraPtr& camera);
+
+	private:
+		friend class HandleDrawManagerCore;
+
+		/**
+		 * @brief	Initializes the core thread portion of the draw manager.
+		 *
+		 * @param	wireMat		Material used for drawing the wireframe objects.
+		 * @param	solidMat	Material used for drawing the solid objects.
+		 */
+		void initializeCore(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat);
+
+		/**
+		 * @brief	Destroys the core thread portion of the draw manager.
+		 */
+		void destroyCore(HandleDrawManagerCore* core);
+
+		static const UINT32 SPHERE_QUALITY;
+		static const UINT32 WIRE_SPHERE_QUALITY;
+		static const UINT32 ARC_QUALITY;
+
+		Matrix4 mTransform;
+		std::atomic<HandleDrawManagerCore*> mCore;
+		DrawHelper* mDrawHelper;
+	};
+
+	/**
+	 * @brief	Core thread specific portion of the HandleDrawManager that
+	 *			handles actual rendering.
+	 */
+	class BS_ED_EXPORT HandleDrawManagerCore
+	{
+		/**
+		 * @brief	Contains information about the material used for 
+		 *			drawing solid objects and its parameters.
+		 */
+		struct SolidMaterialData
+		{
+			SPtr<MaterialCore> mat;
+			GpuParamMat4Core mViewProj;
+			GpuParamVec4Core mViewDir;
+		};
+
+		/**
+		 * @brief	Contains information about the material used for 
+		 *			drawing wireframe objects and its parameters.
+		 */
+		struct WireMaterialData
+		{
+			SPtr<MaterialCore> mat;
+			GpuParamMat4Core mViewProj;
+		};
+
+		/**
+		 * @brief	Type of mesh that can be drawn.
+		 */
+		enum class MeshType
+		{
+			Solid, Wire
+		};
+
+		/**
+		 * @brief	Contains data about a render mesh.
+		 */
+		struct MeshData
+		{
+			MeshData(const SPtr<MeshCoreBase>& mesh, MeshType type)
+				:mesh(mesh), type(type)
+			{ }
+
+			SPtr<MeshCoreBase> mesh;
+			MeshType type;
+		};
+
+		struct PrivatelyConstruct { };
+
+	public:
+		HandleDrawManagerCore(const PrivatelyConstruct& dummy) { }
+		~HandleDrawManagerCore();
+
+	private:
+		friend class HandleDrawManager;
+
+		/**
+		 * @brief	Initializes the object. Must be called right after construction.
+		 *
+		 * @param	wireMat		Material used for drawing the wireframe objects.
+		 * @param	solidMat	Material used for drawing the solid objects.
+		 */
+		void initialize(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat);
+
+		/**
+		 * @brief	Updates the data that will be used for rendering the new frame.
+		 *
+		 * @param	camera	Camera to render to.
+		 * @param	meshes	Meshes to render.
+		 */
+		void updateData(const SPtr<CameraCore>& camera, const Vector<MeshData>& meshes);
+
+		/**
+		 * @brief	Callback triggered by the renderer. Draws the stored meshes.
+		 */
+		void render();
+
+		SPtr<CameraCore> mCamera;
+		Vector<MeshData> mMeshes;
+
+		// Immutable
+		SolidMaterialData mSolidMaterial;
+		WireMaterialData mWireMaterial;
+	};
 }
 }

+ 183 - 178
BansheeEditor/Include/BsHandleSlider.h

@@ -1,179 +1,184 @@
-#pragma once
-
-#include "BsEditorPrerequisites.h"
-#include "BsVector2I.h"
-#include "BsMatrix4.h"
-#include "BsQuaternion.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Base class for all handle sliders. A handle slider is geometry that the user
-	 *			can interact with by selecting or dragging (i.e. sliding) it. Sliders generally
-	 *			output a one- or multi-dimensional delta value that signals the drag amount 
-	 *			(and/or direction).
-	 */
-	class BS_ED_EXPORT HandleSlider
-	{
-	public:
-		/**
-		 * @brief	Possible states the slider can be in.
-		 */
-		enum class State
-		{
-			Inactive, /**< Slider is not being interacted with. */
-			Active, /**< Slider is clicked on and being dragged. */
-			Hover /**< Slider is being hovered over but isn't clicked on. */
-		};
-
-		/**
-		 * @brief	Constructs a new handle slider.
-		 *
-		 * @param	fixedScale	If true the handle slider will always try to maintain the same visible
-		 *						area in the viewport regardless of distance from camera. 
-		 */
-		HandleSlider(bool fixedScale);
-		virtual ~HandleSlider() { }
-
-		/**
-		 * @brief	Attempts to find an intersection between the provided ray and the slider geometry.
-		 *
-		 * @param	ray	Ray in world space to try to interect with geometry.
-		 * @param	t	Position of the intersection along the ray. Only if intersection happened.
-		 *
-		 * @return	Whether an intersection was detected.
-		 */
-		virtual bool intersects(const Ray& ray, float& t) const = 0;
-
-		/**
-		 * @brief	Updates a slider that is currently active (being dragged).
-		 *
-		 * @param	camera		Camera through which we're interacting with the slider.
-		 * @param	inputDelta	Pointer movement since the last time this method was called.
-		 */
-		virtual void handleInput(const CameraPtr& camera, const Vector2I& inputDelta) = 0;
-
-		/**
-		 * @brief	Updates the state of the slider. Must be called every frame.
-		 *
-		 * @param	camera	Camera through which we're interacting with the slider.
-		 */
-		void update(const CameraPtr& camera);
-
-		/**
-		 * @brief	Returns the state the slider is currently in.
-		 */
-		State getState() const { return mState; }
-		
-		/**
-		 * @brief	Returns if fixed scale is enabled. If enabled the handle slider will 
-		 *			always try to maintain the same visible area in the viewport regardless 
-		 *			of distance from camera.
-		 */
-		bool getFixedScale() const { return mFixedScale; }
-
-		/**
-		 * @brief	Sets the world position of the slider.
-		 */
-		void setPosition(const Vector3& position);
-
-		/**
-		 * @brief	Sets the world rotation of the slider.
-		 */
-		void setRotation(const Quaternion& rotation);
-
-		/**
-		 * @brief	Sets the scale of the slider.
-		 */
-		void setScale(const Vector3& scale);
-
-		/**
-		 * @brief	Gets the world position of the slider.
-		 */
-		const Vector3& getPosition() const { return mPosition; }
-
-		/**
-		 * @brief	Gets the world rotation of the slider.
-		 */
-		const Quaternion& getRotation() const { return mRotation; }
-
-		/**
-		 * @brief	Gets the scale of the slider.
-		 */
-		const Vector3& getScale() const { return mScale; }
-
-	protected:
-		friend class HandleSliderManager;
-
-		/**
-		 * @brief	Toggles the slider state to inactive.
-		 */
-		void setInactive();
-
-		/**
-		 * @brief	Toggles the slider state to active.
-		 *
-		 * @param	camera		Camera through which the slider was activated.
-		 * @param	pointerPos	Position of the pointer when the slider was activated.
-		 */
-		void setActive(const CameraPtr& camera, const Vector2I& pointerPos);
-
-		/**
-		 * @brief	Toggles the slider state to hovered.
-		 */
-		void setHover();
-
-		/**
-		 * @brief	Gets the slider transform depending on set position, rotation and scale values.
-		 */
-		const Matrix4& getTransform() const;
-
-		/**
-		 * @brief	Gets the inverse of the slider transform depending on 
-		 *			set position, rotation and scale values.
-		 */
-		const Matrix4& getTransformInv() const;
-
-		/**
-		 * @brief	Triggered when the slider state is changed to active.
-		 */
-		virtual void activate(const CameraPtr& camera, const Vector2I& pointerPos) { }
-
-		/**
-		 * @brief	Triggered when the slider state is changed from active to some other state.
-		 */
-		virtual void reset() { }
-
-		/**
-		 * @brief	Updates the internal transform from the stored position, rotation and scale values.
-		 */
-		void updateCachedTransform() const;
-
-		/**
-		 * @brief	Calculates amount of movement along the provided ray depending on pointer movement.
-		 *
-		 * @param	camera			Camera on which the pointer movement is occurring.
-		 * @param	position		Position of the ray to calculate movement on.
-		 * @param	direction		Direction of the ray to calculate movement on. Must be normalized.
-		 * @param	pointerStart	Starting position of the pointer when movement started, in pixels relative to provided camera.
-		 * @param	pointerEnd		Current position of the pointer, in pixels relative to provided camera.
-		 */
-		float calcDelta(const CameraPtr& camera, const Vector3& position, const Vector3& direction,
-			const Vector2I& pointerStart, const Vector2I& pointerEnd);
-
-		bool mFixedScale;
-
-		Vector3 mPosition;
-		Quaternion mRotation;
-		Vector3 mScale;
-		float mDistanceScale;
-
-		Vector2I mStartPointerPos;
-		Vector2I mCurrentPointerPos;
-		State mState;
-
-		mutable bool mTransformDirty;
-		mutable Matrix4 mTransform;
-		mutable Matrix4 mTransformInv;
-	};
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+#include "BsVector2I.h"
+#include "BsMatrix4.h"
+#include "BsQuaternion.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Base class for all handle sliders. A handle slider is geometry that the user
+	 *			can interact with by selecting or dragging (i.e. sliding) it. Sliders generally
+	 *			output a one- or multi-dimensional delta value that signals the drag amount 
+	 *			(and/or direction).
+	 */
+	class BS_ED_EXPORT HandleSlider
+	{
+	public:
+		/**
+		 * @brief	Possible states the slider can be in.
+		 */
+		enum class State
+		{
+			Inactive, /**< Slider is not being interacted with. */
+			Active, /**< Slider is clicked on and being dragged. */
+			Hover /**< Slider is being hovered over but isn't clicked on. */
+		};
+
+		/**
+		 * @brief	Constructs a new handle slider.
+		 *
+		 * @param	fixedScale	If true the handle slider will always try to maintain the same visible
+		 *						area in the viewport regardless of distance from camera. 
+		 * @param	layer		Layer that allows filtering of which sliders are interacted with from a specific camera.
+		 */
+		HandleSlider(bool fixedScale, UINT64 layer);
+		virtual ~HandleSlider() { }
+
+		/**
+		 * @brief	Attempts to find an intersection between the provided ray and the slider geometry.
+		 *
+		 * @param	ray	Ray in world space to try to interect with geometry.
+		 * @param	t	Position of the intersection along the ray. Only if intersection happened.
+		 *
+		 * @return	Whether an intersection was detected.
+		 */
+		virtual bool intersects(const Ray& ray, float& t) const = 0;
+
+		/**
+		 * @brief	Updates a slider that is currently active (being dragged).
+		 *
+		 * @param	camera		Camera through which we're interacting with the slider.
+		 * @param	inputDelta	Pointer movement since the last time this method was called.
+		 */
+		virtual void handleInput(const CameraPtr& camera, const Vector2I& inputDelta) = 0;
+
+		/**
+		 * @brief	Updates the state of the slider. Must be called every frame.
+		 *
+		 * @param	camera	Camera through which we're interacting with the slider.
+		 */
+		void update(const CameraPtr& camera);
+
+		/**
+		 * @brief	Returns the state the slider is currently in.
+		 */
+		State getState() const { return mState; }
+		
+		/**
+		 * @brief	Returns if fixed scale is enabled. If enabled the handle slider will 
+		 *			always try to maintain the same visible area in the viewport regardless 
+		 *			of distance from camera.
+		 */
+		bool getFixedScale() const { return mFixedScale; }
+
+		/** Returns a layer that determines which sliders are interacted with from a specific camera. */
+		UINT64 getLayer() const { return mLayer; }
+
+		/**
+		 * @brief	Sets the world position of the slider.
+		 */
+		void setPosition(const Vector3& position);
+
+		/**
+		 * @brief	Sets the world rotation of the slider.
+		 */
+		void setRotation(const Quaternion& rotation);
+
+		/**
+		 * @brief	Sets the scale of the slider.
+		 */
+		void setScale(const Vector3& scale);
+
+		/**
+		 * @brief	Gets the world position of the slider.
+		 */
+		const Vector3& getPosition() const { return mPosition; }
+
+		/**
+		 * @brief	Gets the world rotation of the slider.
+		 */
+		const Quaternion& getRotation() const { return mRotation; }
+
+		/**
+		 * @brief	Gets the scale of the slider.
+		 */
+		const Vector3& getScale() const { return mScale; }
+
+	protected:
+		friend class HandleSliderManager;
+
+		/**
+		 * @brief	Toggles the slider state to inactive.
+		 */
+		void setInactive();
+
+		/**
+		 * @brief	Toggles the slider state to active.
+		 *
+		 * @param	camera		Camera through which the slider was activated.
+		 * @param	pointerPos	Position of the pointer when the slider was activated.
+		 */
+		void setActive(const CameraPtr& camera, const Vector2I& pointerPos);
+
+		/**
+		 * @brief	Toggles the slider state to hovered.
+		 */
+		void setHover();
+
+		/**
+		 * @brief	Gets the slider transform depending on set position, rotation and scale values.
+		 */
+		const Matrix4& getTransform() const;
+
+		/**
+		 * @brief	Gets the inverse of the slider transform depending on 
+		 *			set position, rotation and scale values.
+		 */
+		const Matrix4& getTransformInv() const;
+
+		/**
+		 * @brief	Triggered when the slider state is changed to active.
+		 */
+		virtual void activate(const CameraPtr& camera, const Vector2I& pointerPos) { }
+
+		/**
+		 * @brief	Triggered when the slider state is changed from active to some other state.
+		 */
+		virtual void reset() { }
+
+		/**
+		 * @brief	Updates the internal transform from the stored position, rotation and scale values.
+		 */
+		void updateCachedTransform() const;
+
+		/**
+		 * @brief	Calculates amount of movement along the provided ray depending on pointer movement.
+		 *
+		 * @param	camera			Camera on which the pointer movement is occurring.
+		 * @param	position		Position of the ray to calculate movement on.
+		 * @param	direction		Direction of the ray to calculate movement on. Must be normalized.
+		 * @param	pointerStart	Starting position of the pointer when movement started, in pixels relative to provided camera.
+		 * @param	pointerEnd		Current position of the pointer, in pixels relative to provided camera.
+		 */
+		float calcDelta(const CameraPtr& camera, const Vector3& position, const Vector3& direction,
+			const Vector2I& pointerStart, const Vector2I& pointerEnd);
+
+		bool mFixedScale;
+		UINT64 mLayer;
+
+		Vector3 mPosition;
+		Quaternion mRotation;
+		Vector3 mScale;
+		float mDistanceScale;
+
+		Vector2I mStartPointerPos;
+		Vector2I mCurrentPointerPos;
+		State mState;
+
+		mutable bool mTransformDirty;
+		mutable Matrix4 mTransform;
+		mutable Matrix4 mTransformInv;
+	};
 }
 }

+ 112 - 111
BansheeEditor/Include/BsHandleSliderDisc.h

@@ -1,112 +1,113 @@
-#pragma once
-
-#include "BsEditorPrerequisites.h"
-#include "BsHandleSlider.h"
-#include "BsTorus.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Handle slider that returns a delta value as you drag the pointer
-	 *			along a disc. For intersection purposes the disc is internally 
-	 *			represented by a torus.
-	 */
-	class BS_ED_EXPORT HandleSliderDisc : public HandleSlider
-	{
-	public:
-		/**
-		 * @brief	Constructs a new disc slider.
-		 *
-		 * @param	normal		Normal that determines the orientation of the disc.
-		 * @param	radius		Radius of the disc.
-		 * @param	fixedScale	If true the handle slider will always try to maintain the same visible
-		 *						area in the viewport regardless of distance from camera.
-		 */
-		HandleSliderDisc(const Vector3& normal, float radius, bool fixedScale);
-		~HandleSliderDisc();
-
-		/**
-		 * @copydoc	HandleSlider::intersects
-		 */
-		bool intersects(const Ray& ray, float& t) const override;
-
-		/**
-		 * @copydoc	HandleSlider::handleInput
-		 */
-		void handleInput(const CameraPtr& camera, const Vector2I& inputDelta) override;
-
-		/**
-		 * @brief	Enables or disables a cut-off plane that can allow the disc to be intersected
-		 *			with only in an 180 degree arc.
-		 *
-		 * @param	angle	Angle at which to start the cut-off. Points on the dist at the specified angle and the next
-		 *					180 degrees won't be interactable.	
-		 */
-		void setCutoffPlane(Degree angle, bool enabled);
-
-		/**
-		 * @brief	Returns a delta value that is the result of dragging/sliding the pointer 
-		 *			along the disc. This changes every frame and will be zero unless the slider is active.
-		 */
-		Radian getDelta() const { return mDelta; }
-
-		/**
-		 * @brief	Gets the initial angle at which the drag/slide operation started. This is only
-		 *			valid when the slider is active.
-		 */
-		Radian getStartAngle() const { return mStartAngle; }
-
-	protected:
-
-		/**
-		 * @copydoc	HandleSlider::activate
-		 */
-		void activate(const CameraPtr& camera, const Vector2I& pointerPos) override;
-
-		/**
-		 * @copydoc	HandleSlider::reset
-		 */
-		void reset() override { mDelta = 0.0f; }
-
-		/**
-		 * @brief	Calculates the closest point on an arc from a ray.
-		 *
-		 * @param	inputRay	Ray to use for determining the point.
-		 * @param	center		Center of the arc.
-		 * @param	up			Normal vector of the arc. Must be normalized.
-		 * @param	radius		Radius of the arc.
-		 * @param	startAngle	Starting angle of the arc.
-		 * @param	angleAmount	Length of the arc.
-		 *
-		 * @return	A point on the arc closest to the provided ray.
-		 */
-		Vector3 calculateClosestPointOnArc(const Ray& inputRay, const Vector3& center, const Vector3& up,
-			float radius, Degree startAngle, Degree angleAmount);
-
-		/**
-		 * @brief	Determines an angle of a point on a circle.
-		 *
-		 * @param	up		Normal vector of the circle. Must be normalized.
-		 * @param	point	Point to try to find the angle for. Caller must ensure the
-		 *					point is actually somewhere on the circle otherwise the result
-		 *					is undefined.
-		 *
-		 * @return	Angle at which the provided point lies on the circle.
-		 */
-		Degree pointOnCircleToAngle(Vector3 up, Vector3 point);
-
-		static const float TORUS_RADIUS;
-
-		Vector3 mNormal;
-		float mRadius;
-		bool mHasCutoffPlane;
-		Plane mCutoffPlane;
-
-		Vector3 mDirection;
-		Vector3 mStartPosition;
-		Degree mStartAngle;
-		Degree mDelta;
-
-		Torus mCollider;
-	};
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+#include "BsHandleSlider.h"
+#include "BsTorus.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Handle slider that returns a delta value as you drag the pointer
+	 *			along a disc. For intersection purposes the disc is internally 
+	 *			represented by a torus.
+	 */
+	class BS_ED_EXPORT HandleSliderDisc : public HandleSlider
+	{
+	public:
+		/**
+		 * @brief	Constructs a new disc slider.
+		 *
+		 * @param	normal		Normal that determines the orientation of the disc.
+		 * @param	radius		Radius of the disc.
+		 * @param	fixedScale	If true the handle slider will always try to maintain the same visible
+		 *						area in the viewport regardless of distance from camera.
+		 * @param	layer		Layer that allows filtering of which sliders are interacted with from a specific camera.
+		 */
+		HandleSliderDisc(const Vector3& normal, float radius, bool fixedScale, UINT64 layer);
+		~HandleSliderDisc();
+
+		/**
+		 * @copydoc	HandleSlider::intersects
+		 */
+		bool intersects(const Ray& ray, float& t) const override;
+
+		/**
+		 * @copydoc	HandleSlider::handleInput
+		 */
+		void handleInput(const CameraPtr& camera, const Vector2I& inputDelta) override;
+
+		/**
+		 * @brief	Enables or disables a cut-off plane that can allow the disc to be intersected
+		 *			with only in an 180 degree arc.
+		 *
+		 * @param	angle	Angle at which to start the cut-off. Points on the dist at the specified angle and the next
+		 *					180 degrees won't be interactable.	
+		 */
+		void setCutoffPlane(Degree angle, bool enabled);
+
+		/**
+		 * @brief	Returns a delta value that is the result of dragging/sliding the pointer 
+		 *			along the disc. This changes every frame and will be zero unless the slider is active.
+		 */
+		Radian getDelta() const { return mDelta; }
+
+		/**
+		 * @brief	Gets the initial angle at which the drag/slide operation started. This is only
+		 *			valid when the slider is active.
+		 */
+		Radian getStartAngle() const { return mStartAngle; }
+
+	protected:
+
+		/**
+		 * @copydoc	HandleSlider::activate
+		 */
+		void activate(const CameraPtr& camera, const Vector2I& pointerPos) override;
+
+		/**
+		 * @copydoc	HandleSlider::reset
+		 */
+		void reset() override { mDelta = 0.0f; }
+
+		/**
+		 * @brief	Calculates the closest point on an arc from a ray.
+		 *
+		 * @param	inputRay	Ray to use for determining the point.
+		 * @param	center		Center of the arc.
+		 * @param	up			Normal vector of the arc. Must be normalized.
+		 * @param	radius		Radius of the arc.
+		 * @param	startAngle	Starting angle of the arc.
+		 * @param	angleAmount	Length of the arc.
+		 *
+		 * @return	A point on the arc closest to the provided ray.
+		 */
+		Vector3 calculateClosestPointOnArc(const Ray& inputRay, const Vector3& center, const Vector3& up,
+			float radius, Degree startAngle, Degree angleAmount);
+
+		/**
+		 * @brief	Determines an angle of a point on a circle.
+		 *
+		 * @param	up		Normal vector of the circle. Must be normalized.
+		 * @param	point	Point to try to find the angle for. Caller must ensure the
+		 *					point is actually somewhere on the circle otherwise the result
+		 *					is undefined.
+		 *
+		 * @return	Angle at which the provided point lies on the circle.
+		 */
+		Degree pointOnCircleToAngle(Vector3 up, Vector3 point);
+
+		static const float TORUS_RADIUS;
+
+		Vector3 mNormal;
+		float mRadius;
+		bool mHasCutoffPlane;
+		Plane mCutoffPlane;
+
+		Vector3 mDirection;
+		Vector3 mStartPosition;
+		Degree mStartAngle;
+		Degree mDelta;
+
+		Torus mCollider;
+	};
 }
 }

+ 69 - 68
BansheeEditor/Include/BsHandleSliderLine.h

@@ -1,69 +1,70 @@
-#pragma once
-
-#include "BsEditorPrerequisites.h"
-#include "BsHandleSlider.h"
-#include "BsCapsule.h"
-#include "BsSphere.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Handle slider that returns a delta value as you drag the pointer
-	 *			along a line. For intersection purposes the line is internally 
-	 *			by a capsule and a sphere at its cap (assuming this will be used 
-	 *			for arrow-like handles).
-	 */
-	class BS_ED_EXPORT HandleSliderLine : public HandleSlider
-	{
-	public:
-		/**
-		 * @brief	Constructs a new line slider.
-		 *
-		 * @param	direction	Direction of the line.
-		 * @param	length		Length of the slider (i.e. the line).
-		 * @param	fixedScale	If true the handle slider will always try to maintain the same visible
-		 *						area in the viewport regardless of distance from camera.
-		 */
-		HandleSliderLine(const Vector3& direction, float length, bool fixedScale);
-		~HandleSliderLine();
-
-		/**
-		 * @copydoc	HandleSlider::intersects
-		 */
-		bool intersects(const Ray& ray, float& t) const override;
-
-		/**
-		 * @copydoc	HandleSlider::handleInput
-		 */
-		void handleInput(const CameraPtr& camera, const Vector2I& inputDelta) override;
-
-		/**
-		 * @brief	Returns a delta value that is the result of dragging/sliding the pointer 
-		 *			along the line. This changes every frame and will be zero unless the slider is active.
-		 */
-		float getDelta() const { return mDelta; }
-
-	protected:
-		/**
-		 * @copydoc	HandleSlider::activate
-		 */
-		void activate(const CameraPtr& camera, const Vector2I& pointerPos) override { mStartPosition = getPosition(); }
-
-		/**
-		 * @copydoc	HandleSlider::reset
-		 */
-		void reset() override { mDelta = 0.0f; }
-
-		static const float CAPSULE_RADIUS;
-		static const float SPHERE_RADIUS;
-
-		Vector3 mDirection;
-		float mLength;
-
-		float mDelta;
-		Vector3 mStartPosition;
-
-		Capsule mCapsuleCollider;
-		Sphere mSphereCollider;
-	};
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+#include "BsHandleSlider.h"
+#include "BsCapsule.h"
+#include "BsSphere.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Handle slider that returns a delta value as you drag the pointer
+	 *			along a line. For intersection purposes the line is internally 
+	 *			by a capsule and a sphere at its cap (assuming this will be used 
+	 *			for arrow-like handles).
+	 */
+	class BS_ED_EXPORT HandleSliderLine : public HandleSlider
+	{
+	public:
+		/**
+		 * @brief	Constructs a new line slider.
+		 *
+		 * @param	direction	Direction of the line.
+		 * @param	length		Length of the slider (i.e. the line).
+		 * @param	fixedScale	If true the handle slider will always try to maintain the same visible
+		 *						area in the viewport regardless of distance from camera.
+		 * @param	layer		Layer that allows filtering of which sliders are interacted with from a specific camera.
+		 */
+		HandleSliderLine(const Vector3& direction, float length, bool fixedScale, UINT64 layer);
+		~HandleSliderLine();
+
+		/**
+		 * @copydoc	HandleSlider::intersects
+		 */
+		bool intersects(const Ray& ray, float& t) const override;
+
+		/**
+		 * @copydoc	HandleSlider::handleInput
+		 */
+		void handleInput(const CameraPtr& camera, const Vector2I& inputDelta) override;
+
+		/**
+		 * @brief	Returns a delta value that is the result of dragging/sliding the pointer 
+		 *			along the line. This changes every frame and will be zero unless the slider is active.
+		 */
+		float getDelta() const { return mDelta; }
+
+	protected:
+		/**
+		 * @copydoc	HandleSlider::activate
+		 */
+		void activate(const CameraPtr& camera, const Vector2I& pointerPos) override { mStartPosition = getPosition(); }
+
+		/**
+		 * @copydoc	HandleSlider::reset
+		 */
+		void reset() override { mDelta = 0.0f; }
+
+		static const float CAPSULE_RADIUS;
+		static const float SPHERE_RADIUS;
+
+		Vector3 mDirection;
+		float mLength;
+
+		float mDelta;
+		Vector3 mStartPosition;
+
+		Capsule mCapsuleCollider;
+		Sphere mSphereCollider;
+	};
 }
 }

+ 79 - 78
BansheeEditor/Include/BsHandleSliderPlane.h

@@ -1,79 +1,80 @@
-#pragma once
-
-#include "BsEditorPrerequisites.h"
-#include "BsHandleSlider.h"
-#include "BsRect3.h"
-#include "BsVector2.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Handle slider that returns a delta value as you drag the pointer
-	 *			along a plane. For intersection purposes the line is internally
-	 *			by a quadrilateral (a bounded plane).
-	 */
-	class BS_ED_EXPORT HandleSliderPlane : public HandleSlider
-	{
-	public:
-		/**
-		 * @brief	Constructs a new plane slider. The plane is constructed from two
-		 *			direction vectors.
-		 *
-		 * @param	dir1		First direction of the plane. The x component of returned delta value will be in 
-		 *						this direction. Should be perpendicular to \p dir2.
-		 * @param	dir2		Second direction of the plane. The y component of returned delta value will be in 
-		 *						this direction. Should be perpendicular to \p dir1.
-		 * @param	length		Determines size of the plane. 
-		 * @param	fixedScale	If true the handle slider will always try to maintain the same visible
-		 *						area in the viewport regardless of distance from camera.
-		 */
-		HandleSliderPlane(const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale);
-		~HandleSliderPlane();
-
-		/**
-		 * @copydoc	HandleSlider::intersects
-		 */
-		bool intersects(const Ray& ray, float& t) const override;
-
-		/**
-		 * @copydoc	HandleSlider::handleInput
-		 */
-		void handleInput(const CameraPtr& camera, const Vector2I& inputDelta) override;
-
-		/**
-		 * @brief	Returns a delta value that is the result of dragging/sliding the pointer 
-		 *			along the plane. Returned movement is in terms of the two directions originally provided
-		 *			when constructing the slider. This changes every frame and will be zero unless the slider 
-		 *			is active.
-		 */
-		Vector2 getDelta() const { return mDelta; }
-	protected:
-		/**
-		 * @copydoc	HandleSlider::activate
-		 */
-		void activate(const CameraPtr& camera, const Vector2I& pointerPos) override;
-
-		/**
-		 * @copydoc	HandleSlider::reset
-		 */
-		void reset() override { mDelta = Vector2::ZERO; }
-
-		/**
-		 * @brief	Returns the position on plane based on pointer position.
-		 *
-		 * @param	camera		Camera we're interacting through.
-		 * @param	pointerPos	Position of the pointer in pixels relative to the provided camera's viewport.
-		 */
-		Vector3 getPositionOnPlane(const CameraPtr& camera, const Vector2I& pointerPos) const;
-
-		Vector3 mDirection1;
-		Vector3 mDirection2;
-		float mLength;
-
-		Rect3 mCollider;
-
-		Vector2 mDelta;
-		Vector3 mStartPlanePosition;
-		Vector3 mStartClickPosition;
-	};
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+#include "BsHandleSlider.h"
+#include "BsRect3.h"
+#include "BsVector2.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Handle slider that returns a delta value as you drag the pointer
+	 *			along a plane. For intersection purposes the line is internally
+	 *			by a quadrilateral (a bounded plane).
+	 */
+	class BS_ED_EXPORT HandleSliderPlane : public HandleSlider
+	{
+	public:
+		/**
+		 * @brief	Constructs a new plane slider. The plane is constructed from two
+		 *			direction vectors.
+		 *
+		 * @param	dir1		First direction of the plane. The x component of returned delta value will be in 
+		 *						this direction. Should be perpendicular to \p dir2.
+		 * @param	dir2		Second direction of the plane. The y component of returned delta value will be in 
+		 *						this direction. Should be perpendicular to \p dir1.
+		 * @param	length		Determines size of the plane. 
+		 * @param	fixedScale	If true the handle slider will always try to maintain the same visible
+		 *						area in the viewport regardless of distance from camera.
+		 * @param	layer		Layer that allows filtering of which sliders are interacted with from a specific camera.
+		 */
+		HandleSliderPlane(const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale, UINT64 layer);
+		~HandleSliderPlane();
+
+		/**
+		 * @copydoc	HandleSlider::intersects
+		 */
+		bool intersects(const Ray& ray, float& t) const override;
+
+		/**
+		 * @copydoc	HandleSlider::handleInput
+		 */
+		void handleInput(const CameraPtr& camera, const Vector2I& inputDelta) override;
+
+		/**
+		 * @brief	Returns a delta value that is the result of dragging/sliding the pointer 
+		 *			along the plane. Returned movement is in terms of the two directions originally provided
+		 *			when constructing the slider. This changes every frame and will be zero unless the slider 
+		 *			is active.
+		 */
+		Vector2 getDelta() const { return mDelta; }
+	protected:
+		/**
+		 * @copydoc	HandleSlider::activate
+		 */
+		void activate(const CameraPtr& camera, const Vector2I& pointerPos) override;
+
+		/**
+		 * @copydoc	HandleSlider::reset
+		 */
+		void reset() override { mDelta = Vector2::ZERO; }
+
+		/**
+		 * @brief	Returns the position on plane based on pointer position.
+		 *
+		 * @param	camera		Camera we're interacting through.
+		 * @param	pointerPos	Position of the pointer in pixels relative to the provided camera's viewport.
+		 */
+		Vector3 getPositionOnPlane(const CameraPtr& camera, const Vector2I& pointerPos) const;
+
+		Vector3 mDirection1;
+		Vector3 mDirection2;
+		float mLength;
+
+		Rect3 mCollider;
+
+		Vector2 mDelta;
+		Vector3 mStartPlanePosition;
+		Vector3 mStartClickPosition;
+	};
 }
 }

+ 284 - 279
BansheeEditor/Source/BsHandleDrawManager.cpp

@@ -1,280 +1,285 @@
-#include "BsHandleDrawManager.h"
-#include "BsDrawHelper.h"
-#include "BsMaterial.h"
-#include "BsBuiltinEditorResources.h"
-#include "BsCoreThread.h"
-#include "BsRendererManager.h"
-#include "BsCoreRenderer.h"
-#include "BsTransientMesh.h"
-#include "BsCamera.h"
-#include "BsRendererUtility.h"
-#include "BsSceneObject.h"
-
-using namespace std::placeholders;
-
-namespace BansheeEngine
-{
-	const UINT32 HandleDrawManager::SPHERE_QUALITY = 1;
-	const UINT32 HandleDrawManager::WIRE_SPHERE_QUALITY = 10;
-	const UINT32 HandleDrawManager::ARC_QUALITY = 10;
-
-	HandleDrawManager::HandleDrawManager()
-		:mCore(nullptr)
-	{
-		mTransform = Matrix4::IDENTITY;
-		mDrawHelper = bs_new<DrawHelper>();
-
-		HMaterial solidMaterial = BuiltinEditorResources::instance().createSolidHandleMat();
-		HMaterial wireMaterial = BuiltinEditorResources::instance().createWireHandleMat();
-
-		SPtr<MaterialCore> solidMaterialProxy = solidMaterial->getCore();
-		SPtr<MaterialCore> wireMaterialProxy = wireMaterial->getCore();
-
-		mCore.store(bs_new<HandleDrawManagerCore>(HandleDrawManagerCore::PrivatelyConstruct()), std::memory_order_release);
-
-		gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::initializeCore, this, wireMaterialProxy, solidMaterialProxy));
-	}
-
-	HandleDrawManager::~HandleDrawManager()
-	{
-		bs_delete(mDrawHelper);
-
-		gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::destroyCore, this, mCore.load(std::memory_order_relaxed)));
-	}
-
-	void HandleDrawManager::initializeCore(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		mCore.load(std::memory_order_acquire)->initialize(wireMat, solidMat);
-	}
-
-	void HandleDrawManager::destroyCore(HandleDrawManagerCore* core)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		bs_delete(core);
-	}
-
-	void HandleDrawManager::setColor(const Color& color)
-	{
-		mDrawHelper->setColor(color);
-	}
-
-	void HandleDrawManager::setTransform(const Matrix4& transform)
-	{
-		mTransform = transform;
-	}
-
-	void HandleDrawManager::drawCube(const Vector3& position, const Vector3& extents, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->cube(position, extents);
-	}
-
-	void HandleDrawManager::drawSphere(const Vector3& position, float radius, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->sphere(position, radius);
-	}
-
-	void HandleDrawManager::drawWireCube(const Vector3& position, const Vector3& extents, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->wireCube(position, extents);
-	}
-
-	void HandleDrawManager::drawWireSphere(const Vector3& position, float radius, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->wireSphere(position, radius);
-	}
-
-	void HandleDrawManager::drawCone(const Vector3& base, const Vector3& normal, float height, float radius, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-
-		mDrawHelper->setTransform(mTransform * scale);
-		mDrawHelper->cone(base, normal, height, radius);
-	}
-
-	void HandleDrawManager::drawLine(const Vector3& start, const Vector3& end, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->line(start, end);
-	}
-
-	void HandleDrawManager::drawDisc(const Vector3& position, const Vector3& normal, float radius, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->disc(position, normal, radius);
-	}
-
-	void HandleDrawManager::drawWireDisc(const Vector3& position, const Vector3& normal, float radius, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->wireDisc(position, normal, radius);
-	}
-
-	void HandleDrawManager::drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->arc(position, normal, radius, startAngle, amountAngle);
-	}
-
-	void HandleDrawManager::drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->wireArc(position, normal, radius, startAngle, amountAngle);
-	}
-
-	void HandleDrawManager::drawRect(const Rect3& area, float size)
-	{
-		Matrix4 scale = Matrix4::scaling(size);
-		mDrawHelper->setTransform(mTransform * scale);
-
-		mDrawHelper->rectangle(area);
-	}
-
-	void HandleDrawManager::draw(const CameraPtr& camera)
-	{
-		mDrawHelper->clearMeshes();
-		mDrawHelper->buildMeshes(DrawHelper::SortType::BackToFront, camera->getPosition());
-
-		const Vector<DrawHelper::ShapeMeshData>& meshes = mDrawHelper->getMeshes();
-		
-		Vector<HandleDrawManagerCore::MeshData> proxyData;
-		for (auto& meshData : meshes)
-		{
-			if (meshData.type == DrawHelper::MeshType::Solid)
-			{
-				proxyData.push_back(HandleDrawManagerCore::MeshData(
-					meshData.mesh->getCore(), HandleDrawManagerCore::MeshType::Solid));
-			}
-			else // Wire
-			{
-				proxyData.push_back(HandleDrawManagerCore::MeshData(
-					meshData.mesh->getCore(), HandleDrawManagerCore::MeshType::Wire));
-			}
-		}
-
-		HandleDrawManagerCore* core = mCore.load(std::memory_order_relaxed);
-
-		gCoreAccessor().queueCommand(std::bind(&HandleDrawManagerCore::updateData, core,
-			camera->getCore(), proxyData));
-
-		mDrawHelper->clear();
-	}
-
-	HandleDrawManagerCore::~HandleDrawManagerCore()
-	{
-		CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
-		if (mCamera != nullptr)
-			activeRenderer->_unregisterRenderCallback(mCamera.get(), 20);
-	}
-
-	void HandleDrawManagerCore::initialize(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat)
-	{
-		{
-			mWireMaterial.mat = wireMat;
-			SPtr<GpuParamsCore> vertParams = wireMat->getPassParameters(0)->mVertParams;
-
-			vertParams->getParam("matViewProj", mWireMaterial.mViewProj);
-		}
-
-		{
-			mSolidMaterial.mat = solidMat;
-			SPtr<GpuParamsCore> vertParams = solidMat->getPassParameters(0)->mVertParams;
-			SPtr<GpuParamsCore> fragParams = solidMat->getPassParameters(0)->mFragParams;
-
-			vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
-			fragParams->getParam("viewDir", mSolidMaterial.mViewDir);
-		}
-	}
-
-	void HandleDrawManagerCore::updateData(const SPtr<CameraCore>& camera, const Vector<MeshData>& meshes)
-	{
-		if (mCamera != camera)
-		{
-			CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
-			if (mCamera != nullptr)
-				activeRenderer->_unregisterRenderCallback(mCamera.get(), 20);
-
-			if (camera != nullptr)
-				activeRenderer->_registerRenderCallback(camera.get(), 20, std::bind(&HandleDrawManagerCore::render, this));
-		}
-
-		mCamera = camera;
-		mMeshes = meshes;
-	}
-
-	void HandleDrawManagerCore::render()
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		if (mCamera == nullptr)
-			return;
-
-		SPtr<RenderTargetCore> renderTarget = mCamera->getViewport()->getTarget();
-
-		float width = (float)renderTarget->getProperties().getWidth();
-		float height = (float)renderTarget->getProperties().getHeight();
-
-		Rect2 normArea = mCamera->getViewport()->getNormArea();
-
-		Rect2I screenArea;
-		screenArea.x = (int)(normArea.x * width);
-		screenArea.y = (int)(normArea.y * height);
-		screenArea.width = (int)(normArea.width * width);
-		screenArea.height = (int)(normArea.height * height);
-
-		Matrix4 viewProjMat = mCamera->getProjectionMatrixRS() * mCamera->getViewMatrix();
-		mSolidMaterial.mViewProj.set(viewProjMat);
-		mSolidMaterial.mViewDir.set((Vector4)mCamera->getForward());
-		mWireMaterial.mViewProj.set(viewProjMat);
-
-		MeshType currentType = MeshType::Solid;
-		if (mMeshes.size() > 0)
-		{
-			currentType = mMeshes[0].type;
-
-			if (currentType == MeshType::Solid)
-				gRendererUtility().setPass(mSolidMaterial.mat, 0);
-			else
-				gRendererUtility().setPass(mWireMaterial.mat, 0);
-		}
-
-		for (auto& meshData : mMeshes)
-		{
-			if (currentType != meshData.type)
-			{
-				if (meshData.type == MeshType::Solid)
-					gRendererUtility().setPass(mSolidMaterial.mat, 0);
-				else
-					gRendererUtility().setPass(mWireMaterial.mat, 0);
-
-				currentType = meshData.type;
-			}
-
-			gRendererUtility().draw(meshData.mesh, meshData.mesh->getProperties().getSubMesh(0));
-		}
-	}
+#include "BsHandleDrawManager.h"
+#include "BsDrawHelper.h"
+#include "BsMaterial.h"
+#include "BsBuiltinEditorResources.h"
+#include "BsCoreThread.h"
+#include "BsRendererManager.h"
+#include "BsCoreRenderer.h"
+#include "BsTransientMesh.h"
+#include "BsCamera.h"
+#include "BsRendererUtility.h"
+#include "BsSceneObject.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	const UINT32 HandleDrawManager::SPHERE_QUALITY = 1;
+	const UINT32 HandleDrawManager::WIRE_SPHERE_QUALITY = 10;
+	const UINT32 HandleDrawManager::ARC_QUALITY = 10;
+
+	HandleDrawManager::HandleDrawManager()
+		:mCore(nullptr)
+	{
+		mTransform = Matrix4::IDENTITY;
+		mDrawHelper = bs_new<DrawHelper>();
+
+		HMaterial solidMaterial = BuiltinEditorResources::instance().createSolidHandleMat();
+		HMaterial wireMaterial = BuiltinEditorResources::instance().createWireHandleMat();
+
+		SPtr<MaterialCore> solidMaterialProxy = solidMaterial->getCore();
+		SPtr<MaterialCore> wireMaterialProxy = wireMaterial->getCore();
+
+		mCore.store(bs_new<HandleDrawManagerCore>(HandleDrawManagerCore::PrivatelyConstruct()), std::memory_order_release);
+
+		gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::initializeCore, this, wireMaterialProxy, solidMaterialProxy));
+	}
+
+	HandleDrawManager::~HandleDrawManager()
+	{
+		bs_delete(mDrawHelper);
+
+		gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::destroyCore, this, mCore.load(std::memory_order_relaxed)));
+	}
+
+	void HandleDrawManager::initializeCore(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat)
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		mCore.load(std::memory_order_acquire)->initialize(wireMat, solidMat);
+	}
+
+	void HandleDrawManager::destroyCore(HandleDrawManagerCore* core)
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		bs_delete(core);
+	}
+
+	void HandleDrawManager::setColor(const Color& color)
+	{
+		mDrawHelper->setColor(color);
+	}
+
+	void HandleDrawManager::setTransform(const Matrix4& transform)
+	{
+		mTransform = transform;
+	}
+
+	void HandleDrawManager::setLayer(UINT64 layer)
+	{
+		mDrawHelper->setLayer(layer);
+	}
+
+	void HandleDrawManager::drawCube(const Vector3& position, const Vector3& extents, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->cube(position, extents);
+	}
+
+	void HandleDrawManager::drawSphere(const Vector3& position, float radius, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->sphere(position, radius);
+	}
+
+	void HandleDrawManager::drawWireCube(const Vector3& position, const Vector3& extents, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->wireCube(position, extents);
+	}
+
+	void HandleDrawManager::drawWireSphere(const Vector3& position, float radius, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->wireSphere(position, radius);
+	}
+
+	void HandleDrawManager::drawCone(const Vector3& base, const Vector3& normal, float height, float radius, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+
+		mDrawHelper->setTransform(mTransform * scale);
+		mDrawHelper->cone(base, normal, height, radius);
+	}
+
+	void HandleDrawManager::drawLine(const Vector3& start, const Vector3& end, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->line(start, end);
+	}
+
+	void HandleDrawManager::drawDisc(const Vector3& position, const Vector3& normal, float radius, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->disc(position, normal, radius);
+	}
+
+	void HandleDrawManager::drawWireDisc(const Vector3& position, const Vector3& normal, float radius, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->wireDisc(position, normal, radius);
+	}
+
+	void HandleDrawManager::drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->arc(position, normal, radius, startAngle, amountAngle);
+	}
+
+	void HandleDrawManager::drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->wireArc(position, normal, radius, startAngle, amountAngle);
+	}
+
+	void HandleDrawManager::drawRect(const Rect3& area, float size)
+	{
+		Matrix4 scale = Matrix4::scaling(size);
+		mDrawHelper->setTransform(mTransform * scale);
+
+		mDrawHelper->rectangle(area);
+	}
+
+	void HandleDrawManager::draw(const CameraPtr& camera)
+	{
+		mDrawHelper->clearMeshes();
+		mDrawHelper->buildMeshes(DrawHelper::SortType::BackToFront, camera->getPosition(), camera->getLayers());
+
+		const Vector<DrawHelper::ShapeMeshData>& meshes = mDrawHelper->getMeshes();
+		
+		Vector<HandleDrawManagerCore::MeshData> proxyData;
+		for (auto& meshData : meshes)
+		{
+			if (meshData.type == DrawHelper::MeshType::Solid)
+			{
+				proxyData.push_back(HandleDrawManagerCore::MeshData(
+					meshData.mesh->getCore(), HandleDrawManagerCore::MeshType::Solid));
+			}
+			else // Wire
+			{
+				proxyData.push_back(HandleDrawManagerCore::MeshData(
+					meshData.mesh->getCore(), HandleDrawManagerCore::MeshType::Wire));
+			}
+		}
+
+		HandleDrawManagerCore* core = mCore.load(std::memory_order_relaxed);
+
+		gCoreAccessor().queueCommand(std::bind(&HandleDrawManagerCore::updateData, core,
+			camera->getCore(), proxyData));
+
+		mDrawHelper->clear();
+	}
+
+	HandleDrawManagerCore::~HandleDrawManagerCore()
+	{
+		CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
+		if (mCamera != nullptr)
+			activeRenderer->_unregisterRenderCallback(mCamera.get(), 20);
+	}
+
+	void HandleDrawManagerCore::initialize(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat)
+	{
+		{
+			mWireMaterial.mat = wireMat;
+			SPtr<GpuParamsCore> vertParams = wireMat->getPassParameters(0)->mVertParams;
+
+			vertParams->getParam("matViewProj", mWireMaterial.mViewProj);
+		}
+
+		{
+			mSolidMaterial.mat = solidMat;
+			SPtr<GpuParamsCore> vertParams = solidMat->getPassParameters(0)->mVertParams;
+			SPtr<GpuParamsCore> fragParams = solidMat->getPassParameters(0)->mFragParams;
+
+			vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
+			fragParams->getParam("viewDir", mSolidMaterial.mViewDir);
+		}
+	}
+
+	void HandleDrawManagerCore::updateData(const SPtr<CameraCore>& camera, const Vector<MeshData>& meshes)
+	{
+		if (mCamera != camera)
+		{
+			CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
+			if (mCamera != nullptr)
+				activeRenderer->_unregisterRenderCallback(mCamera.get(), 20);
+
+			if (camera != nullptr)
+				activeRenderer->_registerRenderCallback(camera.get(), 20, std::bind(&HandleDrawManagerCore::render, this));
+		}
+
+		mCamera = camera;
+		mMeshes = meshes;
+	}
+
+	void HandleDrawManagerCore::render()
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		if (mCamera == nullptr)
+			return;
+
+		SPtr<RenderTargetCore> renderTarget = mCamera->getViewport()->getTarget();
+
+		float width = (float)renderTarget->getProperties().getWidth();
+		float height = (float)renderTarget->getProperties().getHeight();
+
+		Rect2 normArea = mCamera->getViewport()->getNormArea();
+
+		Rect2I screenArea;
+		screenArea.x = (int)(normArea.x * width);
+		screenArea.y = (int)(normArea.y * height);
+		screenArea.width = (int)(normArea.width * width);
+		screenArea.height = (int)(normArea.height * height);
+
+		Matrix4 viewProjMat = mCamera->getProjectionMatrixRS() * mCamera->getViewMatrix();
+		mSolidMaterial.mViewProj.set(viewProjMat);
+		mSolidMaterial.mViewDir.set((Vector4)mCamera->getForward());
+		mWireMaterial.mViewProj.set(viewProjMat);
+
+		MeshType currentType = MeshType::Solid;
+		if (mMeshes.size() > 0)
+		{
+			currentType = mMeshes[0].type;
+
+			if (currentType == MeshType::Solid)
+				gRendererUtility().setPass(mSolidMaterial.mat, 0);
+			else
+				gRendererUtility().setPass(mWireMaterial.mat, 0);
+		}
+
+		for (auto& meshData : mMeshes)
+		{
+			if (currentType != meshData.type)
+			{
+				if (meshData.type == MeshType::Solid)
+					gRendererUtility().setPass(mSolidMaterial.mat, 0);
+				else
+					gRendererUtility().setPass(mWireMaterial.mat, 0);
+
+				currentType = meshData.type;
+			}
+
+			gRendererUtility().draw(meshData.mesh, meshData.mesh->getProperties().getSubMesh(0));
+		}
+	}
 }
 }

+ 124 - 124
BansheeEditor/Source/BsHandleSlider.cpp

@@ -1,125 +1,125 @@
-#include "BsHandleSlider.h"
-#include "BsCCamera.h"
-#include "BsHandleManager.h"
-#include "BsDebug.h"
-
-namespace BansheeEngine
-{
-	HandleSlider::HandleSlider(bool fixedScale)
-		:mFixedScale(fixedScale), mScale(Vector3::ONE), mTransformDirty(true),
-		mDistanceScale(1.0f)
-	{
-
-	}
-
-	void HandleSlider::update(const CameraPtr& camera)
-	{
-		if (mFixedScale)
-		{
-			mDistanceScale = HandleManager::instance().getHandleSize(camera, mPosition);
-			mTransformDirty = true;
-		}
-	}
-
-	void HandleSlider::setPosition(const Vector3& position)
-	{
-		mPosition = position;
-		mTransformDirty = true;
-	}
-
-	void HandleSlider::setRotation(const Quaternion& rotation)
-	{
-		mRotation = rotation;
-		mTransformDirty = true;
-	}
-
-	void HandleSlider::setScale(const Vector3& scale)
-	{
-		mScale = scale;
-		mTransformDirty = true;
-	}
-
-	const Matrix4& HandleSlider::getTransform() const
-	{
-		if (mTransformDirty)
-			updateCachedTransform();
-
-		return mTransform;
-	}
-
-	const Matrix4& HandleSlider::getTransformInv() const
-	{
-		if (mTransformDirty)
-			updateCachedTransform();
-
-		return mTransformInv;
-	}
-
-	void HandleSlider::updateCachedTransform() const
-	{
-		if (mFixedScale)
-		{
-			mTransform.setTRS(mPosition, mRotation, mScale * mDistanceScale);
-			mTransformInv.setInverseTRS(mPosition, mRotation, mScale * mDistanceScale);
-		}
-		else
-		{
-			mTransform.setTRS(mPosition, mRotation, mScale);
-			mTransformInv.setInverseTRS(mPosition, mRotation, mScale);
-		}
-
-		mTransformDirty = false;
-	}
-
-	void HandleSlider::setInactive() 
-	{ 
-		mState = State::Inactive; 
-		reset(); 
-	}
-
-	void HandleSlider::setActive(const CameraPtr& camera, const Vector2I& pointerPos)
-	{ 
-		mState = State::Active; 
-		mStartPointerPos = pointerPos; 
-		mCurrentPointerPos = pointerPos;
-		activate(camera, pointerPos);
-	}
-
-	void HandleSlider::setHover() 
-	{ 
-		mState = State::Hover; 
-		reset(); 
-	}
-
-	float HandleSlider::calcDelta(const CameraPtr& camera, const Vector3& position, const Vector3& direction,
-		const Vector2I& pointerStart, const Vector2I& pointerEnd)
-	{
-		// position + direction can sometimes project behind the camera (if the camera is looking at position
-		// from very close and at an angle), which will cause the delta to be reversed, so we compensate.
-
-		float negate = 1.0f;
-		Vector3 cameraDir = -camera->getRotation().zAxis();
-		if (cameraDir.dot((position + direction) - camera->getPosition()) <= 0.0f)
-			negate = -1.0f; // Point behind the camera
-
-		Vector2I handleStart2D = camera->worldToScreenPoint(position);
-		Vector2I handleEnd2D = camera->worldToScreenPoint(position + direction);
-
-		Vector2I handleDir2D = handleEnd2D - handleStart2D;
-
-		INT32 sqrdMag = handleDir2D.squaredLength();
-
-		if (sqrdMag == 0)
-			return 0.0f;
-
-		Vector2I diffStart = pointerStart - handleStart2D;
-		Vector2I diffEnd = pointerEnd - handleStart2D;
-
-		float mag = sqrt((float)sqrdMag);
-		float tStart = handleDir2D.dot(diffStart) / mag;
-		float tEnd = handleDir2D.dot(diffEnd) / mag;
-
-		float arbitraryScale = 1.0f / 100.0f;
-		return negate * (tEnd - tStart) * arbitraryScale;
-	}
+#include "BsHandleSlider.h"
+#include "BsCCamera.h"
+#include "BsHandleManager.h"
+#include "BsDebug.h"
+
+namespace BansheeEngine
+{
+	HandleSlider::HandleSlider(bool fixedScale, UINT64 layer)
+		:mFixedScale(fixedScale), mScale(Vector3::ONE), mTransformDirty(true),
+		mDistanceScale(1.0f), mLayer(layer)
+	{
+
+	}
+
+	void HandleSlider::update(const CameraPtr& camera)
+	{
+		if (mFixedScale)
+		{
+			mDistanceScale = HandleManager::instance().getHandleSize(camera, mPosition);
+			mTransformDirty = true;
+		}
+	}
+
+	void HandleSlider::setPosition(const Vector3& position)
+	{
+		mPosition = position;
+		mTransformDirty = true;
+	}
+
+	void HandleSlider::setRotation(const Quaternion& rotation)
+	{
+		mRotation = rotation;
+		mTransformDirty = true;
+	}
+
+	void HandleSlider::setScale(const Vector3& scale)
+	{
+		mScale = scale;
+		mTransformDirty = true;
+	}
+
+	const Matrix4& HandleSlider::getTransform() const
+	{
+		if (mTransformDirty)
+			updateCachedTransform();
+
+		return mTransform;
+	}
+
+	const Matrix4& HandleSlider::getTransformInv() const
+	{
+		if (mTransformDirty)
+			updateCachedTransform();
+
+		return mTransformInv;
+	}
+
+	void HandleSlider::updateCachedTransform() const
+	{
+		if (mFixedScale)
+		{
+			mTransform.setTRS(mPosition, mRotation, mScale * mDistanceScale);
+			mTransformInv.setInverseTRS(mPosition, mRotation, mScale * mDistanceScale);
+		}
+		else
+		{
+			mTransform.setTRS(mPosition, mRotation, mScale);
+			mTransformInv.setInverseTRS(mPosition, mRotation, mScale);
+		}
+
+		mTransformDirty = false;
+	}
+
+	void HandleSlider::setInactive() 
+	{ 
+		mState = State::Inactive; 
+		reset(); 
+	}
+
+	void HandleSlider::setActive(const CameraPtr& camera, const Vector2I& pointerPos)
+	{ 
+		mState = State::Active; 
+		mStartPointerPos = pointerPos; 
+		mCurrentPointerPos = pointerPos;
+		activate(camera, pointerPos);
+	}
+
+	void HandleSlider::setHover() 
+	{ 
+		mState = State::Hover; 
+		reset(); 
+	}
+
+	float HandleSlider::calcDelta(const CameraPtr& camera, const Vector3& position, const Vector3& direction,
+		const Vector2I& pointerStart, const Vector2I& pointerEnd)
+	{
+		// position + direction can sometimes project behind the camera (if the camera is looking at position
+		// from very close and at an angle), which will cause the delta to be reversed, so we compensate.
+
+		float negate = 1.0f;
+		Vector3 cameraDir = -camera->getRotation().zAxis();
+		if (cameraDir.dot((position + direction) - camera->getPosition()) <= 0.0f)
+			negate = -1.0f; // Point behind the camera
+
+		Vector2I handleStart2D = camera->worldToScreenPoint(position);
+		Vector2I handleEnd2D = camera->worldToScreenPoint(position + direction);
+
+		Vector2I handleDir2D = handleEnd2D - handleStart2D;
+
+		INT32 sqrdMag = handleDir2D.squaredLength();
+
+		if (sqrdMag == 0)
+			return 0.0f;
+
+		Vector2I diffStart = pointerStart - handleStart2D;
+		Vector2I diffEnd = pointerEnd - handleStart2D;
+
+		float mag = sqrt((float)sqrdMag);
+		float tStart = handleDir2D.dot(diffStart) / mag;
+		float tEnd = handleDir2D.dot(diffEnd) / mag;
+
+		float arbitraryScale = 1.0f / 100.0f;
+		return negate * (tEnd - tStart) * arbitraryScale;
+	}
 }
 }

+ 182 - 182
BansheeEditor/Source/BsHandleSliderDisc.cpp

@@ -1,183 +1,183 @@
-#include "BsHandleSliderDisc.h"
-#include "BsHandleManager.h"
-#include "BsHandleSliderManager.h"
-#include "BsRay.h"
-#include "BsVector3.h"
-#include "BsQuaternion.h"
-#include "BsCCamera.h"
-
-// DEBUG ONLY
-#include "BsDebug.h"
-#include "BsGizmoManager.h"
-
-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), mHasCutoffPlane(false)
-	{
-		mCollider = Torus(normal, radius, TORUS_RADIUS);
-
-		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
-		sliderManager._registerSlider(this);
-	}
-
-	HandleSliderDisc::~HandleSliderDisc()
-	{
-		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
-		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;
-		localRay.transform(getTransformInv());
-
-		auto intersect = mCollider.intersects(localRay);
-		if (intersect.first)
-		{
-			t = intersect.second;
-
-			if (mHasCutoffPlane)
-			{
-				auto cutoffIntersect = mCutoffPlane.intersects(localRay);
-				if (cutoffIntersect.first && cutoffIntersect.second < t)
-					return false;
-			}
-
-			return true;
-		}
-
-		return false;
-	}
-
-	Vector3 HandleSliderDisc::calculateClosestPointOnArc(const Ray& inputRay, const Vector3& center, const Vector3& up,
-		float radius, Degree startAngle, Degree angleAmount)
-	{
-		Vector3 arcBasis[3];
-		arcBasis[1] = up;
-		arcBasis[1].orthogonalComplement(arcBasis[2], arcBasis[0]);
-
-		Matrix4 worldToPlane = Matrix4::IDENTITY;
-		worldToPlane.setColumn(0, (Vector4)arcBasis[0]);
-		worldToPlane.setColumn(1, (Vector4)arcBasis[1]);
-		worldToPlane.setColumn(2, (Vector4)arcBasis[2]);
-		worldToPlane.setColumn(3, (Vector4)worldToPlane.multiplyAffine(-center));
-		worldToPlane[3][3] = 1;
-
-		Plane plane(up, (-center).dot(up));
-		Vector3 pointOnPlane;
-
-		auto intersectResult = plane.intersects(inputRay);
-
-		float t = 0.0f;
-		if (intersectResult.first)
-			pointOnPlane = inputRay.getPoint(intersectResult.second);
-		else
-			pointOnPlane = Vector3::ZERO;
-
-		pointOnPlane = worldToPlane.multiplyAffine(pointOnPlane);
-		Vector2 pointOnPlane2D(pointOnPlane.x, pointOnPlane.z); // y always 0
-
-		Vector2 closestPoint2D;
-		float dist = pointOnPlane2D.length();
-		if (dist > 0.0f)
-			closestPoint2D = mRadius * (pointOnPlane2D / dist);
-		else
-			closestPoint2D = Vector2(mRadius, 0);
-
-		Radian angle = Math::atan2(-closestPoint2D.y, -closestPoint2D.x) + Math::PI;
-
-		float angleRad = angle.valueRadians();
-		float angleAmountRad = Math::clamp(angleAmount.valueRadians(), 0.0f, Math::PI * 2);
-
-		float startAngleRad = startAngle.wrap().valueRadians();
-		float endAngleRad = startAngleRad + angleAmountRad;
-
-		float clampedAngle = angleRad;
-		if (endAngleRad <= Math::PI * 2)
-		{
-			clampedAngle = Math::clamp(angleRad, startAngleRad, endAngleRad);
-		}
-		else
-		{
-			if (angleRad >= startAngleRad)
-				clampedAngle = Math::clamp(angleRad, startAngleRad, Math::PI * 2);
-			else
-			{
-				endAngleRad -= Math::PI * 2;
-				if (angleRad > endAngleRad)
-				{
-					if ((startAngleRad - angleRad) > (angleRad - endAngleRad))
-						clampedAngle = endAngleRad;
-					else
-						clampedAngle = startAngleRad;
-				}
-				else
-					clampedAngle = angleRad;
-			}
-		}
-
-		Vector3 clampedAnglePoint;
-		clampedAnglePoint.x = Math::cos(clampedAngle) * radius;
-		clampedAnglePoint.z = Math::sin(clampedAngle) * radius;
-
-		return worldToPlane.inverseAffine().multiplyAffine(clampedAnglePoint);
-	}
-
-	Degree HandleSliderDisc::pointOnCircleToAngle(Vector3 up, Vector3 point)
-	{
-		Quaternion rot = Quaternion::getRotationFromTo(up, Vector3::UNIT_Y);
-
-		Matrix4 worldToPlane = Matrix4::TRS(Vector3::ZERO, rot, Vector3::ONE);
-		point = worldToPlane.multiplyAffine(point);
-
-		return Radian(Math::atan2(-point.z, -point.x) + Math::PI);
-	}
-
-	void HandleSliderDisc::activate(const CameraPtr& camera, const Vector2I& pointerPos)
-	{
-		Ray localRay = camera->screenPointToRay(pointerPos);
-		localRay.transformAffine(getTransformInv());
-
-		mStartPosition = calculateClosestPointOnArc(localRay, Vector3::ZERO, mNormal, mRadius, Degree(0.0f), Degree(360.0f));
-		mStartAngle = pointOnCircleToAngle(mNormal, mStartPosition);
-		mStartPosition = getTransform().multiplyAffine(mStartPosition);
-
-		Vector3 worldNormal = getTransform().multiplyDirection(mNormal);
-		worldNormal.normalize();
-
-		Vector3 toStart = mStartPosition - getPosition();
-		mDirection = worldNormal.cross(toStart);
-		mDirection.normalize();
-	}
-
-	void HandleSliderDisc::handleInput(const CameraPtr& camera, const Vector2I& inputDelta)
-	{
-		assert(getState() == State::Active);
-
-		mCurrentPointerPos += inputDelta;
-		mDelta = calcDelta(camera, mStartPosition, mDirection, mStartPointerPos, mCurrentPointerPos) * Math::RAD2DEG;
-	}
+#include "BsHandleSliderDisc.h"
+#include "BsHandleManager.h"
+#include "BsHandleSliderManager.h"
+#include "BsRay.h"
+#include "BsVector3.h"
+#include "BsQuaternion.h"
+#include "BsCCamera.h"
+
+// DEBUG ONLY
+#include "BsDebug.h"
+#include "BsGizmoManager.h"
+
+namespace BansheeEngine
+{
+	const float HandleSliderDisc::TORUS_RADIUS = 0.1f;
+
+	HandleSliderDisc::HandleSliderDisc(const Vector3& normal, float radius, bool fixedScale, UINT64 layer)
+		:HandleSlider(fixedScale, layer), mRadius(radius), mNormal(normal), mDelta(0.0f), mHasCutoffPlane(false)
+	{
+		mCollider = Torus(normal, radius, TORUS_RADIUS);
+
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._registerSlider(this);
+	}
+
+	HandleSliderDisc::~HandleSliderDisc()
+	{
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		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;
+		localRay.transform(getTransformInv());
+
+		auto intersect = mCollider.intersects(localRay);
+		if (intersect.first)
+		{
+			t = intersect.second;
+
+			if (mHasCutoffPlane)
+			{
+				auto cutoffIntersect = mCutoffPlane.intersects(localRay);
+				if (cutoffIntersect.first && cutoffIntersect.second < t)
+					return false;
+			}
+
+			return true;
+		}
+
+		return false;
+	}
+
+	Vector3 HandleSliderDisc::calculateClosestPointOnArc(const Ray& inputRay, const Vector3& center, const Vector3& up,
+		float radius, Degree startAngle, Degree angleAmount)
+	{
+		Vector3 arcBasis[3];
+		arcBasis[1] = up;
+		arcBasis[1].orthogonalComplement(arcBasis[2], arcBasis[0]);
+
+		Matrix4 worldToPlane = Matrix4::IDENTITY;
+		worldToPlane.setColumn(0, (Vector4)arcBasis[0]);
+		worldToPlane.setColumn(1, (Vector4)arcBasis[1]);
+		worldToPlane.setColumn(2, (Vector4)arcBasis[2]);
+		worldToPlane.setColumn(3, (Vector4)worldToPlane.multiplyAffine(-center));
+		worldToPlane[3][3] = 1;
+
+		Plane plane(up, (-center).dot(up));
+		Vector3 pointOnPlane;
+
+		auto intersectResult = plane.intersects(inputRay);
+
+		float t = 0.0f;
+		if (intersectResult.first)
+			pointOnPlane = inputRay.getPoint(intersectResult.second);
+		else
+			pointOnPlane = Vector3::ZERO;
+
+		pointOnPlane = worldToPlane.multiplyAffine(pointOnPlane);
+		Vector2 pointOnPlane2D(pointOnPlane.x, pointOnPlane.z); // y always 0
+
+		Vector2 closestPoint2D;
+		float dist = pointOnPlane2D.length();
+		if (dist > 0.0f)
+			closestPoint2D = mRadius * (pointOnPlane2D / dist);
+		else
+			closestPoint2D = Vector2(mRadius, 0);
+
+		Radian angle = Math::atan2(-closestPoint2D.y, -closestPoint2D.x) + Math::PI;
+
+		float angleRad = angle.valueRadians();
+		float angleAmountRad = Math::clamp(angleAmount.valueRadians(), 0.0f, Math::PI * 2);
+
+		float startAngleRad = startAngle.wrap().valueRadians();
+		float endAngleRad = startAngleRad + angleAmountRad;
+
+		float clampedAngle = angleRad;
+		if (endAngleRad <= Math::PI * 2)
+		{
+			clampedAngle = Math::clamp(angleRad, startAngleRad, endAngleRad);
+		}
+		else
+		{
+			if (angleRad >= startAngleRad)
+				clampedAngle = Math::clamp(angleRad, startAngleRad, Math::PI * 2);
+			else
+			{
+				endAngleRad -= Math::PI * 2;
+				if (angleRad > endAngleRad)
+				{
+					if ((startAngleRad - angleRad) > (angleRad - endAngleRad))
+						clampedAngle = endAngleRad;
+					else
+						clampedAngle = startAngleRad;
+				}
+				else
+					clampedAngle = angleRad;
+			}
+		}
+
+		Vector3 clampedAnglePoint;
+		clampedAnglePoint.x = Math::cos(clampedAngle) * radius;
+		clampedAnglePoint.z = Math::sin(clampedAngle) * radius;
+
+		return worldToPlane.inverseAffine().multiplyAffine(clampedAnglePoint);
+	}
+
+	Degree HandleSliderDisc::pointOnCircleToAngle(Vector3 up, Vector3 point)
+	{
+		Quaternion rot = Quaternion::getRotationFromTo(up, Vector3::UNIT_Y);
+
+		Matrix4 worldToPlane = Matrix4::TRS(Vector3::ZERO, rot, Vector3::ONE);
+		point = worldToPlane.multiplyAffine(point);
+
+		return Radian(Math::atan2(-point.z, -point.x) + Math::PI);
+	}
+
+	void HandleSliderDisc::activate(const CameraPtr& camera, const Vector2I& pointerPos)
+	{
+		Ray localRay = camera->screenPointToRay(pointerPos);
+		localRay.transformAffine(getTransformInv());
+
+		mStartPosition = calculateClosestPointOnArc(localRay, Vector3::ZERO, mNormal, mRadius, Degree(0.0f), Degree(360.0f));
+		mStartAngle = pointOnCircleToAngle(mNormal, mStartPosition);
+		mStartPosition = getTransform().multiplyAffine(mStartPosition);
+
+		Vector3 worldNormal = getTransform().multiplyDirection(mNormal);
+		worldNormal.normalize();
+
+		Vector3 toStart = mStartPosition - getPosition();
+		mDirection = worldNormal.cross(toStart);
+		mDirection.normalize();
+	}
+
+	void HandleSliderDisc::handleInput(const CameraPtr& camera, const Vector2I& inputDelta)
+	{
+		assert(getState() == State::Active);
+
+		mCurrentPointerPos += inputDelta;
+		mDelta = calcDelta(camera, mStartPosition, mDirection, mStartPointerPos, mCurrentPointerPos) * Math::RAD2DEG;
+	}
 }
 }

+ 83 - 83
BansheeEditor/Source/BsHandleSliderLine.cpp

@@ -1,84 +1,84 @@
-#include "BsHandleSliderLine.h"
-#include "BsHandleManager.h"
-#include "BsHandleSliderManager.h"
-#include "BsCapsule.h"
-#include "BsLineSegment3.h"
-#include "BsSphere.h"
-#include "BsRay.h"
-
-#include "BsDebug.h"
-
-namespace BansheeEngine
-{
-	const float HandleSliderLine::CAPSULE_RADIUS = 0.05f;
-	const float HandleSliderLine::SPHERE_RADIUS = 0.2f;
-
-	HandleSliderLine::HandleSliderLine(const Vector3& direction, float length, bool fixedScale)
-		:HandleSlider(fixedScale), mLength(length), mDelta(0.0f)
-	{
-		mDirection = Vector3::normalize(direction);
-
-		Vector3 start = Vector3::ZERO;
-		Vector3 end = start + mDirection * length;
-
-		Vector3 sphereCenter = start + mDirection * std::max(0.0f, length - SPHERE_RADIUS);
-
-		mCapsuleCollider = Capsule(LineSegment3(start, end), CAPSULE_RADIUS);
-		mSphereCollider = Sphere(sphereCenter, SPHERE_RADIUS);
-
-		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
-		sliderManager._registerSlider(this);
-	}
-
-	HandleSliderLine::~HandleSliderLine()
-	{
-		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
-		sliderManager._unregisterSlider(this);
-	}
-
-	bool HandleSliderLine::intersects(const Ray& ray, float& t) const
-	{
-		Ray localRay = ray;
-		localRay.transformAffine(getTransformInv());
-
-		auto capsuleIntersect = mCapsuleCollider.intersects(localRay);
-		auto sphereIntersect = mSphereCollider.intersects(localRay);
-
-		t = std::numeric_limits<float>::max();
-		bool gotIntersect = false;
-
-		if (capsuleIntersect.first)
-		{
-			t = capsuleIntersect.second;
-			gotIntersect = true;
-		}
-
-		if (sphereIntersect.first)
-		{
-			if (sphereIntersect.second < t)
-			{
-				t = sphereIntersect.second;
-				gotIntersect = true;
-			}
-		}
-
-		if (gotIntersect)
-		{
-			Vector3 intrPoint = localRay.getPoint(t);
-			intrPoint = getTransform().multiplyAffine(intrPoint);
-			t = (intrPoint - ray.getOrigin()).length(); // Get distance in world space
-		}
-
-		return gotIntersect;
-	}
-
-	void HandleSliderLine::handleInput(const CameraPtr& camera, const Vector2I& inputDelta)
-	{
-		assert(getState() == State::Active);
-
-		mCurrentPointerPos += inputDelta;
-
-		Vector3 worldDir = getRotation().rotate(mDirection);
-		mDelta = calcDelta(camera, mStartPosition, worldDir, mStartPointerPos, mCurrentPointerPos);
-	}
+#include "BsHandleSliderLine.h"
+#include "BsHandleManager.h"
+#include "BsHandleSliderManager.h"
+#include "BsCapsule.h"
+#include "BsLineSegment3.h"
+#include "BsSphere.h"
+#include "BsRay.h"
+
+#include "BsDebug.h"
+
+namespace BansheeEngine
+{
+	const float HandleSliderLine::CAPSULE_RADIUS = 0.05f;
+	const float HandleSliderLine::SPHERE_RADIUS = 0.2f;
+
+	HandleSliderLine::HandleSliderLine(const Vector3& direction, float length, bool fixedScale, UINT64 layer)
+		:HandleSlider(fixedScale, layer), mLength(length), mDelta(0.0f)
+	{
+		mDirection = Vector3::normalize(direction);
+
+		Vector3 start = Vector3::ZERO;
+		Vector3 end = start + mDirection * length;
+
+		Vector3 sphereCenter = start + mDirection * std::max(0.0f, length - SPHERE_RADIUS);
+
+		mCapsuleCollider = Capsule(LineSegment3(start, end), CAPSULE_RADIUS);
+		mSphereCollider = Sphere(sphereCenter, SPHERE_RADIUS);
+
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._registerSlider(this);
+	}
+
+	HandleSliderLine::~HandleSliderLine()
+	{
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._unregisterSlider(this);
+	}
+
+	bool HandleSliderLine::intersects(const Ray& ray, float& t) const
+	{
+		Ray localRay = ray;
+		localRay.transformAffine(getTransformInv());
+
+		auto capsuleIntersect = mCapsuleCollider.intersects(localRay);
+		auto sphereIntersect = mSphereCollider.intersects(localRay);
+
+		t = std::numeric_limits<float>::max();
+		bool gotIntersect = false;
+
+		if (capsuleIntersect.first)
+		{
+			t = capsuleIntersect.second;
+			gotIntersect = true;
+		}
+
+		if (sphereIntersect.first)
+		{
+			if (sphereIntersect.second < t)
+			{
+				t = sphereIntersect.second;
+				gotIntersect = true;
+			}
+		}
+
+		if (gotIntersect)
+		{
+			Vector3 intrPoint = localRay.getPoint(t);
+			intrPoint = getTransform().multiplyAffine(intrPoint);
+			t = (intrPoint - ray.getOrigin()).length(); // Get distance in world space
+		}
+
+		return gotIntersect;
+	}
+
+	void HandleSliderLine::handleInput(const CameraPtr& camera, const Vector2I& inputDelta)
+	{
+		assert(getState() == State::Active);
+
+		mCurrentPointerPos += inputDelta;
+
+		Vector3 worldDir = getRotation().rotate(mDirection);
+		mDelta = calcDelta(camera, mStartPosition, worldDir, mStartPointerPos, mCurrentPointerPos);
+	}
 }
 }

+ 131 - 129
BansheeEditor/Source/BsHandleSliderManager.cpp

@@ -1,130 +1,132 @@
-#include "BsHandleSliderManager.h"
-#include "BsDrawHelper.h"
-#include "BsMaterial.h"
-#include "BsBuiltinEditorResources.h"
-#include "BsCoreThread.h"
-#include "BsRendererManager.h"
-#include "BsCoreRenderer.h"
-#include "BsTransientMesh.h"
-#include "BsCCamera.h"
-#include "BsHandleSlider.h"
-
-using namespace std::placeholders;
-
-namespace BansheeEngine
-{
-	HandleSliderManager::HandleSliderManager()
-		:mActiveSlider(nullptr), mHoverSlider(nullptr)
-	{
-
-	}
-
-	HandleSliderManager::~HandleSliderManager()
-	{
-
-	}
-
-	void HandleSliderManager::update(const CameraPtr& camera, const Vector2I& inputPos, const Vector2I& inputDelta)
-	{
-		for (auto& slider : mSliders)
-			slider->update(camera);
-
-		if (mActiveSlider != nullptr)
-		{
-			mActiveSlider->handleInput(camera, inputDelta);
-		}
-		else
-		{
-			HandleSlider* newHoverSlider = findUnderCursor(camera, inputPos);
-
-			if (newHoverSlider != mHoverSlider)
-			{
-				if (mHoverSlider != nullptr)
-				{
-					mHoverSlider->setInactive();
-					mHoverSlider = nullptr;
-				}
-
-				if (newHoverSlider != nullptr)
-				{
-					mHoverSlider = newHoverSlider;
-					mHoverSlider->setHover();
-				}
-			}
-		}
-	}
-
-	void HandleSliderManager::trySelect(const CameraPtr& camera, const Vector2I& inputPos)
-	{
-		HandleSlider* newActiveSlider = findUnderCursor(camera, inputPos);
-
-		if (mHoverSlider != nullptr)
-		{
-			mHoverSlider->setInactive();
-			mHoverSlider = nullptr;
-		}
-
-		if (newActiveSlider != mActiveSlider)
-		{
-			if (mActiveSlider != nullptr)
-			{
-				mActiveSlider->setInactive();
-				mActiveSlider = nullptr;
-			}
-
-			if (newActiveSlider != nullptr)
-			{
-				mActiveSlider = newActiveSlider;
-				mActiveSlider->setActive(camera, inputPos);
-			}
-		}
-	}
-
-	void HandleSliderManager::clearSelection()
-	{
-		if (mActiveSlider != nullptr)
-		{
-			mActiveSlider->setInactive();
-			mActiveSlider = nullptr;
-		}
-	}
-
-	HandleSlider* HandleSliderManager::findUnderCursor(const CameraPtr& camera, const Vector2I& inputPos) const
-	{
-		Ray inputRay = camera->screenPointToRay(inputPos);
-
-		float nearestT = std::numeric_limits<float>::max();
-		HandleSlider* overSlider = nullptr;
-		
-		for (auto& slider : mSliders)
-		{
-			float t;
-			if (slider->intersects(inputRay, t))
-			{
-				if (t < nearestT)
-				{
-					overSlider = slider;
-					nearestT = t;
-				}
-			}
-		}
-
-		return overSlider;
-	}
-
-	void HandleSliderManager::_registerSlider(HandleSlider* slider)
-	{
-		mSliders.insert(slider);
-	}
-
-	void HandleSliderManager::_unregisterSlider(HandleSlider* slider)
-	{
-		mSliders.erase(slider);
-
-		if (mActiveSlider == slider)
-			mActiveSlider = nullptr;
-
-		if (mHoverSlider == slider)
-			mHoverSlider = nullptr;
-	}
+#include "BsHandleSliderManager.h"
+#include "BsDrawHelper.h"
+#include "BsMaterial.h"
+#include "BsBuiltinEditorResources.h"
+#include "BsCoreThread.h"
+#include "BsRendererManager.h"
+#include "BsCoreRenderer.h"
+#include "BsTransientMesh.h"
+#include "BsCCamera.h"
+#include "BsHandleSlider.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	HandleSliderManager::HandleSliderManager()
+		:mActiveSlider(nullptr), mHoverSlider(nullptr)
+	{
+
+	}
+
+	HandleSliderManager::~HandleSliderManager()
+	{
+
+	}
+
+	void HandleSliderManager::update(const CameraPtr& camera, const Vector2I& inputPos, const Vector2I& inputDelta)
+	{
+		for (auto& slider : mSliders)
+			slider->update(camera);
+
+		if (mActiveSlider != nullptr)
+		{
+			mActiveSlider->handleInput(camera, inputDelta);
+		}
+		else
+		{
+			HandleSlider* newHoverSlider = findUnderCursor(camera, inputPos);
+
+			if (newHoverSlider != mHoverSlider)
+			{
+				if (mHoverSlider != nullptr)
+				{
+					mHoverSlider->setInactive();
+					mHoverSlider = nullptr;
+				}
+
+				if (newHoverSlider != nullptr)
+				{
+					mHoverSlider = newHoverSlider;
+					mHoverSlider->setHover();
+				}
+			}
+		}
+	}
+
+	void HandleSliderManager::trySelect(const CameraPtr& camera, const Vector2I& inputPos)
+	{
+		HandleSlider* newActiveSlider = findUnderCursor(camera, inputPos);
+
+		if (mHoverSlider != nullptr)
+		{
+			mHoverSlider->setInactive();
+			mHoverSlider = nullptr;
+		}
+
+		if (newActiveSlider != mActiveSlider)
+		{
+			if (mActiveSlider != nullptr)
+			{
+				mActiveSlider->setInactive();
+				mActiveSlider = nullptr;
+			}
+
+			if (newActiveSlider != nullptr)
+			{
+				mActiveSlider = newActiveSlider;
+				mActiveSlider->setActive(camera, inputPos);
+			}
+		}
+	}
+
+	void HandleSliderManager::clearSelection()
+	{
+		if (mActiveSlider != nullptr)
+		{
+			mActiveSlider->setInactive();
+			mActiveSlider = nullptr;
+		}
+	}
+
+	HandleSlider* HandleSliderManager::findUnderCursor(const CameraPtr& camera, const Vector2I& inputPos) const
+	{
+		Ray inputRay = camera->screenPointToRay(inputPos);
+
+		float nearestT = std::numeric_limits<float>::max();
+		HandleSlider* overSlider = nullptr;
+		
+		for (auto& slider : mSliders)
+		{
+			bool layerMatches = (camera->getLayers() & slider->getLayer()) != 0;
+
+			float t;
+			if (layerMatches && slider->intersects(inputRay, t))
+			{
+				if (t < nearestT)
+				{
+					overSlider = slider;
+					nearestT = t;
+				}
+			}
+		}
+
+		return overSlider;
+	}
+
+	void HandleSliderManager::_registerSlider(HandleSlider* slider)
+	{
+		mSliders.insert(slider);
+	}
+
+	void HandleSliderManager::_unregisterSlider(HandleSlider* slider)
+	{
+		mSliders.erase(slider);
+
+		if (mActiveSlider == slider)
+			mActiveSlider = nullptr;
+
+		if (mHoverSlider == slider)
+			mHoverSlider = nullptr;
+	}
 }
 }

+ 91 - 91
BansheeEditor/Source/BsHandleSliderPlane.cpp

@@ -1,92 +1,92 @@
-#include "BsHandleSliderPlane.h"
-#include "BsHandleManager.h"
-#include "BsHandleSliderManager.h"
-#include "BsVector3.h"
-#include "BsRay.h"
-#include "BsPlane.h"
-#include "BsCamera.h"
-
-namespace BansheeEngine
-{
-	HandleSliderPlane::HandleSliderPlane(const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale)
-		:HandleSlider(fixedScale), mLength(length)
-	{
-		mDirection1 = Vector3::normalize(dir1);
-		mDirection2 = Vector3::normalize(dir2);
-
-		float halfLength = length * 0.5f;
-		std::array<Vector3, 2> axes = { mDirection1, mDirection2 };
-		std::array<float, 2> extents = { halfLength, halfLength };
-
-		Vector3 center = (dir1 * length + dir2 * length) * 0.5f;
-		mCollider = Rect3(center, axes, extents);
-
-		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
-		sliderManager._registerSlider(this);
-	}
-
-	HandleSliderPlane::~HandleSliderPlane()
-	{
-		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
-		sliderManager._unregisterSlider(this);
-	}
-
-	bool HandleSliderPlane::intersects(const Ray& ray, float& t) const
-	{
-		Ray localRay = ray;
-		localRay.transform(getTransformInv());
-
-		auto intersect = mCollider.intersects(localRay);
-
-		if (intersect.first)
-		{
-			t = intersect.second;
-
-			return true;
-		}
-
-		return false;
-	}
-
-	void HandleSliderPlane::activate(const CameraPtr& camera, const Vector2I& pointerPos)
-	{
-		mStartPlanePosition = getPosition();
-		mStartClickPosition = getPositionOnPlane(camera, pointerPos);
-	}
-
-	void HandleSliderPlane::handleInput(const CameraPtr& camera, const Vector2I& inputDelta)
-	{
-		assert(getState() == State::Active);
-
-		mCurrentPointerPos += inputDelta;
-
-		Vector3 worldDir1 = getRotation().rotate(mDirection1);
-		Vector3 worldDir2 = getRotation().rotate(mDirection2);
-
-		Vector3 intersectPosition = getPositionOnPlane(camera, mCurrentPointerPos);
-		Vector3 positionDelta = intersectPosition - mStartClickPosition;
-
-		mDelta.x = positionDelta.dot(worldDir1);
-		mDelta.y = positionDelta.dot(worldDir2);
-	}
-
-	Vector3 HandleSliderPlane::getPositionOnPlane(const CameraPtr& camera, const Vector2I& pointerPos) const
-	{
-		Vector3 worldDir1 = getRotation().rotate(mDirection1);
-		Vector3 worldDir2 = getRotation().rotate(mDirection2);
-
-		Vector3 normal = worldDir1.cross(worldDir2);
-		float dot = normal.dot(camera->getForward());
-		if (dot > 0)
-			normal = -normal;
-
-		Plane plane(normal, mStartPlanePosition);
-
-		Ray clickRay = camera->screenPointToRay(pointerPos);
-		auto intersectResult = plane.intersects(clickRay);
-		if (intersectResult.first)
-			return clickRay.getPoint(intersectResult.second);
-
-		return mStartClickPosition;
-	}
+#include "BsHandleSliderPlane.h"
+#include "BsHandleManager.h"
+#include "BsHandleSliderManager.h"
+#include "BsVector3.h"
+#include "BsRay.h"
+#include "BsPlane.h"
+#include "BsCamera.h"
+
+namespace BansheeEngine
+{
+	HandleSliderPlane::HandleSliderPlane(const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale, UINT64 layer)
+		:HandleSlider(fixedScale, layer), mLength(length)
+	{
+		mDirection1 = Vector3::normalize(dir1);
+		mDirection2 = Vector3::normalize(dir2);
+
+		float halfLength = length * 0.5f;
+		std::array<Vector3, 2> axes = { mDirection1, mDirection2 };
+		std::array<float, 2> extents = { halfLength, halfLength };
+
+		Vector3 center = (dir1 * length + dir2 * length) * 0.5f;
+		mCollider = Rect3(center, axes, extents);
+
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._registerSlider(this);
+	}
+
+	HandleSliderPlane::~HandleSliderPlane()
+	{
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._unregisterSlider(this);
+	}
+
+	bool HandleSliderPlane::intersects(const Ray& ray, float& t) const
+	{
+		Ray localRay = ray;
+		localRay.transform(getTransformInv());
+
+		auto intersect = mCollider.intersects(localRay);
+
+		if (intersect.first)
+		{
+			t = intersect.second;
+
+			return true;
+		}
+
+		return false;
+	}
+
+	void HandleSliderPlane::activate(const CameraPtr& camera, const Vector2I& pointerPos)
+	{
+		mStartPlanePosition = getPosition();
+		mStartClickPosition = getPositionOnPlane(camera, pointerPos);
+	}
+
+	void HandleSliderPlane::handleInput(const CameraPtr& camera, const Vector2I& inputDelta)
+	{
+		assert(getState() == State::Active);
+
+		mCurrentPointerPos += inputDelta;
+
+		Vector3 worldDir1 = getRotation().rotate(mDirection1);
+		Vector3 worldDir2 = getRotation().rotate(mDirection2);
+
+		Vector3 intersectPosition = getPositionOnPlane(camera, mCurrentPointerPos);
+		Vector3 positionDelta = intersectPosition - mStartClickPosition;
+
+		mDelta.x = positionDelta.dot(worldDir1);
+		mDelta.y = positionDelta.dot(worldDir2);
+	}
+
+	Vector3 HandleSliderPlane::getPositionOnPlane(const CameraPtr& camera, const Vector2I& pointerPos) const
+	{
+		Vector3 worldDir1 = getRotation().rotate(mDirection1);
+		Vector3 worldDir2 = getRotation().rotate(mDirection2);
+
+		Vector3 normal = worldDir1.cross(worldDir2);
+		float dot = normal.dot(camera->getForward());
+		if (dot > 0)
+			normal = -normal;
+
+		Plane plane(normal, mStartPlanePosition);
+
+		Ray clickRay = camera->screenPointToRay(pointerPos);
+		auto intersectResult = plane.intersects(clickRay);
+		if (intersectResult.first)
+			return clickRay.getPoint(intersectResult.second);
+
+		return mStartClickPosition;
+	}
 }
 }

+ 15 - 5
BansheeEngine/Include/BsDrawHelper.h

@@ -56,6 +56,11 @@ namespace BansheeEngine
 		 */
 		 */
 		void setTransform(const Matrix4& transform);
 		void setTransform(const Matrix4& transform);
 
 
+		/**
+		 * Sets the layer bitfield that can be used for filtering which objects are output into the final mesh.
+		 */
+		void setLayer(UINT64 layer);
+
 		/**
 		/**
 		 * @brief	Records a solid cuboid with the specified properties in the internal draw queue.
 		 * @brief	Records a solid cuboid with the specified properties in the internal draw queue.
 		 */
 		 */
@@ -138,17 +143,20 @@ namespace BansheeEngine
 		 *			The meshes can be accessed via getMeshes() and released via clearMeshes(). 
 		 *			The meshes can be accessed via getMeshes() and released via clearMeshes(). 
 		 *			Any previously active meshes will be cleared when this method is called.
 		 *			Any previously active meshes will be cleared when this method is called.
 		 *
 		 *
-		 * @param	sorting		Determines how (and if) should elements be sorted
+		 * @param	sorting		(optional) Determines how (and if) should elements be sorted
 		 *						based on their distance from the reference point.
 		 *						based on their distance from the reference point.
-		 * @param	reference	Reference point to use for determining distance when
+		 * @param	reference	(optional) Reference point to use for determining distance when
 		 *						sorting.
 		 *						sorting.
+		 * @param	layers		(optional) Layers bitfield that can be used for controlling which shapes will be included
+		 *						in the mesh. This bitfield will be ANDed with the layer specified when recording the shape.
 		 *
 		 *
-		 * @note	You must call releaseSolidMesh() when done.
+		 * @note	You must call clearMeshes() when done.
 		 */
 		 */
-		void buildMeshes(SortType sorting = SortType::None, const Vector3& reference = Vector3::ZERO);
+		void buildMeshes(SortType sorting = SortType::None, const Vector3& reference = Vector3::ZERO, 
+			UINT64 layers = 0xFFFFFFFFFFFFFFFF);
 
 
 		/**
 		/**
-		 * @brief	Returns a set of meshes you have previously built using buildMeshes().
+		 * @brief	Returns a set of meshes that were previously built using buildMeshes().
 		 */
 		 */
 		const Vector<ShapeMeshData>& getMeshes() const { return mMeshes; }
 		const Vector<ShapeMeshData>& getMeshes() const { return mMeshes; }
 
 
@@ -163,6 +171,7 @@ namespace BansheeEngine
 			Color color;
 			Color color;
 			Matrix4 transform;
 			Matrix4 transform;
 			Vector3 center;
 			Vector3 center;
+			UINT64 layer;
 		};
 		};
 
 
 		struct CubeData : public CommonData
 		struct CubeData : public CommonData
@@ -238,6 +247,7 @@ namespace BansheeEngine
 
 
 		Color mColor;
 		Color mColor;
 		Matrix4 mTransform;
 		Matrix4 mTransform;
+		UINT64 mLayer;
 
 
 		Vector<CubeData> mSolidCubeData;
 		Vector<CubeData> mSolidCubeData;
 		Vector<CubeData> mWireCubeData;
 		Vector<CubeData> mWireCubeData;

+ 130 - 41
BansheeEngine/Source/BsDrawHelper.cpp

@@ -14,6 +14,7 @@ namespace BansheeEngine
 	const UINT32 DrawHelper::INDEX_BUFFER_GROWTH = 4096 * 2;
 	const UINT32 DrawHelper::INDEX_BUFFER_GROWTH = 4096 * 2;
 
 
 	DrawHelper::DrawHelper()
 	DrawHelper::DrawHelper()
+		:mLayer(1)
 	{
 	{
 		mTransform = Matrix4::IDENTITY;
 		mTransform = Matrix4::IDENTITY;
 
 
@@ -51,6 +52,11 @@ namespace BansheeEngine
 		mTransform = transform;
 		mTransform = transform;
 	}
 	}
 
 
+	void DrawHelper::setLayer(UINT64 layer)
+	{
+		mLayer = layer;
+	}
+
 	void DrawHelper::cube(const Vector3& position, const Vector3& extents)
 	void DrawHelper::cube(const Vector3& position, const Vector3& extents)
 	{
 	{
 		mSolidCubeData.push_back(CubeData());
 		mSolidCubeData.push_back(CubeData());
@@ -60,6 +66,7 @@ namespace BansheeEngine
 		cubeData.extents = extents;
 		cubeData.extents = extents;
 		cubeData.color = mColor;
 		cubeData.color = mColor;
 		cubeData.transform = mTransform;
 		cubeData.transform = mTransform;
+		cubeData.layer = mLayer;
 		cubeData.center = mTransform.multiplyAffine(position);
 		cubeData.center = mTransform.multiplyAffine(position);
 	}
 	}
 
 
@@ -73,6 +80,7 @@ namespace BansheeEngine
 		sphereData.quality = quality;
 		sphereData.quality = quality;
 		sphereData.color = mColor;
 		sphereData.color = mColor;
 		sphereData.transform = mTransform;
 		sphereData.transform = mTransform;
+		sphereData.layer = mLayer;
 		sphereData.center = mTransform.multiplyAffine(position);
 		sphereData.center = mTransform.multiplyAffine(position);
 	}
 	}
 
 
@@ -85,6 +93,7 @@ namespace BansheeEngine
 		cubeData.extents = extents;
 		cubeData.extents = extents;
 		cubeData.color = mColor;
 		cubeData.color = mColor;
 		cubeData.transform = mTransform;
 		cubeData.transform = mTransform;
+		cubeData.layer = mLayer;
 		cubeData.center = mTransform.multiplyAffine(position);
 		cubeData.center = mTransform.multiplyAffine(position);
 	}
 	}
 
 
@@ -98,6 +107,7 @@ namespace BansheeEngine
 		sphereData.quality = quality;
 		sphereData.quality = quality;
 		sphereData.color = mColor;
 		sphereData.color = mColor;
 		sphereData.transform = mTransform;
 		sphereData.transform = mTransform;
+		sphereData.layer = mLayer;
 		sphereData.center = mTransform.multiplyAffine(position);
 		sphereData.center = mTransform.multiplyAffine(position);
 	}
 	}
 
 
@@ -110,6 +120,7 @@ namespace BansheeEngine
 		lineData.end = end;
 		lineData.end = end;
 		lineData.color = mColor;
 		lineData.color = mColor;
 		lineData.transform = mTransform;
 		lineData.transform = mTransform;
+		lineData.layer = mLayer;
 		lineData.center = mTransform.multiplyAffine((start + end) * 0.5f);
 		lineData.center = mTransform.multiplyAffine((start + end) * 0.5f);
 	}
 	}
 
 
@@ -125,6 +136,7 @@ namespace BansheeEngine
 		frustumData.far = far;
 		frustumData.far = far;
 		frustumData.color = mColor;
 		frustumData.color = mColor;
 		frustumData.transform = mTransform;
 		frustumData.transform = mTransform;
+		frustumData.layer = mLayer;
 		frustumData.center = mTransform.multiplyAffine(position);
 		frustumData.center = mTransform.multiplyAffine(position);
 	}
 	}
 
 
@@ -140,6 +152,7 @@ namespace BansheeEngine
 		coneData.quality = quality;
 		coneData.quality = quality;
 		coneData.color = mColor;
 		coneData.color = mColor;
 		coneData.transform = mTransform;
 		coneData.transform = mTransform;
+		coneData.layer = mLayer;
 		coneData.center = mTransform.multiplyAffine(base + normal * height * 0.5f);
 		coneData.center = mTransform.multiplyAffine(base + normal * height * 0.5f);
 	}
 	}
 
 
@@ -154,6 +167,7 @@ namespace BansheeEngine
 		discData.quality = quality;
 		discData.quality = quality;
 		discData.color = mColor;
 		discData.color = mColor;
 		discData.transform = mTransform;
 		discData.transform = mTransform;
+		discData.layer = mLayer;
 		discData.center = mTransform.multiplyAffine(position);
 		discData.center = mTransform.multiplyAffine(position);
 	}
 	}
 
 
@@ -168,6 +182,7 @@ namespace BansheeEngine
 		discData.quality = quality;
 		discData.quality = quality;
 		discData.color = mColor;
 		discData.color = mColor;
 		discData.transform = mTransform;
 		discData.transform = mTransform;
+		discData.layer = mLayer;
 		discData.center = mTransform.multiplyAffine(position);
 		discData.center = mTransform.multiplyAffine(position);
 	}
 	}
 
 
@@ -185,6 +200,7 @@ namespace BansheeEngine
 		arcData.quality = quality;
 		arcData.quality = quality;
 		arcData.color = mColor;
 		arcData.color = mColor;
 		arcData.transform = mTransform;
 		arcData.transform = mTransform;
+		arcData.layer = mLayer;
 		arcData.center = mTransform.multiplyAffine(position);
 		arcData.center = mTransform.multiplyAffine(position);
 	}
 	}
 
 
@@ -202,6 +218,7 @@ namespace BansheeEngine
 		arcData.quality = quality;
 		arcData.quality = quality;
 		arcData.color = mColor;
 		arcData.color = mColor;
 		arcData.transform = mTransform;
 		arcData.transform = mTransform;
+		arcData.layer = mLayer;
 		arcData.center = mTransform.multiplyAffine(position);
 		arcData.center = mTransform.multiplyAffine(position);
 	}
 	}
 
 
@@ -213,6 +230,7 @@ namespace BansheeEngine
 		rectData.area = area;
 		rectData.area = area;
 		rectData.color = mColor;
 		rectData.color = mColor;
 		rectData.transform = mTransform;
 		rectData.transform = mTransform;
+		rectData.layer = mLayer;
 		rectData.center = mTransform.multiplyAffine(area.getCenter());
 		rectData.center = mTransform.multiplyAffine(area.getCenter());
 	}
 	}
 
 
@@ -227,6 +245,7 @@ namespace BansheeEngine
 		textData.position = position;
 		textData.position = position;
 		textData.color = mColor;
 		textData.color = mColor;
 		textData.transform = mTransform;
 		textData.transform = mTransform;
+		textData.layer = mLayer;
 		textData.center = mTransform.multiplyAffine(position);
 		textData.center = mTransform.multiplyAffine(position);
 		textData.text = text;
 		textData.text = text;
 		textData.font = font;
 		textData.font = font;
@@ -251,7 +270,7 @@ namespace BansheeEngine
 		mText2DData.clear();
 		mText2DData.clear();
 	}
 	}
 
 
-	void DrawHelper::buildMeshes(SortType sorting, const Vector3& reference)
+	void DrawHelper::buildMeshes(SortType sorting, const Vector3& reference, UINT64 layers)
 	{
 	{
 		clearMeshes();
 		clearMeshes();
 
 
@@ -276,17 +295,20 @@ namespace BansheeEngine
 		/* 			Sort everything according to specified sorting rule         */
 		/* 			Sort everything according to specified sorting rule         */
 		/************************************************************************/
 		/************************************************************************/
 
 
-		UINT32 totalNumShapes = (UINT32)(mSolidCubeData.size() + mSolidSphereData.size() + 
-			mWireCubeData.size() + mWireSphereData.size() + mLineData.size() + mFrustumData.size() + mConeData.size() +
-			mDiscData.size() + mWireDiscData.size() + mArcData.size() + mWireArcData.size() + mRect3Data.size() + mText2DData.size());
-
 		UINT32 idx = 0;
 		UINT32 idx = 0;
-		Vector<RawData> allShapes(totalNumShapes);
+		Vector<RawData> allShapes;
 
 
 		UINT32 localIdx = 0;
 		UINT32 localIdx = 0;
 		for (auto& shapeData : mSolidCubeData)
 		for (auto& shapeData : mSolidCubeData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -295,13 +317,19 @@ namespace BansheeEngine
 			rawData.distance = shapeData.center.distance(reference);
 			rawData.distance = shapeData.center.distance(reference);
 
 
 			ShapeMeshes3D::getNumElementsAABox(rawData.numVertices, rawData.numIndices);
 			ShapeMeshes3D::getNumElementsAABox(rawData.numVertices, rawData.numIndices);
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mSolidSphereData)
 		for (auto& shapeData : mSolidSphereData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -311,14 +339,19 @@ namespace BansheeEngine
 
 
 			ShapeMeshes3D::getNumElementsSphere(shapeData.quality, 
 			ShapeMeshes3D::getNumElementsSphere(shapeData.quality, 
 				rawData.numVertices, rawData.numIndices);
 				rawData.numVertices, rawData.numIndices);
-
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mConeData)
 		for (auto& shapeData : mConeData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -328,14 +361,19 @@ namespace BansheeEngine
 
 
 			ShapeMeshes3D::getNumElementsCone(shapeData.quality, 
 			ShapeMeshes3D::getNumElementsCone(shapeData.quality, 
 				rawData.numVertices, rawData.numIndices);
 				rawData.numVertices, rawData.numIndices);
-
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mDiscData)
 		for (auto& shapeData : mDiscData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -345,14 +383,19 @@ namespace BansheeEngine
 
 
 			ShapeMeshes3D::getNumElementsDisc(shapeData.quality,
 			ShapeMeshes3D::getNumElementsDisc(shapeData.quality,
 				rawData.numVertices, rawData.numIndices);
 				rawData.numVertices, rawData.numIndices);
-
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mArcData)
 		for (auto& shapeData : mArcData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -362,14 +405,19 @@ namespace BansheeEngine
 
 
 			ShapeMeshes3D::getNumElementsArc(shapeData.quality, 
 			ShapeMeshes3D::getNumElementsArc(shapeData.quality, 
 				rawData.numVertices, rawData.numIndices);
 				rawData.numVertices, rawData.numIndices);
-
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mRect3Data)
 		for (auto& shapeData : mRect3Data)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -378,13 +426,19 @@ namespace BansheeEngine
 			rawData.distance = shapeData.center.distance(reference);
 			rawData.distance = shapeData.center.distance(reference);
 
 
 			ShapeMeshes3D::getNumElementsQuad(rawData.numVertices, rawData.numIndices);
 			ShapeMeshes3D::getNumElementsQuad(rawData.numVertices, rawData.numIndices);
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mWireCubeData)
 		for (auto& shapeData : mWireCubeData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -393,13 +447,19 @@ namespace BansheeEngine
 			rawData.distance = shapeData.center.distance(reference);
 			rawData.distance = shapeData.center.distance(reference);
 
 
 			ShapeMeshes3D::getNumElementsWireAABox(rawData.numVertices, rawData.numIndices);
 			ShapeMeshes3D::getNumElementsWireAABox(rawData.numVertices, rawData.numIndices);
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mWireSphereData)
 		for (auto& shapeData : mWireSphereData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -409,14 +469,19 @@ namespace BansheeEngine
 
 
 			ShapeMeshes3D::getNumElementsWireSphere(shapeData.quality,
 			ShapeMeshes3D::getNumElementsWireSphere(shapeData.quality,
 				rawData.numVertices, rawData.numIndices);
 				rawData.numVertices, rawData.numIndices);
-
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mLineData)
 		for (auto& shapeData : mLineData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -425,13 +490,19 @@ namespace BansheeEngine
 			rawData.distance = shapeData.center.distance(reference);
 			rawData.distance = shapeData.center.distance(reference);
 			rawData.numVertices = 2;
 			rawData.numVertices = 2;
 			rawData.numIndices = 2;
 			rawData.numIndices = 2;
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mFrustumData)
 		for (auto& shapeData : mFrustumData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -440,13 +511,19 @@ namespace BansheeEngine
 			rawData.distance = shapeData.center.distance(reference);
 			rawData.distance = shapeData.center.distance(reference);
 
 
 			ShapeMeshes3D::getNumElementsFrustum(rawData.numVertices, rawData.numIndices);
 			ShapeMeshes3D::getNumElementsFrustum(rawData.numVertices, rawData.numIndices);
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mWireDiscData)
 		for (auto& shapeData : mWireDiscData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -456,14 +533,19 @@ namespace BansheeEngine
 
 
 			ShapeMeshes3D::getNumElementsWireDisc(shapeData.quality, 
 			ShapeMeshes3D::getNumElementsWireDisc(shapeData.quality, 
 				rawData.numVertices, rawData.numIndices);
 				rawData.numVertices, rawData.numIndices);
-
-			idx++;
 		}
 		}
 
 
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mWireArcData)
 		for (auto& shapeData : mWireArcData)
 		{
 		{
-			RawData& rawData = allShapes[idx];
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
 
 
 			rawData.idx = localIdx++;
 			rawData.idx = localIdx++;
 			rawData.textIdx = 0;
 			rawData.textIdx = 0;
@@ -473,8 +555,6 @@ namespace BansheeEngine
 
 
 			ShapeMeshes3D::getNumElementsWireArc(shapeData.quality,
 			ShapeMeshes3D::getNumElementsWireArc(shapeData.quality,
 				rawData.numVertices, rawData.numIndices);
 				rawData.numVertices, rawData.numIndices);
-
-			idx++;
 		}
 		}
 
 
 		struct TextRenderData
 		struct TextRenderData
@@ -489,6 +569,12 @@ namespace BansheeEngine
 		localIdx = 0;
 		localIdx = 0;
 		for (auto& shapeData : mText2DData)
 		for (auto& shapeData : mText2DData)
 		{
 		{
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
 			SPtr<TextData<>> textData = bs_shared_ptr_new<TextData<>>(shapeData.text, shapeData.font, shapeData.size);
 			SPtr<TextData<>> textData = bs_shared_ptr_new<TextData<>>(shapeData.text, shapeData.font, shapeData.size);
 
 
 			UINT32 numPages = textData->getNumPages();
 			UINT32 numPages = textData->getNumPages();
@@ -496,7 +582,8 @@ namespace BansheeEngine
 			{
 			{
 				UINT32 numQuads = textData->getNumQuadsForPage(j);
 				UINT32 numQuads = textData->getNumQuadsForPage(j);
 
 
-				RawData& rawData = allShapes[idx];
+				allShapes.push_back(RawData());
+				RawData& rawData = allShapes.back();
 
 
 				rawData.idx = localIdx;
 				rawData.idx = localIdx;
 				rawData.textIdx = textIdx;
 				rawData.textIdx = textIdx;
@@ -547,8 +634,10 @@ namespace BansheeEngine
 			UINT32 numIndices;
 			UINT32 numIndices;
 		};
 		};
 
 
+		UINT32 numShapes = (UINT32)allShapes.size();
+
 		Vector<Batch> batches;
 		Vector<Batch> batches;
-		if (totalNumShapes > 0)
+		if (numShapes > 0)
 		{
 		{
 			batches.push_back(Batch());
 			batches.push_back(Batch());
 
 
@@ -566,7 +655,7 @@ namespace BansheeEngine
 				}
 				}
 			}
 			}
 
 
-			for (UINT32 i = 1; i < totalNumShapes; i++)
+			for (UINT32 i = 1; i < numShapes; i++)
 			{
 			{
 				Batch& currentBatch = batches.back();
 				Batch& currentBatch = batches.back();
 
 
@@ -611,7 +700,7 @@ namespace BansheeEngine
 
 
 			{
 			{
 				Batch& currentBatch = batches.back();
 				Batch& currentBatch = batches.back();
-				currentBatch.endIdx = totalNumShapes - 1;
+				currentBatch.endIdx = numShapes - 1;
 			}
 			}
 		}
 		}
 
 

+ 13 - 0
MBansheeEditor/Scene/HandleDrawing.cs

@@ -1,5 +1,6 @@
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
 using BansheeEngine;
 using BansheeEngine;
+using System;
 
 
 namespace BansheeEditor
 namespace BansheeEditor
 {
 {
@@ -25,6 +26,15 @@ namespace BansheeEditor
             set { Internal_SetTransform(ref value); }
             set { Internal_SetTransform(ref value); }
         }
         }
 
 
+        /// <summary>
+        /// Layer bitfield that controls whether a handle is considered visible in a specific camera. Handle layer 
+        /// must match camera layer in order for the camera to render it.
+        /// </summary>
+        public static UInt64 Layer
+        {
+            set { Internal_SetLayer(value); }
+        }
+
         /// <summary>
         /// <summary>
         /// Draws an axis aligned solid cube.
         /// Draws an axis aligned solid cube.
         /// </summary>
         /// </summary>
@@ -176,6 +186,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetTransform(ref Matrix4 transform);
         private static extern void Internal_SetTransform(ref Matrix4 transform);
 
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetLayer(UInt64 layer);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_DrawCube(ref Vector3 position, ref Vector3 extents, float size);
         private static extern void Internal_DrawCube(ref Vector3 position, ref Vector3 extents, float size);
 
 

+ 5 - 3
MBansheeEditor/Scene/HandleSliderDisc.cs

@@ -18,10 +18,11 @@ namespace BansheeEditor
         /// <param name="radius">Radius of the disc.</param>
         /// <param name="radius">Radius of the disc.</param>
         /// <param name="fixedScale">If true the handle slider will always try to maintain the same visible area in the 
         /// <param name="fixedScale">If true the handle slider will always try to maintain the same visible area in the 
         ///                          viewport regardless of distance from camera.</param>
         ///                          viewport regardless of distance from camera.</param>
-        public HandleSliderDisc(Handle parentHandle, Vector3 normal, float radius, bool fixedScale = true)
+        /// <param name="layer">Layer that allows filtering of which sliders are interacted with from a specific camera.</param>
+        public HandleSliderDisc(Handle parentHandle, Vector3 normal, float radius, bool fixedScale = true, UInt64 layer = 1)
             :base(parentHandle)
             :base(parentHandle)
         {
         {
-            Internal_CreateInstance(this, ref normal, radius, fixedScale);
+            Internal_CreateInstance(this, ref normal, radius, fixedScale, layer);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -63,7 +64,8 @@ namespace BansheeEditor
         }
         }
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstance(HandleSliderDisc instance, ref Vector3 normal, float radius, bool fixedScale);
+        private static extern void Internal_CreateInstance(HandleSliderDisc instance, ref Vector3 normal, float radius, 
+            bool fixedScale, UInt64 layer);
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_GetDelta(IntPtr nativeInstance, out float value);
         private static extern void Internal_GetDelta(IntPtr nativeInstance, out float value);

+ 5 - 3
MBansheeEditor/Scene/HandleSliderLine.cs

@@ -18,10 +18,11 @@ namespace BansheeEditor
         /// <param name="length">Length of the line.</param>
         /// <param name="length">Length of the line.</param>
         /// <param name="fixedScale">If true the handle slider will always try to maintain the same visible area in the
         /// <param name="fixedScale">If true the handle slider will always try to maintain the same visible area in the
         ///                          viewport regardless of distance from camera.</param>
         ///                          viewport regardless of distance from camera.</param>
-        public HandleSliderLine(Handle parentHandle, Vector3 direction, float length, bool fixedScale = true)
+        /// <param name="layer">Layer that allows filtering of which sliders are interacted with from a specific camera.</param>
+        public HandleSliderLine(Handle parentHandle, Vector3 direction, float length, bool fixedScale = true, UInt64 layer = 1)
             :base(parentHandle)
             :base(parentHandle)
         {
         {
-            Internal_CreateInstance(this, ref direction, length, fixedScale);
+            Internal_CreateInstance(this, ref direction, length, fixedScale, layer);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -39,7 +40,8 @@ namespace BansheeEditor
         }
         }
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstance(HandleSliderLine instance, ref Vector3 direction, float length, bool fixedScale);
+        private static extern void Internal_CreateInstance(HandleSliderLine instance, ref Vector3 direction, float length, 
+            bool fixedScale, UInt64 layer);
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_GetDelta(IntPtr nativeInstance, out float value);
         private static extern void Internal_GetDelta(IntPtr nativeInstance, out float value);

+ 6 - 4
MBansheeEditor/Scene/HandleSliderPlane.cs

@@ -9,7 +9,7 @@ namespace BansheeEditor
     /// is internally by a quadrilateral (a bounded plane).
     /// is internally by a quadrilateral (a bounded plane).
     /// </summary>
     /// </summary>
     public sealed class HandleSliderPlane : HandleSlider
     public sealed class HandleSliderPlane : HandleSlider
-    {        
+    {
         /// <summary>
         /// <summary>
         /// Creates a new plane handle slider. 
         /// Creates a new plane handle slider. 
         /// </summary>
         /// </summary>
@@ -21,10 +21,11 @@ namespace BansheeEditor
         /// <param name="length">Length of the quadrilateral in both directions.</param>
         /// <param name="length">Length of the quadrilateral in both directions.</param>
         /// <param name="fixedScale">If true the handle slider will always try to maintain the same visible area in the
         /// <param name="fixedScale">If true the handle slider will always try to maintain the same visible area in the
         ///                          viewport regardless of distance from camera.</param>
         ///                          viewport regardless of distance from camera.</param>
-        public HandleSliderPlane(Handle parentHandle, Vector3 dir1, Vector3 dir2, float length, bool fixedScale = true)
+        /// <param name="layer">Layer that allows filtering of which sliders are interacted with from a specific camera.</param>
+        public HandleSliderPlane(Handle parentHandle, Vector3 dir1, Vector3 dir2, float length, bool fixedScale = true, UInt64 layer = 1)
             :base(parentHandle)
             :base(parentHandle)
         {
         {
-            Internal_CreateInstance(this, ref dir1, ref dir2, length, fixedScale);
+            Internal_CreateInstance(this, ref dir1, ref dir2, length, fixedScale, layer);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -43,7 +44,8 @@ namespace BansheeEditor
         }
         }
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstance(HandleSliderPlane instance, ref Vector3 dir1, ref Vector3 dir2, float length, bool fixedScale);
+        private static extern void Internal_CreateInstance(HandleSliderPlane instance, ref Vector3 dir1, ref Vector3 dir2, 
+            float length, bool fixedScale, UInt64 layer);
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_GetDelta(IntPtr nativeInstance, out Vector2 value);
         private static extern void Internal_GetDelta(IntPtr nativeInstance, out Vector2 value);

+ 245 - 244
MBansheeEditor/Scene/MoveHandle.cs

@@ -1,244 +1,245 @@
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Handle that allows an object to be translated along the three primary axes.
-    /// </summary>
-    public sealed class MoveHandle : DefaultHandle
-    {
-        private const float CONE_HEIGHT = 0.25f;
-        private const float CONE_RADIUS = 0.175f;
-
-        private Vector3 delta;
-
-        private HandleSliderLine xAxis;
-        private HandleSliderLine yAxis;
-        private HandleSliderLine zAxis;
-
-        private HandleSliderPlane xyPlane;
-        private HandleSliderPlane yzPlane;
-        private HandleSliderPlane zxPlane;
-
-        /// <summary>
-        /// Returns the amount of translation since last frame. Only valid while the handle is being dragged.
-        /// </summary>
-        public Vector3 Delta
-        {
-            get { return delta; }
-        }
-
-        /// <inheritdoc/>
-        internal override bool IsDragged()
-        {
-            return xAxis.State == HandleSlider.StateType.Active ||
-                    yAxis.State == HandleSlider.StateType.Active ||
-                    zAxis.State == HandleSlider.StateType.Active ||
-                    xyPlane.State == HandleSlider.StateType.Active ||
-                    yzPlane.State == HandleSlider.StateType.Active ||
-                    zxPlane.State == HandleSlider.StateType.Active;
-        }
-
-        /// <summary>
-        /// Creates a new move handle.
-        /// </summary>
-        public MoveHandle()
-        {
-            xAxis = new HandleSliderLine(this, Vector3.XAxis, 1.0f);
-            yAxis = new HandleSliderLine(this, Vector3.YAxis, 1.0f);
-            zAxis = new HandleSliderLine(this, Vector3.ZAxis, 1.0f);
-
-            xyPlane = new HandleSliderPlane(this, Vector3.XAxis, Vector3.YAxis, 0.3f);
-            yzPlane = new HandleSliderPlane(this, Vector3.YAxis, Vector3.ZAxis, 0.3f);
-            zxPlane = new HandleSliderPlane(this, Vector3.ZAxis, Vector3.XAxis, 0.3f);
-        }
-
-        /// <inheritdoc/>
-        protected internal override void PreInput()
-        {
-            xAxis.Position = position;
-            yAxis.Position = position;
-            zAxis.Position = position;
-
-            xyPlane.Position = position;
-            yzPlane.Position = position;
-            zxPlane.Position = position;
-
-            xAxis.Rotation = rotation;
-            yAxis.Rotation = rotation;
-            zAxis.Rotation = rotation;
-
-            xyPlane.Rotation = rotation;
-            yzPlane.Rotation = rotation;
-            zxPlane.Rotation = rotation;
-        }
-
-        /// <inheritdoc/>
-        protected internal override void PostInput()
-        {
-            delta = Vector3.Zero;
-
-            if (Handles.MoveHandleSnapActive)
-            {
-                delta += Handles.SnapValue(xAxis.Delta, Handles.MoveSnapAmount) * GetXDir();
-                delta += Handles.SnapValue(yAxis.Delta, Handles.MoveSnapAmount) * GetYDir();
-                delta += Handles.SnapValue(zAxis.Delta, Handles.MoveSnapAmount) * GetZDir();
-
-                delta += Handles.SnapValue(xyPlane.Delta.x, Handles.MoveSnapAmount) * GetXDir();
-                delta += Handles.SnapValue(xyPlane.Delta.y, Handles.MoveSnapAmount) * GetYDir();
-                delta += Handles.SnapValue(yzPlane.Delta.x, Handles.MoveSnapAmount) * GetYDir();
-                delta += Handles.SnapValue(yzPlane.Delta.y, Handles.MoveSnapAmount) * GetZDir();
-                delta += Handles.SnapValue(zxPlane.Delta.x, Handles.MoveSnapAmount) * GetZDir();
-                delta += Handles.SnapValue(zxPlane.Delta.y, Handles.MoveSnapAmount) * GetXDir();
-            }
-            else
-            {
-                delta += xAxis.Delta * GetXDir();
-                delta += yAxis.Delta * GetYDir();
-                delta += zAxis.Delta * GetZDir();
-
-                delta += xyPlane.Delta.x * GetXDir();
-                delta += xyPlane.Delta.y * GetYDir();
-                delta += yzPlane.Delta.x * GetYDir();
-                delta += yzPlane.Delta.y * GetZDir();
-                delta += zxPlane.Delta.x * GetZDir();
-                delta += zxPlane.Delta.y * GetXDir();
-            }
-        }
-
-        /// <inheritdoc/>
-        protected internal override void Draw()
-        {
-            HandleDrawing.Transform = Matrix4.TRS(Position, Rotation, Vector3.One);
-            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
-
-            // Draw 1D arrows
-            if (xAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if(xAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = Color.Red;
-
-            Vector3 xConeStart = Vector3.XAxis*(1.0f - CONE_HEIGHT);
-            HandleDrawing.DrawLine(Vector3.Zero, xConeStart, handleSize);
-            HandleDrawing.DrawCone(xConeStart, Vector3.XAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
-
-            if (yAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if (yAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = Color.Green;
-
-            Vector3 yConeStart = Vector3.YAxis * (1.0f - CONE_HEIGHT);
-            HandleDrawing.DrawLine(Vector3.Zero, yConeStart, handleSize);
-            HandleDrawing.DrawCone(yConeStart, Vector3.YAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
-
-            if (zAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if (zAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = Color.Blue;
-
-            Vector3 zConeStart = Vector3.ZAxis * (1.0f - CONE_HEIGHT);
-            HandleDrawing.DrawLine(Vector3.Zero, zConeStart, handleSize);
-            HandleDrawing.DrawCone(zConeStart, Vector3.ZAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
-
-            // Draw 2D planes
-            Color planeNormal = new Color(1.0f, 1.0f, 1.0f, 0.2f);
-            Color planeHover = new Color(1.0f, 1.0f, 1.0f, 0.4f);
-            Color planeActive = new Color(1.0f, 1.0f, 1.0f, 0.6f);
-
-            Vector3 planeXOffset = Vector3.XAxis * 0.3f;
-            Vector3 planeYOffset = Vector3.YAxis * 0.3f;
-            Vector3 planeZOffset = Vector3.ZAxis * 0.3f;
-
-            //// XY plane
-            HandleDrawing.Color = Color.Blue;
-
-            HandleDrawing.DrawLine(planeXOffset, planeXOffset + planeYOffset, handleSize);
-            HandleDrawing.DrawLine(planeYOffset, planeYOffset + planeXOffset, handleSize);
-
-            if (xyPlane.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.Blue * planeActive;
-            else if (xyPlane.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.Blue * planeHover;
-            else
-                HandleDrawing.Color = Color.Blue * planeNormal;
-
-            Rect3 xyPlaneArea = new Rect3(
-                (planeXOffset + planeYOffset) * 0.5f,
-                new Vector3[] { Vector3.XAxis, Vector3.YAxis}, 
-                new float[] { 0.15f, 0.15f});
-            HandleDrawing.DrawRect(xyPlaneArea, handleSize);
-
-            //// YZ plane
-            HandleDrawing.Color = Color.Red;
-
-            HandleDrawing.DrawLine(planeYOffset, planeYOffset + planeZOffset, handleSize);
-            HandleDrawing.DrawLine(planeZOffset, planeZOffset + planeYOffset, handleSize);
-
-            if (yzPlane.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.Red * planeActive;
-            else if (yzPlane.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.Red * planeHover;
-            else
-                HandleDrawing.Color = Color.Red * planeNormal;
-
-            Rect3 yzPlaneArea = new Rect3(
-                (planeYOffset + planeZOffset) * 0.5f,
-                new Vector3[] { Vector3.YAxis, Vector3.ZAxis },
-                new float[] { 0.15f, 0.15f });
-
-            HandleDrawing.DrawRect(yzPlaneArea, handleSize);
-
-            //// ZX plane
-            HandleDrawing.Color = Color.Green;
-
-            HandleDrawing.DrawLine(planeZOffset, planeZOffset + planeXOffset, handleSize);
-            HandleDrawing.DrawLine(planeXOffset, planeXOffset + planeZOffset, handleSize);
-
-            if (zxPlane.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.Green * planeActive;
-            else if (zxPlane.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.Green * planeHover;
-            else
-                HandleDrawing.Color = Color.Green * planeNormal;
-
-            Rect3 zxPlaneArea = new Rect3(
-                (planeZOffset + planeXOffset) * 0.5f,
-                new Vector3[] { Vector3.ZAxis, Vector3.XAxis },
-                new float[] { 0.15f, 0.15f });
-            HandleDrawing.DrawRect(zxPlaneArea, handleSize);
-        }
-
-        /// <summary>
-        /// Returns the direction of the handle's x axis in world space.
-        /// </summary>
-        /// <returns>Direction of the handle's x axis in world space</returns>
-        private Vector3 GetXDir()
-        {
-             return rotation.Rotate(Vector3.XAxis);
-        }
-
-        /// <summary>
-        /// Returns the direction of the handle's y axis in world space.
-        /// </summary>
-        /// <returns>Direction of the handle's y axis in world space</returns>
-        private Vector3 GetYDir()
-        {
-            return rotation.Rotate(Vector3.YAxis);
-        }
-
-        /// <summary>
-        /// Returns the direction of the handle's z axis in world space.
-        /// </summary>
-        /// <returns>Direction of the handle's z axis in world space</returns>
-        private Vector3 GetZDir()
-        {
-            return rotation.Rotate(Vector3.ZAxis);
-        }
-    }
-}
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Handle that allows an object to be translated along the three primary axes.
+    /// </summary>
+    public sealed class MoveHandle : DefaultHandle
+    {
+        private const float CONE_HEIGHT = 0.25f;
+        private const float CONE_RADIUS = 0.175f;
+
+        private Vector3 delta;
+
+        private HandleSliderLine xAxis;
+        private HandleSliderLine yAxis;
+        private HandleSliderLine zAxis;
+
+        private HandleSliderPlane xyPlane;
+        private HandleSliderPlane yzPlane;
+        private HandleSliderPlane zxPlane;
+
+        /// <summary>
+        /// Returns the amount of translation since last frame. Only valid while the handle is being dragged.
+        /// </summary>
+        public Vector3 Delta
+        {
+            get { return delta; }
+        }
+
+        /// <inheritdoc/>
+        internal override bool IsDragged()
+        {
+            return xAxis.State == HandleSlider.StateType.Active ||
+                    yAxis.State == HandleSlider.StateType.Active ||
+                    zAxis.State == HandleSlider.StateType.Active ||
+                    xyPlane.State == HandleSlider.StateType.Active ||
+                    yzPlane.State == HandleSlider.StateType.Active ||
+                    zxPlane.State == HandleSlider.StateType.Active;
+        }
+
+        /// <summary>
+        /// Creates a new move handle.
+        /// </summary>
+        public MoveHandle()
+        {
+            xAxis = new HandleSliderLine(this, Vector3.XAxis, 1.0f);
+            yAxis = new HandleSliderLine(this, Vector3.YAxis, 1.0f);
+            zAxis = new HandleSliderLine(this, Vector3.ZAxis, 1.0f);
+
+            xyPlane = new HandleSliderPlane(this, Vector3.XAxis, Vector3.YAxis, 0.3f);
+            yzPlane = new HandleSliderPlane(this, Vector3.YAxis, Vector3.ZAxis, 0.3f);
+            zxPlane = new HandleSliderPlane(this, Vector3.ZAxis, Vector3.XAxis, 0.3f);
+        }
+
+        /// <inheritdoc/>
+        protected internal override void PreInput()
+        {
+            xAxis.Position = position;
+            yAxis.Position = position;
+            zAxis.Position = position;
+
+            xyPlane.Position = position;
+            yzPlane.Position = position;
+            zxPlane.Position = position;
+
+            xAxis.Rotation = rotation;
+            yAxis.Rotation = rotation;
+            zAxis.Rotation = rotation;
+
+            xyPlane.Rotation = rotation;
+            yzPlane.Rotation = rotation;
+            zxPlane.Rotation = rotation;
+        }
+
+        /// <inheritdoc/>
+        protected internal override void PostInput()
+        {
+            delta = Vector3.Zero;
+
+            if (Handles.MoveHandleSnapActive)
+            {
+                delta += Handles.SnapValue(xAxis.Delta, Handles.MoveSnapAmount) * GetXDir();
+                delta += Handles.SnapValue(yAxis.Delta, Handles.MoveSnapAmount) * GetYDir();
+                delta += Handles.SnapValue(zAxis.Delta, Handles.MoveSnapAmount) * GetZDir();
+
+                delta += Handles.SnapValue(xyPlane.Delta.x, Handles.MoveSnapAmount) * GetXDir();
+                delta += Handles.SnapValue(xyPlane.Delta.y, Handles.MoveSnapAmount) * GetYDir();
+                delta += Handles.SnapValue(yzPlane.Delta.x, Handles.MoveSnapAmount) * GetYDir();
+                delta += Handles.SnapValue(yzPlane.Delta.y, Handles.MoveSnapAmount) * GetZDir();
+                delta += Handles.SnapValue(zxPlane.Delta.x, Handles.MoveSnapAmount) * GetZDir();
+                delta += Handles.SnapValue(zxPlane.Delta.y, Handles.MoveSnapAmount) * GetXDir();
+            }
+            else
+            {
+                delta += xAxis.Delta * GetXDir();
+                delta += yAxis.Delta * GetYDir();
+                delta += zAxis.Delta * GetZDir();
+
+                delta += xyPlane.Delta.x * GetXDir();
+                delta += xyPlane.Delta.y * GetYDir();
+                delta += yzPlane.Delta.x * GetYDir();
+                delta += yzPlane.Delta.y * GetZDir();
+                delta += zxPlane.Delta.x * GetZDir();
+                delta += zxPlane.Delta.y * GetXDir();
+            }
+        }
+
+        /// <inheritdoc/>
+        protected internal override void Draw()
+        {
+            HandleDrawing.Layer = 1;
+            HandleDrawing.Transform = Matrix4.TRS(Position, Rotation, Vector3.One);
+            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
+
+            // Draw 1D arrows
+            if (xAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if(xAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = Color.Red;
+
+            Vector3 xConeStart = Vector3.XAxis*(1.0f - CONE_HEIGHT);
+            HandleDrawing.DrawLine(Vector3.Zero, xConeStart, handleSize);
+            HandleDrawing.DrawCone(xConeStart, Vector3.XAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
+
+            if (yAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if (yAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = Color.Green;
+
+            Vector3 yConeStart = Vector3.YAxis * (1.0f - CONE_HEIGHT);
+            HandleDrawing.DrawLine(Vector3.Zero, yConeStart, handleSize);
+            HandleDrawing.DrawCone(yConeStart, Vector3.YAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
+
+            if (zAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if (zAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = Color.Blue;
+
+            Vector3 zConeStart = Vector3.ZAxis * (1.0f - CONE_HEIGHT);
+            HandleDrawing.DrawLine(Vector3.Zero, zConeStart, handleSize);
+            HandleDrawing.DrawCone(zConeStart, Vector3.ZAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
+
+            // Draw 2D planes
+            Color planeNormal = new Color(1.0f, 1.0f, 1.0f, 0.2f);
+            Color planeHover = new Color(1.0f, 1.0f, 1.0f, 0.4f);
+            Color planeActive = new Color(1.0f, 1.0f, 1.0f, 0.6f);
+
+            Vector3 planeXOffset = Vector3.XAxis * 0.3f;
+            Vector3 planeYOffset = Vector3.YAxis * 0.3f;
+            Vector3 planeZOffset = Vector3.ZAxis * 0.3f;
+
+            //// XY plane
+            HandleDrawing.Color = Color.Blue;
+
+            HandleDrawing.DrawLine(planeXOffset, planeXOffset + planeYOffset, handleSize);
+            HandleDrawing.DrawLine(planeYOffset, planeYOffset + planeXOffset, handleSize);
+
+            if (xyPlane.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.Blue * planeActive;
+            else if (xyPlane.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.Blue * planeHover;
+            else
+                HandleDrawing.Color = Color.Blue * planeNormal;
+
+            Rect3 xyPlaneArea = new Rect3(
+                (planeXOffset + planeYOffset) * 0.5f,
+                new Vector3[] { Vector3.XAxis, Vector3.YAxis}, 
+                new float[] { 0.15f, 0.15f});
+            HandleDrawing.DrawRect(xyPlaneArea, handleSize);
+
+            //// YZ plane
+            HandleDrawing.Color = Color.Red;
+
+            HandleDrawing.DrawLine(planeYOffset, planeYOffset + planeZOffset, handleSize);
+            HandleDrawing.DrawLine(planeZOffset, planeZOffset + planeYOffset, handleSize);
+
+            if (yzPlane.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.Red * planeActive;
+            else if (yzPlane.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.Red * planeHover;
+            else
+                HandleDrawing.Color = Color.Red * planeNormal;
+
+            Rect3 yzPlaneArea = new Rect3(
+                (planeYOffset + planeZOffset) * 0.5f,
+                new Vector3[] { Vector3.YAxis, Vector3.ZAxis },
+                new float[] { 0.15f, 0.15f });
+
+            HandleDrawing.DrawRect(yzPlaneArea, handleSize);
+
+            //// ZX plane
+            HandleDrawing.Color = Color.Green;
+
+            HandleDrawing.DrawLine(planeZOffset, planeZOffset + planeXOffset, handleSize);
+            HandleDrawing.DrawLine(planeXOffset, planeXOffset + planeZOffset, handleSize);
+
+            if (zxPlane.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.Green * planeActive;
+            else if (zxPlane.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.Green * planeHover;
+            else
+                HandleDrawing.Color = Color.Green * planeNormal;
+
+            Rect3 zxPlaneArea = new Rect3(
+                (planeZOffset + planeXOffset) * 0.5f,
+                new Vector3[] { Vector3.ZAxis, Vector3.XAxis },
+                new float[] { 0.15f, 0.15f });
+            HandleDrawing.DrawRect(zxPlaneArea, handleSize);
+        }
+
+        /// <summary>
+        /// Returns the direction of the handle's x axis in world space.
+        /// </summary>
+        /// <returns>Direction of the handle's x axis in world space</returns>
+        private Vector3 GetXDir()
+        {
+             return rotation.Rotate(Vector3.XAxis);
+        }
+
+        /// <summary>
+        /// Returns the direction of the handle's y axis in world space.
+        /// </summary>
+        /// <returns>Direction of the handle's y axis in world space</returns>
+        private Vector3 GetYDir()
+        {
+            return rotation.Rotate(Vector3.YAxis);
+        }
+
+        /// <summary>
+        /// Returns the direction of the handle's z axis in world space.
+        /// </summary>
+        /// <returns>Direction of the handle's z axis in world space</returns>
+        private Vector3 GetZDir()
+        {
+            return rotation.Rotate(Vector3.ZAxis);
+        }
+    }
+}

+ 245 - 244
MBansheeEditor/Scene/RotateHandle.cs

@@ -1,244 +1,245 @@
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Handle that allows an object to be rotated around the three primary axes, as well as a free axis currently
-    /// facing the camera.
-    /// </summary>
-    public sealed class RotateHandle : DefaultHandle
-    {
-        private Quaternion delta;
-
-        private HandleSliderDisc xAxis;
-        private HandleSliderDisc yAxis;
-        private HandleSliderDisc zAxis;
-
-        private HandleSliderDisc freeAxis;
-
-        private bool isDragged;
-        private Quaternion dragStartRotation;
-
-        /// <summary>
-        /// Amount of rotation applied since the last frame. Only valid while the handle is being dragged.
-        /// </summary>
-        public Quaternion Delta
-        {
-            get { return delta; }
-        }
-
-        /// <inheritdoc/>
-        internal override bool IsDragged()
-        {
-            return xAxis.State == HandleSlider.StateType.Active ||
-                    yAxis.State == HandleSlider.StateType.Active ||
-                    zAxis.State == HandleSlider.StateType.Active ||
-                    freeAxis.State == HandleSlider.StateType.Active;
-        }
-
-        /// <summary>
-        /// Creates a new rotation handle.
-        /// </summary>
-        public RotateHandle()
-        {
-            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.2f);
-        }
-
-        /// <inheritdoc/>
-        protected internal override void PreInput()
-        {
-            xAxis.Position = position;
-            yAxis.Position = position;
-            zAxis.Position = position;
-            freeAxis.Position = position;
-
-            Quaternion handleRotation = isDragged ? dragStartRotation : Rotation;
-            xAxis.Rotation = handleRotation;
-            yAxis.Rotation = handleRotation;
-            zAxis.Rotation = handleRotation;
-            freeAxis.Rotation = EditorApplication.SceneViewCamera.SceneObject.Rotation;
-
-            xAxis.SetCutoffPlane(GetXStartAngle(isDragged), true);
-            yAxis.SetCutoffPlane(GetYStartAngle(isDragged), true);
-            zAxis.SetCutoffPlane(GetZStartAngle(isDragged), true);
-        }
-
-        /// <inheritdoc/>
-        protected internal override void PostInput()
-        {
-            if (IsDragged())
-            {
-                if (!isDragged)
-                {
-                    isDragged = true;
-                    dragStartRotation = Rotation;
-                }
-            }
-            else
-            {
-                isDragged = false;
-                dragStartRotation = Quaternion.Identity;
-            }
-
-            Degree xValue = 0.0f;
-            Degree yValue = 0.0f;
-            Degree zValue = 0.0f;
-            Degree freeAxisValue = 0.0f;
-
-            if (Handles.RotateHandleSnapActive)
-            {
-                xValue = Handles.SnapValue(xAxis.Delta, Handles.RotateSnapAmount);
-                yValue = Handles.SnapValue(yAxis.Delta, Handles.RotateSnapAmount);
-                zValue = Handles.SnapValue(zAxis.Delta, Handles.RotateSnapAmount);
-                freeAxisValue = Handles.SnapValue(freeAxis.Delta, Handles.RotateSnapAmount);
-            }
-            else
-            {
-                xValue = xAxis.Delta;
-                yValue = yAxis.Delta;
-                zValue = zAxis.Delta;
-                freeAxisValue = freeAxis.Delta;
-            }
-
-            Vector3 cameraForward = -(dragStartRotation.Inverse * EditorApplication.SceneViewCamera.SceneObject.Rotation).Forward;
-
-            delta = Quaternion.FromEuler(xValue, yValue, zValue);
-            delta *= Quaternion.FromAxisAngle(cameraForward, freeAxisValue);
-        }
-
-        /// <inheritdoc/>
-        protected internal override void Draw()
-        {
-            HandleDrawing.Transform = Matrix4.TRS(Position, Rotation, Vector3.One);
-            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
-
-            // Draw arcs
-            if (xAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if(xAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = Color.Red;
-
-            HandleDrawing.DrawWireArc(Vector3.Zero, Vector3.XAxis, 1.0f, GetXStartAngle(false), -180.0f, handleSize);
-
-            if (yAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if (yAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = Color.Green;
-
-            HandleDrawing.DrawWireArc(Vector3.Zero, Vector3.YAxis, 1.0f, GetYStartAngle(false), -180.0f, handleSize);
-
-            if (zAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if (zAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = Color.Blue;
-
-            HandleDrawing.DrawWireArc(Vector3.Zero, Vector3.ZAxis, 1.0f, GetZStartAngle(false), -180.0f, handleSize);
-
-            // Draw "bounds" and free handle
-            Color gray = new Color(1.0f, 1.0f, 1.0f, 0.3f);
-            Vector3 cameraNormal = EditorApplication.SceneViewCamera.SceneObject.Rotation.Rotate(Vector3.ZAxis);
-            HandleDrawing.Transform = Matrix4.TRS(Position, Quaternion.Identity, Vector3.One);
-            HandleDrawing.Color = gray;
-
-            HandleDrawing.DrawWireDisc(cameraNormal * 0.1f, cameraNormal, 1.0f, handleSize);
-
-            if (freeAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if (freeAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = gray;
-
-            HandleDrawing.DrawWireDisc(Vector3.Zero, cameraNormal, 1.2f, handleSize);
-
-            // Draw active rotation pie
-            HandleDrawing.Color = gray;
-            HandleDrawing.Transform = Matrix4.TRS(Position, EditorApplication.SceneViewCamera.SceneObject.Rotation, Vector3.One);
-
-            if (freeAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.DrawArc(Vector3.Zero, -Vector3.ZAxis, 1.2f, freeAxis.StartAngle, freeAxis.Delta, handleSize);
-
-            HandleDrawing.Transform = Matrix4.TRS(Position, dragStartRotation, Vector3.One);
-
-            if (xAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.DrawArc(Vector3.Zero, Vector3.XAxis, 1.0f, xAxis.StartAngle, xAxis.Delta, handleSize);
-            else if (yAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.DrawArc(Vector3.Zero, Vector3.YAxis, 1.0f, yAxis.StartAngle, yAxis.Delta, handleSize);
-            else if (zAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.DrawArc(Vector3.Zero, Vector3.ZAxis, 1.0f, zAxis.StartAngle, zAxis.Delta, handleSize);
-        }
-
-        /// <summary>
-        /// The rotate handle only displays the 180 degree arc facing the camera and this method returns the angle at which 
-        /// the arc starts for the X axis.
-        /// </summary>
-        /// <param name="frozen">Determines should the local handle rotation be taken into account, or should it be frozen
-        ///                      to the value when handle drag started. This is useful because we do not want the visible
-        ///                      arc to change while the user is in the process of rotating the handle.</param>
-        /// <returns>Angle at which to display the visible arc for the X axis rotations.</returns>
-        private Degree GetXStartAngle(bool frozen)
-        {
-            Quaternion handleRotation = frozen ? dragStartRotation : Rotation;
-
-            Vector3 xStartDir = Vector3.Cross(handleRotation.Inverse.Rotate(EditorApplication.SceneViewCamera.SceneObject.Forward), Vector3.XAxis);
-            return PointOnCircleToAngle(Vector3.XAxis, xStartDir);
-        }
-
-        /// <summary>
-        /// The rotate handle only displays the 180 degree arc facing the camera and this method returns the angle at which 
-        /// the arc starts for the Y axis.
-        /// </summary>
-        /// <param name="frozen">Determines should the local handle rotation be taken into account, or should it be frozen
-        ///                      to the value when handle drag started. This is useful because we do not want the visible
-        ///                      arc to change while the user is in the process of rotating the handle.</param>
-        /// <returns>Angle at which to display the visible arc for the Y axis rotations.</returns>
-        private Degree GetYStartAngle(bool frozen)
-        {
-            Quaternion handleRotation = frozen ? dragStartRotation : Rotation;
-
-            Vector3 yStartDir = Vector3.Cross(handleRotation.Inverse.Rotate(EditorApplication.SceneViewCamera.SceneObject.Forward), Vector3.YAxis);
-            return PointOnCircleToAngle(Vector3.YAxis, yStartDir);
-        }
-
-        /// <summary>
-        /// The rotate handle only displays the 180 degree arc facing the camera and this method returns the angle at which 
-        /// the arc starts for the Z axis.
-        /// </summary>
-        /// <param name="frozen">Determines should the local handle rotation be taken into account, or should it be frozen
-        ///                      to the value when handle drag started. This is useful because we do not want the visible
-        ///                      arc to change while the user is in the process of rotating the handle.</param>
-        /// <returns>Angle at which to display the visible arc for the Z axis rotations.</returns>
-        private Degree GetZStartAngle(bool frozen)
-        {
-            Quaternion handleRotation = frozen ? dragStartRotation : Rotation;
-
-            Vector3 zStartDir = Vector3.Cross(handleRotation.Inverse.Rotate(EditorApplication.SceneViewCamera.SceneObject.Forward), Vector3.ZAxis);
-            return PointOnCircleToAngle(Vector3.ZAxis, zStartDir);
-        }
-
-        /// <summary>
-        /// Converts a point on the circle to an angle on the circle.
-        /// </summary>
-        /// <param name="up">Up vector determining the orientation of the circle.</param>
-        /// <param name="point">Point along a unit circle centered around the origin.</param>
-        /// <returns>Angle at which the provided point is located on the circle.</returns>
-        private Degree PointOnCircleToAngle(Vector3 up, Vector3 point)
-        {
-            Quaternion rot = Quaternion.FromToRotation(up, Vector3.YAxis);
-
-            Matrix4 worldToPlane = Matrix4.TRS(Vector3.Zero, rot, Vector3.One);
-            point = worldToPlane.MultiplyDirection(point);
-
-            return (MathEx.Atan2(-point.z, -point.x) + MathEx.Pi) * MathEx.Rad2Deg;
-        }
-    }
-}
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Handle that allows an object to be rotated around the three primary axes, as well as a free axis currently
+    /// facing the camera.
+    /// </summary>
+    public sealed class RotateHandle : DefaultHandle
+    {
+        private Quaternion delta;
+
+        private HandleSliderDisc xAxis;
+        private HandleSliderDisc yAxis;
+        private HandleSliderDisc zAxis;
+
+        private HandleSliderDisc freeAxis;
+
+        private bool isDragged;
+        private Quaternion dragStartRotation;
+
+        /// <summary>
+        /// Amount of rotation applied since the last frame. Only valid while the handle is being dragged.
+        /// </summary>
+        public Quaternion Delta
+        {
+            get { return delta; }
+        }
+
+        /// <inheritdoc/>
+        internal override bool IsDragged()
+        {
+            return xAxis.State == HandleSlider.StateType.Active ||
+                    yAxis.State == HandleSlider.StateType.Active ||
+                    zAxis.State == HandleSlider.StateType.Active ||
+                    freeAxis.State == HandleSlider.StateType.Active;
+        }
+
+        /// <summary>
+        /// Creates a new rotation handle.
+        /// </summary>
+        public RotateHandle()
+        {
+            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.2f);
+        }
+
+        /// <inheritdoc/>
+        protected internal override void PreInput()
+        {
+            xAxis.Position = position;
+            yAxis.Position = position;
+            zAxis.Position = position;
+            freeAxis.Position = position;
+
+            Quaternion handleRotation = isDragged ? dragStartRotation : Rotation;
+            xAxis.Rotation = handleRotation;
+            yAxis.Rotation = handleRotation;
+            zAxis.Rotation = handleRotation;
+            freeAxis.Rotation = EditorApplication.SceneViewCamera.SceneObject.Rotation;
+
+            xAxis.SetCutoffPlane(GetXStartAngle(isDragged), true);
+            yAxis.SetCutoffPlane(GetYStartAngle(isDragged), true);
+            zAxis.SetCutoffPlane(GetZStartAngle(isDragged), true);
+        }
+
+        /// <inheritdoc/>
+        protected internal override void PostInput()
+        {
+            if (IsDragged())
+            {
+                if (!isDragged)
+                {
+                    isDragged = true;
+                    dragStartRotation = Rotation;
+                }
+            }
+            else
+            {
+                isDragged = false;
+                dragStartRotation = Quaternion.Identity;
+            }
+
+            Degree xValue = 0.0f;
+            Degree yValue = 0.0f;
+            Degree zValue = 0.0f;
+            Degree freeAxisValue = 0.0f;
+
+            if (Handles.RotateHandleSnapActive)
+            {
+                xValue = Handles.SnapValue(xAxis.Delta, Handles.RotateSnapAmount);
+                yValue = Handles.SnapValue(yAxis.Delta, Handles.RotateSnapAmount);
+                zValue = Handles.SnapValue(zAxis.Delta, Handles.RotateSnapAmount);
+                freeAxisValue = Handles.SnapValue(freeAxis.Delta, Handles.RotateSnapAmount);
+            }
+            else
+            {
+                xValue = xAxis.Delta;
+                yValue = yAxis.Delta;
+                zValue = zAxis.Delta;
+                freeAxisValue = freeAxis.Delta;
+            }
+
+            Vector3 cameraForward = -(dragStartRotation.Inverse * EditorApplication.SceneViewCamera.SceneObject.Rotation).Forward;
+
+            delta = Quaternion.FromEuler(xValue, yValue, zValue);
+            delta *= Quaternion.FromAxisAngle(cameraForward, freeAxisValue);
+        }
+
+        /// <inheritdoc/>
+        protected internal override void Draw()
+        {
+            HandleDrawing.Layer = 1;
+            HandleDrawing.Transform = Matrix4.TRS(Position, Rotation, Vector3.One);
+            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
+
+            // Draw arcs
+            if (xAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if(xAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = Color.Red;
+
+            HandleDrawing.DrawWireArc(Vector3.Zero, Vector3.XAxis, 1.0f, GetXStartAngle(false), -180.0f, handleSize);
+
+            if (yAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if (yAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = Color.Green;
+
+            HandleDrawing.DrawWireArc(Vector3.Zero, Vector3.YAxis, 1.0f, GetYStartAngle(false), -180.0f, handleSize);
+
+            if (zAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if (zAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = Color.Blue;
+
+            HandleDrawing.DrawWireArc(Vector3.Zero, Vector3.ZAxis, 1.0f, GetZStartAngle(false), -180.0f, handleSize);
+
+            // Draw "bounds" and free handle
+            Color gray = new Color(1.0f, 1.0f, 1.0f, 0.3f);
+            Vector3 cameraNormal = EditorApplication.SceneViewCamera.SceneObject.Rotation.Rotate(Vector3.ZAxis);
+            HandleDrawing.Transform = Matrix4.TRS(Position, Quaternion.Identity, Vector3.One);
+            HandleDrawing.Color = gray;
+
+            HandleDrawing.DrawWireDisc(cameraNormal * 0.1f, cameraNormal, 1.0f, handleSize);
+
+            if (freeAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if (freeAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = gray;
+
+            HandleDrawing.DrawWireDisc(Vector3.Zero, cameraNormal, 1.2f, handleSize);
+
+            // Draw active rotation pie
+            HandleDrawing.Color = gray;
+            HandleDrawing.Transform = Matrix4.TRS(Position, EditorApplication.SceneViewCamera.SceneObject.Rotation, Vector3.One);
+
+            if (freeAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.DrawArc(Vector3.Zero, -Vector3.ZAxis, 1.2f, freeAxis.StartAngle, freeAxis.Delta, handleSize);
+
+            HandleDrawing.Transform = Matrix4.TRS(Position, dragStartRotation, Vector3.One);
+
+            if (xAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.DrawArc(Vector3.Zero, Vector3.XAxis, 1.0f, xAxis.StartAngle, xAxis.Delta, handleSize);
+            else if (yAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.DrawArc(Vector3.Zero, Vector3.YAxis, 1.0f, yAxis.StartAngle, yAxis.Delta, handleSize);
+            else if (zAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.DrawArc(Vector3.Zero, Vector3.ZAxis, 1.0f, zAxis.StartAngle, zAxis.Delta, handleSize);
+        }
+
+        /// <summary>
+        /// The rotate handle only displays the 180 degree arc facing the camera and this method returns the angle at which 
+        /// the arc starts for the X axis.
+        /// </summary>
+        /// <param name="frozen">Determines should the local handle rotation be taken into account, or should it be frozen
+        ///                      to the value when handle drag started. This is useful because we do not want the visible
+        ///                      arc to change while the user is in the process of rotating the handle.</param>
+        /// <returns>Angle at which to display the visible arc for the X axis rotations.</returns>
+        private Degree GetXStartAngle(bool frozen)
+        {
+            Quaternion handleRotation = frozen ? dragStartRotation : Rotation;
+
+            Vector3 xStartDir = Vector3.Cross(handleRotation.Inverse.Rotate(EditorApplication.SceneViewCamera.SceneObject.Forward), Vector3.XAxis);
+            return PointOnCircleToAngle(Vector3.XAxis, xStartDir);
+        }
+
+        /// <summary>
+        /// The rotate handle only displays the 180 degree arc facing the camera and this method returns the angle at which 
+        /// the arc starts for the Y axis.
+        /// </summary>
+        /// <param name="frozen">Determines should the local handle rotation be taken into account, or should it be frozen
+        ///                      to the value when handle drag started. This is useful because we do not want the visible
+        ///                      arc to change while the user is in the process of rotating the handle.</param>
+        /// <returns>Angle at which to display the visible arc for the Y axis rotations.</returns>
+        private Degree GetYStartAngle(bool frozen)
+        {
+            Quaternion handleRotation = frozen ? dragStartRotation : Rotation;
+
+            Vector3 yStartDir = Vector3.Cross(handleRotation.Inverse.Rotate(EditorApplication.SceneViewCamera.SceneObject.Forward), Vector3.YAxis);
+            return PointOnCircleToAngle(Vector3.YAxis, yStartDir);
+        }
+
+        /// <summary>
+        /// The rotate handle only displays the 180 degree arc facing the camera and this method returns the angle at which 
+        /// the arc starts for the Z axis.
+        /// </summary>
+        /// <param name="frozen">Determines should the local handle rotation be taken into account, or should it be frozen
+        ///                      to the value when handle drag started. This is useful because we do not want the visible
+        ///                      arc to change while the user is in the process of rotating the handle.</param>
+        /// <returns>Angle at which to display the visible arc for the Z axis rotations.</returns>
+        private Degree GetZStartAngle(bool frozen)
+        {
+            Quaternion handleRotation = frozen ? dragStartRotation : Rotation;
+
+            Vector3 zStartDir = Vector3.Cross(handleRotation.Inverse.Rotate(EditorApplication.SceneViewCamera.SceneObject.Forward), Vector3.ZAxis);
+            return PointOnCircleToAngle(Vector3.ZAxis, zStartDir);
+        }
+
+        /// <summary>
+        /// Converts a point on the circle to an angle on the circle.
+        /// </summary>
+        /// <param name="up">Up vector determining the orientation of the circle.</param>
+        /// <param name="point">Point along a unit circle centered around the origin.</param>
+        /// <returns>Angle at which the provided point is located on the circle.</returns>
+        private Degree PointOnCircleToAngle(Vector3 up, Vector3 point)
+        {
+            Quaternion rot = Quaternion.FromToRotation(up, Vector3.YAxis);
+
+            Matrix4 worldToPlane = Matrix4.TRS(Vector3.Zero, rot, Vector3.One);
+            point = worldToPlane.MultiplyDirection(point);
+
+            return (MathEx.Atan2(-point.z, -point.x) + MathEx.Pi) * MathEx.Rad2Deg;
+        }
+    }
+}

+ 183 - 182
MBansheeEditor/Scene/ScaleHandle.cs

@@ -1,182 +1,183 @@
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    /// <summary>
-    /// Handle that allows an object to be scaled along the three primary axes, as well as a free axis currently
-    /// facing the camera.
-    /// </summary>
-    public sealed class ScaleHandle : DefaultHandle
-    {
-        private const float SMALL_CUBE_SIZE = 0.175f;
-        private const float CENTER_CUBE_SIZE = 0.33f;
-
-        private Vector3 delta;
-
-        private HandleSliderLine xAxis;
-        private HandleSliderLine yAxis;
-        private HandleSliderLine zAxis;
-
-        private HandleSliderPlane freeAxis;
-
-        /// <summary>
-        /// Returns the amount of scaling applied since the last frame. Only valid while the handle is being dragged.
-        /// </summary>
-        public Vector3 Delta
-        {
-            get { return delta; }
-        }
-
-        /// <inheritdoc/>
-        internal override bool IsDragged()
-        {
-            return xAxis.State == HandleSlider.StateType.Active ||
-                    yAxis.State == HandleSlider.StateType.Active ||
-                    zAxis.State == HandleSlider.StateType.Active ||
-                    freeAxis.State == HandleSlider.StateType.Active;
-        }
-
-        /// <summary>
-        /// Creates a new scale handle.
-        /// </summary>
-        public ScaleHandle()
-        {
-            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.4f);
-        }
-
-        /// <inheritdoc/>
-        protected internal override void PreInput()
-        {
-            xAxis.Position = position;
-            yAxis.Position = position;
-            zAxis.Position = position;
-
-            xAxis.Rotation = rotation;
-            yAxis.Rotation = rotation;
-            zAxis.Rotation = rotation;
-
-            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
-            Vector3 freeAxisOffset = (Vector3.XAxis * -0.2f + Vector3.YAxis * -0.2f) * handleSize;
-            freeAxis.Rotation = EditorApplication.SceneViewCamera.SceneObject.Rotation;
-            freeAxis.Position = position + freeAxis.Rotation.Rotate(freeAxisOffset);
-        }
-
-        /// <inheritdoc/>
-        protected internal override void PostInput()
-        {
-            delta = Vector3.Zero;
-
-            delta += xAxis.Delta * GetXDir() * 0.1f;
-            delta += yAxis.Delta * GetYDir() * 0.1f;
-            delta += zAxis.Delta * GetZDir() * 0.1f;
-            delta += (freeAxis.Delta.x + freeAxis.Delta.y) * Vector3.One * 0.1f;
-        }
-
-        /// <inheritdoc/>
-        protected internal override void Draw()
-        {
-            HandleDrawing.Transform = Matrix4.TRS(Position, Rotation, Vector3.One);
-            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
-
-            // Draw 1D sliders
-            Vector3 smallCubeExtents = new Vector3(SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f);
-
-            if (xAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if (xAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = Color.Red;
-
-            Vector3 xCubeOffset = Vector3.XAxis * SMALL_CUBE_SIZE * 0.5f;
-            Vector3 xCubeStart = Vector3.XAxis - xCubeOffset;
-            
-            HandleDrawing.DrawLine(Vector3.Zero, xCubeStart, handleSize);
-            HandleDrawing.DrawCube(xCubeStart + xCubeOffset, smallCubeExtents, handleSize);
-
-            if (yAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if (yAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = Color.Green;
-
-            Vector3 yCubeOffset = Vector3.YAxis * SMALL_CUBE_SIZE * 0.5f;
-            Vector3 yCubeStart = Vector3.YAxis - yCubeOffset;
-
-            HandleDrawing.DrawLine(Vector3.Zero, yCubeStart, handleSize);
-            HandleDrawing.DrawCube(yCubeStart + yCubeOffset, smallCubeExtents, handleSize);
-
-            if (zAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if (zAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = Color.Blue;
-
-            Vector3 zCubeOffset = Vector3.ZAxis * SMALL_CUBE_SIZE * 0.5f;
-            Vector3 zCubeStart = Vector3.ZAxis - zCubeOffset;
-
-            HandleDrawing.DrawLine(Vector3.Zero, zCubeStart, handleSize);
-            HandleDrawing.DrawCube(zCubeStart + zCubeOffset, smallCubeExtents, handleSize);
-
-            // Draw free scale handle
-            if (freeAxis.State == HandleSlider.StateType.Active)
-                HandleDrawing.Color = Color.White;
-            else if (freeAxis.State == HandleSlider.StateType.Hover)
-                HandleDrawing.Color = Color.BansheeOrange;
-            else
-                HandleDrawing.Color = 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.2f - Vector3.YAxis * 0.2f;
-            Vector3 topLeft = -Vector3.XAxis * 0.2f + Vector3.YAxis * 0.2f;
-            Vector3 topRight = Vector3.XAxis * 0.2f + Vector3.YAxis * 0.2f;
-            Vector3 bottomRight = Vector3.XAxis * 0.2f - Vector3.YAxis * 0.2f;
-
-            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);
-        }
-
-        /// <summary>
-        /// Returns the direction of the handle's x axis in world space.
-        /// </summary>
-        /// <returns>Direction of the handle's x axis in world space</returns>
-        private Vector3 GetXDir()
-        {
-            return rotation.Rotate(Vector3.XAxis);
-        }
-
-        /// <summary>
-        /// Returns the direction of the handle's y axis in world space.
-        /// </summary>
-        /// <returns>Direction of the handle's y axis in world space</returns>
-        private Vector3 GetYDir()
-        {
-            return rotation.Rotate(Vector3.YAxis);
-        }
-
-        /// <summary>
-        /// Returns the direction of the handle's z axis in world space.
-        /// </summary>
-        /// <returns>Direction of the handle's z axis in world space</returns>
-        private Vector3 GetZDir()
-        {
-            return rotation.Rotate(Vector3.ZAxis);
-        }
-    }
-}
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Handle that allows an object to be scaled along the three primary axes, as well as a free axis currently
+    /// facing the camera.
+    /// </summary>
+    public sealed class ScaleHandle : DefaultHandle
+    {
+        private const float SMALL_CUBE_SIZE = 0.175f;
+        private const float CENTER_CUBE_SIZE = 0.33f;
+
+        private Vector3 delta;
+
+        private HandleSliderLine xAxis;
+        private HandleSliderLine yAxis;
+        private HandleSliderLine zAxis;
+
+        private HandleSliderPlane freeAxis;
+
+        /// <summary>
+        /// Returns the amount of scaling applied since the last frame. Only valid while the handle is being dragged.
+        /// </summary>
+        public Vector3 Delta
+        {
+            get { return delta; }
+        }
+
+        /// <inheritdoc/>
+        internal override bool IsDragged()
+        {
+            return xAxis.State == HandleSlider.StateType.Active ||
+                    yAxis.State == HandleSlider.StateType.Active ||
+                    zAxis.State == HandleSlider.StateType.Active ||
+                    freeAxis.State == HandleSlider.StateType.Active;
+        }
+
+        /// <summary>
+        /// Creates a new scale handle.
+        /// </summary>
+        public ScaleHandle()
+        {
+            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.4f);
+        }
+
+        /// <inheritdoc/>
+        protected internal override void PreInput()
+        {
+            xAxis.Position = position;
+            yAxis.Position = position;
+            zAxis.Position = position;
+
+            xAxis.Rotation = rotation;
+            yAxis.Rotation = rotation;
+            zAxis.Rotation = rotation;
+
+            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
+            Vector3 freeAxisOffset = (Vector3.XAxis * -0.2f + Vector3.YAxis * -0.2f) * handleSize;
+            freeAxis.Rotation = EditorApplication.SceneViewCamera.SceneObject.Rotation;
+            freeAxis.Position = position + freeAxis.Rotation.Rotate(freeAxisOffset);
+        }
+
+        /// <inheritdoc/>
+        protected internal override void PostInput()
+        {
+            delta = Vector3.Zero;
+
+            delta += xAxis.Delta * GetXDir() * 0.1f;
+            delta += yAxis.Delta * GetYDir() * 0.1f;
+            delta += zAxis.Delta * GetZDir() * 0.1f;
+            delta += (freeAxis.Delta.x + freeAxis.Delta.y) * Vector3.One * 0.1f;
+        }
+
+        /// <inheritdoc/>
+        protected internal override void Draw()
+        {
+            HandleDrawing.Layer = 1;
+            HandleDrawing.Transform = Matrix4.TRS(Position, Rotation, Vector3.One);
+            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
+
+            // Draw 1D sliders
+            Vector3 smallCubeExtents = new Vector3(SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f);
+
+            if (xAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if (xAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = Color.Red;
+
+            Vector3 xCubeOffset = Vector3.XAxis * SMALL_CUBE_SIZE * 0.5f;
+            Vector3 xCubeStart = Vector3.XAxis - xCubeOffset;
+            
+            HandleDrawing.DrawLine(Vector3.Zero, xCubeStart, handleSize);
+            HandleDrawing.DrawCube(xCubeStart + xCubeOffset, smallCubeExtents, handleSize);
+
+            if (yAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if (yAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = Color.Green;
+
+            Vector3 yCubeOffset = Vector3.YAxis * SMALL_CUBE_SIZE * 0.5f;
+            Vector3 yCubeStart = Vector3.YAxis - yCubeOffset;
+
+            HandleDrawing.DrawLine(Vector3.Zero, yCubeStart, handleSize);
+            HandleDrawing.DrawCube(yCubeStart + yCubeOffset, smallCubeExtents, handleSize);
+
+            if (zAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if (zAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = Color.Blue;
+
+            Vector3 zCubeOffset = Vector3.ZAxis * SMALL_CUBE_SIZE * 0.5f;
+            Vector3 zCubeStart = Vector3.ZAxis - zCubeOffset;
+
+            HandleDrawing.DrawLine(Vector3.Zero, zCubeStart, handleSize);
+            HandleDrawing.DrawCube(zCubeStart + zCubeOffset, smallCubeExtents, handleSize);
+
+            // Draw free scale handle
+            if (freeAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.Color = Color.White;
+            else if (freeAxis.State == HandleSlider.StateType.Hover)
+                HandleDrawing.Color = Color.BansheeOrange;
+            else
+                HandleDrawing.Color = 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.2f - Vector3.YAxis * 0.2f;
+            Vector3 topLeft = -Vector3.XAxis * 0.2f + Vector3.YAxis * 0.2f;
+            Vector3 topRight = Vector3.XAxis * 0.2f + Vector3.YAxis * 0.2f;
+            Vector3 bottomRight = Vector3.XAxis * 0.2f - Vector3.YAxis * 0.2f;
+
+            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);
+        }
+
+        /// <summary>
+        /// Returns the direction of the handle's x axis in world space.
+        /// </summary>
+        /// <returns>Direction of the handle's x axis in world space</returns>
+        private Vector3 GetXDir()
+        {
+            return rotation.Rotate(Vector3.XAxis);
+        }
+
+        /// <summary>
+        /// Returns the direction of the handle's y axis in world space.
+        /// </summary>
+        /// <returns>Direction of the handle's y axis in world space</returns>
+        private Vector3 GetYDir()
+        {
+            return rotation.Rotate(Vector3.YAxis);
+        }
+
+        /// <summary>
+        /// Returns the direction of the handle's z axis in world space.
+        /// </summary>
+        /// <returns>Direction of the handle's z axis in world space</returns>
+        private Vector3 GetZDir()
+        {
+            return rotation.Rotate(Vector3.ZAxis);
+        }
+    }
+}

+ 8 - 4
MBansheeEditor/Scene/SceneAxesHandle.cs

@@ -8,8 +8,10 @@ namespace BansheeEditor
     /// one of the axes, or change projection modes.
     /// one of the axes, or change projection modes.
     /// </summary>
     /// </summary>
     [CustomHandle(null)]
     [CustomHandle(null)]
-    public class SceneAxesHandle : Handle
+    internal class SceneAxesHandle : Handle
     {
     {
+        public const UInt64 LAYER = 0x7000000000000000;
+
         private const float CONE_HEIGHT = 0.25f;
         private const float CONE_HEIGHT = 0.25f;
         private const float CONE_RADIUS = 0.175f;
         private const float CONE_RADIUS = 0.175f;
 
 
@@ -28,9 +30,9 @@ namespace BansheeEditor
         /// </summary>
         /// </summary>
         public SceneAxesHandle()
         public SceneAxesHandle()
         {
         {
-            xAxis = new HandleSliderLine(this, Vector3.XAxis, 1.0f);
-            yAxis = new HandleSliderLine(this, Vector3.YAxis, 1.0f);
-            zAxis = new HandleSliderLine(this, Vector3.ZAxis, 1.0f);
+            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);
 
 
             projTypePlane = new HandleSliderPlane(this, Vector3.XAxis, Vector3.YAxis, 0.4f);
             projTypePlane = new HandleSliderPlane(this, Vector3.XAxis, Vector3.YAxis, 0.4f);
         }
         }
@@ -99,10 +101,12 @@ namespace BansheeEditor
         /// <inheritdoc/>
         /// <inheritdoc/>
         protected internal override void Draw()
         protected internal override void Draw()
         {
         {
+            HandleDrawing.Layer = LAYER;
             HandleDrawing.Transform = Matrix4.TRS(position, rotation, Vector3.One);
             HandleDrawing.Transform = Matrix4.TRS(position, rotation, Vector3.One);
             Vector3 cameraForward = EditorApplication.SceneViewCamera.SceneObject.Forward;
             Vector3 cameraForward = EditorApplication.SceneViewCamera.SceneObject.Forward;
             float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
             float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
 
 
+           
             // Draw 1D arrows
             // Draw 1D arrows
             Color xColor = Color.Red;
             Color xColor = Color.Red;
             if (xAxis.State == HandleSlider.StateType.Active)
             if (xAxis.State == HandleSlider.StateType.Active)

+ 1 - 0
MBansheeEditor/Scene/SceneWindow.cs

@@ -639,6 +639,7 @@ namespace BansheeEditor
                 camera.NearClipPlane = 0.05f;
                 camera.NearClipPlane = 0.05f;
                 camera.FarClipPlane = 2500.0f;
                 camera.FarClipPlane = 2500.0f;
                 camera.ClearColor = ClearColor;
                 camera.ClearColor = ClearColor;
+		        camera.Layers = UInt64.MaxValue & ~SceneAxesHandle.LAYER; // Don't draw scene axes in this camera
 
 
                 cameraController = sceneCameraSO.AddComponent<SceneCamera>();
                 cameraController = sceneCameraSO.AddComponent<SceneCamera>();
 
 

+ 1 - 0
SBansheeEditor/Include/BsScriptHandleDrawing.h

@@ -23,6 +23,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		static void internal_SetColor(Color* color);
 		static void internal_SetColor(Color* color);
 		static void internal_SetTransform(Matrix4* transform);
 		static void internal_SetTransform(Matrix4* transform);
+		static void internal_SetLayer(UINT64 layer);
 
 
 		static void internal_DrawCube(Vector3* position, Vector3* extents, float size);
 		static void internal_DrawCube(Vector3* position, Vector3* extents, float size);
 		static void internal_DrawSphere(Vector3* position, float radius, float size);
 		static void internal_DrawSphere(Vector3* position, float radius, float size);

+ 2 - 2
SBansheeEditor/Include/BsScriptHandleSliderDisc.h

@@ -28,7 +28,7 @@ namespace BansheeEngine
 		virtual void destroyInternal() override;
 		virtual void destroyInternal() override;
 
 
 	private:
 	private:
-		ScriptHandleSliderDisc(MonoObject* instance, const Vector3& normal, float radius, bool fixedScale);
+		ScriptHandleSliderDisc(MonoObject* instance, const Vector3& normal, float radius, bool fixedScale, UINT64 layer);
 		~ScriptHandleSliderDisc();
 		~ScriptHandleSliderDisc();
 
 
 		HandleSliderDisc* mSlider;
 		HandleSliderDisc* mSlider;
@@ -36,7 +36,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		static void internal_CreateInstance(MonoObject* instance, Vector3* normal, float radius, bool fixedScale);
+		static void internal_CreateInstance(MonoObject* instance, Vector3* normal, float radius, bool fixedScale, UINT64 layer);
 		static void internal_GetDelta(ScriptHandleSliderDisc* nativeInstance, float* value);
 		static void internal_GetDelta(ScriptHandleSliderDisc* nativeInstance, float* value);
 		static void internal_GetStartAngle(ScriptHandleSliderDisc* nativeInstance, float* value);
 		static void internal_GetStartAngle(ScriptHandleSliderDisc* nativeInstance, float* value);
 		static void internal_SetCutoffPlane(ScriptHandleSliderDisc* nativeInstance, float value, bool enabled);
 		static void internal_SetCutoffPlane(ScriptHandleSliderDisc* nativeInstance, float value, bool enabled);

+ 2 - 2
SBansheeEditor/Include/BsScriptHandleSliderLine.h

@@ -28,7 +28,7 @@ namespace BansheeEngine
 		virtual void destroyInternal() override;
 		virtual void destroyInternal() override;
 
 
 	private:
 	private:
-		ScriptHandleSliderLine(MonoObject* instance, const Vector3& direction, float length, bool fixedScale);
+		ScriptHandleSliderLine(MonoObject* instance, const Vector3& direction, float length, bool fixedScale, UINT64 layer);
 		~ScriptHandleSliderLine();
 		~ScriptHandleSliderLine();
 
 
 		HandleSliderLine* mSlider;
 		HandleSliderLine* mSlider;
@@ -36,7 +36,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		static void internal_CreateInstance(MonoObject* instance, Vector3* direction, float length, bool fixedScale);
+		static void internal_CreateInstance(MonoObject* instance, Vector3* direction, float length, bool fixedScale, UINT64 layer);
 		static void internal_GetDelta(ScriptHandleSliderLine* nativeInstance, float* value);
 		static void internal_GetDelta(ScriptHandleSliderLine* nativeInstance, float* value);
 	};
 	};
 }
 }

+ 4 - 2
SBansheeEditor/Include/BsScriptHandleSliderPlane.h

@@ -28,7 +28,8 @@ namespace BansheeEngine
 		virtual void destroyInternal() override;
 		virtual void destroyInternal() override;
 
 
 	private:
 	private:
-		ScriptHandleSliderPlane(MonoObject* instance, const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale);
+		ScriptHandleSliderPlane(MonoObject* instance, const Vector3& dir1, const Vector3& dir2, float length, 
+			bool fixedScale, UINT64 layer);
 		~ScriptHandleSliderPlane();
 		~ScriptHandleSliderPlane();
 
 
 		HandleSliderPlane* mSlider;
 		HandleSliderPlane* mSlider;
@@ -36,7 +37,8 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		static void internal_CreateInstance(MonoObject* instance, Vector3* dir1, Vector3* dir2, float length, bool fixedScale);
+		static void internal_CreateInstance(MonoObject* instance, Vector3* dir1, Vector3* dir2, float length, 
+			bool fixedScale, UINT64 layer);
 		static void internal_GetDelta(ScriptHandleSliderPlane* nativeInstance, Vector2* value);
 		static void internal_GetDelta(ScriptHandleSliderPlane* nativeInstance, Vector2* value);
 	};
 	};
 }
 }

+ 6 - 0
SBansheeEditor/Source/BsScriptHandleDrawing.cpp

@@ -12,6 +12,7 @@ namespace BansheeEngine
 	{
 	{
 		metaData.scriptClass->addInternalCall("Internal_SetColor", &ScriptHandleDrawing::internal_SetColor);
 		metaData.scriptClass->addInternalCall("Internal_SetColor", &ScriptHandleDrawing::internal_SetColor);
 		metaData.scriptClass->addInternalCall("Internal_SetTransform", &ScriptHandleDrawing::internal_SetTransform);
 		metaData.scriptClass->addInternalCall("Internal_SetTransform", &ScriptHandleDrawing::internal_SetTransform);
+		metaData.scriptClass->addInternalCall("Internal_SetLayer", &ScriptHandleDrawing::internal_SetLayer);
 		metaData.scriptClass->addInternalCall("Internal_DrawCube", &ScriptHandleDrawing::internal_DrawCube);
 		metaData.scriptClass->addInternalCall("Internal_DrawCube", &ScriptHandleDrawing::internal_DrawCube);
 		metaData.scriptClass->addInternalCall("Internal_DrawSphere", &ScriptHandleDrawing::internal_DrawSphere);
 		metaData.scriptClass->addInternalCall("Internal_DrawSphere", &ScriptHandleDrawing::internal_DrawSphere);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireCube", &ScriptHandleDrawing::internal_DrawWireCube);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireCube", &ScriptHandleDrawing::internal_DrawWireCube);
@@ -35,6 +36,11 @@ namespace BansheeEngine
 		HandleManager::instance().getDrawManager().setTransform(*transform);
 		HandleManager::instance().getDrawManager().setTransform(*transform);
 	}
 	}
 
 
+	void ScriptHandleDrawing::internal_SetLayer(UINT64 layer)
+	{
+		HandleManager::instance().getDrawManager().setLayer(layer);
+	}
+
 	void ScriptHandleDrawing::internal_DrawCube(Vector3* position, Vector3* extents, float size)
 	void ScriptHandleDrawing::internal_DrawCube(Vector3* position, Vector3* extents, float size)
 	{
 	{
 		HandleManager::instance().getDrawManager().drawCube(*position, *extents, size);
 		HandleManager::instance().getDrawManager().drawCube(*position, *extents, size);

+ 4 - 4
SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp

@@ -6,10 +6,10 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	ScriptHandleSliderDisc::ScriptHandleSliderDisc(MonoObject* instance, const Vector3& normal, float radius, bool fixedScale)
+	ScriptHandleSliderDisc::ScriptHandleSliderDisc(MonoObject* instance, const Vector3& normal, float radius, bool fixedScale, UINT64 layer)
 		:ScriptObject(instance), mSlider(nullptr)
 		:ScriptObject(instance), mSlider(nullptr)
 	{
 	{
-		mSlider = bs_new<HandleSliderDisc>(normal, radius, fixedScale);
+		mSlider = bs_new<HandleSliderDisc>(normal, radius, fixedScale, layer);
 	}
 	}
 
 
 	ScriptHandleSliderDisc::~ScriptHandleSliderDisc()
 	ScriptHandleSliderDisc::~ScriptHandleSliderDisc()
@@ -34,10 +34,10 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetCutoffPlane", &ScriptHandleSliderDisc::internal_SetCutoffPlane);
 		metaData.scriptClass->addInternalCall("Internal_SetCutoffPlane", &ScriptHandleSliderDisc::internal_SetCutoffPlane);
 	}
 	}
 
 
-	void ScriptHandleSliderDisc::internal_CreateInstance(MonoObject* instance, Vector3* normal, float radius, bool fixedScale)
+	void ScriptHandleSliderDisc::internal_CreateInstance(MonoObject* instance, Vector3* normal, float radius, bool fixedScale, UINT64 layer)
 	{
 	{
 		ScriptHandleSliderDisc* nativeInstance = new (bs_alloc<ScriptHandleSliderDisc>())
 		ScriptHandleSliderDisc* nativeInstance = new (bs_alloc<ScriptHandleSliderDisc>())
-			ScriptHandleSliderDisc(instance, *normal, radius, fixedScale);
+			ScriptHandleSliderDisc(instance, *normal, radius, fixedScale, layer);
 	}
 	}
 
 
 	void ScriptHandleSliderDisc::internal_GetDelta(ScriptHandleSliderDisc* nativeInstance, float* value)
 	void ScriptHandleSliderDisc::internal_GetDelta(ScriptHandleSliderDisc* nativeInstance, float* value)

+ 6 - 4
SBansheeEditor/Source/BsScriptHandleSliderLine.cpp

@@ -6,10 +6,11 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	ScriptHandleSliderLine::ScriptHandleSliderLine(MonoObject* instance, const Vector3& direction, float length, bool fixedScale)
+	ScriptHandleSliderLine::ScriptHandleSliderLine(MonoObject* instance, const Vector3& direction, float length, 
+		bool fixedScale, UINT64 layer)
 		:ScriptObject(instance), mSlider(nullptr)
 		:ScriptObject(instance), mSlider(nullptr)
 	{
 	{
-		mSlider = bs_new<HandleSliderLine>(direction, length, fixedScale);
+		mSlider = bs_new<HandleSliderLine>(direction, length, fixedScale, layer);
 	}
 	}
 
 
 	ScriptHandleSliderLine::~ScriptHandleSliderLine()
 	ScriptHandleSliderLine::~ScriptHandleSliderLine()
@@ -32,10 +33,11 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetDelta", &ScriptHandleSliderLine::internal_GetDelta);
 		metaData.scriptClass->addInternalCall("Internal_GetDelta", &ScriptHandleSliderLine::internal_GetDelta);
 	}
 	}
 
 
-	void ScriptHandleSliderLine::internal_CreateInstance(MonoObject* instance, Vector3* direction, float length, bool fixedScale)
+	void ScriptHandleSliderLine::internal_CreateInstance(MonoObject* instance, Vector3* direction, float length, 
+		bool fixedScale, UINT64 layer)
 	{
 	{
 		ScriptHandleSliderLine* nativeInstance = new (bs_alloc<ScriptHandleSliderLine>()) 
 		ScriptHandleSliderLine* nativeInstance = new (bs_alloc<ScriptHandleSliderLine>()) 
-			ScriptHandleSliderLine(instance, *direction, length, fixedScale);
+			ScriptHandleSliderLine(instance, *direction, length, fixedScale, layer);
 	}
 	}
 
 
 	void ScriptHandleSliderLine::internal_GetDelta(ScriptHandleSliderLine* nativeInstance, float* value)
 	void ScriptHandleSliderLine::internal_GetDelta(ScriptHandleSliderLine* nativeInstance, float* value)

+ 6 - 4
SBansheeEditor/Source/BsScriptHandleSliderPlane.cpp

@@ -6,10 +6,11 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	ScriptHandleSliderPlane::ScriptHandleSliderPlane(MonoObject* instance, const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale)
+	ScriptHandleSliderPlane::ScriptHandleSliderPlane(MonoObject* instance, const Vector3& dir1, const Vector3& dir2, 
+		float length, bool fixedScale, UINT64 layer)
 		:ScriptObject(instance), mSlider(nullptr)
 		:ScriptObject(instance), mSlider(nullptr)
 	{
 	{
-		mSlider = bs_new<HandleSliderPlane>(dir1, dir2, length, fixedScale);
+		mSlider = bs_new<HandleSliderPlane>(dir1, dir2, length, fixedScale, layer);
 	}
 	}
 
 
 	ScriptHandleSliderPlane::~ScriptHandleSliderPlane()
 	ScriptHandleSliderPlane::~ScriptHandleSliderPlane()
@@ -32,10 +33,11 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetDelta", &ScriptHandleSliderPlane::internal_GetDelta);
 		metaData.scriptClass->addInternalCall("Internal_GetDelta", &ScriptHandleSliderPlane::internal_GetDelta);
 	}
 	}
 
 
-	void ScriptHandleSliderPlane::internal_CreateInstance(MonoObject* instance, Vector3* dir1, Vector3* dir2, float length, bool fixedScale)
+	void ScriptHandleSliderPlane::internal_CreateInstance(MonoObject* instance, Vector3* dir1, Vector3* dir2, 
+		float length, bool fixedScale, UINT64 layer)
 	{
 	{
 		ScriptHandleSliderPlane* nativeInstance = new (bs_alloc<ScriptHandleSliderPlane>())
 		ScriptHandleSliderPlane* nativeInstance = new (bs_alloc<ScriptHandleSliderPlane>())
-			ScriptHandleSliderPlane(instance, *dir1, *dir2, length, fixedScale);
+			ScriptHandleSliderPlane(instance, *dir1, *dir2, length, fixedScale, layer);
 	}
 	}
 
 
 	void ScriptHandleSliderPlane::internal_GetDelta(ScriptHandleSliderPlane* nativeInstance, Vector2* value)
 	void ScriptHandleSliderPlane::internal_GetDelta(ScriptHandleSliderPlane* nativeInstance, Vector2* value)