Browse Source

Work on handles (WIP)

Marko Pintera 11 years ago
parent
commit
e6275065f4
47 changed files with 1620 additions and 151 deletions
  1. 4 0
      BansheeEditor/BansheeEditor.vcxproj
  2. 18 6
      BansheeEditor/BansheeEditor.vcxproj.filters
  3. 5 0
      BansheeEditor/Include/BsEditorPrerequisites.h
  4. 1 0
      BansheeEditor/Include/BsGizmoManager.h
  5. 78 0
      BansheeEditor/Include/BsHandleDrawManager.h
  6. 12 30
      BansheeEditor/Include/BsHandleManager.h
  7. 16 3
      BansheeEditor/Include/BsHandleSlider.h
  8. 5 1
      BansheeEditor/Include/BsHandleSliderDisc.h
  9. 3 0
      BansheeEditor/Include/BsHandleSliderLine.h
  10. 34 0
      BansheeEditor/Include/BsHandleSliderManager.h
  11. 4 0
      BansheeEditor/Include/BsHandleSliderPlane.h
  12. 6 5
      BansheeEditor/Source/BsGizmoManager.cpp
  13. 205 0
      BansheeEditor/Source/BsHandleDrawManager.cpp
  14. 19 27
      BansheeEditor/Source/BsHandleManager.cpp
  15. 19 1
      BansheeEditor/Source/BsHandleSlider.cpp
  16. 8 4
      BansheeEditor/Source/BsHandleSliderDisc.cpp
  17. 6 3
      BansheeEditor/Source/BsHandleSliderLine.cpp
  18. 76 0
      BansheeEditor/Source/BsHandleSliderManager.cpp
  19. 6 2
      BansheeEditor/Source/BsHandleSliderPlane.cpp
  20. 41 0
      MBansheeEditor/DebugCameraHandle.cs
  21. 8 0
      MBansheeEditor/MBansheeEditor.csproj
  22. 15 0
      MBansheeEditor/Scene/CustomHandle.cs
  23. 112 0
      MBansheeEditor/Scene/HandleDrawing.cs
  24. 92 0
      MBansheeEditor/Scene/HandleSlider.cs
  25. 56 0
      MBansheeEditor/Scene/HandleSliderDisc.cs
  26. 43 0
      MBansheeEditor/Scene/HandleSliderLine.cs
  27. 56 0
      MBansheeEditor/Scene/HandleSliderPlane.cs
  28. 11 0
      MBansheeEditor/Scene/IHandle.cs
  29. 5 0
      MBansheeEngine/Component.cs
  30. 1 0
      MBansheeEngine/MBansheeEngine.csproj
  31. 51 0
      MBansheeEngine/Math/BsRect3.cs
  32. 30 0
      MBansheeEngine/SceneObject.cs
  33. 33 0
      SBansheeEditor/Include/BsScriptHandleDrawing.h
  34. 15 0
      SBansheeEditor/Include/BsScriptHandleManager.h
  35. 36 0
      SBansheeEditor/Include/BsScriptHandleSlider.h
  36. 30 0
      SBansheeEditor/Include/BsScriptHandleSliderDisc.h
  37. 29 0
      SBansheeEditor/Include/BsScriptHandleSliderLine.h
  38. 30 0
      SBansheeEditor/Include/BsScriptHandleSliderPlane.h
  39. 12 0
      SBansheeEditor/SBansheeEditor.vcxproj
  40. 36 0
      SBansheeEditor/SBansheeEditor.vcxproj.filters
  41. 92 0
      SBansheeEditor/Source/BsScriptHandleDrawing.cpp
  42. 33 0
      SBansheeEditor/Source/BsScriptHandleManager.cpp
  43. 64 0
      SBansheeEditor/Source/BsScriptHandleSlider.cpp
  44. 48 0
      SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp
  45. 42 0
      SBansheeEditor/Source/BsScriptHandleSliderLine.cpp
  46. 48 0
      SBansheeEditor/Source/BsScriptHandleSliderPlane.cpp
  47. 26 69
      SceneView.txt

+ 4 - 0
BansheeEditor/BansheeEditor.vcxproj

@@ -291,7 +291,9 @@
     <ClInclude Include="Include\BsGUIToggleField.h" />
     <ClInclude Include="Include\BsGUIVector3Field.h" />
     <ClInclude Include="Include\BsGUIVector4Field.h" />
+    <ClInclude Include="Include\BsHandleDrawManager.h" />
     <ClInclude Include="Include\BsHandleManager.h" />
+    <ClInclude Include="Include\BsHandleSliderManager.h" />
     <ClInclude Include="Include\BsHandleSlider.h" />
     <ClInclude Include="Include\BsHandleSliderDisc.h" />
     <ClInclude Include="Include\BsHandleSliderLine.h" />
@@ -372,7 +374,9 @@
     <ClCompile Include="Source\BsGUIWindowFrame.cpp" />
     <ClCompile Include="Source\BsGUIWindowFrameWidget.cpp" />
     <ClCompile Include="Source\BsGUIWindowDropArea.cpp" />
+    <ClCompile Include="Source\BsHandleDrawManager.cpp" />
     <ClCompile Include="Source\BsHandleManager.cpp" />
+    <ClCompile Include="Source\BsHandleSliderManager.cpp" />
     <ClCompile Include="Source\BsHandleSlider.cpp" />
     <ClCompile Include="Source\BsHandleSliderDisc.cpp" />
     <ClCompile Include="Source\BsHandleSliderLine.cpp" />

+ 18 - 6
BansheeEditor/BansheeEditor.vcxproj.filters

@@ -219,9 +219,6 @@
     <ClInclude Include="Include\BsSelection.h">
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsHandleManager.h">
-      <Filter>Header Files\Editor</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsHandleSliderLine.h">
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
@@ -234,6 +231,15 @@
     <ClInclude Include="Include\BsHandleSliderDisc.h">
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsHandleDrawManager.h">
+      <Filter>Header Files\Editor</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsHandleSliderManager.h">
+      <Filter>Header Files\Editor</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsHandleManager.h">
+      <Filter>Header Files\Editor</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsEditorWidgetContainer.cpp">
@@ -401,9 +407,6 @@
     <ClCompile Include="Source\BsSelection.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsHandleManager.cpp">
-      <Filter>Source Files\Editor</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsHandleSlider.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
@@ -416,5 +419,14 @@
     <ClCompile Include="Source\BsHandleSliderDisc.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsHandleDrawManager.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsHandleSliderManager.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsHandleManager.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 5 - 0
BansheeEditor/Include/BsEditorPrerequisites.h

@@ -57,6 +57,11 @@ namespace BansheeEngine
 	class ProjectResourceMeta;
 	class SceneGrid;
 	class HandleSlider;
+	class HandleSliderLine;
+	class HandleSliderPlane;
+	class HandleSliderDisc;
+	class HandleSliderManager;
+	class HandleDrawManager;
 
 	typedef std::shared_ptr<ProjectResourceMeta> ProjectResourceMetaPtr;
 	typedef std::shared_ptr<DockManagerLayout> DockManagerLayoutPtr;

+ 1 - 0
BansheeEditor/Include/BsGizmoManager.h

@@ -165,6 +165,7 @@ namespace BansheeEngine
 		typedef Set<IconData, std::function<bool(const IconData&, const IconData&)>> IconSet;
 
 		HCamera mCamera;
+		RenderTargetPtr mSceneRenderTarget;
 
 		Color mColor;
 		Matrix4 mTransform;

+ 78 - 0
BansheeEditor/Include/BsHandleDrawManager.h

@@ -0,0 +1,78 @@
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+#include "BsGpuParams.h"
+
+namespace BansheeEngine
+{
+	class BS_ED_EXPORT HandleDrawManager
+	{
+		struct SolidMaterialData
+		{
+			HMaterial material;
+
+			// Core
+			MaterialProxyPtr proxy;
+			GpuParamMat4 mViewProj;
+			GpuParamMat4 mViewIT;
+		};
+
+		struct WireMaterialData
+		{
+			HMaterial material;
+
+			// Core
+			MaterialProxyPtr proxy;
+			GpuParamMat4 mViewProj;
+		};
+
+	public:
+		HandleDrawManager(const HCamera& camera);
+		~HandleDrawManager();
+
+		void setColor(const Color& color);
+		void setTransform(const Matrix4& transform);
+
+		void drawCube(const Vector3& position, const Vector3& extents);
+		void drawSphere(const Vector3& position, float radius);
+		void drawWireCube(const Vector3& position, const Vector3& extents);
+		void drawWireSphere(const Vector3& position, float radius);
+		void drawCone(const Vector3& base, const Vector3& normal, float height, float radius);
+		void drawLine(const Vector3& start, const Vector3& end);
+		void drawDisc(const Vector3& position, const Vector3& normal, float radius);
+		void drawWireDisc(const Vector3& position, const Vector3& normal, float radius);
+		void drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle);
+		void drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle);
+		void drawRect(const Rect3& area);
+
+		void draw();
+
+	private:
+		void coreRender(const CameraProxy& camera);
+		void coreRenderSolid(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr mesh);
+		void coreRenderWire(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr mesh);
+
+		void coreUpdateData(const MeshProxyPtr& solidMeshProxy, const MeshProxyPtr& wireMeshProxy);
+		void initializeCore();
+
+		static const UINT32 SPHERE_QUALITY;
+		static const UINT32 WIRE_SPHERE_QUALITY;
+		static const UINT32 ARC_QUALITY;
+
+		HCamera mCamera;
+		RenderTargetPtr mSceneRenderTarget;
+
+		DrawHelper* mDrawHelper;
+
+		TransientMeshPtr mSolidMesh;
+		TransientMeshPtr mWireMesh;
+
+		// Immutable
+		SolidMaterialData mSolidMaterial;
+		WireMaterialData mWireMaterial;
+
+		// Core
+		MeshProxyPtr mSolidMeshProxy;
+		MeshProxyPtr mWireMeshProxy;
+	};
+}

