Explorar o código

WIP Scene window
Added C# EditorSettings & SceneViewHandler

Marko Pintera %!s(int64=11) %!d(string=hai) anos
pai
achega
46eb1edb0f
Modificáronse 59 ficheiros con 1165 adicións e 312 borrados
  1. 6 0
      BansheeCore/Include/BsInput.h
  2. 7 0
      BansheeCore/Source/BsInput.cpp
  3. 4 5
      BansheeEditor/BansheeEditor.vcxproj
  4. 16 19
      BansheeEditor/BansheeEditor.vcxproj.filters
  5. 2 2
      BansheeEditor/Include/BsEditorApplication.h
  6. 3 2
      BansheeEditor/Include/BsEditorPrerequisites.h
  7. 63 0
      BansheeEditor/Include/BsEditorSettings.h
  8. 1 1
      BansheeEditor/Include/BsEditorWidget.h
  9. 1 1
      BansheeEditor/Include/BsEditorWidgetContainer.h
  10. 1 0
      BansheeEditor/Include/BsGizmoManager.h
  11. 10 11
      BansheeEditor/Include/BsHandleManager.h
  12. 6 4
      BansheeEditor/Include/BsHandleSliderManager.h
  13. 0 45
      BansheeEditor/Include/BsProjectSettings.h
  14. 0 2
      BansheeEditor/Include/BsSceneEditorWidget.h
  15. 7 1
      BansheeEditor/Include/BsSceneGrid.h
  16. 25 0
      BansheeEditor/Include/BsSceneViewHandler.h
  17. 1 1
      BansheeEditor/Include/DbgEditorWidget1.h
  18. 1 1
      BansheeEditor/Source/BsDockManager.cpp
  19. 2 5
      BansheeEditor/Source/BsEditorApplication.cpp
  20. 6 0
      BansheeEditor/Source/BsEditorSettings.cpp
  21. 2 2
      BansheeEditor/Source/BsEditorWidgetContainer.cpp
  22. 1 1
      BansheeEditor/Source/BsEditorWindow.cpp
  23. 36 37
      BansheeEditor/Source/BsGizmoManager.cpp
  24. 20 8
      BansheeEditor/Source/BsHandleManager.cpp
  25. 57 63
      BansheeEditor/Source/BsHandleSliderManager.cpp
  26. 0 17
      BansheeEditor/Source/BsMainEditorWindow.cpp
  27. 1 3
      BansheeEditor/Source/BsSceneEditorWidget.cpp
  28. 24 1
      BansheeEditor/Source/BsSceneGrid.cpp
  29. 90 0
      BansheeEditor/Source/BsSceneViewHandler.cpp
  30. 1 1
      BansheeEditor/Source/DbgEditorWidget1.cpp
  31. 59 2
      MBansheeEditor/EditorApplication.cs
  32. 90 0
      MBansheeEditor/EditorSettings.cs
  33. 2 2
      MBansheeEditor/Inspector/InspectorWindow.cs
  34. 2 0
      MBansheeEditor/MBansheeEditor.csproj
  35. 3 16
      MBansheeEditor/Program.cs
  36. 41 10
      MBansheeEditor/Scene/Handles.cs
  37. 1 1
      MBansheeEditor/Scene/MoveHandle.cs
  38. 45 0
      MBansheeEditor/Scene/SceneViewHandler.cs
  39. 96 1
      MBansheeEditor/Scene/SceneWindow.cs
  40. 34 26
      MBansheeEngine/Camera.cs
  41. 20 9
      MBansheeEngine/GUI/GUIRenderTexture.cs
  42. 13 0
      MBansheeEngine/Input.cs
  43. 53 0
      MBansheeEngine/Math/Quaternion.cs
  44. 11 0
      MBansheeEngine/Math/Rect2I.cs
  45. 5 0
      MBansheeEngine/SceneObject.cs
  46. 31 0
      SBansheeEditor/Include/BsScriptEditorSettings.h
  47. 9 1
      SBansheeEditor/Include/BsScriptEditorWindow.h
  48. 24 0
      SBansheeEditor/Include/BsScriptSceneViewHandler.h
  49. 4 0
      SBansheeEditor/SBansheeEditor.vcxproj
  50. 12 0
      SBansheeEditor/SBansheeEditor.vcxproj.filters
  51. 116 0
      SBansheeEditor/Source/BsScriptEditorSettings.cpp
  52. 23 4
      SBansheeEditor/Source/BsScriptEditorWindow.cpp
  53. 48 0
      SBansheeEditor/Source/BsScriptSceneViewHandler.cpp
  54. 4 0
      SBansheeEngine/Include/BsScriptCamera.h
  55. 1 0
      SBansheeEngine/Include/BsScriptEnginePrerequisites.h
  56. 1 0
      SBansheeEngine/Include/BsScriptInput.h
  57. 7 0
      SBansheeEngine/Source/BsScriptCamera.cpp
  58. 6 0
      SBansheeEngine/Source/BsScriptInput.cpp
  59. 10 7
      TODO.txt

+ 6 - 0
BansheeCore/Include/BsInput.h

@@ -131,6 +131,11 @@ namespace BansheeEngine
 		 */
 		bool isButtonDown(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
 
+		/**
+		 * @brief	Returns positions of the pointer (e.g. mouse cursor) relative to the screen.
+		 */
+		Vector2I getPointerPosition() const;
+
 		/**
 		 * @brief	Enables or disables mouse smoothing. Smoothing makes the changes to
 		 *			mouse axes more gradual.
@@ -193,6 +198,7 @@ namespace BansheeEngine
 		std::shared_ptr<OSInputHandler> mOSInputHandler;
 
 		Vector<DeviceData> mDevices;
+		Vector2I mPointerPosition;
 
 		/************************************************************************/
 		/* 								STATICS		                      		*/

+ 7 - 0
BansheeCore/Source/BsInput.cpp

@@ -145,6 +145,8 @@ namespace BansheeEngine
 	{
 		if(!onPointerMoved.empty())
 			onPointerMoved(event);
+
+		mPointerPosition = event.screenPos;
 	}
 
 	void Input::cursorPressed(const PointerEvent& event)
@@ -219,6 +221,11 @@ namespace BansheeEngine
 		return mDevices[deviceIdx].keyStates[button & 0x0000FFFF] == ButtonState::ToggledOn;
 	}
 
