Browse Source

A lot more work on handles (WIP)

Marko Pintera 11 years ago
parent
commit
e9fc86930e
72 changed files with 965 additions and 183 deletions
  1. 7 1
      BansheeCore/Include/BsSceneObject.h
  2. 2 0
      BansheeEditor/BansheeEditor.vcxproj
  3. 6 0
      BansheeEditor/BansheeEditor.vcxproj.filters
  4. 1 1
      BansheeEditor/Include/BsHandleManager.h
  5. 3 0
      BansheeEditor/Include/BsHandleSlider.h
  6. 54 0
      BansheeEditor/Source/BsEditorUtility.cpp
  7. 2 2
      BansheeEditor/Source/BsHandleManager.cpp
  8. 22 0
      BansheeEditor/Source/BsHandleSlider.cpp
  9. 8 1
      BansheeEditor/Source/BsHandleSliderManager.cpp
  10. 12 0
      BansheeEngine/Include/BsCamera.h
  11. 5 0
      BansheeEngine/Include/BsRenderable.h
  12. 52 20
      BansheeEngine/Source/BsCamera.cpp
  13. 21 0
      BansheeEngine/Source/BsRenderable.cpp
  14. 8 6
      BansheeMono/Include/BsMonoClass.h
  15. 7 10
      BansheeMono/Source/BsMonoClass.cpp
  16. 1 0
      BansheeUtility/Include/BsFwdDeclUtil.h
  17. 16 0
      BansheeUtility/Include/BsVector2I.h
  18. 1 0
      BansheeUtility/Include/BsVector3.h
  19. 2 0
      BansheeUtility/Source/BsVector3.cpp
  20. 4 4
      MBansheeEditor/DebugCameraHandle.cs
  21. 41 1
      MBansheeEditor/EditorApplication.cs
  22. 7 1
      MBansheeEditor/MBansheeEditor.csproj
  23. 13 0
      MBansheeEditor/Scene/HandleSlider.cs
  24. 3 2
      MBansheeEditor/Scene/HandleSliderDisc.cs
  25. 3 2
      MBansheeEditor/Scene/HandleSliderLine.cs
  26. 3 2
      MBansheeEditor/Scene/HandleSliderPlane.cs
  27. 0 11
      MBansheeEditor/Scene/IHandle.cs
  28. 3 3
      MBansheeEditor/Selection.cs
  29. 4 1
      MBansheeEngine/Component.cs
  30. 1 0
      MBansheeEngine/MBansheeEngine.csproj
  31. 98 10
      MBansheeEngine/SceneObject.cs
  32. 1 0
      Notes.txt
  33. 60 0
      SBansheeEditor/Include/BsScriptHandleManager.h
  34. 6 0
      SBansheeEditor/Include/BsScriptHandleSlider.h
  35. 1 0
      SBansheeEditor/Include/BsScriptHandleSliderDisc.h
  36. 1 0
      SBansheeEditor/Include/BsScriptHandleSliderLine.h
  37. 1 0
      SBansheeEditor/Include/BsScriptHandleSliderPlane.h
  38. 2 0
      SBansheeEditor/SBansheeEditor.vcxproj
  39. 6 0
      SBansheeEditor/SBansheeEditor.vcxproj.filters
  40. 1 1
      SBansheeEditor/Source/BsEditorScriptManager.cpp
  41. 52 0
      SBansheeEditor/Source/BsScriptEditorUtility.cpp
  42. 1 1
      SBansheeEditor/Source/BsScriptEditorWindow.cpp
  43. 1 1
      SBansheeEditor/Source/BsScriptGUIColorField.cpp
  44. 1 1
      SBansheeEditor/Source/BsScriptGUIComponentFoldout.cpp
  45. 1 1
      SBansheeEditor/Source/BsScriptGUIFloatField.cpp
  46. 1 1
      SBansheeEditor/Source/BsScriptGUIFoldout.cpp
  47. 1 1
      SBansheeEditor/Source/BsScriptGUIGameObjectField.cpp
  48. 1 1
      SBansheeEditor/Source/BsScriptGUIIntField.cpp
  49. 1 1
      SBansheeEditor/Source/BsScriptGUIResourceField.cpp
  50. 1 1
      SBansheeEditor/Source/BsScriptGUITextField.cpp
  51. 1 1
      SBansheeEditor/Source/BsScriptGUIToggleField.cpp
  52. 1 1
      SBansheeEditor/Source/BsScriptGUIVector2Field.cpp
  53. 1 1
      SBansheeEditor/Source/BsScriptGUIVector3Field.cpp
  54. 1 1
      SBansheeEditor/Source/BsScriptGUIVector4Field.cpp
  55. 1 1
      SBansheeEditor/Source/BsScriptGizmoManager.cpp
  56. 250 12
      SBansheeEditor/Source/BsScriptHandleManager.cpp
  57. 7 1
      SBansheeEditor/Source/BsScriptHandleSlider.cpp
  58. 11 2
      SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp
  59. 11 2
      SBansheeEditor/Source/BsScriptHandleSliderLine.cpp
  60. 11 2
      SBansheeEditor/Source/BsScriptHandleSliderPlane.cpp
  61. 1 0
      SBansheeEngine/Include/BsScriptComponent.h
  62. 13 0
      SBansheeEngine/Include/BsScriptSceneObject.h
  63. 2 2
      SBansheeEngine/Source/BsManagedSerializableArray.cpp
  64. 3 3
      SBansheeEngine/Source/BsManagedSerializableDictionary.cpp
  65. 1 1
      SBansheeEngine/Source/BsManagedSerializableList.cpp
  66. 2 2
      SBansheeEngine/Source/BsRuntimeScriptObjects.cpp
  67. 12 0
      SBansheeEngine/Source/BsScriptComponent.cpp
  68. 3 3
      SBansheeEngine/Source/BsScriptGUIButton.cpp
  69. 1 1
      SBansheeEngine/Source/BsScriptGUIListBox.cpp
  70. 4 4
      SBansheeEngine/Source/BsScriptGUIToggle.cpp
  71. 68 0
      SBansheeEngine/Source/BsScriptSceneObject.cpp
  72. 10 55
      SceneView.txt

+ 7 - 1
BansheeCore/Include/BsSceneObject.h

@@ -432,7 +432,13 @@ namespace BansheeEngine
 			static_assert((std::is_base_of<BansheeEngine::Component, T>::value), 
 			static_assert((std::is_base_of<BansheeEngine::Component, T>::value), 
 				"Specified type is not a valid Component.");
 				"Specified type is not a valid Component.");
 
 
-			return hasComponent(T::getRTTIStatic()->getRTTIId());
+			for (auto iter = mComponents.begin(); iter != mComponents.end(); ++iter)
+			{
+				if ((*iter)->getRTTI()->getRTTIId() == T::getRTTIStatic()->getRTTIId())
+					return true;
+			}
+
+			return false;
 		}
 		}
 
 
 		/**
 		/**

+ 2 - 0
BansheeEditor/BansheeEditor.vcxproj

@@ -275,6 +275,7 @@
     <ClInclude Include="Include\BsEditorCommand.h" />
     <ClInclude Include="Include\BsEditorCommand.h" />
     <ClInclude Include="Include\BsBuiltinEditorResources.h" />
     <ClInclude Include="Include\BsBuiltinEditorResources.h" />
     <ClInclude Include="Include\BsEditorTestSuite.h" />
     <ClInclude Include="Include\BsEditorTestSuite.h" />
+    <ClInclude Include="Include\BsEditorUtility.h" />
     <ClInclude Include="Include\BsEditorWidgetLayout.h" />
     <ClInclude Include="Include\BsEditorWidgetLayout.h" />
     <ClInclude Include="Include\BsEditorWidgetLayoutRTTI.h" />
     <ClInclude Include="Include\BsEditorWidgetLayoutRTTI.h" />
     <ClInclude Include="Include\BsEditorWidgetManager.h" />
     <ClInclude Include="Include\BsEditorWidgetManager.h" />
@@ -342,6 +343,7 @@
     <ClCompile Include="Source\BsEditorCommand.cpp" />
     <ClCompile Include="Source\BsEditorCommand.cpp" />
     <ClCompile Include="Source\BsBuiltinEditorResources.cpp" />
     <ClCompile Include="Source\BsBuiltinEditorResources.cpp" />
     <ClCompile Include="Source\BsEditorTestSuite.cpp" />
     <ClCompile Include="Source\BsEditorTestSuite.cpp" />
+    <ClCompile Include="Source\BsEditorUtility.cpp" />
     <ClCompile Include="Source\BsEditorWidget.cpp" />
     <ClCompile Include="Source\BsEditorWidget.cpp" />
     <ClCompile Include="Source\BsEditorWidgetContainer.cpp" />
     <ClCompile Include="Source\BsEditorWidgetContainer.cpp" />
     <ClCompile Include="Source\BsEditorWidgetLayout.cpp" />
     <ClCompile Include="Source\BsEditorWidgetLayout.cpp" />

+ 6 - 0
BansheeEditor/BansheeEditor.vcxproj.filters

@@ -240,6 +240,9 @@
     <ClInclude Include="Include\BsHandleManager.h">
     <ClInclude Include="Include\BsHandleManager.h">
       <Filter>Header Files\Editor</Filter>
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsEditorUtility.h">
+      <Filter>Header Files\Editor</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsEditorWidgetContainer.cpp">
     <ClCompile Include="Source\BsEditorWidgetContainer.cpp">
@@ -428,5 +431,8 @@
     <ClCompile Include="Source\BsHandleManager.cpp">
     <ClCompile Include="Source\BsHandleManager.cpp">
       <Filter>Source Files\Editor</Filter>
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsEditorUtility.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 1 - 1
BansheeEditor/Include/BsHandleManager.h

@@ -8,7 +8,7 @@ namespace BansheeEngine
 	class BS_ED_EXPORT HandleManager : public Module<HandleManager>
 	class BS_ED_EXPORT HandleManager : public Module<HandleManager>
 	{
 	{
 	public:
 	public:
-		HandleManager();
+		HandleManager(const HCamera& camera);
 		virtual ~HandleManager();
 		virtual ~HandleManager();
 
 
 		void update(const Vector2I& inputPos, const Ray& inputRay, const Matrix4& viewMatrix, bool pressed);
 		void update(const Vector2I& inputPos, const Ray& inputRay, const Matrix4& viewMatrix, bool pressed);

+ 3 - 0
BansheeEditor/Include/BsHandleSlider.h

@@ -42,6 +42,9 @@ namespace BansheeEngine
 		void setHover() { mState = State::Hover; }
 		void setHover() { mState = State::Hover; }
 		void registerDrag(const Vector2I& pointerPos);
 		void registerDrag(const Vector2I& pointerPos);
 
 
+		float calcDelta(const HCamera& camera, const Vector3& position, const Vector3& direction, 
+			const Vector2I& pointerStart, const Vector2I& pointerEnd);
+
 		bool mFixedScale;
 		bool mFixedScale;
 		float mSnapValue;
 		float mSnapValue;
 
 

+ 54 - 0
BansheeEditor/Source/BsEditorUtility.cpp

@@ -0,0 +1,54 @@
+#include "BsEditorUtility.h"
+#include "BsSceneObject.h"
+#include "BsRenderable.h"
+
+namespace BansheeEngine
+{
+	AABox EditorUtility::calculateBounds(const HSceneObject& object)
+	{
+		Vector<HSceneObject> objects = { object };
+
+		return calculateBounds(objects);
+	}
+
+	AABox EditorUtility::calculateBounds(const Vector<HSceneObject>& objects)
+	{
+		if (objects.size() == 0)
+			return AABox(Vector3::ZERO, Vector3::ZERO);
+
+		AABox bounds = AABox(Vector3::INF, -Vector3::INF);
+		bool gotOneMesh = false;
+
+		for (auto& object : objects)
+		{
+			AABox meshBounds;
+			if (calculateMeshBounds(object, meshBounds))
+			{
+				bounds.merge(meshBounds);
+
+				gotOneMesh = true;
+			}
+		}
+
+		if (!gotOneMesh)
+		{
+			for (auto& object : objects)
+				bounds.merge(object->getWorldPosition());
+		}
+
+		return bounds;
+	}
+
+	bool EditorUtility::calculateMeshBounds(const HSceneObject& object, AABox& bounds)
+	{
+		if (object->hasComponent<Renderable>())
+		{
+			HRenderable renderable = object->getComponent<Renderable>();
+			bounds = renderable->getBounds().getBox();
+
+			return true;
+		}
+
+		return false;
+	}
+}

+ 2 - 2
BansheeEditor/Source/BsHandleManager.cpp

@@ -4,11 +4,11 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	HandleManager::HandleManager()
+	HandleManager::HandleManager(const HCamera& camera)
 		:mSliderManager(nullptr), mDrawManager(nullptr)
 		:mSliderManager(nullptr), mDrawManager(nullptr)
 	{
 	{
 		mSliderManager = bs_new<HandleSliderManager>();
 		mSliderManager = bs_new<HandleSliderManager>();
-		mDrawManager = bs_new<HandleDrawManager>();
+		mDrawManager = bs_new<HandleDrawManager>(camera);
 	}
 	}
 
 
 	HandleManager::~HandleManager()
 	HandleManager::~HandleManager()

+ 22 - 0
BansheeEditor/Source/BsHandleSlider.cpp

@@ -1,4 +1,5 @@
 #include "BsHandleSlider.h"
 #include "BsHandleSlider.h"
+#include "BsCamera.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -33,4 +34,25 @@ namespace BansheeEngine
 		mLastPointerPos = mCurPointerPos;
 		mLastPointerPos = mCurPointerPos;
 		mCurPointerPos = pointerPos;
 		mCurPointerPos = pointerPos;
 	}
 	}
+
+	float HandleSlider::calcDelta(const HCamera& camera, const Vector3& position, const Vector3& direction,
+		const Vector2I& pointerStart, const Vector2I& pointerEnd)
+	{
+		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 tStart = handleDir2D.dot(diffStart) / (float)sqrdMag;
+		float tEnd = handleDir2D.dot(diffEnd) / (float)sqrdMag;
+
+		return tEnd - tStart;
+	}
 }
 }

+ 8 - 1
BansheeEditor/Source/BsHandleSliderManager.cpp

@@ -7,6 +7,7 @@
 #include "BsRenderer.h"
 #include "BsRenderer.h"
 #include "BsTransientMesh.h"
 #include "BsTransientMesh.h"
 #include "BsCamera.h"
 #include "BsCamera.h"
+#include "BsHandleSlider.h"
 
 
 using namespace std::placeholders;
 using namespace std::placeholders;
 
 
@@ -30,7 +31,13 @@ namespace BansheeEngine
 
 
 	bool HandleSliderManager::isSliderActive() const
 	bool HandleSliderManager::isSliderActive() const
 	{
 	{
-		// TODO - Return true if we are dragging any slider
+		for (auto& slider : mSliders)
+		{
+			if (slider->getState() == HandleSlider::State::Active)
+				return true;
+		}
+
+		return false;
 	}
 	}
 
 
 	void HandleSliderManager::_registerCapsuleCollider(const Capsule& collider, HandleSlider* slider)
 	void HandleSliderManager::_registerCapsuleCollider(const Capsule& collider, HandleSlider* slider)

+ 12 - 0
BansheeEngine/Include/BsCamera.h

@@ -358,6 +358,13 @@ namespace BansheeEngine
 		 */
 		 */
 		Vector2I clipToScreenPoint(const Vector2& clipPoint) const;
 		Vector2I clipToScreenPoint(const Vector2& clipPoint) const;
 
 