+ 12 - 30
BansheeEditor/Include/BsHandleManager.h

@@ -2,46 +2,28 @@
 
 #include "BsEditorPrerequisites.h"
 #include "BsModule.h"
-#include "BsCapsule.h"
-#include "BsSphere.h"
-#include "BsRect3.h"
-#include "BsTorus.h"
 
 namespace BansheeEngine
 {
 	class BS_ED_EXPORT HandleManager : public Module<HandleManager>
 	{
 	public:
-		// TODO - Add a bunch of draw methods similar to GizmoManager
-		//      - And a similar render method
+		HandleManager();
+		virtual ~HandleManager();
 
-		void setColor(const Color& color);
-		void setTransform(const Matrix4& transform);
+		void update(const Vector2I& inputPos, const Ray& inputRay, const Matrix4& viewMatrix, bool pressed);
 
-		void drawCube(const Vector3& position, const Vector3& extents);
-		void drawSphere(const Vector3& position, float radius);
-		void drawWireCube(const Vector3& position, const Vector3& extents);
-		void drawWireSphere(const Vector3& position, float radius);
-		void drawCone(const Vector3& base, const Vector3& normal, float height, float radius);
-		void drawLine(const Vector3& start, const Vector3& end);
-		void drawDisc(const Vector3& position, const Vector3& normal, float radius);
-		void drawWireDisc(const Vector3& position, const Vector3& normal, float radius);
-		void drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle);
-		void drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle);
+		HandleSliderManager& getSliderManager() const { return *mSliderManager; }
+		HandleDrawManager& getDrawManager() const { return *mDrawManager; }
 
-		// TODO - Add update method that handles mouse input
+		bool isHandleActive() const;
 
-		void _registerCapsuleCollider(const Capsule& collider, HandleSlider* slider);
-		void _registerSphereCollider(const Sphere& collider, HandleSlider* slider);
-		void _registerRectCollider(const Rect3& collider, HandleSlider* slider);
-		void _registerTorusCollider(const Torus& collider, HandleSlider* slider);
-		void _unregisterSlider(HandleSlider* slider);
-	private:
-		UnorderedSet<HandleSlider*> mSliders;
+	protected:
+		HandleSliderManager* mSliderManager;
+		HandleDrawManager* mDrawManager;
 
-		UnorderedMap<HandleSlider*, Capsule> mCapsuleColliders;
-		UnorderedMap<HandleSlider*, Sphere> mSphereColliders;
-		UnorderedMap<HandleSlider*, Rect3> mRectColliders;
-		UnorderedMap<HandleSlider*, Torus> mTorusColliders;
+		virtual void refreshHandles() = 0;
+		virtual void triggerHandles() = 0;
+		virtual void queueDrawCommands() = 0;
 	};
 }

+ 16 - 3
BansheeEditor/Include/BsHandleSlider.h

@@ -3,6 +3,7 @@
 #include "BsEditorPrerequisites.h"
 #include "BsVector2I.h"
 #include "BsMatrix4.h"
+#include "BsQuaternion.h"
 
 namespace BansheeEngine
 {
@@ -23,8 +24,15 @@ namespace BansheeEngine
 		bool getFixedScale() const { return mFixedScale; }
 		float getSnapValue() const { return mSnapValue; }
 
-		virtual void setCustomTransform(const Matrix4& transform) { mCustomTransform = transform; }
-		virtual const Matrix4& getCustomTransform() const { return mCustomTransform; }
+		void setPosition(const Vector3& position);
+		void setRotation(const Quaternion& rotation);
+		void setScale(const Vector3& scale);
+
+		const Vector3& getPosition() const { return mPosition; }
+		const Quaternion& getRotation() const { return mRotation; }
+		const Vector3& getScale() const { return mScale; }
+
+		virtual const Matrix4& getTransform() const { return mTransform; }
 
 	protected:
 		friend class HandleManager;
@@ -36,7 +44,12 @@ namespace BansheeEngine
 
 		bool mFixedScale;
 		float mSnapValue;
-		Matrix4 mCustomTransform;
+
+		Vector3 mPosition;
+		Quaternion mRotation;
+		Vector3 mScale;
+
+		Matrix4 mTransform;
 
 		Vector2I mLastPointerPos;
 		Vector2I mCurPointerPos;

+ 5 - 1
BansheeEditor/Include/BsHandleSliderDisc.h

@@ -13,7 +13,11 @@ namespace BansheeEngine
 
 		Quaternion updateDelta(const Quaternion& oldValue) const;
 
-		void setCustomTransform(const Matrix4& transform);
+		float getDelta() const { return 0.0f; /* TODO */ }
+		Vector3 getDeltaDirection() const { return Vector3::ZERO; /* TODO */ }
+		Quaternion getNewRotation() const { return mRotation; /* TODO */ }
+
+		virtual const Matrix4& getTransform() const;
 	protected:
 		static const float TORUS_RADIUS;
 

+ 3 - 0
BansheeEditor/Include/BsHandleSliderLine.h

@@ -13,6 +13,9 @@ namespace BansheeEngine
 
 		Vector3 updateDelta(const Vector3& oldValue) const;
 
+		float getDelta() const { return 0.0f; /* TODO */ }
+		Vector3 getNewPosition() const { return mPosition; /* TODO */ }
+
 	protected:
 		static const float CAPSULE_RADIUS;
 		static const float SPHERE_RADIUS;

+ 34 - 0
BansheeEditor/Include/BsHandleSliderManager.h

@@ -0,0 +1,34 @@
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+#include "BsCapsule.h"
+#include "BsSphere.h"
+#include "BsRect3.h"
+#include "BsTorus.h"
+
+namespace BansheeEngine
+{
+	class BS_ED_EXPORT HandleSliderManager
+	{
+	public:
+		HandleSliderManager();
+		~HandleSliderManager();
+
+		void update(const Vector2I& inputPos, const Ray& inputRay, const Matrix4& viewMatrix, bool pressed);
+		bool isSliderActive() const;
+
+		void _registerCapsuleCollider(const Capsule& collider, HandleSlider* slider);
+		void _registerSphereCollider(const Sphere& collider, HandleSlider* slider);
+		void _registerRectCollider(const Rect3& collider, HandleSlider* slider);
+		void _registerTorusCollider(const Torus& collider, HandleSlider* slider);
+		void _unregisterSlider(HandleSlider* slider);
+
+	private:
+		UnorderedSet<HandleSlider*> mSliders;
+
+		UnorderedMap<HandleSlider*, Capsule> mCapsuleColliders;
+		UnorderedMap<HandleSlider*, Sphere> mSphereColliders;
+		UnorderedMap<HandleSlider*, Rect3> mRectColliders;
+		UnorderedMap<HandleSlider*, Torus> mTorusColliders;
+	};
+}

+ 4 - 0
BansheeEditor/Include/BsHandleSliderPlane.h

@@ -13,6 +13,10 @@ namespace BansheeEngine
 
 		Vector3 updateDelta(const Vector3& oldValue) const;
 
+		float getDelta() const { return 0.0f; /* TODO */ }
+		Vector3 getDeltaDirection() const { return Vector3::ZERO; /* TODO */ }
+		Vector3 getNewPosition() const { return mPosition; /* TODO */ }
+
 	protected:
 		Vector3 mDirection1;
 		Vector3 mDirection2;

+ 6 - 5
BansheeEditor/Source/BsGizmoManager.cpp

@@ -31,8 +31,10 @@ namespace BansheeEngine
 	const float GizmoManager::PICKING_ALPHA_CUTOFF = 0.5f;
 
 	GizmoManager::GizmoManager(const HCamera& camera)
-		:mCamera(camera), mPickable(false)
+		:mCamera(camera), mPickable(false), mDrawHelper(nullptr), mPickingDrawHelper(nullptr)
 	{
+		mSceneRenderTarget = mCamera->getViewport()->getTarget();
+
 		mDrawHelper = bs_new<DrawHelper>();
 		mPickingDrawHelper = bs_new<DrawHelper>();
 
@@ -614,12 +616,11 @@ namespace BansheeEngine
 
 	void GizmoManager::coreRender(const CameraProxy& camera)
 	{
-		RenderTargetPtr sceneRenderTarget = mCamera->getViewport()->getTarget();
-		if (camera.viewport.getTarget() != sceneRenderTarget)
+		if (camera.viewport.getTarget() != mSceneRenderTarget)
 			return;
 
-		float width = (float)sceneRenderTarget->getCore()->getProperties().getWidth();
-		float height = (float)sceneRenderTarget->getCore()->getProperties().getHeight();
+		float width = (float)mSceneRenderTarget->getCore()->getProperties().getWidth();
+		float height = (float)mSceneRenderTarget->getCore()->getProperties().getHeight();
 
 		Rect2 normArea = camera.viewport.getNormArea();
 

+ 205 - 0
BansheeEditor/Source/BsHandleDrawManager.cpp

@@ -0,0 +1,205 @@
+#include "BsHandleDrawManager.h"
+#include "BsDrawHelper.h"
+#include "BsMaterial.h"
+#include "BsBuiltinEditorResources.h"
+#include "BsCoreThread.h"
+#include "BsRendererManager.h"
+#include "BsRenderer.h"
+#include "BsTransientMesh.h"
+#include "BsCamera.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(const HCamera& camera)
+		:mCamera(camera)
+	{
+		mSceneRenderTarget = mCamera->getViewport()->getTarget();
+		mDrawHelper = bs_new<DrawHelper>();
+
+		mSolidMaterial.material = BuiltinEditorResources::instance().createSolidGizmoMat();
+		mWireMaterial.material = BuiltinEditorResources::instance().createWireGizmoMat();
+
+		mSolidMaterial.proxy = mSolidMaterial.material->_createProxy();
+		mWireMaterial.proxy = mWireMaterial.material->_createProxy();
+
+		gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::initializeCore, this));
+	}
+
+	HandleDrawManager::~HandleDrawManager()
+	{
+		bs_delete(mDrawHelper);
+
+		if (mSolidMesh != nullptr)
+			mDrawHelper->releaseSolidMesh(mSolidMesh);
+
+		if (mWireMesh != nullptr)
+			mDrawHelper->releaseWireMesh(mWireMesh);
+	}
+
+	void HandleDrawManager::initializeCore()
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		// TODO - Make a better interface when dealing with parameters through proxies?
+		{
+			MaterialProxyPtr proxy = mWireMaterial.proxy;
+			GpuParamsPtr vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
+
+			vertParams->getParam("matViewProj", mWireMaterial.mViewProj);
+		}
+
+		{
+			MaterialProxyPtr proxy = mSolidMaterial.proxy;
+			GpuParamsPtr vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
+
+			vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
+			vertParams->getParam("matViewIT", mSolidMaterial.mViewIT);
+		}
+
+		RendererPtr activeRenderer = RendererManager::instance().getActive();
+		activeRenderer->onCorePostRenderViewport.connect(std::bind(&HandleDrawManager::coreRender, this, _1));
+	}
+
+	void HandleDrawManager::setColor(const Color& color)
+	{
+		mDrawHelper->setColor(color);
+	}
+
+	void HandleDrawManager::setTransform(const Matrix4& transform)
+	{
+		mDrawHelper->setTransform(transform);
+	}
+
+	void HandleDrawManager::drawCube(const Vector3& position, const Vector3& extents)
+	{
+		mDrawHelper->cube(position, extents);
+	}
+
+	void HandleDrawManager::drawSphere(const Vector3& position, float radius)
+	{
+		mDrawHelper->sphere(position, radius);
+	}
+
+	void HandleDrawManager::drawWireCube(const Vector3& position, const Vector3& extents)
+	{
+		mDrawHelper->wireCube(position, extents);
+	}
+
+	void HandleDrawManager::drawWireSphere(const Vector3& position, float radius)
+	{
+		mDrawHelper->wireSphere(position, radius);
+	}
+
+	void HandleDrawManager::drawCone(const Vector3& base, const Vector3& normal, float height, float radius)
+	{
+		mDrawHelper->cone(base, normal, height, radius);
+	}
+
+	void HandleDrawManager::drawLine(const Vector3& start, const Vector3& end)
+	{
+		mDrawHelper->line(start, end);
+	}
+
+	void HandleDrawManager::drawDisc(const Vector3& position, const Vector3& normal, float radius)
+	{
+		mDrawHelper->disc(position, normal, radius);
+	}
+
+	void HandleDrawManager::drawWireDisc(const Vector3& position, const Vector3& normal, float radius)
+	{
+		mDrawHelper->wireDisc(position, normal, radius);
+	}
+
+	void HandleDrawManager::drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle)
+	{
+		mDrawHelper->arc(position, normal, radius, startAngle, amountAngle);
+	}
+
+	void HandleDrawManager::drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle)
+	{
+		mDrawHelper->wireArc(position, normal, radius, startAngle, amountAngle);
+	}
+
+	void HandleDrawManager::drawRect(const Rect3& area)
+	{
+		mDrawHelper->rectangle(area);
+	}
+
+	void HandleDrawManager::draw()
+	{
+		if (mSolidMesh != nullptr)
+			mDrawHelper->releaseSolidMesh(mSolidMesh);
+
+		if (mWireMesh != nullptr)
+			mDrawHelper->releaseWireMesh(mWireMesh);
+
+		mSolidMesh = mDrawHelper->buildSolidMesh();
+		mWireMesh = mDrawHelper->buildWireMesh();
+
+		MeshProxyPtr solidMeshProxy = mSolidMesh->_createProxy(0);
+		MeshProxyPtr wireMeshProxy = mWireMesh->_createProxy(0);
+
+		gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::coreUpdateData, this, solidMeshProxy, wireMeshProxy));
+
+		mDrawHelper->clear();
+	}
+
+	void HandleDrawManager::coreUpdateData(const MeshProxyPtr& solidMeshProxy, const MeshProxyPtr& wireMeshProxy)
+	{
+		mSolidMeshProxy = solidMeshProxy;
+		mWireMeshProxy = wireMeshProxy;
+	}
+
+	void HandleDrawManager::coreRender(const CameraProxy& camera)
+	{
+		if (camera.viewport.getTarget() != mSceneRenderTarget)
+			return;
+
+		float width = (float)mSceneRenderTarget->getCore()->getProperties().getWidth();
+		float height = (float)mSceneRenderTarget->getCore()->getProperties().getHeight();
+
+		Rect2 normArea = camera.viewport.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);
+
+		coreRenderSolid(camera.viewMatrix, camera.projMatrix, mSolidMeshProxy);
+		coreRenderWire(camera.viewMatrix, camera.projMatrix, mWireMeshProxy);
+	}
+
+	void HandleDrawManager::coreRenderSolid(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr meshProxy)
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		Matrix4 viewProjMat = projMatrix * viewMatrix;
+		Matrix4 viewIT = viewMatrix.inverse().transpose();
+
+		mSolidMaterial.mViewProj.set(viewProjMat);
+		mSolidMaterial.mViewIT.set(viewIT);
+
+		Renderer::setPass(*mSolidMaterial.proxy, 0);
+		Renderer::draw(*meshProxy);
+	}
+
+	void HandleDrawManager::coreRenderWire(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr meshProxy)
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		Matrix4 viewProjMat = projMatrix * viewMatrix;
+		Matrix4 viewIT = viewMatrix.inverse().transpose();
+
+		mWireMaterial.mViewProj.set(viewProjMat);
+
+		Renderer::setPass(*mWireMaterial.proxy, 0);
+		Renderer::draw(*meshProxy);
+	}
+}