+	Vector2I Input::getPointerPosition() const
+	{
+		return mPointerPosition;
+	}
+
 	void Input::setMouseSmoothing(bool enable)
 	{
 		mRawInputHandler->setMouseSmoothing(enable);

+ 4 - 5
BansheeEditor/BansheeEditor.vcxproj

@@ -305,7 +305,7 @@
     <ClInclude Include="Include\BsHandleSliderDisc.h" />
     <ClInclude Include="Include\BsHandleSliderLine.h" />
     <ClInclude Include="Include\BsHandleSliderPlane.h" />
-    <ClInclude Include="Include\BsProjectSettings.h" />
+    <ClInclude Include="Include\BsEditorSettings.h" />
     <ClInclude Include="Include\BsScenePicking.h" />
     <ClInclude Include="Include\BsProjectLibraryEntriesRTTI.h" />
     <ClInclude Include="Include\BsEditorPrerequisites.h" />
@@ -332,9 +332,8 @@
     <ClInclude Include="Include\BsProjectResourceMetaRTTI.h" />
     <ClInclude Include="Include\BsGUIVector2Field.h" />
     <ClInclude Include="Include\BsResourceImporter.h" />
-    <ClInclude Include="Include\BsSceneCameraController.h" />
-    <ClInclude Include="Include\BsSceneEditorWidget.h" />
     <ClInclude Include="Include\BsSceneGrid.h" />
+    <ClInclude Include="Include\BsSceneViewHandler.h" />
     <ClInclude Include="Include\BsSelection.h" />
     <ClInclude Include="Include\BsTestTextSprite.h" />
     <ClInclude Include="Include\DbgEditorWidget1.h" />
@@ -391,14 +390,14 @@
     <ClCompile Include="Source\BsHandleSliderLine.cpp" />
     <ClCompile Include="Source\BsHandleSliderPlane.cpp" />
     <ClCompile Include="Source\BsMainEditorWindow.cpp" />
+    <ClCompile Include="Source\BsEditorSettings.cpp" />
     <ClCompile Include="Source\BsScenePicking.cpp" />
     <ClCompile Include="Source\BsProjectLibrary.cpp" />
     <ClCompile Include="Source\BsProjectLibraryEntries.cpp" />
     <ClCompile Include="Source\BsProjectResourceMeta.cpp" />
     <ClCompile Include="Source\BsResourceImporter.cpp" />
-    <ClCompile Include="Source\BsSceneCameraController.cpp" />
-    <ClCompile Include="Source\BsSceneEditorWidget.cpp" />
     <ClCompile Include="Source\BsSceneGrid.cpp" />
+    <ClCompile Include="Source\BsSceneViewHandler.cpp" />
     <ClCompile Include="Source\BsSelection.cpp" />
     <ClCompile Include="Source\BsUndoRedo.cpp" />
     <ClCompile Include="Source\BsEditorApplication.cpp" />

+ 16 - 19
BansheeEditor/BansheeEditor.vcxproj.filters

@@ -198,12 +198,6 @@
     <ClInclude Include="Include\BsGUIFoldout.h">
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsSceneEditorWidget.h">
-      <Filter>Header Files\Editor</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsSceneCameraController.h">
-      <Filter>Header Files\Editor</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsSceneGrid.h">
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
@@ -243,7 +237,10 @@
     <ClInclude Include="Include\BsEditorUtility.h">
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsProjectSettings.h">
+    <ClInclude Include="Include\BsSceneViewHandler.h">
+      <Filter>Header Files\Editor</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsEditorSettings.h">
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
   </ItemGroup>
@@ -302,9 +299,6 @@
     <ClCompile Include="Source\BsGUISceneTreeView.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsGUITreeViewEditBox.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsEditorCommand.cpp">
       <Filter>Source Files\Editor\Command</Filter>
     </ClCompile>
@@ -392,12 +386,6 @@
     <ClCompile Include="Source\BsGUIFoldout.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsSceneEditorWidget.cpp">
-      <Filter>Source Files\Editor</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsSceneCameraController.cpp">
-      <Filter>Source Files\Editor</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsSceneGrid.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
@@ -407,9 +395,6 @@
     <ClCompile Include="Source\BsScenePicking.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsGizmoManager.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsSelection.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
@@ -437,5 +422,17 @@
     <ClCompile Include="Source\BsEditorUtility.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsSceneViewHandler.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGizmoManager.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGUITreeViewEditBox.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsEditorSettings.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 2 - 2
BansheeEditor/Include/BsEditorApplication.h

@@ -19,7 +19,7 @@ namespace BansheeEngine
 		bool isSceneViewFocused() const;
 		const Path& getActiveProjectPath() const;
 
-		ProjectSettingsPtr getProjectSettings() const { return mProjectSettings; }
+		EditorSettingsPtr getEditorSettings() const { return mEditorSettings; }
 
 	private:
 		virtual void onStartUp();
@@ -34,7 +34,7 @@ namespace BansheeEngine
 	private:
 		static const Path WIDGET_LAYOUT_PATH;
 		RenderSystemPlugin mActiveRSPlugin;
-		ProjectSettingsPtr mProjectSettings;
+		EditorSettingsPtr mEditorSettings;
 
 		DynLib* mSBansheeEditorPlugin;
 

+ 3 - 2
BansheeEditor/Include/BsEditorPrerequisites.h

@@ -63,12 +63,13 @@ namespace BansheeEngine
 	class HandleSliderManager;
 	class HandleDrawManager;
 	class SceneCameraController;
-	class ProjectSettings;
+	class EditorSettings;
+	class SceneViewHandler;
 
 	typedef std::shared_ptr<ProjectResourceMeta> ProjectResourceMetaPtr;
 	typedef std::shared_ptr<DockManagerLayout> DockManagerLayoutPtr;
 	typedef std::shared_ptr<EditorWidgetLayout> EditorWidgetLayoutPtr;
-	typedef std::shared_ptr<ProjectSettings> ProjectSettingsPtr;
+	typedef std::shared_ptr<EditorSettings> EditorSettingsPtr;
 
 	enum class DragAndDropType
 	{

+ 63 - 0
BansheeEditor/Include/BsEditorSettings.h

@@ -0,0 +1,63 @@
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+#include "BsDegree.h"
+
+namespace BansheeEngine
+{
+	class BS_ED_EXPORT EditorSettings
+	{
+	public:
+		bool getMoveHandleSnapActive() const { return mMoveSnapActive; }
+		bool getRotateHandleSnapActive() const { return mRotateSnapActive; }
+		bool getScaleHandleSnapActive() const { return mScaleSnapActive; }
+
+		float getMoveHandleSnap() const { return mMoveSnap; }
+		Degree getRotationHandleSnap() const { return mRotationSnap; }
+		float getScaleHandleSnap() const { return mScaleSnap; }
+
+		UINT32 getGridSize() const { return mGridSize; }
+		float getGridSpacing() const { return mGridAxisSpacing; }
+		UINT32 getGridMajorAxisSpacing() const { return mGridMajorAxisSpacing; }
+		UINT32 getGridAxisMarkerSpacing() const { return mGridAxisMarkerSpacing; }
+
+		float getHandleSize() const { return mHandleSize; }
+
+		void setMoveHandleSnapActive(bool snapActive) { mMoveSnapActive = snapActive; markAsDirty(); }
+		void setRotateHandleSnapActive(bool snapActive) { mRotateSnapActive = snapActive; markAsDirty(); }
+		void setScaleHandleSnapActive(bool snapActive) { mScaleSnapActive = snapActive; markAsDirty(); }
+
+		void setMoveHandleSnap(float value) { mMoveSnap = value; markAsDirty(); }
+		void setRotationHandleSnap(Degree value) { mRotationSnap = value; markAsDirty(); }
+		void setScaleHandleSnap(float value) { mScaleSnap = value; markAsDirty(); }
+
+		void setGridSize(UINT32 value) { mGridSize = value; markAsDirty(); }
+		void setGridSpacing(float value) { mGridAxisSpacing = value; markAsDirty(); }
+		void setGridMajorAxisSpacing(UINT32 value) { mGridMajorAxisSpacing = value; markAsDirty(); }
+		void setGridAxisMarkerSpacing(UINT32 value) { mGridMajorAxisSpacing = value; markAsDirty(); }
+
+		void setHandleSize(float value) { mHandleSize = value; markAsDirty(); }
+
+		UINT32 getHash() const { return mHash; }
+
+	private:
+		void markAsDirty() const { mHash++; }
+
+		bool mMoveSnapActive = false;
+		bool mRotateSnapActive = false;
+		bool mScaleSnapActive = false;
+
+		float mMoveSnap = 0.1f;
+		Degree mRotationSnap = Degree(20.0f);
+		float mScaleSnap = 0.1f;
+
+		UINT32 mGridSize = 256;
+		float mGridAxisSpacing = 1.0f;
+		UINT32 mGridMajorAxisSpacing = 10;
+		UINT32 mGridAxisMarkerSpacing = 25;
+
+		float mHandleSize = 20.0f;
+
+		mutable UINT32 mHash = 0;
+	};
+}

+ 1 - 1
BansheeEditor/Include/BsEditorWidget.h

@@ -32,7 +32,7 @@ namespace BansheeEngine
 
 		void close();
 
-		virtual void _update() { }
+		virtual void update() { }
 
 		Event<void(UINT32, UINT32)> onResized;
 		Event<void(INT32, INT32)> onMoved;

+ 1 - 1
BansheeEditor/Include/BsEditorWidgetContainer.h

@@ -28,7 +28,7 @@ namespace BansheeEngine
 		Rect2I getContentBounds() const;
 		Vector<Rect2I> getDraggableAreas() const;
 
-		void _update();
+		void update();
 
 		void _notifyWidgetDestroyed(EditorWidgetBase* widget);
 

+ 1 - 0
BansheeEditor/Include/BsGizmoManager.h

@@ -35,6 +35,7 @@ namespace BansheeEngine
 		void update(const CameraHandlerPtr& camera);
 		void renderForPicking(const CameraHandlerPtr& camera, std::function<Color(UINT32)> idxToColorCallback);
 		void clearGizmos();
+		void clearRenderData();
 
 		HSceneObject getSceneObject(UINT32 gizmoIdx);
 

+ 10 - 11
BansheeEditor/Include/BsHandleManager.h

@@ -12,9 +12,10 @@ namespace BansheeEngine
 		HandleManager();
 		virtual ~HandleManager();
 
-		bool hasHitHandle(const CameraHandlerPtr& camera, const Vector2I& inputPos) const;
-		void handleInput(const CameraHandlerPtr& camera, const Vector2I& inputPos, bool pressed);
-		void update(const CameraHandlerPtr& camera);
+		void update(const CameraHandlerPtr& camera, const Vector2I& inputPos);
+		void trySelect(const CameraHandlerPtr& camera, const Vector2I& inputPos);
+		void clearSelection();
+		bool isHandleActive() const;
 
 		HandleSliderManager& getSliderManager() const { return *mSliderManager; }
 		HandleDrawManager& getDrawManager() const { return *mDrawManager; }
@@ -22,20 +23,18 @@ namespace BansheeEngine
 		float getHandleSize(const CameraHandlerPtr& camera, const Vector3& handlePos) const;
 
 		void setDefaultHandleSize(float value) { mDefaultHandleSize = value; }
-		void setMoveHandleSnapAmount(float value) { mMoveHandleSnapAmount = value; }
-		void setRotateHandleSnapAmount(Degree value) { mRotateHandleSnapAmount = value; }
-		void setScaleHandleSnapAmount(float value) { mScaleHandleSnapAmount = value; }
-
-		bool isHandleActive() const;
+		void setSettings(const EditorSettingsPtr& settings);
 
 	protected:
+		void updateFromProjectSettings();
+
 		HandleSliderManager* mSliderManager;
 		HandleDrawManager* mDrawManager;
 
 		float mDefaultHandleSize = 20.0f;
-		float mMoveHandleSnapAmount = 0.1f;
-		Degree mRotateHandleSnapAmount = Degree(20.0f);
-		float mScaleHandleSnapAmount = 0.1f;
+
+		EditorSettingsPtr mSettings;
+		UINT32 mSettingsHash;
 
 		virtual void refreshHandles() = 0;
 		virtual void triggerHandles() = 0;

+ 6 - 4
BansheeEditor/Include/BsHandleSliderManager.h

@@ -10,15 +10,17 @@ namespace BansheeEngine
 		HandleSliderManager();
 		~HandleSliderManager();
 
-		void update(const CameraHandlerPtr& camera);
-		bool hasHitSlider(const CameraHandlerPtr& camera, const Vector2I& inputPos) const;
-		void handleInput(const CameraHandlerPtr& camera, const Vector2I& inputPos, bool pressed);
-		bool isSliderActive() const;
+		void update(const CameraHandlerPtr& camera, const Vector2I& inputPos);
+		void trySelect(const CameraHandlerPtr& camera, const Vector2I& inputPos);
+		void clearSelection();
+		bool isSliderActive() const { return mActiveSlider != nullptr; }
 
 		void _registerSlider(HandleSlider* slider);
 		void _unregisterSlider(HandleSlider* slider);
 
 	private:
+		HandleSlider* findUnderCursor(const CameraHandlerPtr& camera, const Vector2I& inputPos) const;
+
 		HandleSlider* mActiveSlider;
 		HandleSlider* mHoverSlider;
 		UnorderedSet<HandleSlider*> mSliders;

+ 0 - 45
BansheeEditor/Include/BsProjectSettings.h

@@ -1,45 +0,0 @@
-#pragma once
-
-#include "BsEditorPrerequisites.h"
-#include "BsDegree.h"
-
-namespace BansheeEngine
-{
-	class BS_ED_EXPORT ProjectSettings
-	{
-	public:
-		float getMoveHandleSnap() const { return mMoveSnap; }
-		Degree getRotationHandleSnap() const { return mRotationSnap; }
-		float getScaleHandleSnap() const { return mScaleSnap; }
-
-		UINT32 getGridSize() const { return mGridSize; }
-		float getGridSpacing() const { return mGridAxisSpacing; }
-		UINT32 getGridMajorAxisSpacing() const { return mGridMajorAxisSpacing; }
-		UINT32 getGridAxisMarkerSpacing() const { return mGridAxisMarkerSpacing; }
-
-		float getHandleSize() const { return mHandleSize; }
-
-		void setMoveHandleSnap(float value) { mMoveSnap = value; }
-		void setRotationHandleSnap(Degree value) { mRotationSnap = value; }
-		void setScaleHandleSnap(float value) { mScaleSnap = value; }
-
-		void setGridSize(UINT32 value) { mGridSize = value; }
-		void setGridSpacing(float value) { mGridAxisSpacing = value; }
-		void setGridMajorAxisSpacing(UINT32 value) { mGridMajorAxisSpacing = value; }
-		void setGridAxisMarkerSpacing(UINT32 value) { mGridMajorAxisSpacing = value; }
-
-		void setHandleSize(float value) { mHandleSize = value; }
-
-	private:
-		float mMoveSnap = 0.1f;
-		Degree mRotationSnap = Degree(20.0f);
-		float mScaleSnap = 0.1f;
-
-		UINT32 mGridSize = 256;
-		float mGridAxisSpacing = 1.0f;
-		UINT32 mGridMajorAxisSpacing = 10;
-		UINT32 mGridAxisMarkerSpacing = 25;
-
-		float mHandleSize = 20.0f;
-	};
-}

+ 0 - 2
BansheeEditor/Include/BsSceneEditorWidget.h

@@ -62,6 +62,4 @@ namespace BansheeEngine
 		HEvent mOnPointerPressedConn;
 		HEvent mOnPointerReleasedConn;
 	};
-
-	typedef ServiceLocator<SceneEditorWidget> SceneViewLocator;
 }

+ 7 - 1
BansheeEditor/Include/BsSceneGrid.h

@@ -17,16 +17,22 @@ namespace BansheeEngine
 		void setSpacing(float spacing);
 		void setMajorAxisSpacing(UINT32 spacing);
 		void setAxisMarkerSpacing(UINT32 spacing);
+		void setSettings(const EditorSettingsPtr& settings);
 
-		void render(const CameraPtr& camera, DrawList& drawList);
+		void render(const CameraHandlerPtr& camera, DrawList& drawList);
+		void update();
 	private:
 		void updateGridMesh();
+		void updateFromProjectSettings();
 
 		HMesh mGridMesh;
 		HMaterial mGridMaterial;
 		MaterialParamMat4 mViewProjParam;
 		VertexDataDescPtr mVertexDesc;
 
+		EditorSettingsPtr mSettings;
+		UINT32 mSettingsHash = 0;
+
 		Vector3 mOrigin;
 		float mSpacing = 1.0f;
 		UINT32 mSize = 256;