+		/**
+		 * @brief	Converts a point in screen space (pixels corresponding to
+		 *			render target attached to the camera) to a ray in world space
+		 *			originating at the selected point on the camera near plane.
+		 */
+		Ray screenPointToRay(const Vector2I& screenPoint) const;
+
         static const float INFINITE_FAR_PLANE_ADJUST; /**< Small constant used to reduce far plane projection to avoid inaccuracies. */
         static const float INFINITE_FAR_PLANE_ADJUST; /**< Small constant used to reduce far plane projection to avoid inaccuracies. */
 
 
 		/************************************************************************/
 		/************************************************************************/
@@ -401,6 +408,11 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual void calcProjectionParameters(float& left, float& right, float& bottom, float& top) const;
 		virtual void calcProjectionParameters(float& left, float& right, float& bottom, float& top) const;
 
 
+		/**
+		 * @brief	Un-projects a point in clip space to world space.
+		 */
+		Vector3 unprojectPoint(const Vector3& point) const;
+
 		/**
 		/**
 		 * @brief	Recalculate frustum if dirty.
 		 * @brief	Recalculate frustum if dirty.
 		 */
 		 */

+ 5 - 0
BansheeEngine/Include/BsRenderable.h

@@ -78,6 +78,11 @@ namespace BansheeEngine
 		 */
 		 */
 		HMaterial getMaterial(UINT32 idx) const;
 		HMaterial getMaterial(UINT32 idx) const;
 
 
+		/**
+		 * @brief	Gets world bounds of the mesh rendered by this object.
+		 */
+		Bounds getBounds() const;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CORE PROXY                      		*/
 		/* 								CORE PROXY                      		*/
 		/************************************************************************/
 		/************************************************************************/

+ 52 - 20
BansheeEngine/Source/BsCamera.cpp

@@ -559,30 +559,13 @@ namespace BansheeEngine
 
 
 	Vector3 Camera::clipToWorldPoint(const Vector2& clipPoint) const
 	Vector3 Camera::clipToWorldPoint(const Vector2& clipPoint) const
 	{
 	{
-		Vector2I screenPoint = clipToScreenPoint(clipPoint);
-		return screenToWorldPoint(screenPoint);
+		Vector3 viewPoint = clipToViewPoint(clipPoint);
+		return viewToWorldPoint(viewPoint);
 	}
 	}
 
 
 	Vector3 Camera::clipToViewPoint(const Vector2& clipPoint) const
 	Vector3 Camera::clipToViewPoint(const Vector2& clipPoint) const
 	{
 	{
-		Vector4 unprojPoint(clipPoint.x, clipPoint.y, 0.5f, 1.0f); // 0.5f arbitrary depth
-		unprojPoint = getProjectionMatrix().inverse().multiply(unprojPoint);
-
-		if (unprojPoint.w > 1e-7f)
-		{
-			float invW = 1.0f / unprojPoint.w;
-			unprojPoint.x *= invW;
-			unprojPoint.y *= invW;
-			unprojPoint.z *= invW;
-		}
-		else
-		{
-			unprojPoint.x = 0.0f;
-			unprojPoint.y = 0.0f;
-			unprojPoint.z = 0.0f;
-		}
-
-		return Vector3(unprojPoint.x, unprojPoint.y, unprojPoint.z);
+		return unprojectPoint(Vector3(clipPoint.x, clipPoint.y, 0.5f));
 	}
 	}
 
 
 	Vector2I Camera::clipToScreenPoint(const Vector2& clipPoint) const
 	Vector2I Camera::clipToScreenPoint(const Vector2& clipPoint) const
@@ -594,6 +577,55 @@ namespace BansheeEngine
 		return screenPoint;
 		return screenPoint;
 	}
 	}
 
 
+	Ray Camera::screenPointToRay(const Vector2I& screenPoint) const
+	{
+		Vector2 clipPoint = screenToClipPoint(screenPoint);
+
+		Vector3 near = unprojectPoint(Vector3(clipPoint.x, clipPoint.y, mNearDist));
+		Vector3 far = unprojectPoint(Vector3(clipPoint.x, clipPoint.y, mNearDist + 1.0f));
+
+		return Ray(near, Vector3::normalize(far - near));
+	}
+
+	Vector3 Camera::unprojectPoint(const Vector3& point) const
+	{
+		Vector4 dir4(point.x, point.y, 0.95f, 1.0f); // 0.95f arbitrary
+		dir4 = getProjectionMatrix().inverse().multiply(dir4);
+
+		Vector3 dir;
+		dir.x = dir4.x;
+		dir.y = dir4.y;
+		dir.z = dir4.z;
+
+		if (dir4.w > 1e-7f)
+		{
+			float invW = 1.0f / dir4.w;
+			dir.x *= invW;
+			dir.y *= invW;
+			dir.z *= invW;
+
+			// Find a point along a ray from camera origin to point on near plane we just found, 
+			// at point.z distance from the origin
+
+			float distToPlane = dir.dot(-Vector3::UNIT_Z);
+			if (distToPlane >= 0.0f)
+			{
+				if (mProjType == PT_PERSPECTIVE)
+					dir *= point.z / distToPlane;
+				else
+					dir += Vector3::UNIT_Z * (distToPlane - point.z);
+			}
+		}
+		else
+		{
+			dir.x = 0.0f;
+			dir.y = 0.0f;
+			dir.z = 0.0f;
+		}
+
+		return Vector3(dir.x, dir.y, dir.z);
+	}
+
 	CameraProxyPtr Camera::_createProxy() const
 	CameraProxyPtr Camera::_createProxy() const
 	{
 	{
 		CameraProxyPtr proxy = bs_shared_ptr<CameraProxy>();
 		CameraProxyPtr proxy = bs_shared_ptr<CameraProxy>();

+ 21 - 0
BansheeEngine/Source/BsRenderable.cpp

@@ -5,6 +5,7 @@
 #include "BsMesh.h"
 #include "BsMesh.h"
 #include "BsMaterial.h"
 #include "BsMaterial.h"
 #include "BsRenderQueue.h"
 #include "BsRenderQueue.h"
+#include "BsBounds.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -56,6 +57,26 @@ namespace BansheeEngine
 			return mMaterialData[0].material;
 			return mMaterialData[0].material;
 	}
 	}
 
 
+	Bounds Renderable::getBounds() const
+	{
+		if (mMeshData.mesh == nullptr || !mMeshData.mesh.isLoaded())
+		{
+			Vector3 pos = SO()->getWorldPosition();
+
+			AABox box(pos, pos);
+			Sphere sphere(pos, 0.0f);
+
+			return Bounds(box, sphere);
+		}
+		else
+		{
+			Bounds bounds = mMeshData.mesh->getBounds();
+			bounds.transformAffine(SO()->getWorldTfrm());
+
+			return bounds;
+		}
+	}
+
 	void Renderable::setLayer(UINT64 layer)
 	void Renderable::setLayer(UINT64 layer)
 	{
 	{
 		bool isPow2 = layer && !((layer - 1) & layer);
 		bool isPow2 = layer && !((layer - 1) & layer);

+ 8 - 6
BansheeMono/Include/BsMonoClass.h

@@ -52,11 +52,12 @@ namespace BansheeEngine
 
 
 		/**
 		/**
 		 * @brief	Returns an object referencing a method with the specified name and number of parameters.
 		 * @brief	Returns an object referencing a method with the specified name and number of parameters.
-		 *			If the method is overloaded then you should use "getMethodExact". Throws an exception
-		 *			if method cannot be found.
+		 *			
+		 * @note	If the method is overloaded then you should use "getMethodExact". 
 		 *			Does not query base class methods.
 		 *			Does not query base class methods.
+		 *			Returns null if method cannot be found.
 		 */
 		 */
-		MonoMethod& getMethod(const String& name, UINT32 numParams = 0) const;
+		MonoMethod* getMethod(const String& name, UINT32 numParams = 0) const;
 
 
 		/**
 		/**
 		 * @brief	Returns an object referencing a field with the specified name.
 		 * @brief	Returns an object referencing a field with the specified name.
@@ -85,9 +86,10 @@ namespace BansheeEngine
 
 
 		/**
 		/**
 		 * @brief	Returns an object referencing a method, expects exact method name with parameters.
 		 * @brief	Returns an object referencing a method, expects exact method name with parameters.
-		 *			Does not query base class methods.
-		 *
-		 * @note	Example: name = "CreateInstance", signature = "Vector2,int[]"
+		 *			
+		 * @note	Does not query base class methods.
+		 *			Returns null if method cannot be found.
+		 *			Example: name = "CreateInstance", signature = "Vector2,int[]"
 		 */
 		 */
 		MonoMethod* getMethodExact(const String& name, const String& signature) const;
 		MonoMethod* getMethodExact(const String& name, const String& signature) const;
 
 

+ 7 - 10
BansheeMono/Source/BsMonoClass.cpp

@@ -61,24 +61,21 @@ namespace BansheeEngine
 		mProperties.clear();
 		mProperties.clear();
 	}
 	}
 
 
-	MonoMethod& MonoClass::getMethod(const String& name, UINT32 numParams) const
+	MonoMethod* MonoClass::getMethod(const String& name, UINT32 numParams) const
 	{
 	{
 		MethodId mehodId(name, numParams);
 		MethodId mehodId(name, numParams);
 		auto iterFind = mMethods.find(mehodId);
 		auto iterFind = mMethods.find(mehodId);
 		if(iterFind != mMethods.end())
 		if(iterFind != mMethods.end())
-			return *iterFind->second;
+			return iterFind->second;
 
 
 		::MonoMethod* method = mono_class_get_method_from_name(mClass, name.c_str(), (int)numParams);
 		::MonoMethod* method = mono_class_get_method_from_name(mClass, name.c_str(), (int)numParams);
-		if(method == nullptr)
-		{
-			String fullMethodName = mFullName + "::" + name;
-			BS_EXCEPT(InvalidParametersException, "Cannot get Mono method: " + fullMethodName);
-		}
+		if (method == nullptr)
+			return nullptr;
 
 
 		MonoMethod* newMethod = new (bs_alloc<MonoMethod>()) MonoMethod(method);
 		MonoMethod* newMethod = new (bs_alloc<MonoMethod>()) MonoMethod(method);
 		mMethods[mehodId] = newMethod;
 		mMethods[mehodId] = newMethod;
 
 
-		return *newMethod;
+		return newMethod;
 	}
 	}
 
 
 	MonoMethod* MonoClass::getMethodExact(const String& name, const String& signature) const
 	MonoMethod* MonoClass::getMethodExact(const String& name, const String& signature) const