+ 19 - 27
BansheeEditor/Source/BsHandleManager.cpp

@@ -1,45 +1,37 @@
 #include "BsHandleManager.h"
+#include "BsHandleDrawManager.h"
+#include "BsHandleSliderManager.h"
 
 namespace BansheeEngine
 {
-	void HandleManager::_registerCapsuleCollider(const Capsule& collider, HandleSlider* slider)
+	HandleManager::HandleManager()
+		:mSliderManager(nullptr), mDrawManager(nullptr)
 	{
-		if (mSliders.find(slider) == mSliders.end())
-			mSliders.insert(slider);
-
-		mCapsuleColliders[slider] = collider;
+		mSliderManager = bs_new<HandleSliderManager>();
+		mDrawManager = bs_new<HandleDrawManager>();
 	}
 
-	void HandleManager::_registerSphereCollider(const Sphere& collider, HandleSlider* slider)
+	HandleManager::~HandleManager()
 	{
-		if (mSliders.find(slider) == mSliders.end())
-			mSliders.insert(slider);
-
-		mSphereColliders[slider] = collider;
+		bs_delete(mSliderManager);
+		bs_delete(mDrawManager);
 	}
 
-	void HandleManager::_registerRectCollider(const Rect3& collider, HandleSlider* slider)
+	bool HandleManager::isHandleActive() const
 	{
-		if (mSliders.find(slider) == mSliders.end())
-			mSliders.insert(slider);
-
-		mRectColliders[slider] = collider;
+		return mSliderManager->isSliderActive();
 	}
 
-	void HandleManager::_registerTorusCollider(const Torus& collider, HandleSlider* slider)
+	void HandleManager::update(const Vector2I& inputPos, const Ray& inputRay, const Matrix4& viewMatrix, bool pressed)
 	{
-		if (mSliders.find(slider) == mSliders.end())
-			mSliders.insert(slider);
+		refreshHandles();
 
-		mTorusColliders[slider] = collider;
-	}
+		mSliderManager->update(inputPos, inputRay, viewMatrix, pressed);
 
-	void HandleManager::_unregisterSlider(HandleSlider* slider)
-	{
-		mCapsuleColliders.erase(slider);
-		mSphereColliders.erase(slider);
-		mRectColliders.erase(slider);
-		mTorusColliders.erase(slider);
-		mSliders.erase(slider);
+		triggerHandles();
+
+		queueDrawCommands();
+
+		mDrawManager->draw();
 	}
 }

+ 19 - 1
BansheeEditor/Source/BsHandleSlider.cpp

@@ -3,9 +3,27 @@
 namespace BansheeEngine
 {
 	HandleSlider::HandleSlider(bool fixedScale, float snapValue)
-		:mFixedScale(fixedScale), mSnapValue(snapValue)
+		:mFixedScale(fixedScale), mSnapValue(snapValue), mScale(Vector3::ONE)
 	{
+		mTransform.setTRS(mPosition, mRotation, mScale);
+	}
+
+	void HandleSlider::setPosition(const Vector3& position)
+	{
+		mPosition = position;
+		mTransform.setTRS(mPosition, mRotation, mScale);
+	}
 
+	void HandleSlider::setRotation(const Quaternion& rotation)
+	{
+		mRotation = rotation;
+		mTransform.setTRS(mPosition, mRotation, mScale);
+	}
+
+	void HandleSlider::setScale(const Vector3& scale)
+	{
+		mScale = scale;
+		mTransform.setTRS(mPosition, mRotation, mScale);
 	}
 
 	void HandleSlider::registerDrag(const Vector2I& pointerPos)

+ 8 - 4
BansheeEditor/Source/BsHandleSliderDisc.cpp

@@ -1,5 +1,6 @@
 #include "BsHandleSliderDisc.h"
 #include "BsHandleManager.h"
+#include "BsHandleSliderManager.h"
 #include "BsTorus.h"
 #include "BsVector3.h"
 #include "BsQuaternion.h"
@@ -17,12 +18,15 @@ namespace BansheeEngine
 		mTorusRotation = (Matrix4)Matrix3(x, mNormal, z); // Our Torus class doesn't allow us to specify a normal so we embed it here
 
 		Torus collider(radius, TORUS_RADIUS);
-		HandleManager::instance()._registerTorusCollider(collider, this);
+
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._registerTorusCollider(collider, this);
 	}
 
 	HandleSliderDisc::~HandleSliderDisc()
 	{
-		HandleManager::instance()._unregisterSlider(this);
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._unregisterSlider(this);
 	}
 
 	Quaternion HandleSliderDisc::updateDelta(const Quaternion& oldValue) const