+ 25 - 0
BansheeEditor/Include/BsSceneViewHandler.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+
+namespace BansheeEngine
+{
+	class BS_ED_EXPORT SceneViewHandler
+	{
+	public:
+		SceneViewHandler(const SPtr<CameraHandler>& camera);
+		virtual ~SceneViewHandler();
+
+		void update(const Vector2I& position);
+		void pointerPressed(const Vector2I& position);
+		void pointerReleased(const Vector2I& position, bool controlHeld);
+
+	protected:
+		void render(const Viewport* viewport, DrawList& drawList);
+
+	private:
+		SPtr<CameraHandler> mCamera;
+		SceneGrid* mSceneGrid;
+		HEvent mRenderCallback;
+	};
+}

+ 1 - 1
BansheeEditor/Include/DbgEditorWidget1.h

@@ -11,7 +11,7 @@ namespace BansheeEngine
 		DbgEditorWidget1(const ConstructPrivately& dummy, EditorWidgetContainer& parentContainer);
 		virtual ~DbgEditorWidget1();
 
-		virtual void _update();
+		virtual void update();
 
 		static DbgEditorWidget1* instance();
 		static DbgEditorWidget1* open();

+ 1 - 1
BansheeEditor/Source/BsDockManager.cpp

@@ -396,7 +396,7 @@ namespace BansheeEngine
 		if (mIsLeaf)
 		{
 			if (mWidgets != nullptr)
-				mWidgets->_update();
+				mWidgets->update();
 		}
 		else
 		{

+ 2 - 5
BansheeEditor/Source/BsEditorApplication.cpp

@@ -10,7 +10,6 @@
 #include "BsPath.h"
 #include "BsResourceImporter.h"
 #include "BsEditorWidgetLayout.h"
-#include "BsSceneEditorWidget.h"
 #include "BsScenePicking.h"
 #include "BsSelection.h"
 #include "BsGizmoManager.h"
@@ -40,7 +39,7 @@
 #include "BsGUILayout.h"
 #include "BsEvent.h"
 #include "BsCoreRenderer.h"
-#include "BsProjectSettings.h"
+#include "BsEditorSettings.h"
 #include "BsMesh.h"
 
 namespace BansheeEngine
@@ -63,7 +62,7 @@ namespace BansheeEngine
 		mActiveRSPlugin(renderSystemPlugin), mSBansheeEditorPlugin(nullptr)
 	{
 		// TODO - Load project settings
-		mProjectSettings = bs_shared_ptr<ProjectSettings>();
+		mEditorSettings = bs_shared_ptr<EditorSettings>();
 
 		BuiltinEditorResources::startUp(renderSystemPlugin);
 
@@ -157,8 +156,6 @@ namespace BansheeEngine
 		if (layout != nullptr)
 			EditorWidgetManager::instance().setLayout(layout);
 
-		SceneEditorWidget::open();
-
 		/************************************************************************/
 		/* 								DEBUG CODE                      		*/
 		/************************************************************************/

+ 6 - 0
BansheeEditor/Source/BsEditorSettings.cpp

@@ -0,0 +1,6 @@
+#include "BsEditorSettings.h"
+
+namespace BansheeEngine
+{
+
+}

+ 2 - 2
BansheeEditor/Source/BsEditorWidgetContainer.cpp

@@ -42,11 +42,11 @@ namespace BansheeEngine
 		GUIElement::destroy(mTitleBar);
 	}
 
-	void EditorWidgetContainer::_update()
+	void EditorWidgetContainer::update()
 	{
 		for (auto& widget : mWidgets)
 		{
-			widget.second->_update();
+			widget.second->update();
 		}
 	}
 

+ 1 - 1
BansheeEditor/Source/BsEditorWindow.cpp

@@ -21,7 +21,7 @@ namespace BansheeEngine
 
 	void EditorWindow::update()
 	{
-		mWidgets->_update();
+		mWidgets->update();
 	}
 
 	void EditorWindow::resized()

+ 36 - 37
BansheeEditor/Source/BsGizmoManager.cpp

@@ -16,7 +16,6 @@
 #include "BsTransientMesh.h"
 #include "BsRendererManager.h"
 #include "BsDrawHelper.h"
-#include "BsSceneEditorWidget.h"
 
 using namespace std::placeholders;
 
@@ -236,49 +235,36 @@ namespace BansheeEngine
 		if (mIconMesh != nullptr)
 			mIconMeshHeap->dealloc(mIconMesh);
 
-		RenderTargetPtr rt;
-		SceneEditorWidget* sceneView = SceneViewLocator::instance();
-		if (sceneView != nullptr)
-		{
-			rt = camera->getViewport()->getTarget();
-
-			IconRenderDataVecPtr iconRenderData;
+		RenderTargetPtr rt = camera->getViewport()->getTarget();
+		IconRenderDataVecPtr iconRenderData;
 
-			mDrawHelper->buildMeshes();
-			const Vector<DrawHelper::ShapeMeshData>& meshes = mDrawHelper->getMeshes();
+		mDrawHelper->buildMeshes();
+		const Vector<DrawHelper::ShapeMeshData>& meshes = mDrawHelper->getMeshes();
 
-			SPtr<MeshCoreBase> solidMesh = nullptr;
-			SPtr<MeshCoreBase> wireMesh = nullptr;
-			for (auto& meshData : meshes)
+		SPtr<MeshCoreBase> solidMesh = nullptr;
+		SPtr<MeshCoreBase> wireMesh = nullptr;
+		for (auto& meshData : meshes)
+		{
+			if (meshData.type == DrawHelper::MeshType::Solid)
 			{
-				if (meshData.type == DrawHelper::MeshType::Solid)
-				{
-					if (solidMesh == nullptr)
-						solidMesh = meshData.mesh->getCore();
-				}
-				else // Wire
-				{
-					if (wireMesh == nullptr)
-						wireMesh = meshData.mesh->getCore();
-				}
+				if (solidMesh == nullptr)
+					solidMesh = meshData.mesh->getCore();
 			}
+			else // Wire
+			{
+				if (wireMesh == nullptr)
+					wireMesh = meshData.mesh->getCore();
+			}
+		}
 
-			// Since there is no sorting used with draw helper meshes we only expect up to two of them,
-			// one for solids, one for wireframe
-			assert(meshes.size() <= 2);
-
-			mIconMesh = buildIconMesh(camera, mIconData, false, iconRenderData);
-			SPtr<MeshCoreBase> iconMesh = mIconMesh->getCore();
+		// Since there is no sorting used with draw helper meshes we only expect up to two of them,
+		// one for solids, one for wireframe
+		assert(meshes.size() <= 2);
 
-			gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::updateData, mCore, rt, solidMesh, wireMesh, iconMesh, iconRenderData));
-		}
-		else
-		{
-			mIconMesh = nullptr;
+		mIconMesh = buildIconMesh(camera, mIconData, false, iconRenderData);
+		SPtr<MeshCoreBase> iconMesh = mIconMesh->getCore();
 
-			IconRenderDataVecPtr iconRenderData = bs_shared_ptr<IconRenderDataVec>();
-			gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::updateData, mCore, nullptr, nullptr, nullptr, nullptr, iconRenderData));
-		}
+		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::updateData, mCore, rt, solidMesh, wireMesh, iconMesh, iconRenderData));
 	}
 
 	void GizmoManager::renderForPicking(const CameraHandlerPtr& camera, std::function<Color(UINT32)> idxToColorCallback)
@@ -413,6 +399,19 @@ namespace BansheeEngine
 		mCurrentIdx = 0;
 	}
 
+	void GizmoManager::clearRenderData()
+	{
+		mDrawHelper->clearMeshes();
+
+		if (mIconMesh != nullptr)
+			mIconMeshHeap->dealloc(mIconMesh);
+
+		mIconMesh = nullptr;
+
+		IconRenderDataVecPtr iconRenderData = bs_shared_ptr<IconRenderDataVec>();
+		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::updateData, mCore, nullptr, nullptr, nullptr, nullptr, iconRenderData));
+	}
+
 	TransientMeshPtr GizmoManager::buildIconMesh(const CameraHandlerPtr& camera, const Vector<IconData>& iconData,
 		bool forPicking, GizmoManager::IconRenderDataVecPtr& iconRenderData)
 	{

+ 20 - 8
BansheeEditor/Source/BsHandleManager.cpp

@@ -1,9 +1,9 @@
 #include "BsHandleManager.h"
 #include "BsHandleDrawManager.h"
 #include "BsHandleSliderManager.h"
-#include "BsSceneEditorWidget.h"
 #include "BsCamera.h"
 #include "BsSceneObject.h"
+#include "BsEditorSettings.h"
 
 namespace BansheeEngine
 {
@@ -25,22 +25,34 @@ namespace BansheeEngine
 		return mSliderManager->isSliderActive();
 	}
 
-	void HandleManager::update(const CameraHandlerPtr& camera)
+	void HandleManager::update(const CameraHandlerPtr& camera, const Vector2I& inputPos)
 	{
+		if (mSettings != nullptr && mSettingsHash != mSettings->getHash())
+			updateFromProjectSettings();
+
+		refreshHandles();
+		mSliderManager->update(camera, inputPos);
+		triggerHandles();
+
 		queueDrawCommands();
 		mDrawManager->draw(camera);
 	}
 
-	bool HandleManager::hasHitHandle(const CameraHandlerPtr& camera, const Vector2I& inputPos) const
+	void HandleManager::updateFromProjectSettings()
+	{
+		setDefaultHandleSize(mSettings->getHandleSize());
+
+		mSettingsHash = mSettings->getHash();
+	}
+
+	void HandleManager::trySelect(const CameraHandlerPtr& camera, const Vector2I& inputPos)
 	{
-		return mSliderManager->hasHitSlider(camera, inputPos);
+		return mSliderManager->trySelect(camera, inputPos);
 	}
 
-	void HandleManager::handleInput(const CameraHandlerPtr& camera, const Vector2I& inputPos, bool pressed)
+	void HandleManager::clearSelection()
 	{
-		refreshHandles();
-		mSliderManager->handleInput(camera, inputPos, pressed);
-		triggerHandles();
+		return mSliderManager->clearSelection();
 	}
 
 	float HandleManager::getHandleSize(const CameraHandlerPtr& camera, const Vector3& handlePos) const

+ 57 - 63
BansheeEditor/Source/BsHandleSliderManager.cpp

@@ -24,30 +24,48 @@ namespace BansheeEngine
 
 	}
 
-	void HandleSliderManager::update(const CameraHandlerPtr& camera)
+	void HandleSliderManager::update(const CameraHandlerPtr& camera, const Vector2I& inputPos)
 	{
 		for (auto& slider : mSliders)
 			slider->update(camera);
-	}
 
-	bool HandleSliderManager::hasHitSlider(const CameraHandlerPtr& camera, const Vector2I& inputPos) const
-	{
-		Ray inputRay = camera->screenPointToRay(inputPos);
-		for (auto& slider : mSliders)
+		if (mActiveSlider != nullptr)
 		{
-			float t;
-			if (slider->intersects(inputRay, t))
-				return true;
+			Ray inputRay = camera->screenPointToRay(inputPos);
+			mActiveSlider->handleInput(camera, inputPos, inputRay);
 		}
+		else
+		{
+			HandleSlider* newHoverSlider = findUnderCursor(camera, inputPos);
+
+			if (newHoverSlider != mHoverSlider)
+			{
+				if (mHoverSlider != nullptr)
+				{
+					mHoverSlider->setInactive();
+					mHoverSlider = nullptr;
+				}
 
-		return false;
+				if (newHoverSlider != nullptr)
+				{
+					mHoverSlider = newHoverSlider;
+					mHoverSlider->setHover();
+				}
+			}
+		}
 	}
 