@@ -212,7 +209,7 @@ namespace BansheeEngine
 
 
 	MonoObject* MonoClass::invokeMethod(const String& name, MonoObject* instance, void** params, UINT32 numParams)
 	MonoObject* MonoClass::invokeMethod(const String& name, MonoObject* instance, void** params, UINT32 numParams)
 	{
 	{
-		return getMethod(name, numParams).invoke(instance, params);
+		return getMethod(name, numParams)->invoke(instance, params);
 	}
 	}
 
 
 	void MonoClass::addInternalCall(const String& name, const void* method)
 	void MonoClass::addInternalCall(const String& name, const void* method)
@@ -234,7 +231,7 @@ namespace BansheeEngine
 	MonoObject* MonoClass::createInstance(void** params, UINT32 numParams)
 	MonoObject* MonoClass::createInstance(void** params, UINT32 numParams)
 	{
 	{
 		MonoObject* obj = mono_object_new(MonoManager::instance().getDomain(), mClass);
 		MonoObject* obj = mono_object_new(MonoManager::instance().getDomain(), mClass);
-		getMethod(".ctor", numParams).invoke(obj, params);
+		getMethod(".ctor", numParams)->invoke(obj, params);
 
 
 		return obj;
 		return obj;
 	}
 	}

+ 1 - 0
BansheeUtility/Include/BsFwdDeclUtil.h

@@ -35,6 +35,7 @@ namespace BansheeEngine
 	struct Vector2I;
 	struct Vector2I;
 	class Rect2I;
 	class Rect2I;
 	class Rect2;
 	class Rect2;
+	class Rect3;
 	class Color;
 	class Color;
 	class DynLib;
 	class DynLib;
 	class DynLibManager;
 	class DynLibManager;

+ 16 - 0
BansheeUtility/Include/BsVector2I.h

@@ -183,5 +183,21 @@ namespace BansheeEngine
 
 
             return *this;
             return *this;
         }
         }
+
+        /**
+         * @brief	Returns the square of the length(magnitude) of the vector.
+         */
+        INT32 squaredLength() const
+        {
+            return x * x + y * y;
+        }
+
+        /**
+         * @brief	Calculates the dot (scalar) product of this vector with another.
+         */
+		INT32 dot(const Vector2I& vec) const
+        {
+            return x * vec.x + y * vec.y;
+        }
 	};
 	};
 }
 }

+ 1 - 0
BansheeUtility/Include/BsVector3.h

@@ -467,6 +467,7 @@ namespace BansheeEngine
 
 
         static const Vector3 ZERO;
         static const Vector3 ZERO;
 		static const Vector3 ONE;
 		static const Vector3 ONE;
+		static const Vector3 INF;
         static const Vector3 UNIT_X;
         static const Vector3 UNIT_X;
         static const Vector3 UNIT_Y;
         static const Vector3 UNIT_Y;
         static const Vector3 UNIT_Z;
         static const Vector3 UNIT_Z;

+ 2 - 0
BansheeUtility/Source/BsVector3.cpp