@@ -33,8 +37,8 @@ namespace BansheeEngine
 		// - Both position and direction need to consider it
 	}
 
-	void HandleSliderDisc::setCustomTransform(const Matrix4& transform)
+	const Matrix4& HandleSliderDisc::getTransform() const
 	{
-		HandleSlider::setCustomTransform(transform * mTorusRotation);
+		return mTransform * mTorusRotation;
 	}
 }

+ 6 - 3
BansheeEditor/Source/BsHandleSliderLine.cpp

@@ -1,5 +1,6 @@
 #include "BsHandleSliderLine.h"
 #include "BsHandleManager.h"
+#include "BsHandleSliderManager.h"
 #include "BsCapsule.h"
 #include "BsLineSegment3.h"
 #include "BsSphere.h"
@@ -19,13 +20,15 @@ namespace BansheeEngine
 
 		Vector3 sphereCenter = start + mDirection * std::max(0.0f, length - SPHERE_RADIUS * 2);
 
-		HandleManager::instance()._registerCapsuleCollider(Capsule(LineSegment3(start, end), CAPSULE_RADIUS), this);
-		HandleManager::instance()._registerSphereCollider(Sphere(sphereCenter, SPHERE_RADIUS), this);
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._registerCapsuleCollider(Capsule(LineSegment3(start, end), CAPSULE_RADIUS), this);
+		sliderManager._registerSphereCollider(Sphere(sphereCenter, SPHERE_RADIUS), this);
 	}
 
 	HandleSliderLine::~HandleSliderLine()
 	{
-		HandleManager::instance()._unregisterSlider(this);
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._unregisterSlider(this);
 	}
 
 	Vector3 HandleSliderLine::updateDelta(const Vector3& oldValue) const

+ 76 - 0
BansheeEditor/Source/BsHandleSliderManager.cpp

@@ -0,0 +1,76 @@
+#include "BsHandleSliderManager.h"
+#include "BsDrawHelper.h"
+#include "BsMaterial.h"
+#include "BsBuiltinEditorResources.h"
+#include "BsCoreThread.h"
+#include "BsRendererManager.h"
+#include "BsRenderer.h"
+#include "BsTransientMesh.h"
+#include "BsCamera.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	HandleSliderManager::HandleSliderManager()
+	{
+
+	}
+
+	HandleSliderManager::~HandleSliderManager()
+	{
+
+	}
+
+	void HandleSliderManager::update(const Vector2I& inputPos, const Ray& inputRay, const Matrix4& viewMatrix, bool pressed)
+	{
+		// TODO - Handle mouse input
+		//  - Detect active and hover sliders
+	}
+
+	bool HandleSliderManager::isSliderActive() const
+	{
+		// TODO - Return true if we are dragging any slider
+	}
+
+	void HandleSliderManager::_registerCapsuleCollider(const Capsule& collider, HandleSlider* slider)
+	{
+		if (mSliders.find(slider) == mSliders.end())
+			mSliders.insert(slider);
+
+		mCapsuleColliders[slider] = collider;
+	}
+
+	void HandleSliderManager::_registerSphereCollider(const Sphere& collider, HandleSlider* slider)
+	{
+		if (mSliders.find(slider) == mSliders.end())
+			mSliders.insert(slider);
+
+		mSphereColliders[slider] = collider;
+	}
+
+	void HandleSliderManager::_registerRectCollider(const Rect3& collider, HandleSlider* slider)
+	{
+		if (mSliders.find(slider) == mSliders.end())
+			mSliders.insert(slider);
+
+		mRectColliders[slider] = collider;
+	}
+
+	void HandleSliderManager::_registerTorusCollider(const Torus& collider, HandleSlider* slider)
+	{
+		if (mSliders.find(slider) == mSliders.end())
+			mSliders.insert(slider);
+
+		mTorusColliders[slider] = collider;
+	}
+
+	void HandleSliderManager::_unregisterSlider(HandleSlider* slider)
+	{
+		mCapsuleColliders.erase(slider);
+		mSphereColliders.erase(slider);
+		mRectColliders.erase(slider);
+		mTorusColliders.erase(slider);
+		mSliders.erase(slider);
+	}
+}

+ 6 - 2
BansheeEditor/Source/BsHandleSliderPlane.cpp

@@ -1,5 +1,6 @@
 #include "BsHandleSliderPlane.h"
 #include "BsHandleManager.h"
+#include "BsHandleSliderManager.h"
 #include "BsRect3.h"
 #include "BsVector3.h"
 
@@ -15,12 +16,15 @@ namespace BansheeEngine
 		std::array<float, 2> extents = { length, length };
 
 		Rect3 collider(Vector3::ZERO, axes, extents);
-		HandleManager::instance()._registerRectCollider(collider, this);
+
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._registerRectCollider(collider, this);
 	}
 
 	HandleSliderPlane::~HandleSliderPlane()
 	{
-		HandleManager::instance()._unregisterSlider(this);
+		HandleSliderManager& sliderManager = HandleManager::instance().getSliderManager();
+		sliderManager._unregisterSlider(this);
 	}
 
 	Vector3 HandleSliderPlane::updateDelta(const Vector3& oldValue) const

+ 41 - 0
MBansheeEditor/DebugCameraHandle.cs

@@ -0,0 +1,41 @@
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    [CustomHandle(typeof(Component))]
+    public class DebugCameraHandle : IHandle
+    {
+        private Component target;
+        private HandleSliderLine xAxis;
+
+        public DebugCameraHandle(Component target)
+        {
+            this.target = target;
+
+            xAxis = new HandleSliderLine(Vector3.xAxis, 5.0f);
+        }
+
+        protected override void Update()
+        {
+            xAxis.Position = target.sceneObject.position;
+        }
+
+        protected override void Response()
+        {
+            target.sceneObject.position = xAxis.NewPosition;
+        }
+
+        protected override void Draw()
+        {
+            Vector3 end = target.sceneObject.position + Vector3.xAxis * 5;
+
+            if (xAxis.State == HandleSlider.StateType.Active)
+                HandleDrawing.SetColor(Color.white);
+            else
+                HandleDrawing.SetColor(Color.green);
+            
+            HandleDrawing.DrawLine(target.sceneObject.position, end);
+        }
+    }
+}

+ 8 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -42,6 +42,7 @@
     <Compile Include="DbgCustomInspector.cs" />
     <Compile Include="DbgEditorWindow.cs" />
     <Compile Include="DbgResource.cs" />
+    <Compile Include="DebugCameraHandle.cs" />
     <Compile Include="Debug_Component1.cs" />
     <Compile Include="Debug_Component2.cs" />
     <Compile Include="EditorApplication.cs" />
@@ -81,8 +82,15 @@
     <Compile Include="Program.cs" />
     <Compile Include="ProjectLibrary.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Scene\CustomHandle.cs" />
     <Compile Include="Scene\DrawGizmo.cs" />
     <Compile Include="Scene\Gizmos.cs" />
+    <Compile Include="Scene\HandleDrawing.cs" />
+    <Compile Include="Scene\HandleSlider.cs" />
+    <Compile Include="Scene\HandleSliderDisc.cs" />
+    <Compile Include="Scene\HandleSliderLine.cs" />
+    <Compile Include="Scene\HandleSliderPlane.cs" />
+    <Compile Include="Scene\IHandle.cs" />
     <Compile Include="Selection.cs" />
   </ItemGroup>
   <ItemGroup>

+ 15 - 0
MBansheeEditor/Scene/CustomHandle.cs

@@ -0,0 +1,15 @@
+using System;
+
+namespace BansheeEditor
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public sealed class CustomHandle : Attribute
+    {
+        private Type type;
+
+        public CustomHandle(Type type)
+        {
+            this.type = type;
+        }
+    }
+}

+ 112 - 0
MBansheeEditor/Scene/HandleDrawing.cs

@@ -0,0 +1,112 @@
+using System.Runtime.CompilerServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public sealed class HandleDrawing
+    {
+        public static void SetColor(Color color)
+        {
+            Internal_SetColor(color);    
+        }
+
+        public static void SetTransform(Matrix4 transform)
+        {
+            Internal_SetTransform(transform);
+        }
+
+        public static void DrawCube(Vector3 position, Vector3 extents)
+        {
+            Internal_DrawCube(position, extents);
+        }
+
+        public static void DrawSphere(Vector3 position, float radius)
+        {
+            Internal_DrawSphere(position, radius);
+        }
+
+        public static void DrawWireCube(Vector3 position, Vector3 extents)
+        {
+            Internal_DrawWireCube(position, extents);
+        }
+
+        public static void DrawWireSphere(Vector3 position, float radius)
+        {
+            Internal_DrawWireSphere(position, radius);
+        }
+
+        public static void DrawCone(Vector3 coneBase, Vector3 normal, float height, float radius)
+        {
+            Internal_DrawCone(coneBase, normal, height, radius);
+        }
+
+        public static void DrawLine(Vector3 start, Vector3 end)
+        {
+            Internal_DrawLine(start, end);
+        }
+
+        public static void DrawDisc(Vector3 position, Vector3 normal, float radius)
+        {
+            Internal_DrawDisc(position, normal, radius);
+        }
+
+        public static void DrawWireDisc(Vector3 position, Vector3 normal, float radius)
+        {
+            Internal_DrawWireDisc(position, normal, radius);
+        }
+
+        public static void DrawArc(Vector3 position, Vector3 normal, float radius, Degree startAngle, Degree amountAngle)
+        {
+            Internal_DrawArc(position, normal, radius, startAngle, amountAngle);
+        }
+
+        public static void DrawWireArc(Vector3 position, Vector3 normal, float radius, Degree startAngle, Degree amountAngle)
+        {
+            Internal_DrawWireArc(position, normal, radius, startAngle, amountAngle);
+        }
+
+        public static void DrawRect(Rect3 area)
+        {
+            Internal_DrawRect(area);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetColor(Color color);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetTransform(Matrix4 transform);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawCube(Vector3 position, Vector3 extents);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawSphere(Vector3 position, float radius);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawWireCube(Vector3 position, Vector3 extents);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawWireSphere(Vector3 position, float radius);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawCone(Vector3 coneBase, Vector3 normal, float height, float radius);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawLine(Vector3 start, Vector3 end);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawDisc(Vector3 position, Vector3 normal, float radius);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawWireDisc(Vector3 position, Vector3 normal, float radius);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawArc(Vector3 position, Vector3 normal, float radius, Degree startAngle, Degree amountAngle);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawWireArc(Vector3 position, Vector3 normal, float radius, Degree startAngle, Degree amountAngle);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawRect(Rect3 area);
+    }
+}