-	void HandleSliderManager::handleInput(const CameraHandlerPtr& camera, const Vector2I& inputPos, bool pressed)
+	void HandleSliderManager::trySelect(const CameraHandlerPtr& camera, const Vector2I& inputPos)
 	{
-		Ray inputRay = camera->screenPointToRay(inputPos);
+		HandleSlider* newActiveSlider = findUnderCursor(camera, inputPos);
 
-		if (!pressed)
+		if (mHoverSlider != nullptr)
+		{
+			mHoverSlider->setInactive();
+			mHoverSlider = nullptr;
+		}
+
+		if (newActiveSlider != mActiveSlider)
 		{
 			if (mActiveSlider != nullptr)
 			{
@@ -55,68 +73,44 @@ namespace BansheeEngine
 				mActiveSlider = nullptr;
 			}
 
-			float nearestT = std::numeric_limits<float>::max();
-			HandleSlider* overSlider = nullptr;
-			for (auto& slider : mSliders)
+			if (newActiveSlider != nullptr)
 			{
-				float t;
-				if (slider->intersects(inputRay, t))
-				{
-					if (t < nearestT)
-					{
-						overSlider = slider;
-						nearestT = t;
-					}
-				}
+				mActiveSlider = newActiveSlider;
+				mActiveSlider->setActive(inputPos);
 			}
+		}
+	}
 
-			if (mHoverSlider != overSlider)
-			{
-				if (mHoverSlider != nullptr)
-					mHoverSlider->setInactive();
+	void HandleSliderManager::clearSelection()
+	{
+		if (mActiveSlider != nullptr)
+		{
+			mActiveSlider->setInactive();
+			mActiveSlider = nullptr;
+		}
+	}
 
-				mHoverSlider = overSlider;
+	HandleSlider* HandleSliderManager::findUnderCursor(const CameraHandlerPtr& camera, const Vector2I& inputPos) const
+	{
+		Ray inputRay = camera->screenPointToRay(inputPos);
 
-				if (mHoverSlider != nullptr)
-					overSlider->setHover();
-			}
-		}
-		else
+		float nearestT = std::numeric_limits<float>::max();
+		HandleSlider* overSlider = nullptr;
+		
+		for (auto& slider : mSliders)
 		{
-			if (mActiveSlider == nullptr)
+			float t;
+			if (slider->intersects(inputRay, t))
 			{
-				float nearestT = std::numeric_limits<float>::max();
-				HandleSlider* overSlider = nullptr;
-				for (auto& slider : mSliders)
-				{
-					float t;
-					if (slider->intersects(inputRay, t))
-					{
-						if (t < nearestT)
-						{
-							overSlider = slider;
-							nearestT = t;
-						}
-					}
-				}
-
-				if (overSlider != nullptr)
+				if (t < nearestT)
 				{
-					mActiveSlider = overSlider;
-					mActiveSlider->setActive(inputPos);
+					overSlider = slider;
+					nearestT = t;
 				}
 			}
-
-			if (mActiveSlider != nullptr)
-			{
-				mActiveSlider->handleInput(camera, inputPos, inputRay);
-			}
 		}
-	}
 
-	bool HandleSliderManager::isSliderActive() const
-	{
-		return mActiveSlider != nullptr;
+		return overSlider;
 	}
 
 	void HandleSliderManager::_registerSlider(HandleSlider* slider)

+ 0 - 17
BansheeEditor/Source/BsMainEditorWindow.cpp

@@ -12,7 +12,6 @@
 #include "BsEditorTestSuite.h"
 #include "BsTestOutput.h"
 #include "BsVirtualInput.h"
-#include "BsSceneCameraController.h"
 
 // DEBUG ONLY
 #include "BsTestTextSprite.h"
@@ -50,22 +49,6 @@ namespace BansheeEngine
 		mMenuBar->addMenuItem(L"File/Exit", nullptr);
 		mMenuBar->addMenuItem(L"Window/Scene", nullptr);
 
-		// Set up default editor input
-		auto inputConfig = VirtualInput::instance().getConfiguration();
-
-		inputConfig->registerButton(SceneCameraController::MOVE_FORWARD_BTN, BC_W);
-		inputConfig->registerButton(SceneCameraController::MOVE_BACKWARD_BTN, BC_S);
-		inputConfig->registerButton(SceneCameraController::MOVE_LEFT_BTN, BC_A);
-		inputConfig->registerButton(SceneCameraController::MOVE_RIGHT_BTN, BC_D);
-		inputConfig->registerButton(SceneCameraController::MOVE_FORWARD_BTN, BC_UP);
-		inputConfig->registerButton(SceneCameraController::MOVE_BACKWARD_BTN, BC_BACK);
-		inputConfig->registerButton(SceneCameraController::MOVE_LEFT_BTN, BC_LEFT);
-		inputConfig->registerButton(SceneCameraController::MOVE_RIGHT_BTN, BC_RIGHT);
-		inputConfig->registerButton(SceneCameraController::FAST_MOVE_BTN, BC_LSHIFT);
-		inputConfig->registerButton(SceneCameraController::ROTATE_BTN, BC_MOUSE_RIGHT);
-		inputConfig->registerAxis(SceneCameraController::HORIZONTAL_AXIS, VIRTUAL_AXIS_DESC((UINT32)InputAxis::MouseX));
-		inputConfig->registerAxis(SceneCameraController::VERTICAL_AXIS, VIRTUAL_AXIS_DESC((UINT32)InputAxis::MouseY));
-
 		//GameObjectHandle<TestTextSprite> textSprite = mSceneObject->addComponent<TestTextSprite>(mCamera->getViewport().get());
 
 		//textSprite->init(sceneCamera, "Testing in a new row, does this work?", sceneRenderTarget);

+ 1 - 3
BansheeEditor/Source/BsSceneEditorWidget.cpp

@@ -45,8 +45,6 @@ namespace BansheeEngine
 		:EditorWidget<SceneEditorWidget>(HString(L"SceneEditorWidget"), parentContainer), mGUIRenderTexture(nullptr), 
 		mLeftButtonPressed(false)
 	{
-		SceneViewLocator::_provide(this);
-
 		updateRenderTexture(getWidth(), getHeight());
 
 		mRenderCallback = RendererManager::instance().getActive()->onRenderViewport.connect(std::bind(&SceneEditorWidget::render, this, _1, _2));
@@ -67,7 +65,7 @@ namespace BansheeEngine
 		mOnPointerPressedConn.disconnect();
 		mOnPointerReleasedConn.disconnect();
 
-		SceneViewLocator::_provide(nullptr);
+		GizmoManager::instance().clearRenderData();
 	}
 
 	void SceneEditorWidget::_update()

+ 24 - 1
BansheeEditor/Source/BsSceneGrid.cpp

@@ -7,6 +7,7 @@
 #include "BsDrawList.h"
 #include "BsBuiltinEditorResources.h"
 #include "BsCamera.h"
+#include "BsEditorSettings.h"
 
 namespace BansheeEngine
 {
@@ -76,7 +77,19 @@ namespace BansheeEngine
 		}
 	}
 
-	void SceneGrid::render(const CameraPtr& camera, DrawList& drawList)
+	void SceneGrid::setSettings(const EditorSettingsPtr& settings)
+	{
+		mSettings = settings;
+		updateFromProjectSettings();
+	}
+
+	void SceneGrid::update()
+	{
+		if (mSettings != nullptr && mSettingsHash != mSettings->getHash())
+			updateFromProjectSettings();
+	}
+
+	void SceneGrid::render(const CameraHandlerPtr& camera, DrawList& drawList)
 	{
 		MaterialPtr mat = mGridMaterial.getInternalPtr();
 		MeshPtr mesh = mGridMesh.getInternalPtr();
@@ -90,6 +103,16 @@ namespace BansheeEngine
 		drawList.add(mat, mesh, 0, Vector3::ZERO);
 	}
 
+	void SceneGrid::updateFromProjectSettings()
+	{
+		setSize(mSettings->getGridSize());
+		setSpacing(mSettings->getGridSpacing());
+		setMajorAxisSpacing(mSettings->getGridMajorAxisSpacing());
+		setAxisMarkerSpacing(mSettings->getGridAxisMarkerSpacing());
+
+		mSettingsHash = mSettings->getHash();
+	}
+
 	void SceneGrid::updateGridMesh()
 	{
 		UINT32 numLines = (UINT32)Math::roundToInt(mSize / mSpacing);

+ 90 - 0
BansheeEditor/Source/BsSceneViewHandler.cpp

@@ -0,0 +1,90 @@
+#include "BsSceneViewHandler.h"
+#include "BsRendererManager.h"
+#include "BsRenderer.h"
+#include "BsGizmoManager.h"
+#include "BsHandleManager.h"
+#include "BsSceneGrid.h"
+#include "BsSelection.h"
+#include "BsScenePicking.h"
+#include "BsCameraHandler.h"
+#include "BsEditorApplication.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	SceneViewHandler::SceneViewHandler(const SPtr<CameraHandler>& camera)
+		:mCamera(camera), mSceneGrid(nullptr)
+	{
+		mRenderCallback = RendererManager::instance().getActive()->onRenderViewport.connect(std::bind(&SceneViewHandler::render, this, _1, _2));
+		mSceneGrid = bs_new<SceneGrid>();
+		mSceneGrid->setSettings(gEditorApplication().getEditorSettings());
+	}
+
+	SceneViewHandler::~SceneViewHandler()
+	{
+		bs_delete(mSceneGrid);
+		mRenderCallback.disconnect();
+
+		GizmoManager::instance().clearRenderData();
+	}
+
+	void SceneViewHandler::update(const Vector2I& position)
+	{
+		GizmoManager::instance().update(mCamera);
+		HandleManager::instance().update(mCamera, position); // TODO - Make sure these internally check ProjectSettings
+		mSceneGrid->update();
+	}
+
+	void SceneViewHandler::pointerPressed(const Vector2I& position)
+	{
+		HandleManager::instance().trySelect(mCamera, position);
+	}
+
+	void SceneViewHandler::pointerReleased(const Vector2I& position, bool controlHeld)
+	{
+		if (HandleManager::instance().isHandleActive())
+			HandleManager::instance().clearSelection();
+		else
+		{
+			// TODO - Handle multi-selection (i.e. selection rectangle when dragging)
+			HSceneObject pickedObject = ScenePicking::instance().pickClosestObject(mCamera, position, Vector2I(1, 1));
+
+			if (pickedObject)
+			{
+				if (controlHeld) // Append to existing selection
+				{
+					Vector<HSceneObject> selectedSOs = Selection::instance().getSceneObjects();
+
+					auto iterFind = std::find_if(selectedSOs.begin(), selectedSOs.end(),
+						[&](const HSceneObject& obj) { return obj == pickedObject; }
+					);
+
+					if (iterFind != selectedSOs.end())
+						selectedSOs.push_back(pickedObject);
+
+					Selection::instance().setSceneObjects(selectedSOs);
+				}
+				else
+				{
+					Vector<HSceneObject> selectedSOs = { pickedObject };
+
+					Selection::instance().setSceneObjects(selectedSOs);
+				}
+			}
+			else
+				Selection::instance().clearSceneSelection();
+		}
+	}
+
+	void SceneViewHandler::render(const Viewport* viewport, DrawList& drawList)
+	{
+		if (mCamera == nullptr)
+			return;
+
+		if (mCamera->getViewport().get() != viewport)
+			return;
+
+		mSceneGrid->render(mCamera, drawList);
+	}
+}

+ 1 - 1
BansheeEditor/Source/DbgEditorWidget1.cpp

@@ -82,7 +82,7 @@ namespace BansheeEngine
 
 	}
 
-	void DbgEditorWidget1::_update()
+	void DbgEditorWidget1::update()
 	{
 		mSceneTreeView->update();
 		mResourceTreeView->update();

+ 59 - 2
MBansheeEditor/EditorApplication.cs

@@ -48,9 +48,66 @@ namespace BansheeEditor
             set { handleCoordinateMode = value; } // TODO - Will likely need to update active GUI button when this changes
         }
 