@@ -5,6 +5,8 @@ namespace BansheeEngine
 {
 {
     const Vector3 Vector3::ZERO(0, 0, 0);
     const Vector3 Vector3::ZERO(0, 0, 0);
 	const Vector3 Vector3::ONE(1, 1, 1);
 	const Vector3 Vector3::ONE(1, 1, 1);
+	const Vector3 Vector3::INF =
+		Vector3(std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity());
 
 
     const Vector3 Vector3::UNIT_X(1, 0, 0);
     const Vector3 Vector3::UNIT_X(1, 0, 0);
     const Vector3 Vector3::UNIT_Y(0, 1, 0);
     const Vector3 Vector3::UNIT_Y(0, 1, 0);

+ 4 - 4
MBansheeEditor/DebugCameraHandle.cs

@@ -4,7 +4,7 @@ using BansheeEngine;
 namespace BansheeEditor
 namespace BansheeEditor
 {
 {
     [CustomHandle(typeof(Component))]
     [CustomHandle(typeof(Component))]
-    public class DebugCameraHandle : IHandle
+    public class DebugCameraHandle : Handle
     {
     {
         private Component target;
         private Component target;
         private HandleSliderLine xAxis;
         private HandleSliderLine xAxis;
@@ -13,15 +13,15 @@ namespace BansheeEditor
         {
         {
             this.target = target;
             this.target = target;
 
 
-            xAxis = new HandleSliderLine(Vector3.xAxis, 5.0f);
+            xAxis = new HandleSliderLine(this, Vector3.xAxis, 5.0f);
         }
         }
 
 
-        protected override void Update()
+        protected override void PreInput()
         {
         {
             xAxis.Position = target.sceneObject.position;
             xAxis.Position = target.sceneObject.position;
         }
         }
 
 
-        protected override void Response()
+        protected override void PostInput()
         {
         {
             target.sceneObject.position = xAxis.NewPosition;
             target.sceneObject.position = xAxis.NewPosition;
         }
         }

+ 41 - 1
MBansheeEditor/EditorApplication.cs

@@ -3,8 +3,48 @@ using System.Collections.Generic;
 
 
 namespace BansheeEditor
 namespace BansheeEditor
 {
 {
+    public enum SceneViewTool
+    {
+        View,
+        Move,
+        Rotate,
+        Scale
+    }
+
+    public enum HandlePositionMode
+    {
+        Center,
+        Pivot
+    }
+
+    public enum HandleCoordinateMode
+    {
+        Local,
+        World
+    }
+
     public class EditorApplication
     public class EditorApplication
     {
     {
-        
+        private static SceneViewTool activeSceneTool = SceneViewTool.Move; // TODO - Actually retrieve this from somewhere
+        private static HandlePositionMode handlePositionMode = HandlePositionMode.Pivot; // TODO - Actually retrieve this from somewhere
+        private static HandleCoordinateMode handleCoordinateMode = HandleCoordinateMode.World; // TODO - Actually retrieve this from somewhere
+
+        public static SceneViewTool ActiveSceneTool
+        {
+            get { return activeSceneTool; }
+            set { activeSceneTool = value; } // TODO - Will likely need to update active GUI button when this changes
+        }
+
+        public static HandlePositionMode HandlePositionMode
+        {
+            get { return handlePositionMode; }
+            set { handlePositionMode = value; } // TODO - Will likely need to update active GUI button when this changes
+        }
+
+        public static HandleCoordinateMode HandleCoordinateMode
+        {
+            get { return handleCoordinateMode; }
+            set { handleCoordinateMode = value; } // TODO - Will likely need to update active GUI button when this changes
+        }
     }
     }
 }
 }

+ 7 - 1
MBansheeEditor/MBansheeEditor.csproj

@@ -46,6 +46,7 @@
     <Compile Include="Debug_Component1.cs" />
     <Compile Include="Debug_Component1.cs" />
     <Compile Include="Debug_Component2.cs" />
     <Compile Include="Debug_Component2.cs" />
     <Compile Include="EditorApplication.cs" />
     <Compile Include="EditorApplication.cs" />
+    <Compile Include="EditorUtility.cs" />
     <Compile Include="EditorWindow.cs" />
     <Compile Include="EditorWindow.cs" />
     <Compile Include="GUI\GUIFoldout.cs" />
     <Compile Include="GUI\GUIFoldout.cs" />
     <Compile Include="GUI\GUIGameObjectField.cs" />
     <Compile Include="GUI\GUIGameObjectField.cs" />
@@ -79,6 +80,9 @@
     <Compile Include="Inspector\InspectableVector4.cs" />
     <Compile Include="Inspector\InspectableVector4.cs" />
     <Compile Include="Inspector\Inspector.cs" />
     <Compile Include="Inspector\Inspector.cs" />
     <Compile Include="Inspector\InspectorWindow.cs" />
     <Compile Include="Inspector\InspectorWindow.cs" />
+    <Compile Include="Scene\DefaultHandle.cs" />
+    <Compile Include="Scene\DefaultHandleManager.cs" />
+    <Compile Include="Scene\MoveHandle.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="ProjectLibrary.cs" />
     <Compile Include="ProjectLibrary.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -90,7 +94,9 @@
     <Compile Include="Scene\HandleSliderDisc.cs" />
     <Compile Include="Scene\HandleSliderDisc.cs" />
     <Compile Include="Scene\HandleSliderLine.cs" />
     <Compile Include="Scene\HandleSliderLine.cs" />
     <Compile Include="Scene\HandleSliderPlane.cs" />
     <Compile Include="Scene\HandleSliderPlane.cs" />
-    <Compile Include="Scene\IHandle.cs" />
+    <Compile Include="Scene\Handle.cs" />
+    <Compile Include="Scene\RotateHandle.cs" />
+    <Compile Include="Scene\ScaleHandle.cs" />
     <Compile Include="Selection.cs" />
     <Compile Include="Selection.cs" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>

+ 13 - 0
MBansheeEditor/Scene/HandleSlider.cs

@@ -13,6 +13,11 @@ namespace BansheeEditor
 	        Hover
 	        Hover
         };
         };
 
 
+        public HandleSlider(Handle parentHandle)
+        {
+            parentHandle.RegisterSlider(this);
+        }
+
         public Vector3 Position
         public Vector3 Position
         {
         {
             get
             get
@@ -68,6 +73,14 @@ namespace BansheeEditor
             }
             }
         }
         }
 
 
+        internal void Destroy()
+        {
+            Internal_Destroy(mCachedPtr);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Destroy(IntPtr nativeInstance);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_GetPosition(IntPtr nativeInstance, out Vector3 value);
         private static extern void Internal_GetPosition(IntPtr nativeInstance, out Vector3 value);
 
 

+ 3 - 2
MBansheeEditor/Scene/HandleSliderDisc.cs

@@ -4,9 +4,10 @@ using BansheeEngine;
 
 
 namespace BansheeEditor
 namespace BansheeEditor
 {
 {
-    public class HandleSliderDisc : HandleSlider
+    public sealed class HandleSliderDisc : HandleSlider
     {
     {
-        public HandleSliderDisc(Vector3 normal, float radius, bool fixedScale = true, float snapValue = 0.0f)
+        public HandleSliderDisc(Handle parentHandle, Vector3 normal, float radius, bool fixedScale = true, float snapValue = 0.0f)
+            :base(parentHandle)
         {
         {
             Internal_CreateInstance(this, normal, radius, fixedScale, snapValue);
             Internal_CreateInstance(this, normal, radius, fixedScale, snapValue);
         }
         }

+ 3 - 2
MBansheeEditor/Scene/HandleSliderLine.cs

@@ -4,9 +4,10 @@ using BansheeEngine;
 
 
 namespace BansheeEditor
 namespace BansheeEditor
 {
 {
-    public class HandleSliderLine : HandleSlider
+    public sealed class HandleSliderLine : HandleSlider
     {
     {
-        public HandleSliderLine(Vector3 direction, float length,  bool fixedScale = true, float snapValue = 0.0f)
+        public HandleSliderLine(Handle parentHandle, Vector3 direction, float length,  bool fixedScale = true, float snapValue = 0.0f)
+            :base(parentHandle)
         {
         {
             Internal_CreateInstance(this, direction, length, fixedScale, snapValue);
             Internal_CreateInstance(this, direction, length, fixedScale, snapValue);
         }
         }

+ 3 - 2
MBansheeEditor/Scene/HandleSliderPlane.cs

@@ -4,9 +4,10 @@ using BansheeEngine;
 
 
 namespace BansheeEditor
 namespace BansheeEditor
 {
 {
-    public class HandleSliderPlane : HandleSlider
+    public sealed class HandleSliderPlane : HandleSlider
     {
     {
-        public HandleSliderPlane(Vector3 dir1, Vector3 dir2, float length, bool fixedScale = true, float snapValue = 0.0f)
+        public HandleSliderPlane(Handle parentHandle, Vector3 dir1, Vector3 dir2, float length, bool fixedScale = true, float snapValue = 0.0f)
+            :base(parentHandle)
         {
         {
             Internal_CreateInstance(this, dir1, dir2, length, fixedScale, snapValue);
             Internal_CreateInstance(this, dir1, dir2, length, fixedScale, snapValue);
         }
         }

+ 0 - 11
MBansheeEditor/Scene/IHandle.cs

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

+ 3 - 3
MBansheeEditor/Selection.cs

@@ -5,7 +5,7 @@ namespace BansheeEditor
 {
 {
     public sealed class Selection
     public sealed class Selection
     {
     {
-        public SceneObject[] sceneObjects
+        public static SceneObject[] sceneObjects
         {
         {
             get
             get
             {
             {
@@ -19,7 +19,7 @@ namespace BansheeEditor
             }
             }
         }
         }
 
 
-        public string[] resourceUUIDs
+        public static string[] resourceUUIDs
         {
         {
             get
             get
             {
             {
@@ -33,7 +33,7 @@ namespace BansheeEditor
             }
             }
         }
         }
 
 
-        public string[] resourcePaths
+        public static string[] resourcePaths
         {
         {
             get
             get
             {
             {

+ 4 - 1
MBansheeEngine/Component.cs

@@ -11,7 +11,7 @@ namespace BansheeEngine
 
 
         public SceneObject sceneObject
         public SceneObject sceneObject
         {
         {
-            get { throw new NotImplementedException(); }
+            get { return Internal_GetSceneObject(mCachedPtr); }
         }
         }
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
@@ -25,5 +25,8 @@ namespace BansheeEngine
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal static extern Component Internal_RemoveComponent(SceneObject parent, Type type);
         internal static extern Component Internal_RemoveComponent(SceneObject parent, Type type);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        internal static extern SceneObject Internal_GetSceneObject(IntPtr nativeInstance);
     }
     }
 }
 }

+ 1 - 0
MBansheeEngine/MBansheeEngine.csproj

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

+ 98 - 10
MBansheeEngine/SceneObject.cs

@@ -14,32 +14,87 @@ namespace BansheeEngine
 
 
         public Vector3 position
         public Vector3 position
         {
         {
-            set { throw new NotImplementedException(); }
-            get { throw new NotImplementedException(); }
+            get
+            {
+                Vector3 value;
+                Internal_GetPosition(mCachedPtr, out value);
+                return value;
+            }
+
+            set
+            {
+                Internal_SetPosition(mCachedPtr, value);
+            }
         }
         }
 
 
         public Vector3 localPosition
         public Vector3 localPosition
         {
         {
-            set { throw new NotImplementedException(); }
-            get { throw new NotImplementedException(); }
+            get
+            {
+                Vector3 value;
+                Internal_GetLocalPosition(mCachedPtr, out value);
+                return value;
+            }
+
+            set
+            {
+                Internal_SetLocalPosition(mCachedPtr, value);
+            }
         }
         }
 
 
         public Quaternion rotation
         public Quaternion rotation
         {
         {
-            set { throw new NotImplementedException(); }
-            get { throw new NotImplementedException(); }
+            get
+            {
+                Quaternion value;
+                Internal_GetRotation(mCachedPtr, out value);
+                return value;
+            }
+
+            set
+            {
+                Internal_SetRotation(mCachedPtr, value);
+            }
         }
         }
 
 
         public Quaternion localRotation
         public Quaternion localRotation
         {
         {
-            set { throw new NotImplementedException(); }
-            get { throw new NotImplementedException(); }
+            get
+            {
+                Quaternion value;
+                Internal_GetLocalRotation(mCachedPtr, out value);
+                return value;
+            }
+
+            set
+            {
+                Internal_SetLocalRotation(mCachedPtr, value);
+            }
         }
         }
 
 
         public Vector3 scale
         public Vector3 scale
         {
         {
-            set { throw new NotImplementedException(); }
-            get { throw new NotImplementedException(); }
+            get
+            {
+                Vector3 value;
+                Internal_GetScale(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        public Vector3 localScale
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetLocalScale(mCachedPtr, out value);
+                return value;
+            }
+
+            set
+            {
+                Internal_SetLocalScale(mCachedPtr, value);
+            }
         }
         }
 
 
         // For internal use
         // For internal use
@@ -97,5 +152,38 @@ namespace BansheeEngine
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern SceneObject Internal_GetChild(IntPtr nativeInstance, int idx);
         private static extern SceneObject Internal_GetChild(IntPtr nativeInstance, int idx);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetPosition(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetLocalPosition(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetRotation(IntPtr nativeInstance, out Quaternion value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetLocalRotation(IntPtr nativeInstance, out Quaternion value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetScale(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetLocalScale(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_SetLocalPosition(IntPtr nativeInstance, Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetRotation(IntPtr nativeInstance, Quaternion value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetLocalRotation(IntPtr nativeInstance, Quaternion value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetLocalScale(IntPtr nativeInstance, Vector3 value);
     }
     }
 }
 }

+ 1 - 0
Notes.txt

@@ -73,6 +73,7 @@ Reminders:
     different importers on different threads this way. And once I hook up progress dialog box, perhaps make it have multiple progress bars in a single window (per thread).
     different importers on different threads this way. And once I hook up progress dialog box, perhaps make it have multiple progress bars in a single window (per thread).
   - Add FolderManager, extensible C# script that can be attached to a folder (can be in a folder .meta) file. Handles processing of assets in that folder. Can get notified 
   - Add FolderManager, extensible C# script that can be attached to a folder (can be in a folder .meta) file. Handles processing of assets in that folder. Can get notified 
     whenever anything in the folder changes. But is that necessary if I can have asset post- and pre- processor that can filter by folder programatically?
     whenever anything in the folder changes. But is that necessary if I can have asset post- and pre- processor that can filter by folder programatically?
+  - Add option to optimize mesh for post-transform cache (triangles sharing vertices are sequential) on import (also pre-transform as well, order vertices by their first reference in IB, and so on)
 
 
 
 
 Potential optimizations:
 Potential optimizations:

+ 60 - 0
SBansheeEditor/Include/BsScriptHandleManager.h

@@ -2,14 +2,74 @@
 
 
 #include "BsScriptEditorPrerequisites.h"
 #include "BsScriptEditorPrerequisites.h"
 #include "BsHandleManager.h"
 #include "BsHandleManager.h"
+#include <mono/jit/jit.h>
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	class BS_SCR_BED_EXPORT ScriptHandleManager : public HandleManager
 	class BS_SCR_BED_EXPORT ScriptHandleManager : public HandleManager
 	{
 	{
+		struct CustomHandleData
+		{
+			UINT32 assemblyId;
+			MonoClass* handleType;
+			MonoClass* componentType;
+			MonoMethod* ctor;
+		};
+
+		struct ActiveCustomHandleData
+		{
+			MonoObject* object;
+			uint32_t gcHandle;
+		};
+
+		struct ActiveCustomHandles
+		{
+			HSceneObject selectedObject;
+			Vector<ActiveCustomHandleData> handles;
+		};
+
+	public:
+		ScriptHandleManager(const HCamera& camera, RuntimeScriptObjects& scriptObjectManager);
+		~ScriptHandleManager();
+
+		void update();
+
 	protected:
 	protected:
 		void refreshHandles();
 		void refreshHandles();
 		void triggerHandles();
 		void triggerHandles();
 		void queueDrawCommands();
 		void queueDrawCommands();
+
+		void reloadAssembly(MonoAssembly* assembly);
+		bool isValidHandleType(MonoClass* type, MonoClass*& componentType, MonoMethod*& ctor);
+
+		void callPreInput(MonoObject* instance);
+		void callPostInput(MonoObject* instance);
+		void callDraw(MonoObject* instance);
+		void callDestroy(MonoObject* instance);
+
+		RuntimeScriptObjects& mScriptObjectManager;
+		HEvent mAssemblyRefreshedConn;
+
+		Map<String, UINT32> mAssemblyNameToId;
+		Map<String, CustomHandleData> mHandles;
+
+		UINT32 mNextAssemblyId = 0;
+
+		ActiveCustomHandles mActiveHandleData;
+
+		MonoObject* mDefaultHandleManager = nullptr;
+		uint32_t mDefaultHandleManagerGCHandle = 0;
+
+		MonoClass* mCustomHandleAttribute = nullptr;
+		MonoField* mTypeField = nullptr;
+		MonoClass* mHandleBaseClass = nullptr;
+		MonoClass* mDefaultHandleManagerClass = nullptr;
+
+		typedef void(__stdcall *DestroyThunkDef) (MonoObject*, MonoException**);
+
+		MonoMethod* mPreInputMethod;
+		MonoMethod* mPostInputMethod;
+		MonoMethod* mDrawMethod;
+		DestroyThunkDef mDestroyThunk;
 	};
 	};
 }
 }

+ 6 - 0
SBansheeEditor/Include/BsScriptHandleSlider.h

@@ -15,6 +15,11 @@ namespace BansheeEngine
 		virtual ~ScriptHandleSliderBase() {}
 		virtual ~ScriptHandleSliderBase() {}
 
 
 		virtual HandleSlider* getSlider() const = 0;
 		virtual HandleSlider* getSlider() const = 0;
+
+	protected:
+		friend class ScriptHandleSlider;
+
+		virtual void destroy() = 0;
 	};
 	};
 
 
 	class BS_SCR_BED_EXPORT ScriptHandleSlider : public ScriptObject <ScriptHandleSlider>
 	class BS_SCR_BED_EXPORT ScriptHandleSlider : public ScriptObject <ScriptHandleSlider>
@@ -23,6 +28,7 @@ namespace BansheeEngine
 		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "HandleSlider")
 		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "HandleSlider")
 
 
 	private:
 	private:
+		static void internal_Destroy(ScriptHandleSliderBase* nativeInstance);
 		static void internal_GetPosition(ScriptHandleSliderBase* nativeInstance, Vector3* value);
 		static void internal_GetPosition(ScriptHandleSliderBase* nativeInstance, Vector3* value);
 		static void internal_SetPosition(ScriptHandleSliderBase* nativeInstance, Vector3 value);
 		static void internal_SetPosition(ScriptHandleSliderBase* nativeInstance, Vector3 value);
 		static void internal_GetRotation(ScriptHandleSliderBase* nativeInstance, Quaternion* value);
 		static void internal_GetRotation(ScriptHandleSliderBase* nativeInstance, Quaternion* value);

+ 1 - 0
SBansheeEditor/Include/BsScriptHandleSliderDisc.h

@@ -15,6 +15,7 @@ namespace BansheeEngine
 
 
 	protected:
 	protected:
 		virtual HandleSlider* getSlider() const { return mSlider; }
 		virtual HandleSlider* getSlider() const { return mSlider; }
+		virtual void destroy();
 
 
 	private:
 	private:
 		static void internal_CreateInstance(MonoObject* instance, Vector3 normal, float radius, bool fixedScale, float snapValue);
 		static void internal_CreateInstance(MonoObject* instance, Vector3 normal, float radius, bool fixedScale, float snapValue);

+ 1 - 0
SBansheeEditor/Include/BsScriptHandleSliderLine.h

@@ -15,6 +15,7 @@ namespace BansheeEngine
 
 
 	protected:
 	protected:
 		virtual HandleSlider* getSlider() const { return mSlider; }
 		virtual HandleSlider* getSlider() const { return mSlider; }
+		virtual void destroy();
 
 
 	private:
 	private:
 		static void internal_CreateInstance(MonoObject* instance, Vector3 direction, float length, bool fixedScale, float snapValue);
 		static void internal_CreateInstance(MonoObject* instance, Vector3 direction, float length, bool fixedScale, float snapValue);

+ 1 - 0
SBansheeEditor/Include/BsScriptHandleSliderPlane.h

@@ -15,6 +15,7 @@ namespace BansheeEngine
 
 
 	protected:
 	protected:
 		virtual HandleSlider* getSlider() const { return mSlider; }
 		virtual HandleSlider* getSlider() const { return mSlider; }
+		virtual void destroy();
 
 
 	private:
 	private:
 		static void internal_CreateInstance(MonoObject* instance, Vector3 dir1, Vector3 dir2, float length, bool fixedScale, float snapValue);
 		static void internal_CreateInstance(MonoObject* instance, Vector3 dir1, Vector3 dir2, float length, bool fixedScale, float snapValue);

+ 2 - 0
SBansheeEditor/SBansheeEditor.vcxproj

@@ -231,6 +231,7 @@
     <ClInclude Include="Include\BsGUIPanelContainer.h" />
     <ClInclude Include="Include\BsGUIPanelContainer.h" />
     <ClInclude Include="Include\BsGUIResourceField.h" />
     <ClInclude Include="Include\BsGUIResourceField.h" />
     <ClInclude Include="Include\BsScriptEditorPrerequisites.h" />
     <ClInclude Include="Include\BsScriptEditorPrerequisites.h" />
+    <ClInclude Include="Include\BsScriptEditorUtility.h" />
     <ClInclude Include="Include\BsScriptEditorWindow.h" />
     <ClInclude Include="Include\BsScriptEditorWindow.h" />
     <ClInclude Include="Include\BsScriptGizmoManager.h" />
     <ClInclude Include="Include\BsScriptGizmoManager.h" />
     <ClInclude Include="Include\BsScriptGizmos.h" />
     <ClInclude Include="Include\BsScriptGizmos.h" />
@@ -262,6 +263,7 @@
     <ClCompile Include="Source\BsGUIPanelContainer.cpp" />
     <ClCompile Include="Source\BsGUIPanelContainer.cpp" />
     <ClCompile Include="Source\BsGUIResourceField.cpp" />
     <ClCompile Include="Source\BsGUIResourceField.cpp" />
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp" />
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp" />
+    <ClCompile Include="Source\BsScriptEditorUtility.cpp" />
     <ClCompile Include="Source\BsScriptEditorWindow.cpp" />
     <ClCompile Include="Source\BsScriptEditorWindow.cpp" />
     <ClCompile Include="Source\BsScriptGizmoManager.cpp" />
     <ClCompile Include="Source\BsScriptGizmoManager.cpp" />
     <ClCompile Include="Source\BsScriptGizmos.cpp" />
     <ClCompile Include="Source\BsScriptGizmos.cpp" />

+ 6 - 0
SBansheeEditor/SBansheeEditor.vcxproj.filters

@@ -102,6 +102,9 @@
     <ClInclude Include="Include\BsScriptHandleSliderDisc.h">
     <ClInclude Include="Include\BsScriptHandleSliderDisc.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptEditorUtility.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
@@ -191,5 +194,8 @@
     <ClCompile Include="Source\BsScriptHandleSliderDisc.cpp">
     <ClCompile Include="Source\BsScriptHandleSliderDisc.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptEditorUtility.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 1 - 1
SBansheeEditor/Source/BsEditorScriptManager.cpp

@@ -28,7 +28,7 @@ namespace BansheeEngine
 		ScriptGizmoManager::startUp(RuntimeScriptObjects::instance());
 		ScriptGizmoManager::startUp(RuntimeScriptObjects::instance());
 
 
 		mProgramEdClass = mEditorAssembly->getClass("BansheeEditor", "ProgramEd");
 		mProgramEdClass = mEditorAssembly->getClass("BansheeEditor", "ProgramEd");
-		mUpdateMethod = &mProgramEdClass->getMethod("EditorUpdate");
+		mUpdateMethod = mProgramEdClass->getMethod("EditorUpdate");
 
 
 		mEditorAssembly->invoke(ASSEMBLY_ENTRY_POINT);
 		mEditorAssembly->invoke(ASSEMBLY_ENTRY_POINT);
 		
 		

+ 52 - 0
SBansheeEditor/Source/BsScriptEditorUtility.cpp

@@ -0,0 +1,52 @@
+#include "BsScriptEditorUtility.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+#include "BsMonoUtil.h"
+#include "BsEditorUtility.h"
+#include "BsScriptSceneObject.h"
+
+namespace BansheeEngine
+{
+	ScriptEditorUtility::ScriptEditorUtility(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptEditorUtility::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_CalculateBounds", &ScriptEditorUtility::internal_CalculateBounds);
+		metaData.scriptClass->addInternalCall("Internal_CalculateBoundsArray", &ScriptEditorUtility::internal_CalculateBoundsArray);
+	}
+
+	static void internal_CalculateBounds(MonoObject* so, AABox* bounds);
+	static void internal_CalculateBounds(MonoArray* objects, AABox* bounds);
+
+	void ScriptEditorUtility::internal_CalculateBounds(MonoObject* so, AABox* bounds)
+	{
+		ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(so);
+
+		if (scriptSO != nullptr)
+			*bounds = EditorUtility::calculateBounds(static_object_cast<SceneObject>(scriptSO->getNativeHandle()));
+		else
+			*bounds = AABox();
+	}
+
+	void ScriptEditorUtility::internal_CalculateBoundsArray(MonoArray* objects, AABox* bounds)
+	{
+		Vector<HSceneObject> sceneObjects;
+
+		UINT32 arrayLen = (UINT32)mono_array_length(objects);
+		for (UINT32 i = 0; i < arrayLen; i++)
+		{
+			MonoObject* curObject = mono_array_get(objects, MonoObject*, i);
+
+			ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(curObject);
+
+			if (scriptSO != nullptr)
+				sceneObjects.push_back(static_object_cast<SceneObject>(scriptSO->getNativeHandle()));
+		}
+
+		*bounds = EditorUtility::calculateBounds(sceneObjects);
+	}
+}

+ 1 - 1
SBansheeEditor/Source/BsScriptEditorWindow.cpp

@@ -41,7 +41,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetWidth", &ScriptEditorWindow::internal_getWidth);
 		metaData.scriptClass->addInternalCall("Internal_GetWidth", &ScriptEditorWindow::internal_getWidth);
 		metaData.scriptClass->addInternalCall("Internal_GetHeight", &ScriptEditorWindow::internal_getHeight);
 		metaData.scriptClass->addInternalCall("Internal_GetHeight", &ScriptEditorWindow::internal_getHeight);
 
 
-		onResizedMethod = &metaData.scriptClass->getMethod("WindowResized", 2);
+		onResizedMethod = metaData.scriptClass->getMethod("WindowResized", 2);
 	}
 	}
 
 
 	MonoObject* ScriptEditorWindow::internal_createOrGetInstance(MonoString* ns, MonoString* typeName)
 	MonoObject* ScriptEditorWindow::internal_createOrGetInstance(MonoString* ns, MonoString* typeName)

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIColorField.cpp

@@ -34,7 +34,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUIColorField::internal_getValue);
 		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUIColorField::internal_getValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIColorField::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIColorField::internal_setValue);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIColorField::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,
 	void ScriptGUIColorField::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIComponentFoldout.cpp

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetExpanded", &ScriptGUIComponentFoldout::internal_setExpanded);
 		metaData.scriptClass->addInternalCall("Internal_SetExpanded", &ScriptGUIComponentFoldout::internal_setExpanded);
 		metaData.scriptClass->addInternalCall("Internal_IsExpanded", &ScriptGUIComponentFoldout::internal_getIsExpanded);
 		metaData.scriptClass->addInternalCall("Internal_IsExpanded", &ScriptGUIComponentFoldout::internal_getIsExpanded);
 
 
-		onToggledThunk = (OnToggledThunkDef)metaData.scriptClass->getMethod("DoOnToggled", 1).getThunk();
+		onToggledThunk = (OnToggledThunkDef)metaData.scriptClass->getMethod("DoOnToggled", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIComponentFoldout::internal_createInstance(MonoObject* instance, MonoObject* content, MonoString* style, MonoArray* guiOptions)
 	void ScriptGUIComponentFoldout::internal_createInstance(MonoObject* instance, MonoObject* content, MonoString* style, MonoArray* guiOptions)

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIFloatField.cpp

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIFloatField::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIFloatField::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIFloatField::internal_hasInputFocus);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIFloatField::internal_hasInputFocus);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIFloatField::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,
 	void ScriptGUIFloatField::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIFoldout.cpp

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetExpanded", &ScriptGUIFoldout::internal_setExpanded);
 		metaData.scriptClass->addInternalCall("Internal_SetExpanded", &ScriptGUIFoldout::internal_setExpanded);
 		metaData.scriptClass->addInternalCall("Internal_IsExpanded", &ScriptGUIFoldout::internal_getIsExpanded);
 		metaData.scriptClass->addInternalCall("Internal_IsExpanded", &ScriptGUIFoldout::internal_getIsExpanded);
 
 
-		onToggledThunk = (OnToggledThunkDef)metaData.scriptClass->getMethod("DoOnToggled", 1).getThunk();
+		onToggledThunk = (OnToggledThunkDef)metaData.scriptClass->getMethod("DoOnToggled", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIFoldout::internal_createInstance(MonoObject* instance, MonoObject* content, MonoString* style, MonoArray* guiOptions)
 	void ScriptGUIFoldout::internal_createInstance(MonoObject* instance, MonoObject* content, MonoString* style, MonoArray* guiOptions)

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIGameObjectField.cpp

@@ -36,7 +36,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUIGameObjectField::internal_getValue);
 		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUIGameObjectField::internal_getValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIGameObjectField::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIGameObjectField::internal_setValue);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIGameObjectField::internal_createInstance(MonoObject* instance, MonoReflectionType* type, MonoObject* title, UINT32 titleWidth,
 	void ScriptGUIGameObjectField::internal_createInstance(MonoObject* instance, MonoReflectionType* type, MonoObject* title, UINT32 titleWidth,

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIIntField.cpp

@@ -36,7 +36,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIIntField::internal_hasInputFocus);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIIntField::internal_hasInputFocus);
 		metaData.scriptClass->addInternalCall("Internal_SetRange", &ScriptGUIIntField::internal_setRange);
 		metaData.scriptClass->addInternalCall("Internal_SetRange", &ScriptGUIIntField::internal_setRange);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIIntField::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth, 
 	void ScriptGUIIntField::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth, 

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIResourceField.cpp

@@ -36,7 +36,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUIResourceField::internal_getValue);
 		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUIResourceField::internal_getValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIResourceField::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIResourceField::internal_setValue);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIResourceField::internal_createInstance(MonoObject* instance, MonoReflectionType* type, MonoObject* title, UINT32 titleWidth,
 	void ScriptGUIResourceField::internal_createInstance(MonoObject* instance, MonoReflectionType* type, MonoObject* title, UINT32 titleWidth,

+ 1 - 1
SBansheeEditor/Source/BsScriptGUITextField.cpp

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUITextField::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUITextField::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUITextField::internal_hasInputFocus);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUITextField::internal_hasInputFocus);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUITextField::internal_createInstance(MonoObject* instance, bool multiline, MonoObject* title, UINT32 titleWidth,
 	void ScriptGUITextField::internal_createInstance(MonoObject* instance, bool multiline, MonoObject* title, UINT32 titleWidth,

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIToggleField.cpp

@@ -34,7 +34,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUIToggleField::internal_getValue);
 		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUIToggleField::internal_getValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIToggleField::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIToggleField::internal_setValue);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIToggleField::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,
 	void ScriptGUIToggleField::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIVector2Field.cpp

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIVector2Field::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIVector2Field::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIVector2Field::internal_hasInputFocus);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIVector2Field::internal_hasInputFocus);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIVector2Field::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,
 	void ScriptGUIVector2Field::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIVector3Field.cpp

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIVector3Field::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIVector3Field::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIVector3Field::internal_hasInputFocus);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIVector3Field::internal_hasInputFocus);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIVector3Field::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,
 	void ScriptGUIVector3Field::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,

+ 1 - 1
SBansheeEditor/Source/BsScriptGUIVector4Field.cpp

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIVector4Field::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIVector4Field::internal_setValue);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIVector4Field::internal_hasInputFocus);
 		metaData.scriptClass->addInternalCall("Internal_HasInputFocus", &ScriptGUIVector4Field::internal_hasInputFocus);
 
 
-		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIVector4Field::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,
 	void ScriptGUIVector4Field::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,

+ 1 - 1
SBansheeEditor/Source/BsScriptGizmoManager.cpp

@@ -18,7 +18,7 @@ namespace BansheeEngine
 	ScriptGizmoManager::ScriptGizmoManager(RuntimeScriptObjects& scriptObjectManager)
 	ScriptGizmoManager::ScriptGizmoManager(RuntimeScriptObjects& scriptObjectManager)
 		:mScriptObjectManager(scriptObjectManager), mDrawGizmoAttribute(nullptr), mNextAssemblyId(0), mFlagsField(nullptr)
 		:mScriptObjectManager(scriptObjectManager), mDrawGizmoAttribute(nullptr), mNextAssemblyId(0), mFlagsField(nullptr)
 	{
 	{
-		mScriptObjectManager.onAssemblyRefreshed.connect(std::bind(&ScriptGizmoManager::reloadAssemblyMethods, this, _1));
+		mAssemblyRefreshedConn = mScriptObjectManager.onAssemblyRefreshed.connect(std::bind(&ScriptGizmoManager::reloadAssemblyMethods, this, _1));
 
 
 		Vector<String> initializedAssemblyNames = mScriptObjectManager.getInitializedAssemblies();
 		Vector<String> initializedAssemblyNames = mScriptObjectManager.getInitializedAssemblies();
 		for (auto& assemblyName : initializedAssemblyNames)
 		for (auto& assemblyName : initializedAssemblyNames)

+ 250 - 12
SBansheeEditor/Source/BsScriptHandleManager.cpp

@@ -1,33 +1,271 @@
 #include "BsScriptHandleManager.h"
 #include "BsScriptHandleManager.h"
+#include "BsRuntimeScriptObjects.h"
+#include "BsMonoManager.h"
+#include "BsMonoAssembly.h"
+#include "BsMonoClass.h"
+#include "BsMonoField.h"
+#include "BsMonoMethod.h"
+#include "BsMonoUtil.h"
+#include "BsSelection.h"
+#include "BsSceneObject.h"
+#include "BsManagedComponent.h"
+
+using namespace std::placeholders;
 
 
 namespace BansheeEngine
 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
+	ScriptHandleManager::ScriptHandleManager(const HCamera& camera, RuntimeScriptObjects& scriptObjectManager)
+		:HandleManager(camera), mScriptObjectManager(scriptObjectManager)
+	{
+		mAssemblyRefreshedConn = mScriptObjectManager.onAssemblyRefreshed.connect(std::bind(&ScriptHandleManager::reloadAssembly, this, _1));
+
+		Vector<String> initializedAssemblyNames = mScriptObjectManager.getInitializedAssemblies();
+		for (auto& assemblyName : initializedAssemblyNames)
+		{
+			MonoAssembly* assembly = MonoManager::instance().getAssembly(assemblyName);
+			if (assembly != nullptr)
+				reloadAssembly(assembly);
+		}
+	}
 
 
-	// TODO - Keep a list of every active ScriptSlider* type
+	ScriptHandleManager::~ScriptHandleManager()
+	{
+		for (auto& handle : mActiveHandleData.handles)
+		{
+			callDestroy(handle.object);
+			mono_gchandle_free(handle.gcHandle);
+		}
+
+		callDestroy(mDefaultHandleManager);
+		mono_gchandle_free(mDefaultHandleManagerGCHandle);
+
+		mAssemblyRefreshedConn.disconnect();
+	}
 
 
 	void ScriptHandleManager::refreshHandles()
 	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
+		const Vector<HSceneObject>& selectedSOs = Selection::instance().getSceneObjects();
+
+		HSceneObject newSelectedObject;
+		if (selectedSOs.size() > 0)
+		{
+			// We only consider the first selected object for custom handles, multiple selection is not supported
+			newSelectedObject = selectedSOs[0]; 
+		}
+
+		if (newSelectedObject != mActiveHandleData.selectedObject)
+		{
+			for (auto& handle : mActiveHandleData.handles)
+			{
+				callDestroy(handle.object);
+				mono_gchandle_free(handle.gcHandle);
+			}
+
+			mActiveHandleData.selectedObject = newSelectedObject;
+			mActiveHandleData.handles.clear();
+
+			if (newSelectedObject)
+			{
+				const Vector<HComponent>& components = newSelectedObject->getComponents();
+
+				for (auto& component : components)
+				{
+					if (!rtti_is_of_type<ManagedComponent>(component.getInternalPtr()))
+						continue;
+
+					HManagedComponent mc = static_object_cast<ManagedComponent>(component);
+					const String& componentTypeName = mc->getManagedFullTypeName();
+
+					auto iterFind = mHandles.find(componentTypeName);
+					if (iterFind == mHandles.end())
+						continue;
+
+					CustomHandleData& handleData = iterFind->second;
+					MonoObject* newHandleInstance = handleData.handleType->createInstance(false);
 
 
-		// TODO - Also handle creation of default move/rotate/scale handles
+					void* params[1] = { mc->getManagedInstance() };
+					handleData.ctor->invoke(newHandleInstance, params);
 
 
-		// TODO - Call Update() method on all active IHandle implementations
+					mActiveHandleData.handles.push_back(ActiveCustomHandleData());
+					ActiveCustomHandleData& newHandleData = mActiveHandleData.handles.back();
 
 
-		// TODO - Update matrices of all active sliders from their corresponding SOs
-		//   - Need to add a new field to SliderHandle for such matrix
+					newHandleData.object = newHandleInstance;
+					newHandleData.gcHandle = mono_gchandle_new(newHandleInstance, false);
+				}
+			}
+		}
+
+		if (mDefaultHandleManager == nullptr)
+		{
+			mDefaultHandleManager = mDefaultHandleManagerClass->createInstance(true);
+			mDefaultHandleManagerGCHandle = mono_gchandle_new(mDefaultHandleManager, false);
+		}
+
+		callPreInput(mDefaultHandleManager);
+
+		for (auto& handle : mActiveHandleData.handles)
+			callPreInput(handle.object);
 	}
 	}
 
 
 	void ScriptHandleManager::triggerHandles()
 	void ScriptHandleManager::triggerHandles()
 	{
 	{
-		// TODO - See if any sliders are active and if so, trigger their callbacks
+		callPostInput(mDefaultHandleManager);
+
+		for (auto& handle : mActiveHandleData.handles)
+		{
+			callPostInput(handle.object);
+		}
 	}
 	}
 
 
 	void ScriptHandleManager::queueDrawCommands()
 	void ScriptHandleManager::queueDrawCommands()
 	{
 	{
-		// TODO - Call Draw methods of all active IHandle implementations
+		callDraw(mDefaultHandleManager);
+
+		for (auto& handle : mActiveHandleData.handles)
+		{
+			callDraw(handle.object);
+		}
+	}
+
+	void ScriptHandleManager::reloadAssembly(MonoAssembly* assembly)
+	{
+		String assemblyName = assembly->getName();
+
+		// If editor assembly, reload needed types
+		if (assemblyName == BansheeEditorAssemblyName)
+		{
+			mCustomHandleAttribute = assembly->getClass("BansheeEditor", "CustomHandle");
+			if (mCustomHandleAttribute == nullptr)
+				BS_EXCEPT(InvalidStateException, "Cannot find CustomHandle managed class.");
+
+			mHandleBaseClass = assembly->getClass("BansheeEditor", "Handle");
+			if (mHandleBaseClass == nullptr)
+				BS_EXCEPT(InvalidStateException, "Cannot find Handle managed class.");
+
+			mDefaultHandleManagerClass = assembly->getClass("BansheeEditor", "DefaultHandleManager");
+			if (mDefaultHandleManagerClass == nullptr)
+				BS_EXCEPT(InvalidStateException, "Cannot find DefaultHandleManager managed class.");
+
+			mTypeField = mCustomHandleAttribute->getField("type");
+
+			mPreInputMethod = mHandleBaseClass->getMethod("PreInput", 0);
+			mPostInputMethod = mHandleBaseClass->getMethod("PostInput", 0);
+			mDrawMethod = mHandleBaseClass->getMethod("Draw", 0);
+			mDestroyThunk = (DestroyThunkDef)mHandleBaseClass->getMethod("Destroy", 0);
+
+			mDefaultHandleManager = nullptr; // Freed on assembly unload, so not valid anymore
+			mDefaultHandleManagerGCHandle = 0;
+		}
+		else
+		{
+			// If we haven't loaded editor assembly yet, do nothing, caller must ensure to load assemblies in order
+			if (mCustomHandleAttribute == nullptr)
+				return;
+		}
+
+		// If we had this assembly previously loaded, clear all of its types
+		UINT32 assemblyId = 0;
+		auto iterFind = mAssemblyNameToId.find(assemblyName);
+		if (iterFind != mAssemblyNameToId.end())
+		{
+			assemblyId = iterFind->second;
+
+			Map<String, CustomHandleData> newHandles;
+			for (auto& handleData : mHandles)
+			{
+				if (handleData.second.assemblyId != assemblyId)
+					newHandles[handleData.first] = handleData.second;
+			}
+
+			mHandles.swap(newHandles);
+		}
+		else
+		{
+			assemblyId = mNextAssemblyId++;
+			mAssemblyNameToId[assemblyName] = assemblyId;
+		}
+
+		// Find new custom handle types
+		const Vector<MonoClass*>& allClasses = assembly->getAllClasses();
+		for (auto curClass : allClasses)
+		{
+			MonoClass* componentType = nullptr;
+			MonoMethod* ctor = nullptr;
+
+			if (isValidHandleType(curClass, componentType, ctor))
+			{
+				String fullComponentName = componentType->getFullName();
+
+				CustomHandleData& newHandleData = mHandles[fullComponentName];
+
+				newHandleData.assemblyId = assemblyId;
+				newHandleData.componentType = componentType;
+				newHandleData.handleType = curClass;
+				newHandleData.ctor = ctor;
+			}
+		}
+	}
+
+	bool ScriptHandleManager::isValidHandleType(MonoClass* type, MonoClass*& componentType, MonoMethod*& ctor)
+	{
+		componentType = nullptr;
+		ctor = nullptr;
+
+		if (!type->hasAttribute(mCustomHandleAttribute))
+			return false;
+
+		if (!type->isSubClassOf(mHandleBaseClass))
+			return false;
+
+		MonoObject* customHandleAttrib = type->getAttribute(mCustomHandleAttribute);
+		MonoReflectionType* attribReflType = nullptr;
+
+		mTypeField->getValue(customHandleAttrib, &attribReflType);
+		MonoType* attribType = mono_reflection_type_get_type(attribReflType);
+		::MonoClass* attribMonoClass = mono_class_from_mono_type(attribType);
+
+		MonoClass* attribClass = MonoManager::instance().findClass(attribMonoClass);
+		if (attribClass == nullptr)
+			return false;
+
+		MonoClass* componentClass = mScriptObjectManager.getComponentClass();
+		if (!attribClass->isSubClassOf(componentClass))
+			return false;
+		
+		MonoMethod* constructor = type->getMethod(".ctor", 1);
+		if (constructor == nullptr)
+			return false;
+
+		MonoClass* paramType = constructor->getParameterType(0);
+		if (paramType != attribClass)
+			return false;
+
+		componentType = paramType;
+		ctor = constructor;
+
+		return true;
+	}
+
+	void ScriptHandleManager::callPreInput(MonoObject* instance)
+	{
+		mPreInputMethod->invokeVirtual(instance, nullptr);
+	}
+
+	void ScriptHandleManager::callPostInput(MonoObject* instance)
+	{
+		mPostInputMethod->invokeVirtual(instance, nullptr);
+	}
+
+	void ScriptHandleManager::callDraw(MonoObject* instance)
+	{
+		mDrawMethod->invokeVirtual(instance, nullptr);
+	}
+
+	void ScriptHandleManager::callDestroy(MonoObject* instance)
+	{
+		MonoException* exception = nullptr;
+		mDestroyThunk(instance, &exception);
+
+		MonoUtil::throwIfException(exception);
 	}
 	}
 }
 }

+ 7 - 1
SBansheeEditor/Source/BsScriptHandleSlider.cpp

@@ -11,13 +11,14 @@ namespace BansheeEngine
 	}
 	}
 
 
 	ScriptHandleSlider::ScriptHandleSlider(MonoObject* instance)
 	ScriptHandleSlider::ScriptHandleSlider(MonoObject* instance)
-		:ScriptObject(instance)
+		: ScriptObject(instance)
 	{
 	{
 
 
 	}
 	}
 
 
 	void ScriptHandleSlider::initRuntimeData()
 	void ScriptHandleSlider::initRuntimeData()
 	{
 	{
+		metaData.scriptClass->addInternalCall("Internal_Destroy", &ScriptHandleSlider::internal_Destroy);
 		metaData.scriptClass->addInternalCall("Internal_GetPosition", &ScriptHandleSlider::internal_GetPosition);
 		metaData.scriptClass->addInternalCall("Internal_GetPosition", &ScriptHandleSlider::internal_GetPosition);
 		metaData.scriptClass->addInternalCall("Internal_SetPosition", &ScriptHandleSlider::internal_SetPosition);
 		metaData.scriptClass->addInternalCall("Internal_SetPosition", &ScriptHandleSlider::internal_SetPosition);
 		metaData.scriptClass->addInternalCall("Internal_GetRotation", &ScriptHandleSlider::internal_GetRotation);
 		metaData.scriptClass->addInternalCall("Internal_GetRotation", &ScriptHandleSlider::internal_GetRotation);
@@ -27,6 +28,11 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetState", &ScriptHandleSlider::internal_GetState);
 		metaData.scriptClass->addInternalCall("Internal_GetState", &ScriptHandleSlider::internal_GetState);
 	}
 	}
 
 
+	void ScriptHandleSlider::internal_Destroy(ScriptHandleSliderBase* nativeInstance)
+	{
+		nativeInstance->destroy();
+	}
+
 	void ScriptHandleSlider::internal_GetPosition(ScriptHandleSliderBase* nativeInstance, Vector3* value)
 	void ScriptHandleSlider::internal_GetPosition(ScriptHandleSliderBase* nativeInstance, Vector3* value)
 	{
 	{
 		*value = nativeInstance->getSlider()->getPosition();
 		*value = nativeInstance->getSlider()->getPosition();

+ 11 - 2
SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp

@@ -9,12 +9,21 @@ namespace BansheeEngine
 	ScriptHandleSliderDisc::ScriptHandleSliderDisc(MonoObject* instance, const Vector3& normal, float radius, bool fixedScale, float snapValue)
 	ScriptHandleSliderDisc::ScriptHandleSliderDisc(MonoObject* instance, const Vector3& normal, float radius, bool fixedScale, float snapValue)
 		:ScriptObject(instance), mSlider(nullptr)
 		:ScriptObject(instance), mSlider(nullptr)
 	{
 	{
-		mSlider = bs_new<HandleSliderDisc>(normal, radius, fixedScale, snapValue);
+		mSlider = bs_new<HandleSliderDisc>(normal, radius, snapValue, fixedScale);
 	}
 	}
 
 
 	ScriptHandleSliderDisc::~ScriptHandleSliderDisc()
 	ScriptHandleSliderDisc::~ScriptHandleSliderDisc()
 	{
 	{
-		bs_delete(mSlider);
+		if (mSlider != nullptr)
+			bs_delete(mSlider);
+	}
+
+	void ScriptHandleSliderDisc::destroy()
+	{
+		if (mSlider != nullptr)
+			bs_delete(mSlider);
+
+		mSlider = nullptr;
 	}
 	}
 
 
 	void ScriptHandleSliderDisc::initRuntimeData()
 	void ScriptHandleSliderDisc::initRuntimeData()

+ 11 - 2
SBansheeEditor/Source/BsScriptHandleSliderLine.cpp

@@ -9,12 +9,21 @@ namespace BansheeEngine
 	ScriptHandleSliderLine::ScriptHandleSliderLine(MonoObject* instance, const Vector3& direction, float length, bool fixedScale, float snapValue)
 	ScriptHandleSliderLine::ScriptHandleSliderLine(MonoObject* instance, const Vector3& direction, float length, bool fixedScale, float snapValue)
 		:ScriptObject(instance), mSlider(nullptr)
 		:ScriptObject(instance), mSlider(nullptr)
 	{
 	{
-		mSlider = bs_new<HandleSliderLine>(direction, length, fixedScale, snapValue);
+		mSlider = bs_new<HandleSliderLine>(direction, length, snapValue, fixedScale);
 	}
 	}
 
 
 	ScriptHandleSliderLine::~ScriptHandleSliderLine()
 	ScriptHandleSliderLine::~ScriptHandleSliderLine()
 	{
 	{
-		bs_delete(mSlider);
+		if (mSlider != nullptr)
+			bs_delete(mSlider);
+	}
+
+	void ScriptHandleSliderLine::destroy()
+	{
+		if (mSlider != nullptr)
+			bs_delete(mSlider);
+
+		mSlider = nullptr;
 	}
 	}
 
 
 	void ScriptHandleSliderLine::initRuntimeData()
 	void ScriptHandleSliderLine::initRuntimeData()

+ 11 - 2
SBansheeEditor/Source/BsScriptHandleSliderPlane.cpp

@@ -9,12 +9,21 @@ namespace BansheeEngine
 	ScriptHandleSliderPlane::ScriptHandleSliderPlane(MonoObject* instance, const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale, float snapValue)
 	ScriptHandleSliderPlane::ScriptHandleSliderPlane(MonoObject* instance, const Vector3& dir1, const Vector3& dir2, float length, bool fixedScale, float snapValue)
 		:ScriptObject(instance), mSlider(nullptr)
 		:ScriptObject(instance), mSlider(nullptr)
 	{
 	{
-		mSlider = bs_new<HandleSliderPlane>(dir1, dir2, length, fixedScale, snapValue);
+		mSlider = bs_new<HandleSliderPlane>(dir1, dir2, length, snapValue, fixedScale);
 	}
 	}
 
 
 	ScriptHandleSliderPlane::~ScriptHandleSliderPlane()
 	ScriptHandleSliderPlane::~ScriptHandleSliderPlane()
 	{
 	{
-		bs_delete(mSlider);
+		if (mSlider != nullptr)
+			bs_delete(mSlider);
+	}
+
+	void ScriptHandleSliderPlane::destroy()
+	{
+		if (mSlider != nullptr)
+			bs_delete(mSlider);
+
+		mSlider = nullptr;
 	}
 	}
 
 
 	void ScriptHandleSliderPlane::initRuntimeData()
 	void ScriptHandleSliderPlane::initRuntimeData()

+ 1 - 0
SBansheeEngine/Include/BsScriptComponent.h

@@ -22,6 +22,7 @@ namespace BansheeEngine
 		static MonoObject* internal_getComponent(MonoObject* parentSceneObject, MonoReflectionType* type);
 		static MonoObject* internal_getComponent(MonoObject* parentSceneObject, MonoReflectionType* type);
 		static MonoArray* internal_getComponents(MonoObject* parentSceneObject);
 		static MonoArray* internal_getComponents(MonoObject* parentSceneObject);
 		static void internal_removeComponent(MonoObject* parentSceneObject, MonoReflectionType* type);
 		static void internal_removeComponent(MonoObject* parentSceneObject, MonoReflectionType* type);
+		static MonoObject* internal_getSceneObject(ScriptComponent* nativeInstance);
 
 
 		ScriptComponent(MonoObject* instance, const GameObjectHandle<ManagedComponent>& managedComponent);
 		ScriptComponent(MonoObject* instance, const GameObjectHandle<ManagedComponent>& managedComponent);
 		~ScriptComponent() {}
 		~ScriptComponent() {}

+ 13 - 0
SBansheeEngine/Include/BsScriptSceneObject.h

@@ -26,6 +26,19 @@ namespace BansheeEngine
 		static UINT32 internal_getNumChildren(ScriptSceneObject* nativeInstance);
 		static UINT32 internal_getNumChildren(ScriptSceneObject* nativeInstance);
 		static MonoObject* internal_getChild(ScriptSceneObject* nativeInstance, UINT32 idx);
 		static MonoObject* internal_getChild(ScriptSceneObject* nativeInstance, UINT32 idx);
 
 
+		static void internal_getPosition(ScriptSceneObject* nativeInstance, Vector3* value);
+		static void internal_getLocalPosition(ScriptSceneObject* nativeInstance, Vector3* value);
+		static void internal_getRotation(ScriptSceneObject* nativeInstance, Quaternion* value);
+		static void internal_getLocalRotation(ScriptSceneObject* nativeInstance, Quaternion* value);
+		static void internal_getScale(ScriptSceneObject* nativeInstance, Vector3* value);
+		static void internal_getLocalScale(ScriptSceneObject* nativeInstance, Vector3* value);
+
+		static void internal_setPosition(ScriptSceneObject* nativeInstance, Vector3 value);
+		static void internal_setLocalPosition(ScriptSceneObject* nativeInstance, Vector3 value);
+		static void internal_setRotation(ScriptSceneObject* nativeInstance, Quaternion value);
+		static void internal_setLocalRotation(ScriptSceneObject* nativeInstance, Quaternion value);
+		static void internal_setLocalScale(ScriptSceneObject* nativeInstance, Vector3 value);
+
 		ScriptSceneObject(MonoObject* instance, const HSceneObject& sceneObject);
 		ScriptSceneObject(MonoObject* instance, const HSceneObject& sceneObject);
 
 
 		void _onManagedInstanceDeleted();
 		void _onManagedInstanceDeleted();

+ 2 - 2
SBansheeEngine/Source/BsManagedSerializableArray.cpp

@@ -179,10 +179,10 @@ namespace BansheeEngine
 	UINT32 ManagedSerializableArray::getLength(UINT32 dimension) const
 	UINT32 ManagedSerializableArray::getLength(UINT32 dimension) const
 	{
 	{
 		MonoClass* systemArray = RuntimeScriptObjects::instance().getSystemArrayClass();
 		MonoClass* systemArray = RuntimeScriptObjects::instance().getSystemArrayClass();
-		MonoMethod& getLength = systemArray->getMethod("GetLength", 1);
+		MonoMethod* getLength = systemArray->getMethod("GetLength", 1);
 
 
 		void* params[1] = { &dimension };
 		void* params[1] = { &dimension };
-		MonoObject* returnObj = getLength.invoke(mManagedInstance, params);
+		MonoObject* returnObj = getLength->invoke(mManagedInstance, params);
 
 
 		return *(UINT32*)mono_object_unbox(returnObj);
 		return *(UINT32*)mono_object_unbox(returnObj);
 	}
 	}

+ 3 - 3
SBansheeEngine/Source/BsManagedSerializableDictionary.cpp

@@ -148,13 +148,13 @@ namespace BansheeEngine
 
 
 	void ManagedSerializableDictionary::initMonoObjects(MonoClass* dictionaryClass)
 	void ManagedSerializableDictionary::initMonoObjects(MonoClass* dictionaryClass)
 	{
 	{
-		mAddMethod = &dictionaryClass->getMethod("Add", 2);
-		mGetEnumerator = &dictionaryClass->getMethod("GetEnumerator");
+		mAddMethod = dictionaryClass->getMethod("Add", 2);
+		mGetEnumerator = dictionaryClass->getMethod("GetEnumerator");
 
 
 		MonoClass* enumeratorClass = mGetEnumerator->getReturnType();
 		MonoClass* enumeratorClass = mGetEnumerator->getReturnType();
 		assert(enumeratorClass != nullptr);
 		assert(enumeratorClass != nullptr);
 
 
-		mEnumMoveNext = &enumeratorClass->getMethod("MoveNext");
+		mEnumMoveNext = enumeratorClass->getMethod("MoveNext");
 		mEnumCurrentProp = &enumeratorClass->getProperty("Current");
 		mEnumCurrentProp = &enumeratorClass->getProperty("Current");
 
 
 		MonoClass* keyValuePairClass = mEnumCurrentProp->getReturnType();
 		MonoClass* keyValuePairClass = mEnumCurrentProp->getReturnType();

+ 1 - 1
SBansheeEngine/Source/BsManagedSerializableList.cpp

@@ -127,7 +127,7 @@ namespace BansheeEngine
 	{
 	{
 		mItemProp = &listClass->getProperty("Item");
 		mItemProp = &listClass->getProperty("Item");
 		mCountProp = &listClass->getProperty("Count");
 		mCountProp = &listClass->getProperty("Count");
-		mAddMethod = &listClass->getMethod("Add", 1);
+		mAddMethod = listClass->getMethod("Add", 1);
 	}
 	}
 
 
 	RTTITypeBase* ManagedSerializableList::getRTTIStatic()
 	RTTITypeBase* ManagedSerializableList::getRTTIStatic()

+ 2 - 2
SBansheeEngine/Source/BsRuntimeScriptObjects.cpp

@@ -318,8 +318,8 @@ namespace BansheeEngine
 			{
 			{
 				std::shared_ptr<ManagedSerializableTypeInfoDictionary> typeInfo = bs_shared_ptr<ManagedSerializableTypeInfoDictionary>();
 				std::shared_ptr<ManagedSerializableTypeInfoDictionary> typeInfo = bs_shared_ptr<ManagedSerializableTypeInfoDictionary>();
 
 
-				MonoMethod& getEnumerator = monoClass->getMethod("GetEnumerator");
-				MonoClass* enumClass = getEnumerator.getReturnType();
+				MonoMethod* getEnumerator = monoClass->getMethod("GetEnumerator");
+				MonoClass* enumClass = getEnumerator->getReturnType();
 
 
 				MonoProperty& currentProp = enumClass->getProperty("Current");
 				MonoProperty& currentProp = enumClass->getProperty("Current");
 				MonoClass* keyValuePair = currentProp.getReturnType();
 				MonoClass* keyValuePair = currentProp.getReturnType();

+ 12 - 0
SBansheeEngine/Source/BsScriptComponent.cpp

@@ -21,6 +21,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetComponent", &ScriptComponent::internal_getComponent);
 		metaData.scriptClass->addInternalCall("Internal_GetComponent", &ScriptComponent::internal_getComponent);
 		metaData.scriptClass->addInternalCall("Internal_GetComponents", &ScriptComponent::internal_getComponents);
 		metaData.scriptClass->addInternalCall("Internal_GetComponents", &ScriptComponent::internal_getComponents);
 		metaData.scriptClass->addInternalCall("Internal_RemoveComponent", &ScriptComponent::internal_removeComponent);
 		metaData.scriptClass->addInternalCall("Internal_RemoveComponent", &ScriptComponent::internal_removeComponent);
+		metaData.scriptClass->addInternalCall("Internal_GetSceneObject", &ScriptComponent::internal_getSceneObject);
 	}
 	}
 
 
 	MonoObject* ScriptComponent::internal_addComponent(MonoObject* parentSceneObject, MonoReflectionType* type)
 	MonoObject* ScriptComponent::internal_addComponent(MonoObject* parentSceneObject, MonoReflectionType* type)
@@ -126,6 +127,17 @@ namespace BansheeEngine
 		LOGWRN("Attempting to remove a component that doesn't exists on SceneObject \"" + so->getName() + "\"");
 		LOGWRN("Attempting to remove a component that doesn't exists on SceneObject \"" + so->getName() + "\"");
 	}
 	}
 
 
+	MonoObject* ScriptComponent::internal_getSceneObject(ScriptComponent* nativeInstance)
+	{
+		HSceneObject sceneObject = nativeInstance->mManagedComponent->sceneObject();
+
+		ScriptSceneObject* scriptSO = ScriptGameObjectManager::instance().getScriptSceneObject(sceneObject);
+		if (scriptSO == nullptr)
+			scriptSO = ScriptGameObjectManager::instance().createScriptSceneObject(sceneObject);
+
+		return scriptSO->getManagedInstance();
+	}
+
 	void ScriptComponent::_onManagedInstanceDeleted()
 	void ScriptComponent::_onManagedInstanceDeleted()
 	{
 	{
 		mManagedInstance = nullptr;
 		mManagedInstance = nullptr;

+ 3 - 3
SBansheeEngine/Source/BsScriptGUIButton.cpp

@@ -32,9 +32,9 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptGUIButton::internal_createInstance);
 		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptGUIButton::internal_createInstance);
 		metaData.scriptClass->addInternalCall("Internal_SetContent", &ScriptGUIButton::internal_setContent);
 		metaData.scriptClass->addInternalCall("Internal_SetContent", &ScriptGUIButton::internal_setContent);
 
 
-		onClickThunk = (OnClickThunkDef)metaData.scriptClass->getMethod("DoOnClick").getThunk();
-		onHoverThunk = (OnHoverThunkDef)metaData.scriptClass->getMethod("DoOnHover").getThunk();
-		onOutThunk = (OnOutThunkDef)metaData.scriptClass->getMethod("DoOnOut").getThunk();
+		onClickThunk = (OnClickThunkDef)metaData.scriptClass->getMethod("DoOnClick")->getThunk();
+		onHoverThunk = (OnHoverThunkDef)metaData.scriptClass->getMethod("DoOnHover")->getThunk();
+		onOutThunk = (OnOutThunkDef)metaData.scriptClass->getMethod("DoOnOut")->getThunk();
 	}
 	}
 
 
 	void ScriptGUIButton::internal_createInstance(MonoObject* instance, MonoObject* content, MonoString* style, MonoArray* guiOptions)
 	void ScriptGUIButton::internal_createInstance(MonoObject* instance, MonoObject* content, MonoString* style, MonoArray* guiOptions)

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIListBox.cpp

@@ -31,7 +31,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptGUIListBox::internal_createInstance);
 		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptGUIListBox::internal_createInstance);
 		metaData.scriptClass->addInternalCall("Internal_SetElements", &ScriptGUIListBox::internal_setElements);
 		metaData.scriptClass->addInternalCall("Internal_SetElements", &ScriptGUIListBox::internal_setElements);
 
 