+ 92 - 0
MBansheeEditor/Scene/HandleSlider.cs

@@ -0,0 +1,92 @@
+using System;
+using System.Runtime.CompilerServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public class HandleSlider : ScriptObject
+    {
+        public enum StateType
+        {
+	        Inactive,
+	        Active,
+	        Hover
+        };
+
+        public Vector3 Position
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetPosition(mCachedPtr, out value);
+                return value;
+            }
+
+            set
+            {
+                Internal_SetPosition(mCachedPtr, value);
+            }
+        }
+
+        public Quaternion Rotation
+        {
+            get
+            {
+                Quaternion value;
+                Internal_GetRotation(mCachedPtr, out value);
+                return value;
+            }
+
+            set
+            {
+                Internal_SetRotation(mCachedPtr, value);
+            }
+        }
+
+        public Vector3 Scale
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetScale(mCachedPtr, out value);
+                return value;
+            }
+
+            set
+            {
+                Internal_SetScale(mCachedPtr, value);
+            }
+        }
+
+        public StateType State
+        {
+            get
+            {
+                StateType value;
+                Internal_GetState(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetPosition(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetPosition(IntPtr nativeInstance, Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetRotation(IntPtr nativeInstance, out Quaternion value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetRotation(IntPtr nativeInstance, Quaternion value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetScale(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetScale(IntPtr nativeInstance, Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetState(IntPtr nativeInstance, out StateType value);
+    }
+}

+ 56 - 0
MBansheeEditor/Scene/HandleSliderDisc.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Runtime.CompilerServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public class HandleSliderDisc : HandleSlider
+    {
+        public HandleSliderDisc(Vector3 normal, float radius, bool fixedScale = true, float snapValue = 0.0f)
+        {
+            Internal_CreateInstance(this, normal, radius, fixedScale, snapValue);
+        }
+
+        public float Delta
+        {
+            get
+            {
+                float value;
+                Internal_GetDelta(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        public Vector3 DeltaDirection
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetDeltaDirection(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        public Quaternion NewRotation
+        {
+            get
+            {
+                Quaternion value;
+                Internal_GetNewRotation(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateInstance(HandleSliderDisc instance, Vector3 normal, float radius, bool fixedScale, float snapValue);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetDelta(IntPtr nativeInstance, out float value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetDeltaDirection(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetNewRotation(IntPtr nativeInstance, out Quaternion value);
+    }
+}

+ 43 - 0
MBansheeEditor/Scene/HandleSliderLine.cs

@@ -0,0 +1,43 @@
+using System;
+using System.Runtime.CompilerServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public class HandleSliderLine : HandleSlider
+    {
+        public HandleSliderLine(Vector3 direction, float length,  bool fixedScale = true, float snapValue = 0.0f)
+        {
+            Internal_CreateInstance(this, direction, length, fixedScale, snapValue);
+        }
+
+        public float Delta
+        {
+            get
+            {
+                float value;
+                Internal_GetDelta(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        public Vector3 NewPosition
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetNewPosition(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateInstance(HandleSliderLine instance, Vector3 direction, float length, bool fixedScale, float snapValue);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetDelta(IntPtr nativeInstance, out float value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetNewPosition(IntPtr nativeInstance, out Vector3 value);
+    }
+}

+ 56 - 0
MBansheeEditor/Scene/HandleSliderPlane.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Runtime.CompilerServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public class HandleSliderPlane : HandleSlider
+    {
+        public HandleSliderPlane(Vector3 dir1, Vector3 dir2, float length, bool fixedScale = true, float snapValue = 0.0f)
+        {
+            Internal_CreateInstance(this, dir1, dir2, length, fixedScale, snapValue);
+        }
+
+        public float Delta
+        {
+            get
+            {
+                float value;
+                Internal_GetDelta(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        public Vector3 DeltaDirection
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetDeltaDirection(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        public Vector3 NewPosition
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetNewPosition(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateInstance(HandleSliderPlane instance, Vector3 dir1, Vector3 dir2, float length, bool fixedScale, float snapValue);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetDelta(IntPtr nativeInstance, out float value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetDeltaDirection(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetNewPosition(IntPtr nativeInstance, out Vector3 value);
+    }
+}

+ 11 - 0
MBansheeEditor/Scene/IHandle.cs

@@ -0,0 +1,11 @@
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public abstract class IHandle
+    {
+        protected abstract void Update();
+        protected abstract void Response();
+        protected abstract void Draw();
+    }
+}

+ 5 - 0
MBansheeEngine/Component.cs

@@ -9,6 +9,11 @@ namespace BansheeEngine
         protected Component()
         { }
 
+        public SceneObject sceneObject
+        {
+            get { throw new NotImplementedException(); }
+        }
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal static extern Component Internal_AddComponent(SceneObject parent, Type type);
 

+ 1 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -77,6 +77,7 @@
     <Compile Include="HideInInspector.cs" />
     <Compile Include="LocString.cs" />
     <Compile Include="ManagedResource.cs" />
+    <Compile Include="Math\BsRect3.cs" />
     <Compile Include="Math\Degree.cs" />
     <Compile Include="Math\MathEx.cs" />
     <Compile Include="Math\Matrix3.cs" />

+ 51 - 0
MBansheeEngine/Math/BsRect3.cs

@@ -0,0 +1,51 @@
+using System.Runtime.InteropServices;
+
+namespace BansheeEngine
+{
+    [StructLayout(LayoutKind.Sequential), SerializeObject]
+	public class Rect3
+	{
+        public Rect3(Vector3 center, Vector3[] axes, float[] extents)
+        {
+            this.center = center;
+            this.axes[0] = axes[0];
+            this.axes[1] = axes[1];
+            this.extents[0] = extents[0];
+            this.extents[1] = extents[1];
+        }
+
+        public Vector3 Center
+        {
+            get { return center; }
+            set { center = value; }
+        }
+
+        public Vector3 AxisHorz
+        {
+            get { return axes[0]; }
+            set { axes[0] = value; }
+        }
+
+        public Vector3 AxisVert
+        {
+            get { return axes[1]; }
+            set { axes[1] = value; }
+        }
+
+        public float ExtentHorz
+        {
+            get { return extents[0]; }
+            set { extents[0] = value; }
+        }
+
+        public float ExtentVert
+        {
+            get { return extents[1]; }
+            set { extents[1] = value; }
+        }
+
+		private Vector3 center;
+        private Vector3[] axes = new Vector3[2];
+        private float[] extents = new float[2];
+	};
+}

+ 30 - 0
MBansheeEngine/SceneObject.cs

@@ -12,6 +12,36 @@ namespace BansheeEngine
             get { return Internal_GetParent(mCachedPtr); }
         }
 
+        public Vector3 position
+        {
+            set { throw new NotImplementedException(); }
+            get { throw new NotImplementedException(); }
+        }
+
+        public Vector3 localPosition
+        {
+            set { throw new NotImplementedException(); }
+            get { throw new NotImplementedException(); }
+        }
+
+        public Quaternion rotation
+        {
+            set { throw new NotImplementedException(); }
+            get { throw new NotImplementedException(); }
+        }
+
+        public Quaternion localRotation
+        {
+            set { throw new NotImplementedException(); }
+            get { throw new NotImplementedException(); }
+        }
+
+        public Vector3 scale
+        {
+            set { throw new NotImplementedException(); }
+            get { throw new NotImplementedException(); }
+        }
+
         // For internal use
         private SceneObject()
         {

+ 33 - 0
SBansheeEditor/Include/BsScriptHandleDrawing.h

@@ -0,0 +1,33 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsVector3.h"
+#include "BsMatrix4.h"
+#include "BsRect3.h"
+#include "BsColor.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptHandleDrawing : public ScriptObject <ScriptHandleDrawing>
+	{
+	public:
+		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "HandleDrawing")
+
+	private:
+		static void internal_SetColor(Color color);
+		static void internal_SetTransform(Matrix4 transform);
+
+		static void internal_DrawCube(Vector3 position, Vector3 extents);
+		static void internal_DrawSphere(Vector3 position, float radius);
+		static void internal_DrawWireCube(Vector3 position, Vector3 extents);
+		static void internal_DrawWireSphere(Vector3 position, float radius);
+		static void internal_DrawLine(Vector3 start, Vector3 end);
+		static void internal_DrawCone(Vector3 coneBase, Vector3 normal, float height, float radius);
+		static void internal_DrawDisc(Vector3 position, Vector3 normal, float radius);
+		static void internal_DrawWireDisc(Vector3 position, Vector3 normal, float radius);
+		static void internal_DrawArc(Vector3 position, Vector3 normal, float radius, Degree startAngle, Degree amountAngle);
+		static void internal_DrawWireArc(Vector3 position, Vector3 normal, float radius, Degree startAngle, Degree amountAngle);
+		static void internal_DrawRect(Rect3 area);
+	};
+}

+ 15 - 0
SBansheeEditor/Include/BsScriptHandleManager.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsHandleManager.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptHandleManager : public HandleManager
+	{
+	protected:
+		void refreshHandles();
+		void triggerHandles();
+		void queueDrawCommands();
+	};
+}

+ 36 - 0
SBansheeEditor/Include/BsScriptHandleSlider.h

@@ -0,0 +1,36 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsHandleSlider.h"
+#include "BsQuaternion.h"
+#include "BsVector3.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptHandleSliderBase : public ScriptObjectBase
+	{
+	public:
+		ScriptHandleSliderBase(MonoObject* managedInstance);
+		virtual ~ScriptHandleSliderBase() {}
+
+		virtual HandleSlider* getSlider() const = 0;
+	};
+
+	class BS_SCR_BED_EXPORT ScriptHandleSlider : public ScriptObject <ScriptHandleSlider>
+	{
+	public:
+		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "HandleSlider")
+
+	private:
+		static void internal_GetPosition(ScriptHandleSliderBase* nativeInstance, Vector3* value);
+		static void internal_SetPosition(ScriptHandleSliderBase* nativeInstance, Vector3 value);
+		static void internal_GetRotation(ScriptHandleSliderBase* nativeInstance, Quaternion* value);
+		static void internal_SetRotation(ScriptHandleSliderBase* nativeInstance, Quaternion value);
+		static void internal_GetScale(ScriptHandleSliderBase* nativeInstance, Vector3* value);
+		static void internal_SetScale(ScriptHandleSliderBase* nativeInstance, Vector3 value);
+		static void internal_GetState(ScriptHandleSliderBase* nativeInstance, HandleSlider::State* value);
+
+		ScriptHandleSlider(MonoObject* instance);
+	};
+}

+ 30 - 0
SBansheeEditor/Include/BsScriptHandleSliderDisc.h

@@ -0,0 +1,30 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsScriptHandleSlider.h"
+#include "BsHandleSliderDisc.h"
+#include "BsVector3.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptHandleSliderDisc : public ScriptObject <ScriptHandleSliderDisc, ScriptHandleSliderBase>
+	{
+	public:
+		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "HandleSliderDisc")
+
+	protected:
+		virtual HandleSlider* getSlider() const { return mSlider; }
+
+	private:
+		static void internal_CreateInstance(MonoObject* instance, Vector3 normal, float radius, bool fixedScale, float snapValue);
+		static void internal_GetDelta(ScriptHandleSliderDisc* nativeInstance, float* value);
+		static void internal_GetDeltaDirection(ScriptHandleSliderDisc* nativeInstance, Vector3* value);
+		static void internal_GetNewRotation(ScriptHandleSliderDisc* nativeInstance, Quaternion* value);
+
+		ScriptHandleSliderDisc(MonoObject* instance, const Vector3& normal, float radius, bool fixedScale, float snapValue);
+		~ScriptHandleSliderDisc();
+
+		HandleSliderDisc* mSlider;
+	};
+}

+ 29 - 0
SBansheeEditor/Include/BsScriptHandleSliderLine.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsScriptHandleSlider.h"
+#include "BsHandleSliderLine.h"
+#include "BsVector3.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptHandleSliderLine : public ScriptObject <ScriptHandleSliderLine, ScriptHandleSliderBase>
+	{
+	public:
+		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "HandleSliderLine")
+
+	protected:
+		virtual HandleSlider* getSlider() const { return mSlider; }
+
+	private:
+		static void internal_CreateInstance(MonoObject* instance, Vector3 direction, float length, bool fixedScale, float snapValue);
+		static void internal_GetDelta(ScriptHandleSliderLine* nativeInstance, float* value);
+		static void internal_GetNewPosition(ScriptHandleSliderLine* nativeInstance, Vector3* value);
+
+		ScriptHandleSliderLine(MonoObject* instance, const Vector3& direction, float length, bool fixedScale, float snapValue);
+		~ScriptHandleSliderLine();
+
+		HandleSliderLine* mSlider;
+	};
+}

+ 30 - 0
SBansheeEditor/Include/BsScriptHandleSliderPlane.h

@@ -0,0 +1,30 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsScriptHandleSlider.h"
+#include "BsHandleSliderPlane.h"
+#include "BsVector3.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptHandleSliderPlane : public ScriptObject <ScriptHandleSliderPlane, ScriptHandleSliderBase>
+	{
+	public:
+		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "HandleSliderPlane")
+
+	protected:
+		virtual HandleSlider* getSlider() const { return mSlider; }
+
+	private:
+		static void internal_CreateInstance(MonoObject* instance, Vector3 dir1, Vector3 dir2, float length, bool fixedScale, float snapValue);
+		static void internal_GetDelta(ScriptHandleSliderPlane* nativeInstance, float* value);
+		static void internal_GetDeltaDirection(ScriptHandleSliderPlane* nativeInstance, Vector3* value);
+		static void internal_GetNewPosition(ScriptHandleSliderPlane* nativeInstance, Vector3* value);
+
+		ScriptHandleSliderPlane(MonoObject* instance, const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale, float snapValue);
+		~ScriptHandleSliderPlane();
+
+		HandleSliderPlane* mSlider;
+	};
+}

+ 12 - 0
SBansheeEditor/SBansheeEditor.vcxproj

@@ -247,6 +247,12 @@
     <ClInclude Include="Include\BsScriptGUIVector2Field.h" />
     <ClInclude Include="Include\BsScriptGUIVector3Field.h" />
     <ClInclude Include="Include\BsScriptGUIVector4Field.h" />
+    <ClInclude Include="Include\BsScriptHandleSliderDisc.h" />
+    <ClInclude Include="Include\BsScriptHandleDrawing.h" />
+    <ClInclude Include="Include\BsScriptHandleManager.h" />
+    <ClInclude Include="Include\BsScriptHandleSlider.h" />
+    <ClInclude Include="Include\BsScriptHandleSliderLine.h" />
+    <ClInclude Include="Include\BsScriptHandleSliderPlane.h" />
     <ClInclude Include="Include\BsScriptProjectLibrary.h" />
     <ClInclude Include="Include\BsScriptSelection.h" />
   </ItemGroup>
@@ -272,6 +278,12 @@
     <ClCompile Include="Source\BsScriptGUIVector2Field.cpp" />
     <ClCompile Include="Source\BsScriptGUIVector3Field.cpp" />
     <ClCompile Include="Source\BsScriptGUIVector4Field.cpp" />
+    <ClCompile Include="Source\BsScriptHandleDrawing.cpp" />
+    <ClCompile Include="Source\BsScriptHandleManager.cpp" />
+    <ClCompile Include="Source\BsScriptHandleSlider.cpp" />
+    <ClCompile Include="Source\BsScriptHandleSliderDisc.cpp" />
+    <ClCompile Include="Source\BsScriptHandleSliderLine.cpp" />
+    <ClCompile Include="Source\BsScriptHandleSliderPlane.cpp" />
     <ClCompile Include="Source\BsScriptProjectLibrary.cpp" />
     <ClCompile Include="Source\BsScriptSelection.cpp" />
   </ItemGroup>

+ 36 - 0
SBansheeEditor/SBansheeEditor.vcxproj.filters

@@ -84,6 +84,24 @@
     <ClInclude Include="Include\BsScriptSelection.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptHandleManager.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptHandleDrawing.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptHandleSlider.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptHandleSliderLine.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptHandleSliderPlane.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptHandleSliderDisc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
@@ -155,5 +173,23 @@
     <ClCompile Include="Source\BsScriptSelection.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptHandleManager.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptHandleDrawing.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptHandleSlider.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptHandleSliderLine.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptHandleSliderPlane.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptHandleSliderDisc.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 92 - 0
SBansheeEditor/Source/BsScriptHandleDrawing.cpp

@@ -0,0 +1,92 @@
+#include "BsScriptHandleDrawing.h"
+#include "BsScriptMeta.h"
+#include "BsMonoClass.h"
+#include "BsScriptSpriteTexture.h"
+#include "BsSpriteTexture.h"
+#include "BsHandleManager.h"
+#include "BsHandleDrawManager.h"
+
+namespace BansheeEngine
+{
+	void ScriptHandleDrawing::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_SetColor", &ScriptHandleDrawing::internal_SetColor);
+		metaData.scriptClass->addInternalCall("Internal_SetTransform", &ScriptHandleDrawing::internal_SetTransform);
+		metaData.scriptClass->addInternalCall("Internal_DrawCube", &ScriptHandleDrawing::internal_DrawCube);
+		metaData.scriptClass->addInternalCall("Internal_DrawSphere", &ScriptHandleDrawing::internal_DrawSphere);
+		metaData.scriptClass->addInternalCall("Internal_DrawWireCube", &ScriptHandleDrawing::internal_DrawWireCube);
+		metaData.scriptClass->addInternalCall("Internal_DrawWireSphere", &ScriptHandleDrawing::internal_DrawWireSphere);
+		metaData.scriptClass->addInternalCall("Internal_DrawLine", &ScriptHandleDrawing::internal_DrawLine);
+		metaData.scriptClass->addInternalCall("Internal_DrawCone", &ScriptHandleDrawing::internal_DrawCone);
+		metaData.scriptClass->addInternalCall("Internal_DrawDisc", &ScriptHandleDrawing::internal_DrawDisc);
+		metaData.scriptClass->addInternalCall("Internal_DrawWireDisc", &ScriptHandleDrawing::internal_DrawWireDisc);
+		metaData.scriptClass->addInternalCall("Internal_DrawArc", &ScriptHandleDrawing::internal_DrawArc);
+		metaData.scriptClass->addInternalCall("Internal_DrawWireArc", &ScriptHandleDrawing::internal_DrawWireArc);
+		metaData.scriptClass->addInternalCall("Internal_DrawRect", &ScriptHandleDrawing::internal_DrawRect);
+	}
+
+	void ScriptHandleDrawing::internal_SetColor(Color color)
+	{
+		HandleManager::instance().getDrawManager().setColor(color);
+	}
+
+	void ScriptHandleDrawing::internal_SetTransform(Matrix4 transform)
+	{
+		HandleManager::instance().getDrawManager().setTransform(transform);
+	}
+
+	void ScriptHandleDrawing::internal_DrawCube(Vector3 position, Vector3 extents)
+	{
+		HandleManager::instance().getDrawManager().drawCube(position, extents);
+	}
+
+	void ScriptHandleDrawing::internal_DrawSphere(Vector3 position, float radius)
+	{
+		HandleManager::instance().getDrawManager().drawSphere(position, radius);
+	}
+
+	void ScriptHandleDrawing::internal_DrawWireCube(Vector3 position, Vector3 extents)
+	{
+		HandleManager::instance().getDrawManager().drawWireCube(position, extents);
+	}
+
+	void ScriptHandleDrawing::internal_DrawWireSphere(Vector3 position, float radius)
+	{
+		HandleManager::instance().getDrawManager().drawWireSphere(position, radius);
+	}
+
+	void ScriptHandleDrawing::internal_DrawLine(Vector3 start, Vector3 end)
+	{
+		HandleManager::instance().getDrawManager().drawLine(start, end);
+	}
+
+	void ScriptHandleDrawing::internal_DrawCone(Vector3 coneBase, Vector3 normal, float height, float radius)
+	{
+		HandleManager::instance().getDrawManager().drawCone(coneBase, normal, height, radius);
+	}
+
+	void ScriptHandleDrawing::internal_DrawDisc(Vector3 position, Vector3 normal, float radius)
+	{
+		HandleManager::instance().getDrawManager().drawDisc(position, normal, radius);
+	}
+
+	void ScriptHandleDrawing::internal_DrawWireDisc(Vector3 position, Vector3 normal, float radius)
+	{
+		HandleManager::instance().getDrawManager().drawWireDisc(position, normal, radius);
+	}
+
+	void ScriptHandleDrawing::internal_DrawArc(Vector3 position, Vector3 normal, float radius, Degree startAngle, Degree amountAngle)
+	{
+		HandleManager::instance().getDrawManager().drawArc(position, normal, radius, startAngle, amountAngle);
+	}
+
+	void ScriptHandleDrawing::internal_DrawWireArc(Vector3 position, Vector3 normal, float radius, Degree startAngle, Degree amountAngle)
+	{
+		HandleManager::instance().getDrawManager().drawWireArc(position, normal, radius, startAngle, amountAngle);
+	}
+
+	void ScriptHandleDrawing::internal_DrawRect(Rect3 area)
+	{
+		HandleManager::instance().getDrawManager().drawRect(area);
+	}
+}

+ 33 - 0
SBansheeEditor/Source/BsScriptHandleManager.cpp

@@ -0,0 +1,33 @@
+#include "BsScriptHandleManager.h"
+
+namespace BansheeEngine
+{
+	// TODO - Query a list of all IHandle implementations and the types they are activated on
+	//  - Make sure the list can be refreshed on assembly reload
+
+	// TODO - Keep a list of every active ScriptSlider* type
+
+	void ScriptHandleManager::refreshHandles()
+	{
+		// TODO - Query Selection class to detect new and removed items from selection
+		//  - Create and destroy IHandle implementations accordingly
+		//    - Query new selection for a list of their components and create new handles appropriately
+
+		// TODO - Also handle creation of default move/rotate/scale handles
+
+		// TODO - Call Update() method on all active IHandle implementations
+
+		// TODO - Update matrices of all active sliders from their corresponding SOs
+		//   - Need to add a new field to SliderHandle for such matrix
+	}
+
+	void ScriptHandleManager::triggerHandles()
+	{
+		// TODO - See if any sliders are active and if so, trigger their callbacks
+	}
+
+	void ScriptHandleManager::queueDrawCommands()
+	{
+		// TODO - Call Draw methods of all active IHandle implementations
+	}
+}

+ 64 - 0
SBansheeEditor/Source/BsScriptHandleSlider.cpp

@@ -0,0 +1,64 @@
+#include "BsScriptHandleSlider.h"
+#include "BsScriptMeta.h"
+#include "BsMonoClass.h"
+
+namespace BansheeEngine
+{
+	ScriptHandleSliderBase::ScriptHandleSliderBase(MonoObject* managedInstance)
+		:ScriptObjectBase(managedInstance)
+	{
+
+	}
+
+	ScriptHandleSlider::ScriptHandleSlider(MonoObject* instance)
+		:ScriptObject(instance)
+	{
+
+	}
+
+	void ScriptHandleSlider::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_GetPosition", &ScriptHandleSlider::internal_GetPosition);
+		metaData.scriptClass->addInternalCall("Internal_SetPosition", &ScriptHandleSlider::internal_SetPosition);
+		metaData.scriptClass->addInternalCall("Internal_GetRotation", &ScriptHandleSlider::internal_GetRotation);
+		metaData.scriptClass->addInternalCall("Internal_SetRotation", &ScriptHandleSlider::internal_SetRotation);
+		metaData.scriptClass->addInternalCall("Internal_SetScale", &ScriptHandleSlider::internal_SetScale);
+		metaData.scriptClass->addInternalCall("Internal_GetScale", &ScriptHandleSlider::internal_GetScale);
+		metaData.scriptClass->addInternalCall("Internal_GetState", &ScriptHandleSlider::internal_GetState);
+	}
+
+	void ScriptHandleSlider::internal_GetPosition(ScriptHandleSliderBase* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->getSlider()->getPosition();
+	}
+
+	void ScriptHandleSlider::internal_SetPosition(ScriptHandleSliderBase* nativeInstance, Vector3 value)
+	{
+		nativeInstance->getSlider()->setPosition(value);
+	}
+
+	void ScriptHandleSlider::internal_GetRotation(ScriptHandleSliderBase* nativeInstance, Quaternion* value)
+	{
+		*value = nativeInstance->getSlider()->getRotation();
+	}
+
+	void ScriptHandleSlider::internal_SetRotation(ScriptHandleSliderBase* nativeInstance, Quaternion value)
+	{
+		nativeInstance->getSlider()->setRotation(value);
+	}
+
+	void ScriptHandleSlider::internal_GetScale(ScriptHandleSliderBase* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->getSlider()->getScale();
+	}
+
+	void ScriptHandleSlider::internal_SetScale(ScriptHandleSliderBase* nativeInstance, Vector3 value)
+	{
+		nativeInstance->getSlider()->setScale(value);
+	}
+
+	void ScriptHandleSlider::internal_GetState(ScriptHandleSliderBase* nativeInstance, HandleSlider::State* value)
+	{
+		*value = nativeInstance->getSlider()->getState();
+	}
+}

+ 48 - 0
SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp

@@ -0,0 +1,48 @@
+#include "BsScriptHandleSliderDisc.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+
+namespace BansheeEngine
+{
+	ScriptHandleSliderDisc::ScriptHandleSliderDisc(MonoObject* instance, const Vector3& normal, float radius, bool fixedScale, float snapValue)
+		:ScriptObject(instance), mSlider(nullptr)
+	{
+		mSlider = bs_new<HandleSliderDisc>(normal, radius, fixedScale, snapValue);
+	}
+
+	ScriptHandleSliderDisc::~ScriptHandleSliderDisc()
+	{
+		bs_delete(mSlider);
+	}
+
+	void ScriptHandleSliderDisc::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("internal_CreateInstance", &ScriptHandleSliderDisc::internal_CreateInstance);
+		metaData.scriptClass->addInternalCall("internal_GetDelta", &ScriptHandleSliderDisc::internal_GetDelta);
+		metaData.scriptClass->addInternalCall("internal_GetDeltaDirection", &ScriptHandleSliderDisc::internal_GetDeltaDirection);
+		metaData.scriptClass->addInternalCall("internal_GetNewRotation", &ScriptHandleSliderDisc::internal_GetNewRotation);
+	}
+
+	void ScriptHandleSliderDisc::internal_CreateInstance(MonoObject* instance, Vector3 normal, float radius, bool fixedScale, float snapValue)
+	{
+		ScriptHandleSliderDisc* nativeInstance = new (bs_alloc<ScriptHandleSliderDisc>())
+			ScriptHandleSliderDisc(instance, normal, radius, fixedScale, snapValue);
+	}
+
+	void ScriptHandleSliderDisc::internal_GetDelta(ScriptHandleSliderDisc* nativeInstance, float* value)
+	{
+		*value = nativeInstance->mSlider->getDelta();
+	}
+
+	void ScriptHandleSliderDisc::internal_GetDeltaDirection(ScriptHandleSliderDisc* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->mSlider->getDeltaDirection();
+	}
+
+	void ScriptHandleSliderDisc::internal_GetNewRotation(ScriptHandleSliderDisc* nativeInstance, Quaternion* value)
+	{
+		*value = nativeInstance->mSlider->getNewRotation();
+	}
+}

+ 42 - 0
SBansheeEditor/Source/BsScriptHandleSliderLine.cpp

@@ -0,0 +1,42 @@
+#include "BsScriptHandleSliderLine.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+
+namespace BansheeEngine
+{
+	ScriptHandleSliderLine::ScriptHandleSliderLine(MonoObject* instance, const Vector3& direction, float length, bool fixedScale, float snapValue)
+		:ScriptObject(instance), mSlider(nullptr)
+	{
+		mSlider = bs_new<HandleSliderLine>(direction, length, fixedScale, snapValue);
+	}
+
+	ScriptHandleSliderLine::~ScriptHandleSliderLine()
+	{
+		bs_delete(mSlider);
+	}
+
+	void ScriptHandleSliderLine::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("internal_CreateInstance", &ScriptHandleSliderLine::internal_CreateInstance);
+		metaData.scriptClass->addInternalCall("internal_GetDelta", &ScriptHandleSliderLine::internal_GetDelta);
+		metaData.scriptClass->addInternalCall("internal_GetNewPosition", &ScriptHandleSliderLine::internal_GetNewPosition);
+	}
+
+	void ScriptHandleSliderLine::internal_CreateInstance(MonoObject* instance, Vector3 direction, float length, bool fixedScale, float snapValue)
+	{
+		ScriptHandleSliderLine* nativeInstance = new (bs_alloc<ScriptHandleSliderLine>()) 
+			ScriptHandleSliderLine(instance, direction, length, fixedScale, snapValue);
+	}
+
+	void ScriptHandleSliderLine::internal_GetDelta(ScriptHandleSliderLine* nativeInstance, float* value)
+	{
+		*value = nativeInstance->mSlider->getDelta();
+	}
+
+	void ScriptHandleSliderLine::internal_GetNewPosition(ScriptHandleSliderLine* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->mSlider->getNewPosition();
+	}
+}

+ 48 - 0
SBansheeEditor/Source/BsScriptHandleSliderPlane.cpp

@@ -0,0 +1,48 @@
+#include "BsScriptHandleSliderPlane.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+
+namespace BansheeEngine
+{
+	ScriptHandleSliderPlane::ScriptHandleSliderPlane(MonoObject* instance, const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale, float snapValue)
+		:ScriptObject(instance), mSlider(nullptr)
+	{
+		mSlider = bs_new<HandleSliderPlane>(dir1, dir2, length, fixedScale, snapValue);
+	}
+
+	ScriptHandleSliderPlane::~ScriptHandleSliderPlane()
+	{
+		bs_delete(mSlider);
+	}
+
+	void ScriptHandleSliderPlane::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("internal_CreateInstance", &ScriptHandleSliderPlane::internal_CreateInstance);
+		metaData.scriptClass->addInternalCall("internal_GetDelta", &ScriptHandleSliderPlane::internal_GetDelta);
+		metaData.scriptClass->addInternalCall("internal_GetDeltaDirection", &ScriptHandleSliderPlane::internal_GetDeltaDirection);
+		metaData.scriptClass->addInternalCall("internal_GetNewPosition", &ScriptHandleSliderPlane::internal_GetNewPosition);
+	}
+
+	void ScriptHandleSliderPlane::internal_CreateInstance(MonoObject* instance, Vector3 dir1, Vector3 dir2, float length, bool fixedScale, float snapValue)
+	{
+		ScriptHandleSliderPlane* nativeInstance = new (bs_alloc<ScriptHandleSliderPlane>())
+			ScriptHandleSliderPlane(instance, dir1, dir2, length, fixedScale, snapValue);
+	}
+
+	void ScriptHandleSliderPlane::internal_GetDelta(ScriptHandleSliderPlane* nativeInstance, float* value)
+	{
+		*value = nativeInstance->mSlider->getDelta();
+	}
+
+	void ScriptHandleSliderPlane::internal_GetDeltaDirection(ScriptHandleSliderPlane* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->mSlider->getDeltaDirection();
+	}
+
+	void ScriptHandleSliderPlane::internal_GetNewPosition(ScriptHandleSliderPlane* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->mSlider->getNewPosition();
+	}
+}

+ 26 - 69
SceneView.txt

@@ -2,15 +2,7 @@
 TODO:
  - Core thread gets stuck on shutdown when OpenGL is used...Somewhere in kernel
 
-Add a DrawHelper class that handles drawing all of ShapeMeshes types.
- -It should be called by both GizmoManager and HandleManager
- - Internally it will have two buffers (wire and solid)
- - You can add new objects to it similar to GizmoManager (using structs per object type)
- - And you can build the mesh from those objects, or clear current data
-
 CONCRETE TASK:
- - Similar to how I have onRenderViewport callback in Renderer have another one that gets triggered from core thread
-   - Hook up gizmo rendering there
  - Hook up gizmo manager to ScenePicking so gizmos are considered when picking
    - I'll likely need to update GizmoManager so I can query gizmo SceneObject based on gizmo index
  - Selection/ScenePicking/GizmoManager need to be started
@@ -19,12 +11,9 @@ IMMEDIATE:
  - SceneGrid is very ugly. Consider using default lines for now and come back with a better approach later.
    - Potentially enable line AA?
  - Picking code is completely untested and will likely need major fixing
- - Disable DX9 for editor as I will likely want to use geometry shaders for icon rendering, and possibly new AA line shader
-   - Or just use MeshHeap and update the icon/lines every frame?
  - Test all the new DrawHelper3D methods
 
  GIZMO TODO:
-  - IMPORTANT: Gizmo rendering happens in update() but it should happen whenever scene view is being rendered as the render target isn't set anywhere
   - Figure out how to deal with builtin components like Camera and Renderable (e.g. how will they have gizmos since they're not managed components?)
 
 LATER:
@@ -51,40 +40,37 @@ SliderDisc - position, normal, radius
   - Outputs a single float
   - A torus is used as a collider
 
-Handles are always the same size regardless of the distance from camera. (Use same code as from gizmo rendering?)
-These three types can be used for creating MoveHandle, RotationHandle, ScaleHandle
-
-In C# user can call Handles class for managing handles
- - It will allow you to draw various handle shapes, similar to gizmo drawing (unify that code? - probably not initially)
-   - e.g. DrawCone, DrawSphere, DrawWireDisc, etc.
- - Including more complex ones like DrawArrow and similar
- - Using the same class user can also set up Sliders which don't have a visible representation
- - AND finally user can also set up combined premade handles like FreeMove which sets up all sliders and draw methods needed automatically
-
-SliderLine, SliderPlane, SliderDisc will all be separate classes in C# and C++
- - They need to have a matrix and color property you can modify on the go 
- - As well a specific properties like length/size/radius (possibly others)
- - Since all of the above are just normal classes C++ can follow the same approach for default handles and custom user ones
-
-Certain classes are marked with [Handle] attribute. The attribute also accepts a type the handle is to be used on.
-Each such class must implement IHandle interface which requires you to implement an Update method
- - Update method receives the instance of the object currently being processed
- - Then you may call handle specific methods like "position = mySliderLine.Update(object.currentPosition)"
- - Drawing - Immediate mode in the Update method. You call Handle.DrawArrow, etc.
-   - Complex handles like FreeMoveHandle are also their own class, but  they have their own Update in which they call immediate mode drawing
- - TODO: Since this entire class essentially boils down to a single method it might be worth making handle sliders immediate mode as well
-   - ACTUALLY looking at Unity code I definitely don't want to do that. It's too clumsy and impossible to guarantee selection if the order of handles changes
-
-CONCRETE TASKS:
- - Need nearest point to disc/arc code
-
-Take into consideration local vs. global handles
 Free move/rotate/scale handles need to exist as well
  - Scale is easy, just perform uniform scale. Use SliderPlane oriented towards camera
  - Move also use SliderPlane oriented towards camera
  - Rotation use SliderDisc oriented towards camera
 
-See for inspiration: http://docs.unity3d.com/ScriptReference/Handles.html
+CONCRETE TODO:
+HandleSliderManager
+ - Detecting input and updating the sliders
+ - isHandleActive
+
+ScriptHandleManager
+ - Pretty much everything (in more detail in .cpp file)
+ - Needs to be started up somewhere
+
+C# Component needs "sceneObject" property
+C# SceneObject needs position/rot/scale (and local variants) properties
+
+SceneEditorWidget
+ - Need to glue everything together
+
+More complex handles (combinations of sliders + draw methods)
+ - In C#, called by ScriptHandleManager
+
+Nearest point to disc/arc code
+More complex types for drawing like DrawArrow in HandleDrawManager
+Handles that remain the same size regardless of distance from camera
+ - For both drawing and collision
+Consider local vs. global handle mode
+
+OPEN QUESTIONS:
+ - How to handle handles with multiple selection?
 
 EXAMPLE:
 
@@ -128,35 +114,6 @@ class CameraHandle : IHandle
      }
 }
 
-
-------------
-
-What if I want a different handle per-object (e.g. object has some flag that makes different handles render)
- - SOLVED
-
-How I can easily access the current target object
- - Manually implement a generic getter?
-
-How will I implement this in C++ and use for default handles?
- - I'm still using classes in C# and C++ can use equivalents. Handle manager can do a special pass to draw default handles before calling the custom handle code.
-
-Do I want to unify gizmo and handle drawing?
- - Not at the moment. Too much to think about, I can always refactor and it will be easier.
-
-Handles can be mouse overed and selected. How will I handle that if I just use normal drawing methods???
- - This can be set in HandleSlider class itself with "isHovering", "isActive". And then its draw method can change appearance appropriately.
-
-Do I handle handle transforms via a matrix that is automatically set by the handle manager, or manually like unity does? 
-  - I shouldn't allow non-uniform scale.
-  - In both cases I need to set handle transform in its Update() method
-  - ALLOW custom matrix (or just custom offset and rotation?) but have handle manager set it normally
-    - custom matrix sounds better for easier control?
-
-How do I handle when an object with a custom handle is deleted?
- - How do I detect that and remove the handle.
-   - I SHOULDN'T HAVE TO
- - I should probably just instantiate he IHandle implementation class once object is selected, and destroy it after
-
 ----------------------------------------------------------------------
 SelectionRenderer