-        public static Camera sceneCamera
+        public static Camera SceneViewCamera
         {
-            get { return null; } // TODO - Return actual scene camera
+            get { return instance.scene.GetCamera(); }
+        }
+
+        private static EditorApplication instance;
+
+        private InspectorWindow inspector;
+        private SceneWindow scene;
+
+        // DEBUG ONLY
+        Debug_Component1 dbgComponent;
+        // END DEBUG ONLY
+
+        internal EditorApplication()
+        {
+            instance = this;
+
+            // Register controls
+            InputConfiguration inputConfig = VirtualInput.KeyConfig;
+
+		    inputConfig.RegisterButton(SceneCamera.MoveForwardBinding, ButtonCode.W);
+            inputConfig.RegisterButton(SceneCamera.MoveBackBinding, ButtonCode.S);
+            inputConfig.RegisterButton(SceneCamera.MoveLeftBinding, ButtonCode.A);
+            inputConfig.RegisterButton(SceneCamera.MoveRightBinding, ButtonCode.D);
+            inputConfig.RegisterButton(SceneCamera.MoveForwardBinding, ButtonCode.Up);
+            inputConfig.RegisterButton(SceneCamera.MoveBackBinding, ButtonCode.Back);
+            inputConfig.RegisterButton(SceneCamera.MoveLeftBinding, ButtonCode.Left);
+            inputConfig.RegisterButton(SceneCamera.MoveRightBinding, ButtonCode.Right);
+            inputConfig.RegisterButton(SceneCamera.FastMoveBinding, ButtonCode.LeftShift);
+            inputConfig.RegisterButton(SceneCamera.RotateBinding, ButtonCode.MouseRight);
+            inputConfig.RegisterAxis(SceneCamera.HorizontalAxisBinding, InputAxis.MouseX);
+            inputConfig.RegisterAxis(SceneCamera.VerticalAxisBinding, InputAxis.MouseY);
+
+            // Open windows
+            inspector = EditorWindow.OpenWindow<InspectorWindow>();
+            scene = EditorWindow.OpenWindow<SceneWindow>();
+
+            // DEBUG ONLY
+
+            SceneObject newDbgObject = new SceneObject("NewDbgObject");
+            dbgComponent = newDbgObject.AddComponent<Debug_Component1>();
+            newDbgObject.AddComponent<Debug_Component2>();
+
+            inspector.SetObjectToInspect(newDbgObject);
+
+            SceneObject gizmoDbgObject = new SceneObject("GizmoDebug");
+            gizmoDbgObject.AddComponent<DbgGizmoComponent>();
+
+            // DEBUG ONLY END
+        }
+
+        internal void EditorUpdate()
+        {
+            // DEBUG ONLY
+
+            if (dbgComponent != null)
+                dbgComponent.intArray[0] = dbgComponent.intArray[0] + 1;
+
+            // DEBUG ONLY END
         }
     }
 }

+ 90 - 0
MBansheeEditor/EditorSettings.cs