-		onSelectionChangedThunk = (OnSelectionChangedThunkDef)metaData.scriptClass->getMethod("DoOnSelectionChanged", 1).getThunk();
+		onSelectionChangedThunk = (OnSelectionChangedThunkDef)metaData.scriptClass->getMethod("DoOnSelectionChanged", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIListBox::internal_createInstance(MonoObject* instance, MonoArray* elements, MonoString* style, MonoArray* guiOptions)
 	void ScriptGUIListBox::internal_createInstance(MonoObject* instance, MonoArray* elements, MonoString* style, MonoArray* guiOptions)

+ 4 - 4
SBansheeEngine/Source/BsScriptGUIToggle.cpp

@@ -39,10 +39,10 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_ToggleOn", &ScriptGUIToggle::internal_toggleOn);
 		metaData.scriptClass->addInternalCall("Internal_ToggleOn", &ScriptGUIToggle::internal_toggleOn);
 		metaData.scriptClass->addInternalCall("Internal_ToggleOff", &ScriptGUIToggle::internal_toggleOff);
 		metaData.scriptClass->addInternalCall("Internal_ToggleOff", &ScriptGUIToggle::internal_toggleOff);
 
 
-		onClickThunk = (OnClickThunkDef)metaData.scriptClass->getMethod("DoOnClick").getThunk();
-		onHoverThunk = (OnHoverThunkDef)metaData.scriptClass->getMethod("DoOnHover").getThunk();
-		onOutThunk = (OnOutThunkDef)metaData.scriptClass->getMethod("DoOnOut").getThunk();
-		onToggledThunk = (OnToggledThunkDef)metaData.scriptClass->getMethod("DoOnToggled", 1).getThunk();
+		onClickThunk = (OnClickThunkDef)metaData.scriptClass->getMethod("DoOnClick")->getThunk();
+		onHoverThunk = (OnHoverThunkDef)metaData.scriptClass->getMethod("DoOnHover")->getThunk();
+		onOutThunk = (OnOutThunkDef)metaData.scriptClass->getMethod("DoOnOut")->getThunk();
+		onToggledThunk = (OnToggledThunkDef)metaData.scriptClass->getMethod("DoOnToggled", 1)->getThunk();
 	}
 	}
 
 
 	void ScriptGUIToggle::internal_createInstance(MonoObject* instance, MonoObject* content, 
 	void ScriptGUIToggle::internal_createInstance(MonoObject* instance, MonoObject* content, 

+ 68 - 0
SBansheeEngine/Source/BsScriptSceneObject.cpp

@@ -22,6 +22,19 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetParent", &ScriptSceneObject::internal_setParent);
 		metaData.scriptClass->addInternalCall("Internal_SetParent", &ScriptSceneObject::internal_setParent);
 		metaData.scriptClass->addInternalCall("Internal_GetNumChildren", &ScriptSceneObject::internal_getNumChildren);
 		metaData.scriptClass->addInternalCall("Internal_GetNumChildren", &ScriptSceneObject::internal_getNumChildren);
 		metaData.scriptClass->addInternalCall("Internal_GetChild", &ScriptSceneObject::internal_getChild);
 		metaData.scriptClass->addInternalCall("Internal_GetChild", &ScriptSceneObject::internal_getChild);
+
+		metaData.scriptClass->addInternalCall("Internal_GetPosition", &ScriptSceneObject::internal_getPosition);
+		metaData.scriptClass->addInternalCall("Internal_GetLocalPosition", &ScriptSceneObject::internal_getLocalPosition);
+		metaData.scriptClass->addInternalCall("Internal_GetRotation", &ScriptSceneObject::internal_getRotation);
+		metaData.scriptClass->addInternalCall("Internal_GetLocalRotation", &ScriptSceneObject::internal_getLocalRotation);
+		metaData.scriptClass->addInternalCall("Internal_GetScale", &ScriptSceneObject::internal_getScale);
+		metaData.scriptClass->addInternalCall("Internal_GetLocalScale", &ScriptSceneObject::internal_getLocalScale);
+
+		metaData.scriptClass->addInternalCall("Internal_SetPosition", &ScriptSceneObject::internal_setPosition);
+		metaData.scriptClass->addInternalCall("Internal_SetLocalPosition", &ScriptSceneObject::internal_setLocalPosition);
+		metaData.scriptClass->addInternalCall("Internal_SetRotation", &ScriptSceneObject::internal_setRotation);
+		metaData.scriptClass->addInternalCall("Internal_SetLocalRotation", &ScriptSceneObject::internal_setLocalRotation);
+		metaData.scriptClass->addInternalCall("Internal_SetLocalScale", &ScriptSceneObject::internal_setLocalScale);
 	}
 	}
 
 
 	void ScriptSceneObject::internal_createInstance(MonoObject* instance, MonoString* name)
 	void ScriptSceneObject::internal_createInstance(MonoObject* instance, MonoString* name)