@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public static class EditorSettings
+    {
+        public static bool MoveHandleSnapActive
+        {
+            get { return Internal_GetMoveHandleSnapActive(); }
+            set { Internal_SetMoveHandleSnapActive(value); }
+        }
+
+        public static bool RotateHandleSnapActive
+        {
+            get { return Internal_GetRotateHandleSnapActive(); }
+            set { Internal_SetRotateHandleSnapActive(value); }
+        }
+
+        public static bool ScaleHandleSnapActive
+        {
+            get { return Internal_GetScaleHandleSnapActive(); }
+            set { Internal_SetScaleHandleSnapActive(value); }
+        }
+
+        public static float MoveHandleSnapAmount
+        {
+            get { return Internal_GetMoveHandleSnapAmount(); }
+            set { Internal_SetMoveHandleSnapAmount(value); }
+        }
+
+        public static float RotateHandleSnapAmount
+        {
+            get { return Internal_GetRotateHandleSnapAmount(); }
+            set { Internal_SetRotateHandleSnapAmount(value); }
+        }
+
+        public static float ScaleHandleSnapAmount
+        {
+            get { return Internal_GetScaleHandleSnapAmount(); }
+            set { Internal_SetScaleHandleSnapAmount(value); }
+        }
+
+        public static float DefaultHandleSize
+        {
+            get { return Internal_GetDefaultHandleSize(); }
+            set { Internal_SetDefaultHandleSize(value); }
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetMoveHandleSnapActive();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetMoveHandleSnapActive(bool value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetRotateHandleSnapActive();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetRotateHandleSnapActive(bool value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetScaleHandleSnapActive();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetScaleHandleSnapActive(bool value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetMoveHandleSnapAmount();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetMoveHandleSnapAmount(float value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetRotateHandleSnapAmount();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetRotateHandleSnapAmount(float value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetScaleHandleSnapAmount();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetScaleHandleSnapAmount(float value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetDefaultHandleSize();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetDefaultHandleSize(float value);
+    }
+}

+ 2 - 2
MBansheeEditor/Inspector/InspectorWindow.cs

@@ -55,7 +55,7 @@ namespace BansheeEditor
             RepositionInspectors();
         }
 
-        void OnComponentFoldoutToggled(InspectorData inspectorData, bool expanded)
+        private void OnComponentFoldoutToggled(InspectorData inspectorData, bool expanded)
         {
             inspectorData.expanded = expanded;
             inspectorData.inspector.SetVisible(expanded);
@@ -63,7 +63,7 @@ namespace BansheeEditor
             RepositionInspectors();
         }
 
-        internal void Refresh()
+        private void EditorUpdate()
         {
             bool anythingModified = false;
 

+ 2 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -48,6 +48,7 @@
     <Compile Include="Debug_Component1.cs" />
     <Compile Include="Debug_Component2.cs" />
     <Compile Include="EditorApplication.cs" />
+    <Compile Include="EditorSettings.cs" />
     <Compile Include="EditorUtility.cs" />
     <Compile Include="EditorWindow.cs" />
     <Compile Include="GUI\GUIFoldout.cs" />
@@ -83,6 +84,7 @@
     <Compile Include="Inspector\Inspector.cs" />
     <Compile Include="Inspector\InspectorWindow.cs" />
     <Compile Include="Scene\SceneCamera.cs" />
+    <Compile Include="Scene\SceneViewHandler.cs" />
     <Compile Include="Scene\SceneWindow.cs" />
     <Compile Include="Scene\DefaultHandle.cs" />
     <Compile Include="Scene\DefaultHandleManager.cs" />

+ 3 - 16
MBansheeEditor/Program.cs

@@ -6,21 +6,11 @@ namespace BansheeEditor
 {
     class ProgramEd
     {
-        private static InspectorWindow window;
-        private static Debug_Component1 dbgComponent;
+        private static EditorApplication app;
 
         static void Main()
         {
-            window = EditorWindow.OpenWindow<InspectorWindow>();
-
-            SceneObject newDbgObject = new SceneObject("NewDbgObject");
-            dbgComponent = newDbgObject.AddComponent<Debug_Component1>();
-            newDbgObject.AddComponent<Debug_Component2>();
-
-            window.SetObjectToInspect(newDbgObject);
-
-            SceneObject gizmoDbgObject = new SceneObject("GizmoDebug");
-            gizmoDbgObject.AddComponent<DbgGizmoComponent>();
+            app = new EditorApplication();
 
             DbgResource testResource = new DbgResource();
             //ProjectLibrary.Create(testResource, @"testResource");
@@ -43,10 +33,7 @@ namespace BansheeEditor
 
         static void EditorUpdate()
         {
-            window.Refresh();
-
-            if (dbgComponent != null)
-                dbgComponent.intArray[0] = dbgComponent.intArray[0] + 1;
+            app.EditorUpdate();
         }
     }
 

+ 41 - 10
MBansheeEditor/Scene/Handles.cs

@@ -1,17 +1,45 @@
-using BansheeEngine;
+using System;
+using BansheeEngine;
 
 namespace BansheeEditor
 {
     public sealed class Handles
     {
-        // TODO - Implement these properly by retrieving them from some user-toggled properly
-        public static bool MoveHandleSnapActive { get { return true; } }
-        public static bool RotateHandleSnapActive { get { return true; } }
-        public static bool ScaleHandleSnapActive { get { return true; } }
+        public static bool MoveHandleSnapActive
+        {
+            get { return EditorSettings.MoveHandleSnapActive; }
+            set { EditorSettings.MoveHandleSnapActive = value; }
+        }
 
-        public static float MoveSnapAmount { get { return 1.0f; /* TODO */ } }
-        public static float RotateSnapAmount { get { return 1.0f; /* TODO */ } }
-        public static float ScaleSnapAmount { get { return 1.0f; /* TODO */ } }
+        public static bool RotateHandleSnapActive
+        {
+            get { return EditorSettings.RotateHandleSnapActive; }
+            set { EditorSettings.RotateHandleSnapActive = value; }
+        }
+
+        public static bool ScaleHandleSnapActive
+        {
+            get { return EditorSettings.ScaleHandleSnapActive; }
+            set { EditorSettings.ScaleHandleSnapActive = value; }
+        }
+
+        public static float MoveSnapAmount
+        {
+            get { return EditorSettings.MoveHandleSnapAmount; }
+            set { EditorSettings.MoveHandleSnapAmount = value; }
+        }
+
+        public static Degree RotateSnapAmount
+        {
+            get { return EditorSettings.RotateHandleSnapAmount; }
+            set { EditorSettings.RotateHandleSnapAmount = value.GetDegrees(); }
+        }
+
+        public static float ScaleSnapAmount
+        {
+            get { return EditorSettings.ScaleHandleSnapAmount; }
+            set { EditorSettings.MoveHandleSnapAmount = value; }
+        }
 
         public static float SnapValue(float value, float snapAmount)
         {
@@ -22,9 +50,12 @@ namespace BansheeEditor
 
         public static float GetHandleSize(Camera camera, Vector3 position)
         {
-            // TODO 
+            Vector3 cameraPos = camera.sceneObject.Position;
+
+		    Vector3 diff = position - cameraPos;
+		    float distAlongViewDir = Vector3.Dot(diff, camera.sceneObject.Rotation.Forward);
 
-            return 1;
+		    return EditorSettings.DefaultHandleSize / Math.Max(distAlongViewDir, 0.0001f);
         }
     }
 }

+ 1 - 1
MBansheeEditor/Scene/MoveHandle.cs

@@ -68,7 +68,7 @@ namespace BansheeEditor
             else
                 HandleDrawing.SetColor(Color.red);
 
-            float handleSize = Handles.GetHandleSize(EditorApplication.sceneCamera, position);
+            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
 
             HandleDrawing.DrawLine(center, xEnd - GetXDir() * CONE_HEIGHT, handleSize);
             HandleDrawing.DrawCone(xEnd - GetXDir() * CONE_HEIGHT, GetXDir(), CONE_HEIGHT, CONE_RADIUS, handleSize);

+ 45 - 0
MBansheeEditor/Scene/SceneViewHandler.cs

@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    internal sealed class SceneViewHandler : ScriptObject
+    {
+        internal SceneViewHandler(Camera sceneCamera)
+        {
+            Internal_Create(this, sceneCamera.GetCachedPtr());
+        }
+
+        internal void Update(Vector2I pointerPos)
+        {
+            Internal_Update(mCachedPtr, pointerPos);
+        }
+
+        internal void PointerPressed(Vector2I pointerPos)
+        {
+            Internal_PointerPressed(mCachedPtr, pointerPos);
+        }
+
+        internal void PointerReleased(Vector2I pointerPos, bool controlHeld)
+        {
+            Internal_PointerReleased(mCachedPtr, pointerPos, controlHeld);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Create(SceneViewHandler managedInstance, IntPtr camera);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Update(IntPtr thisPtr, Vector2I pointerPos);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_PointerPressed(IntPtr thisPtr, Vector2I pointerPos);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_PointerReleased(IntPtr thisPtr, Vector2I pointerPos, bool controlHeld);
+    }
+}

+ 96 - 1
MBansheeEditor/Scene/SceneWindow.cs

@@ -3,19 +3,114 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using BansheeEngine;
 
 namespace BansheeEditor
 {
     internal sealed class SceneWindow : EditorWindow
     {
+        private Camera camera;
+        private SceneCamera cameraController;
+        private RenderTexture2D renderTexture;
+
+        private GUIRenderTexture renderTextureGUI;
+        private SceneViewHandler sceneViewHandler;
+
+        public Camera GetCamera()
+        {
+            return camera;
+        }
+
         internal SceneWindow()
         {
-            
+            UpdateRenderTexture(Width, Height);
+
+            Input.OnPointerPressed += OnPointerPressed;
+            Input.OnPointerReleased += OnPointerReleased;
+        }
+
+        private bool ScreenToScenePos(Vector2I screenPos, out Vector2I scenePos)
+        {
+            scenePos = screenPos;
+            Vector2I windowPos = ScreenToWindowPos(screenPos);
+
+            Rect2I bounds = GUILayoutUtility.CalculateBounds(renderTextureGUI);
+            if (bounds.Contains(windowPos))
+            {
+                scenePos.x = windowPos.x - bounds.x;
+                scenePos.y = windowPos.y - bounds.y;
+
+                return true;
+            }
+
+            return false;
+        }
+
+        private void EditorUpdate()
+        {
+            Vector2I scenePos;
+            if (ScreenToScenePos(Input.PointerPosition, out scenePos))
+            {
+                sceneViewHandler.Update(scenePos);
+            }
+        }
+
+        private void OnPointerPressed(PointerEvent ev)
+        {
+            sceneViewHandler.PointerPressed(ev.ScreenPos);
+        }
+
+        private void OnPointerReleased(PointerEvent ev)
+        {
+            sceneViewHandler.PointerReleased(ev.ScreenPos, ev.Control);
         }
 
         protected override void WindowResized(int width, int height)
         {
+            UpdateRenderTexture(width, height);
+
             base.WindowResized(width, height);
         }
+
+        private void UpdateRenderTexture(int width, int height)
+	    {
+		    width = Math.Max(20, width);
+		    height = Math.Max(20, height);
+
+            renderTexture = new RenderTexture2D(PixelFormat.R8G8B8A8, width, height);
+            renderTexture.Priority = 1;
+
+		    if (camera == null)
+		    {
+			    SceneObject sceneCameraSO = new SceneObject("SceneCamera");
+			    camera = sceneCameraSO.AddComponent<Camera>();
+		        camera.target = renderTexture;
+		        camera.viewportRect = new Rect2(0.0f, 0.0f, 1.0f, 1.0f);
+
+			    sceneCameraSO.Position = new Vector3(0, 0.5f, 1);
+			    sceneCameraSO.LookAt(new Vector3(0, 0, 0));
+
+		        camera.priority = 1;
+		        camera.nearClipPlane = 0.005f;
+		        camera.farClipPlane = 1000.0f;
+
+			    cameraController = sceneCameraSO.AddComponent<SceneCamera>();
+
+                renderTextureGUI = new GUIRenderTexture(renderTexture);
+		        GUI.layout.AddElement(renderTextureGUI);
+
+		        sceneViewHandler = new SceneViewHandler(camera);
+		    }
+		    else
+		    {
+		        camera.target = renderTexture;
+		        renderTextureGUI.RenderTexture = renderTexture;
+		    }
+
+		    // TODO - Consider only doing the resize once user stops resizing the widget in order to reduce constant
+		    // render target destroy/create cycle for every little pixel.
+
+		    camera.aspectRatio = width / (float)height;
+	    }
     }
 }

+ 34 - 26
MBansheeEngine/Camera.cs

@@ -21,132 +21,132 @@ namespace BansheeEngine
 
     public class Camera : Component
     {
-        public float AspectRatio
+        public float aspectRatio
         {
             get { return Internal_GetAspect(mCachedPtr); }
             set { Internal_SetAspect(mCachedPtr, value); }
         }
 
-        public float NearClipPlane
+        public float nearClipPlane
         {
             get { return Internal_GetNearClip(mCachedPtr); }
             set { Internal_SetNearClip(mCachedPtr, value); }
         }
 
-        public float FarClipPlane
+        public float farClipPlane
         {
             get { return Internal_GetFarClip(mCachedPtr); }
             set { Internal_SetFarClip(mCachedPtr, value); }
         }
 
-        public Degree FieldOfView
+        public Degree fieldOfView
         {
             get { return Internal_GetFieldOfView(mCachedPtr); }
             set { Internal_SetFieldOfView(mCachedPtr, value); }
         }
 
-        public Rect2 ViewportRect
+        public Rect2 viewportRect
         {
             get { return Internal_GetViewportRect(mCachedPtr); }
             set { Internal_SetViewportRect(mCachedPtr, value); }
         }
 
-        public ProjectionType ProjectionType
+        public ProjectionType projectionType
         {
             get { return Internal_GetProjectionType(mCachedPtr); }
             set { Internal_SetProjectionType(mCachedPtr, value); }
         }
 
-        public float OrthoHeight
+        public float orthoHeight
         {
             get { return Internal_GetOrthographicHeight(mCachedPtr); }
             set { Internal_SetOrthographicHeight(mCachedPtr, value); }
         }
 
-        public float OrthoWidth
+        public float orthoWidth
         {
             get { return Internal_GetOrthographicWidth(mCachedPtr); }
         }
 
-        public Color ClearColor
+        public Color clearColor
         {
             get { return Internal_GetClearColor(mCachedPtr); }
             set { Internal_SetClearColor(mCachedPtr, value); }
         }
 
-        public float ClearDepth
+        public float clearDepth
         {
             get { return Internal_GetDepthClearValue(mCachedPtr); }
             set { Internal_SetDepthClearValue(mCachedPtr, value); }
         }
 
-        public UInt16 ClearStencil
+        public UInt16 clearStencil
         {
             get { return Internal_GetStencilClearValue(mCachedPtr); }
             set { Internal_SetStencilClearValue(mCachedPtr, value); }
         }
 
-        public ClearFlags ClearFlags
+        public ClearFlags clearFlags
         {
             get { return Internal_GetClearFlags(mCachedPtr); }
             set { Internal_SetClearFlags(mCachedPtr, value); }
         }
 
-        public int Priority
+        public int priority
         {
             get { return Internal_GetPriority(mCachedPtr); }
             set { Internal_SetPriority(mCachedPtr, value); }
         }
 
-        public UInt64 Layers
+        public UInt64 layers
         {
             get { return Internal_GetLayers(mCachedPtr); }
             set { Internal_SetLayers(mCachedPtr, value); }
         }
 
-        public Matrix4 ProjMatrix
+        public Matrix4 projMatrix
         {
             get { return Internal_GetProjMatrix(mCachedPtr); }
         }
 
-        public Matrix4 ProjMatrixInv
+        public Matrix4 projMatrixInv
         {
             get { return Internal_GetProjMatrixInv(mCachedPtr); }
         }
 
-        public Matrix4 ViewMatrix
+        public Matrix4 viewMatrix
         {
             get { return Internal_GetViewMatrix(mCachedPtr); }
         }
 
-        public Matrix4 ViewMatrixInv
+        public Matrix4 viewMatrixInv
         {
             get { return Internal_GetViewMatrixInv(mCachedPtr); }
         }
 
-        public int WidthPixels
+        public int widthPixels
         {
             get { return Internal_GetWidthPixels(mCachedPtr); }
         }
 
-        public int HeightPixels
+        public int heightPixels
         {
             get { return Internal_GetHeightPixels(mCachedPtr); }
         }
 
-        public RenderTarget Target
+        public RenderTarget target
         {
             get
             {
-                return target;
+                return _target;
             }
             set
             {
-                target = value;
+                _target = value;
 
                 IntPtr targetPtr = IntPtr.Zero;
-                if (target != null)
-                    targetPtr = target.mCachedPtr;
+                if (_target != null)
+                    targetPtr = _target.mCachedPtr;
 
                 Internal_SetRenderTarget(mCachedPtr, targetPtr);
             }
@@ -172,13 +172,21 @@ namespace BansheeEngine
         public Vector3 ProjectPoint(Vector3 value) { return Internal_ProjectPoint(mCachedPtr, value); }
         public Vector3 UnprojectPoint(Vector3 value) { return Internal_UnprojectPoint(mCachedPtr, value); }
 
-        private RenderTarget target;
+        private RenderTarget _target;
+
+        public Camera()
+        {
+            Internal_Create(this);
+        }
 
         private void Update()
         {
             Internal_UpdateView(mCachedPtr, sceneObject.mCachedPtr);
         }
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Create(Camera instance);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern float Internal_GetAspect(IntPtr instance);
         [MethodImpl(MethodImplOptions.InternalCall)]

+ 20 - 9
MBansheeEngine/GUI/GUIRenderTexture.cs

@@ -5,6 +5,26 @@ namespace BansheeEngine
 {
     public sealed class GUIRenderTexture : GUIElement
     {
+        private RenderTexture2D renderTexture;
+
+        public RenderTexture2D RenderTexture
+        {
+            get
+            {
+                return renderTexture;
+            }
+
+            set
+            {
+                IntPtr texturePtr = IntPtr.Zero;
+                if (value != null)
+                    texturePtr = value.GetCachedPtr();
+
+                renderTexture = value;
+                Internal_SetTexture(mCachedPtr, texturePtr);
+            }
+        }
+
         public GUIRenderTexture(RenderTexture2D texture, string style, params GUIOption[] options)
         {
             IntPtr texturePtr = IntPtr.Zero;
@@ -23,15 +43,6 @@ namespace BansheeEngine
             Internal_CreateInstance(this, texturePtr, "", options);
         }
 
-        public void SetTexture(RenderTexture2D texture)
-        {
-            IntPtr texturePtr = IntPtr.Zero;
-            if (texture != null)
-                texturePtr = texture.GetCachedPtr();
-
-            Internal_SetTexture(mCachedPtr, texturePtr);
-        }
-
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CreateInstance(GUIRenderTexture instance, IntPtr texture,
             string style, GUIOption[] options);

+ 13 - 0
MBansheeEngine/Input.cs

@@ -111,6 +111,16 @@ namespace BansheeEngine
             return Internal_IsButtonDown(code, deviceIdx);
         }
 
+        public static Vector2I PointerPosition
+        {
+            get
+            {
+                Vector2I value;
+                Internal_GetPointerPosition(out value);
+                return value;
+            }
+        }
+
         private static void Internal_TriggerButtonDown(ButtonCode code, int deviceIdx)
         {
             ButtonEvent ev = new ButtonEvent(code, deviceIdx);
@@ -182,6 +192,9 @@ namespace BansheeEngine
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern bool Internal_IsButtonDown(ButtonCode keyCode, int deviceIdx);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetPointerPosition(out Vector2I position);
     }
 
     // Do not change IDs, must match ButtonCode C++ enum

+ 53 - 0
MBansheeEngine/Math/Quaternion.cs

@@ -72,6 +72,59 @@ namespace BansheeEngine
             }
         }
 
+        public Vector3 Right
+        {
+            get
+            {
+                float fTy = 2.0f*y;
+                float fTz = 2.0f*z;
+                float fTwy = fTy*w;
+                float fTwz = fTz*w;
+                float fTxy = fTy*x;
+                float fTxz = fTz*x;
+                float fTyy = fTy*y;
+                float fTzz = fTz*z;
+
+                return new Vector3(1.0f - (fTyy + fTzz), fTxy + fTwz, fTxz - fTwy);
+            }
+        }
+
+        public Vector3 Up
+        {
+            get
+            {
+                float fTx = 2.0f * x;
+                float fTy = 2.0f * y;
+                float fTz = 2.0f * z;
+                float fTwx = fTx * w;
+                float fTwz = fTz * w;
+                float fTxx = fTx * x;
+                float fTxy = fTy * x;
+                float fTyz = fTz * y;
+                float fTzz = fTz * z;
+
+                return new Vector3(fTxy - fTwz, 1.0f - (fTxx + fTzz), fTyz + fTwx);
+            }
+        }
+
+        public Vector3 Forward
+        {
+            get
+            {
+                float fTx = 2.0f * x;
+                float fTy = 2.0f * y;
+                float fTz = 2.0f * z;
+                float fTwx = fTx * w;
+                float fTwy = fTy * w;
+                float fTxx = fTx * x;
+                float fTxz = fTz * x;
+                float fTyy = fTy * y;
+                float fTyz = fTz * y;
+
+                return new Vector3(fTxz + fTwy, fTyz - fTwx, 1.0f - (fTxx + fTyy));
+            }
+        }
+
         public Quaternion(float x, float y, float z, float w)
         {
             this.x = x;

+ 11 - 0
MBansheeEngine/Math/Rect2I.cs

@@ -27,6 +27,17 @@ namespace BansheeEngine
 			return !(lhs == rhs);
 		}
 
+	    public bool Contains(Vector2I point)
+	    {
+		    if(point.x >= x && point.x < (x + width))
+		    {
+			    if(point.y >= y && point.y < (y + height))
+				    return true;
+		    }
+
+		    return false;
+	    }
+
         public override bool Equals(object other)
         {
             if (!(other is Rect2I))

+ 5 - 0
MBansheeEngine/SceneObject.cs

@@ -191,6 +191,11 @@ namespace BansheeEngine
             return Internal_GetChild(mCachedPtr, idx);
         }
 
+        public void LookAt(Vector3 direction)
+        {
+            Internal_LookAt(mCachedPtr, direction, Vector3.yAxis);
+        }
+
         public void LookAt(Vector3 direction, Vector3 up)
         {
             Internal_LookAt(mCachedPtr, direction, up);

+ 31 - 0
SBansheeEditor/Include/BsScriptEditorSettings.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptEditorSettings : public ScriptObject < ScriptEditorSettings >
+	{
+	public:
+		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "EditorSettings")
+
+	private:
+		ScriptEditorSettings(MonoObject* instance);
+
+		static bool internal_GetMoveHandleSnapActive();
+		static void internal_SetMoveHandleSnapActive(bool value);
+		static bool internal_GetRotateHandleSnapActive();
+		static void internal_SetRotateHandleSnapActive(bool value);
+		static bool internal_GetScaleHandleSnapActive();
+		static void internal_SetScaleHandleSnapActive(bool value);
+		static float internal_GetMoveHandleSnapAmount();
+		static void internal_SetMoveHandleSnapAmount(float value);
+		static float internal_GetRotateHandleSnapAmount();
+		static void internal_SetRotateHandleSnapAmount(float value);
+		static float internal_GetScaleHandleSnapAmount();
+		static void internal_SetScaleHandleSnapAmount(float value);
+		static float internal_GetDefaultHandleSize();
+		static void internal_SetDefaultHandleSize(float value);
+	};
+}

+ 9 - 1
SBansheeEditor/Include/BsScriptEditorWindow.h

@@ -66,10 +66,18 @@ namespace BansheeEngine
 	class BS_SCR_BED_EXPORT ScriptEditorWidget : public EditorWidgetBase
 	{
 	public:
-		ScriptEditorWidget(const String& windowTypeName, const HString& displayName, EditorWidgetContainer& parentContainer);
+		ScriptEditorWidget(const String& windowTypeName, const HString& displayName, 
+			EditorWidgetContainer& parentContainer, MonoClass* monoClass, MonoObject* managedInstance);
 		~ScriptEditorWidget();
 
+		void update();
+
 	private:
+		typedef void(__stdcall *UpdateThunkDef) (MonoObject*, MonoException**);
+
 		String mWindowTypeName;
+		UpdateThunkDef mUpdateThunk;
+		MonoObject* mManagedInstance;
+		ScriptEditorWindow* mScriptParent;
 	};
 }

+ 24 - 0
SBansheeEditor/Include/BsScriptSceneViewHandler.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptSceneViewHandler : public ScriptObject < ScriptSceneViewHandler >
+	{
+	public:
+		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "SceneViewHandler")
+
+	private:
+		static void internal_Create(MonoObject* managedInstance, ScriptCamera* camera);
+		static void internal_Update(ScriptSceneViewHandler* thisPtr, Vector2I inputPos);
+		static void internal_PointerPressed(ScriptSceneViewHandler* thisPtr, Vector2I inputPos);
+		static void internal_PointerReleased(ScriptSceneViewHandler* thisPtr, Vector2I inputPos, bool controlPressed);
+
+		ScriptSceneViewHandler(MonoObject* object, const SPtr<CameraHandler>& camera);
+		~ScriptSceneViewHandler();
+
+		SceneViewHandler* mHandler;
+	};
+}

+ 4 - 0
SBansheeEditor/SBansheeEditor.vcxproj

@@ -237,6 +237,7 @@
     <ClInclude Include="Include\BsGUIPanelContainer.h" />
     <ClInclude Include="Include\BsGUIResourceField.h" />
     <ClInclude Include="Include\BsScriptEditorPrerequisites.h" />
+    <ClInclude Include="Include\BsScriptEditorSettings.h" />
     <ClInclude Include="Include\BsScriptEditorUtility.h" />
     <ClInclude Include="Include\BsScriptEditorWindow.h" />
     <ClInclude Include="Include\BsScriptGizmoManager.h" />
@@ -262,6 +263,7 @@
     <ClInclude Include="Include\BsScriptHandleSliderManager.h" />
     <ClInclude Include="Include\BsScriptHandleSliderPlane.h" />
     <ClInclude Include="Include\BsScriptProjectLibrary.h" />
+    <ClInclude Include="Include\BsScriptSceneViewHandler.h" />
     <ClInclude Include="Include\BsScriptSelection.h" />
   </ItemGroup>
   <ItemGroup>
@@ -270,6 +272,7 @@
     <ClCompile Include="Source\BsGUIPanelContainer.cpp" />
     <ClCompile Include="Source\BsGUIResourceField.cpp" />
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp" />
+    <ClCompile Include="Source\BsScriptEditorSettings.cpp" />
     <ClCompile Include="Source\BsScriptEditorUtility.cpp" />
     <ClCompile Include="Source\BsScriptEditorWindow.cpp" />
     <ClCompile Include="Source\BsScriptGizmoManager.cpp" />
@@ -295,6 +298,7 @@
     <ClCompile Include="Source\BsScriptHandleSliderManager.cpp" />
     <ClCompile Include="Source\BsScriptHandleSliderPlane.cpp" />
     <ClCompile Include="Source\BsScriptProjectLibrary.cpp" />
+    <ClCompile Include="Source\BsScriptSceneViewHandler.cpp" />
     <ClCompile Include="Source\BsScriptSelection.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 12 - 0
SBansheeEditor/SBansheeEditor.vcxproj.filters

@@ -108,6 +108,12 @@
     <ClInclude Include="Include\BsScriptHandleSliderManager.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptSceneViewHandler.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptEditorSettings.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
@@ -203,5 +209,11 @@
     <ClCompile Include="Source\BsScriptHandleSliderManager.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptSceneViewHandler.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptEditorSettings.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 116 - 0
SBansheeEditor/Source/BsScriptEditorSettings.cpp

@@ -0,0 +1,116 @@
+#include "BsScriptEditorSettings.h"
+#include "BsMonoManager.h"
+#include "BsMonoClass.h"
+#include "BsMonoMethod.h"
+#include "BsMonoUtil.h"
+#include "BsEditorApplication.h"
+#include "BsEditorSettings.h"
+
+namespace BansheeEngine
+{
+	ScriptEditorSettings::ScriptEditorSettings(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptEditorSettings::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_GetMoveHandleSnapActive", &ScriptEditorSettings::internal_GetMoveHandleSnapActive);
+		metaData.scriptClass->addInternalCall("Internal_SetMoveHandleSnapActive", &ScriptEditorSettings::internal_SetMoveHandleSnapActive);
+		metaData.scriptClass->addInternalCall("Internal_GetRotateHandleSnapActive", &ScriptEditorSettings::internal_GetRotateHandleSnapActive);
+		metaData.scriptClass->addInternalCall("Internal_SetRotateHandleSnapActive", &ScriptEditorSettings::internal_SetRotateHandleSnapActive);
+		metaData.scriptClass->addInternalCall("Internal_GetScaleHandleSnapActive", &ScriptEditorSettings::internal_GetScaleHandleSnapActive);
+		metaData.scriptClass->addInternalCall("Internal_SetScaleHandleSnapActive", &ScriptEditorSettings::internal_SetScaleHandleSnapActive);
+		metaData.scriptClass->addInternalCall("Internal_GetMoveHandleSnapAmount", &ScriptEditorSettings::internal_GetMoveHandleSnapAmount);
+		metaData.scriptClass->addInternalCall("Internal_SetMoveHandleSnapAmount", &ScriptEditorSettings::internal_SetMoveHandleSnapAmount);
+		metaData.scriptClass->addInternalCall("Internal_GetRotateHandleSnapAmount", &ScriptEditorSettings::internal_GetRotateHandleSnapAmount);
+		metaData.scriptClass->addInternalCall("Internal_SetRotateHandleSnapAmount", &ScriptEditorSettings::internal_SetRotateHandleSnapAmount);
+		metaData.scriptClass->addInternalCall("Internal_GetScaleHandleSnapAmount", &ScriptEditorSettings::internal_GetScaleHandleSnapAmount);
+		metaData.scriptClass->addInternalCall("Internal_SetScaleHandleSnapAmount", &ScriptEditorSettings::internal_SetScaleHandleSnapAmount);
+		metaData.scriptClass->addInternalCall("Internal_GetDefaultHandleSize", &ScriptEditorSettings::internal_GetDefaultHandleSize);
+		metaData.scriptClass->addInternalCall("Internal_SetDefaultHandleSize", &ScriptEditorSettings::internal_SetDefaultHandleSize);
+	}
+
+	bool ScriptEditorSettings::internal_GetMoveHandleSnapActive()
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		return settings->getMoveHandleSnapActive();
+	}
+
+	void ScriptEditorSettings::internal_SetMoveHandleSnapActive(bool value)
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		settings->setMoveHandleSnapActive(value);
+	}
+
+	bool ScriptEditorSettings::internal_GetRotateHandleSnapActive()
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		return settings->getRotateHandleSnapActive();
+	}
+
+	void ScriptEditorSettings::internal_SetRotateHandleSnapActive(bool value)
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		settings->setRotateHandleSnapActive(value);
+	}
+
+	bool ScriptEditorSettings::internal_GetScaleHandleSnapActive()
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		return settings->getScaleHandleSnapActive();
+	}
+
+	void ScriptEditorSettings::internal_SetScaleHandleSnapActive(bool value)
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		settings->setScaleHandleSnapActive(value);
+	}
+
+	float ScriptEditorSettings::internal_GetMoveHandleSnapAmount()
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		return settings->getMoveHandleSnap();
+	}
+
+	void ScriptEditorSettings::internal_SetMoveHandleSnapAmount(float value)
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		settings->setMoveHandleSnap(value);
+	}
+
+	float ScriptEditorSettings::internal_GetRotateHandleSnapAmount()
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		return settings->getRotationHandleSnap().valueDegrees();
+	}
+
+	void ScriptEditorSettings::internal_SetRotateHandleSnapAmount(float value)
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		settings->setRotationHandleSnap(Degree(value));
+	}
+
+	float ScriptEditorSettings::internal_GetScaleHandleSnapAmount()
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		return settings->getScaleHandleSnap();
+	}
+
+	void ScriptEditorSettings::internal_SetScaleHandleSnapAmount(float value)
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		settings->setScaleHandleSnap(value);
+	}
+
+	float ScriptEditorSettings::internal_GetDefaultHandleSize()
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		return settings->getHandleSize();
+	}
+
+	void ScriptEditorSettings::internal_SetDefaultHandleSize(float value)
+	{
+		EditorSettingsPtr settings = gEditorApplication().getEditorSettings();
+		settings->setHandleSize(value);
+	}
+}

+ 23 - 4
SBansheeEditor/Source/BsScriptEditorWindow.cpp

@@ -181,7 +181,7 @@ namespace BansheeEngine
 		String windowFullTypeName = MonoManager::instance().getFullTypeName(editorWindowInstance);
 		String displayName = MonoManager::instance().getTypeName(editorWindowInstance);
 
-		ScriptEditorWidget* editorWidget = bs_new<ScriptEditorWidget>(windowFullTypeName, HString(toWString(displayName)), parentContainer);
+		ScriptEditorWidget* editorWidget = bs_new<ScriptEditorWidget>(windowFullTypeName, HString(toWString(displayName)), parentContainer, editorWindowClass, editorWindowInstance);
 		ScriptEditorWindow* nativeInstance = new (bs_alloc<ScriptEditorWindow>()) ScriptEditorWindow(editorWindowInstance, windowFullTypeName, displayName, editorWidget);
 
 		ScriptEditorWindow::registerScriptEditorWindow(nativeInstance);
@@ -219,14 +219,33 @@ namespace BansheeEngine
 		}
 	}
 
-	ScriptEditorWidget::ScriptEditorWidget(const String& windowTypeName, const HString& displayName, EditorWidgetContainer& parentContainer)
-		:EditorWidgetBase(displayName, windowTypeName, parentContainer), mWindowTypeName(windowTypeName)
+	ScriptEditorWidget::ScriptEditorWidget(const String& windowTypeName, const HString& displayName, 
+		EditorWidgetContainer& parentContainer, MonoClass* monoClass, MonoObject* managedInstance)
+		:EditorWidgetBase(displayName, windowTypeName, parentContainer), 
+		mWindowTypeName(windowTypeName), mUpdateThunk(nullptr), mManagedInstance(managedInstance)
 	{
-		
+		MonoMethod* updateMethod = monoClass->getMethod("EditorUpdate", 0);
+
+		if (updateMethod != nullptr)
+			mUpdateThunk = (UpdateThunkDef)updateMethod->getThunk();
 	}
 
 	ScriptEditorWidget::~ScriptEditorWidget()
 	{
 		ScriptEditorWindow::unregisterScriptEditorWindow(mWindowTypeName);
 	}