@@ -72,6 +85,61 @@ namespace BansheeEngine
 		return childScriptSO->getManagedInstance();
 		return childScriptSO->getManagedInstance();
 	}
 	}
 
 
+	void ScriptSceneObject::internal_getPosition(ScriptSceneObject* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->mSceneObject->getWorldPosition();
+	}
+
+	void ScriptSceneObject::internal_getLocalPosition(ScriptSceneObject* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->mSceneObject->getPosition();
+	}
+
+	void ScriptSceneObject::internal_getRotation(ScriptSceneObject* nativeInstance, Quaternion* value)
+	{
+		*value = nativeInstance->mSceneObject->getWorldRotation();
+	}
+
+	void ScriptSceneObject::internal_getLocalRotation(ScriptSceneObject* nativeInstance, Quaternion* value)
+	{
+		*value = nativeInstance->mSceneObject->getRotation();
+	}
+
+	void ScriptSceneObject::internal_getScale(ScriptSceneObject* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->mSceneObject->getWorldScale();
+	}
+
+	void ScriptSceneObject::internal_getLocalScale(ScriptSceneObject* nativeInstance, Vector3* value)
+	{
+		*value = nativeInstance->mSceneObject->getWorldScale();
+	}
+
+	void ScriptSceneObject::internal_setPosition(ScriptSceneObject* nativeInstance, Vector3 value)
+	{
+		nativeInstance->mSceneObject->setWorldPosition(value);
+	}
+
+	void ScriptSceneObject::internal_setLocalPosition(ScriptSceneObject* nativeInstance, Vector3 value)
+	{
+		nativeInstance->mSceneObject->setPosition(value);
+	}
+
+	void ScriptSceneObject::internal_setRotation(ScriptSceneObject* nativeInstance, Quaternion value)
+	{
+		nativeInstance->mSceneObject->setWorldRotation(value);
+	}
+
+	void ScriptSceneObject::internal_setLocalRotation(ScriptSceneObject* nativeInstance, Quaternion value)
+	{
+		nativeInstance->mSceneObject->setRotation(value);
+	}
+
+	void ScriptSceneObject::internal_setLocalScale(ScriptSceneObject* nativeInstance, Vector3 value)
+	{
+		nativeInstance->mSceneObject->setScale(value);
+	}
+
 	void ScriptSceneObject::_onManagedInstanceDeleted()
 	void ScriptSceneObject::_onManagedInstanceDeleted()
 	{
 	{
 		mManagedInstance = nullptr;
 		mManagedInstance = nullptr;

+ 10 - 55
SceneView.txt

@@ -45,74 +45,29 @@ Free move/rotate/scale handles need to exist as well
  - Move also use SliderPlane oriented towards camera
  - Move also use SliderPlane oriented towards camera
  - Rotation use SliderDisc oriented towards camera
  - Rotation use SliderDisc oriented towards camera
 
 
+----------------------------------------------------
+STAGE 1
+
 CONCRETE TODO:
 CONCRETE TODO:
 HandleSliderManager
 HandleSliderManager
  - Detecting input and updating the sliders
  - Detecting input and updating the sliders
  - isHandleActive
  - isHandleActive
 
 
 ScriptHandleManager
 ScriptHandleManager
- - Pretty much everything (in more detail in .cpp file)
  - Needs to be started up somewhere
  - Needs to be started up somewhere
 
 
-C# Component needs "sceneObject" property
-C# SceneObject needs position/rot/scale (and local variants) properties
-
 SceneEditorWidget
 SceneEditorWidget
  - Need to glue everything together
  - 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
+----------------------------------------------------
+STAGE 2
+Implement RotateHandle & ScaleHandle in C#
+ - Nearest point to disc/arc code
+Add free move, free rotate, free scale functionality
 Handles that remain the same size regardless of distance from camera
 Handles that remain the same size regardless of distance from camera
  - For both drawing and collision
  - For both drawing and collision
-Consider local vs. global handle mode
-
-OPEN QUESTIONS:
- - How to handle handles with multiple selection?
-
-EXAMPLE:
-
-[CustomHandle(typeof(Camera))]
-class CameraHandle : IHandle
-{
-     SliderLine xAxis;
-     SliderLine yAxis;
-     
-     CameraHandle()
-     {
-         xAxis = new SliderLine(Vector3.right, 10.0f);
-         yAxis = new SliderLine(Vector3.up, 10.0f);
-
-         xAxis.onDragged += onXAxis();
-         yAxis.onDragged += onYAxis();
-     }
-
-     void onXAxis()
-     {
-          // Here I can decide whether or not I want to use handle data or not, per object instance
-          target.position = xAxis.getMove(target.position);
-     }
-
-     void onYAxis()
-     {
-          target.position = yAxis.getMove(target.position);
-     }
-
-     void Update()
-     {
-           // Resize handle, change matrix, etc.
-     }
-
-     void Draw()
-     {
-           xAxis.Draw();
-
-           HandleDraw.Arrow(target.position, Vector3.right, 10.0f);
-           HandleDraw.Arrow(target.position, Vector3.up, 10.0f);
-     }
-}
+
+ More complex types for drawing like DrawArrow in HandleDrawManager
 
 
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 SelectionRenderer
 SelectionRenderer