+
+	void ScriptEditorWidget::update()
+	{
+		if (mUpdateThunk != nullptr && mManagedInstance != nullptr)
+		{
+			MonoException* exception = nullptr;
+
+			// Note: Not calling virtual methods. Can be easily done if needed but for now doing this
+			// for some extra speed.
+			mUpdateThunk(mManagedInstance, &exception);
+
+			MonoUtil::throwIfException(exception);
+		}
+	}
 }

+ 48 - 0
SBansheeEditor/Source/BsScriptSceneViewHandler.cpp

@@ -0,0 +1,48 @@
+#include "BsScriptSceneViewHandler.h"
+#include "BsScriptMeta.h"
+#include "BsMonoClass.h"
+#include "BsMonoUtil.h"
+#include "BsSceneViewHandler.h"
+#include "BsScriptCamera.h"
+
+namespace BansheeEngine
+{
+	ScriptSceneViewHandler::ScriptSceneViewHandler(MonoObject* object, const SPtr<CameraHandler>& camera)
+		:ScriptObject(object), mHandler(nullptr)
+	{ 
+		mHandler = bs_new<SceneViewHandler>(camera);
+	}
+
+	ScriptSceneViewHandler::~ScriptSceneViewHandler()
+	{
+		bs_delete(mHandler);
+	}
+
+	void ScriptSceneViewHandler::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_Create", &ScriptSceneViewHandler::internal_Create);
+		metaData.scriptClass->addInternalCall("Internal_Update", &ScriptSceneViewHandler::internal_Update);
+		metaData.scriptClass->addInternalCall("Internal_PointerPressed", &ScriptSceneViewHandler::internal_PointerPressed);
+		metaData.scriptClass->addInternalCall("Internal_PointerReleased", &ScriptSceneViewHandler::internal_PointerReleased);
+	}
+
+	void ScriptSceneViewHandler::internal_Create(MonoObject* managedInstance, ScriptCamera* camera)
+	{
+		new (bs_alloc<ScriptSceneViewHandler>()) ScriptSceneViewHandler(managedInstance, camera->getHandler());
+	}
+
+	void ScriptSceneViewHandler::internal_Update(ScriptSceneViewHandler* thisPtr, Vector2I inputPos)
+	{
+		thisPtr->mHandler->update(inputPos);
+	}
+
+	void ScriptSceneViewHandler::internal_PointerPressed(ScriptSceneViewHandler* thisPtr, Vector2I inputPos)
+	{
+		thisPtr->mHandler->pointerPressed(inputPos);
+	}
+
+	void ScriptSceneViewHandler::internal_PointerReleased(ScriptSceneViewHandler* thisPtr, Vector2I inputPos, bool controlPressed)
+	{
+		thisPtr->mHandler->pointerReleased(inputPos, controlPressed);
+	}
+}

+ 4 - 0
SBansheeEngine/Include/BsScriptCamera.h

@@ -18,12 +18,16 @@ namespace BansheeEngine
 	public:
 		SCRIPT_OBJ(BansheeEngineAssemblyName, "BansheeEngine", "Camera")
 
+		SPtr<CameraHandler> getHandler() const { return mCameraHandler; }
+
 	private:
 		ScriptCamera(MonoObject* managedInstance);
 		~ScriptCamera();
 
 		void updateView(const HSceneObject& parent);
 
+		static void internal_Create(MonoObject* managedInstance);
+
 		static float internal_GetAspect(ScriptCamera* instance);
 		static void internal_SetAspect(ScriptCamera* instance, float value);
 		static float internal_GetNearClip(ScriptCamera* instance);

+ 1 - 0
SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -39,6 +39,7 @@ namespace BansheeEngine
 	class ScriptManagedResource;
 	class ScriptRenderTarget;
 	class ScriptRenderTexture2D;
+	class ScriptCamera;
 	class ManagedComponent;
 	class ManagedSerializableFieldData;
 	class ManagedSerializableFieldKey;

+ 1 - 0
SBansheeEngine/Include/BsScriptInput.h

@@ -27,6 +27,7 @@ namespace BansheeEngine
 		static bool internal_isButtonDown(ButtonCode code, UINT32 deviceIdx);
 		static bool internal_isButtonUp(ButtonCode code, UINT32 deviceIdx);
 		static float internal_getAxisValue(UINT32 axisType, UINT32 deviceIdx);
+		static void internal_getPointerPosition(Vector2I* position);
 
 		typedef void(__stdcall *OnButtonEventThunkDef) (ButtonCode, UINT32, MonoException**);
 		typedef void(__stdcall *OnCharInputEventThunkDef) (UINT32, MonoException**);

+ 7 - 0
SBansheeEngine/Source/BsScriptCamera.cpp

@@ -27,6 +27,8 @@ namespace BansheeEngine
 
 	void ScriptCamera::initRuntimeData()
 	{
+		metaData.scriptClass->addInternalCall("Internal_Create", &ScriptCamera::internal_Create);
+
 		metaData.scriptClass->addInternalCall("Internal_GetAspect", &ScriptCamera::internal_GetAspect);
 		metaData.scriptClass->addInternalCall("Internal_SetAspect", &ScriptCamera::internal_GetAspect);
 		metaData.scriptClass->addInternalCall("Internal_GetNearClip", &ScriptCamera::internal_GetAspect);
@@ -113,6 +115,11 @@ namespace BansheeEngine
 		}
 	}
 
+	void ScriptCamera::internal_Create(MonoObject* managedInstance)
+	{
+		ScriptCamera* nativeInstance = new (bs_alloc<ScriptCamera>()) ScriptCamera(managedInstance);
+	}
+
 	float ScriptCamera::internal_GetAspect(ScriptCamera* instance)
 	{
 		return instance->mCameraHandler->getAspectRatio();

+ 6 - 0
SBansheeEngine/Source/BsScriptInput.cpp

@@ -35,6 +35,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_IsButtonDown", &ScriptInput::internal_isButtonDown);
 		metaData.scriptClass->addInternalCall("Internal_IsButtonUp", &ScriptInput::internal_isButtonUp);
 		metaData.scriptClass->addInternalCall("Internal_GetAxisValue", &ScriptInput::internal_getAxisValue);
+		metaData.scriptClass->addInternalCall("Internal_GetPointerPosition", &ScriptInput::internal_getPointerPosition);
 
 		OnButtonPressedThunk = (OnButtonEventThunkDef)metaData.scriptClass->getMethodExact("Internal_TriggerButtonDown", "ButtonCode,int")->getThunk();
 		OnButtonReleasedThunk = (OnButtonEventThunkDef)metaData.scriptClass->getMethodExact("Internal_TriggerButtonUp", "ButtonCode,int")->getThunk();
@@ -152,4 +153,9 @@ namespace BansheeEngine
 	{
 		return Input::instance().getAxisValue(axisType, deviceIdx);
 	}
+
+	void ScriptInput::internal_getPointerPosition(Vector2I* position)
+	{
+		*position = Input::instance().getPointerPosition();
+	}
 }

+ 10 - 7
TODO.txt

@@ -12,15 +12,17 @@
 
 See GDrive/Resources doc for resources refactor
 
+C# SceneView:
+Test new Scene window and fix every issue
+Add ProjectWindow and HierarchyWindow to C#
+ - Make TreeViews a C# element?
+Set up a default layout and save it
+
+Handle snapping is probably set up wrong. Handles.SnapValue seems to wrap a value instead of snapping, plus I might
+need to store the unsnapped amount somewhere until it reaches some amount worthy of snapping to next value
+
 -----------------
 
-Ensure that EditorWindow resize callback works properly.
- - Perhaps add OnResizeEnd callback that can be used for updating the render texture
-Create a C# wrapper around ProjectSettings
-Make a Script version of SceneEditorWindow
- - This would replace SceneEditorWidget so it would initialize scene grid and call
-    update on handle manager and scene grid, as well as apply ProjectSettings to them.
- 
 Move handle is buggy as hell - It moves in wrong direction sometimes, sometimes it skips, other times collision seems to be wrong
 Need a way to drag and drop items from Scene tree view to Scene view
 When dragging a handle make sure it works when cursor leaves the scene view
@@ -75,6 +77,7 @@ HandleSliderPlane/HandleSliderDisc
 STAGE 2
 Implement RotateHandle & ScaleHandle in C#
  - Nearest point to disc/arc code
+Add 2D move and scale
 Add free move, free rotate, free scale functionality
 Handles that remain the same size regardless of distance from camera
  - For both drawing and collision