瀏覽代碼

Refactored SceneManager so it properly registers all cameras and renderables
Removed SceneManager plugin as it is not needed at the moment
Refactored mouse input so it isn't normalized to [-1, 1] range
Various fixes related to construction of C# Components

Marko Pintera 11 年之前
父節點
當前提交
d0c583e20c
共有 43 個文件被更改,包括 346 次插入653 次删除
  1. 6 0
      BansheeCore/Include/BsComponent.h
  2. 0 2
      BansheeCore/Include/BsCoreApplication.h
  3. 24 8
      BansheeCore/Include/BsCoreSceneManager.h
  4. 2 1
      BansheeCore/Include/BsInput.h
  5. 2 2
      BansheeCore/Include/BsSceneObject.h
  6. 21 0
      BansheeCore/Include/BsSceneObjectRTTI.h
  7. 3 4
      BansheeCore/Source/BsCoreApplication.cpp
  8. 10 3
      BansheeCore/Source/BsCoreSceneManager.cpp
  9. 0 4
      BansheeCore/Source/BsSceneObject.cpp
  10. 3 3
      BansheeEditor/Source/BsScenePicking.cpp
  11. 0 31
      BansheeEngine.sln
  12. 5 0
      BansheeEngine/Include/BsCamera.h
  13. 5 0
      BansheeEngine/Include/BsRenderable.h
  14. 58 7
      BansheeEngine/Include/BsSceneManager.h
  15. 2 1
      BansheeEngine/Include/BsVirtualInput.h
  16. 0 1
      BansheeEngine/Source/BsApplication.cpp
  17. 7 0
      BansheeEngine/Source/BsCamera.cpp
  18. 7 0
      BansheeEngine/Source/BsRenderable.cpp
  19. 22 0
      BansheeEngine/Source/BsSceneManager.cpp
  20. 0 35
      BansheeOISInput/Include/BsInputHandlerOIS.h
  21. 8 22
      BansheeOISInput/Source/BsInputHandlerOIS.cpp
  22. 3 3
      BansheeRenderer/Source/BsBansheeRenderer.cpp
  23. 0 247
      BansheeSceneManager/BansheeSceneManager.vcxproj
  24. 0 33
      BansheeSceneManager/BansheeSceneManager.vcxproj.filters
  25. 0 19
      BansheeSceneManager/Include/BsBansheeSMPrerequisites.h
  26. 0 44
      BansheeSceneManager/Include/BsBansheeSceneManager.h
  27. 0 40
      BansheeSceneManager/Source/BsBansheeManagerPlugin.cpp
  28. 0 68
      BansheeSceneManager/Source/BsBansheeSceneManager.cpp
  29. 7 2
      MBansheeEngine/Camera.cs
  30. 15 3
      MBansheeEngine/CameraHandler.cs
  31. 6 1
      MBansheeEngine/Component.cs
  32. 9 1
      SBansheeEngine/Include/BsManagedComponent.h
  33. 3 19
      SBansheeEngine/Include/BsManagedComponentRTTI.h
  34. 3 2
      SBansheeEngine/Include/BsScriptCameraHandler.h
  35. 4 1
      SBansheeEngine/Include/BsScriptComponent.h
  36. 1 1
      SBansheeEngine/Include/BsScriptGameObjectManager.h
  37. 68 7
      SBansheeEngine/Source/BsManagedComponent.cpp
  38. 2 3
      SBansheeEngine/Source/BsManagedSerializableField.cpp
  39. 6 20
      SBansheeEngine/Source/BsRuntimeScriptObjects.cpp
  40. 15 3
      SBansheeEngine/Source/BsScriptCameraHandler.cpp
  41. 15 5
      SBansheeEngine/Source/BsScriptComponent.cpp
  42. 2 4
      SBansheeEngine/Source/BsScriptGameObjectManager.cpp
  43. 2 3
      TODO.txt

+ 6 - 0
BansheeCore/Include/BsComponent.h

@@ -41,10 +41,16 @@ namespace BansheeEngine
 
 	protected:
 		friend class SceneObject;
+		friend class SceneObjectRTTI;
 
 		Component(const HSceneObject& parent);
 		virtual ~Component();
 
+		/**
+		 * @brief	Called when the component is ready to be initialized.
+		 */
+		virtual void onInitialized() {}
+
 		/**
 		 * @brief	Called just before the component is destroyed.
 		 */

+ 0 - 2
BansheeCore/Include/BsCoreApplication.h

@@ -17,7 +17,6 @@ namespace BansheeEngine
 		String renderer; /**< Name of the renderer plugin to use. */
 
 		String input; /**< Name of the input plugin to use. */
-		String sceneManager; /**< Name of the scene manager plugin to use. */
 
 		RENDER_WINDOW_DESC primaryWindowDesc; /**< Describes the window to create during start-up. */
 
@@ -107,7 +106,6 @@ namespace BansheeEngine
 
 		RenderWindowPtr mPrimaryWindow;
 
-		DynLib* mSceneManagerPlugin;
 		DynLib* mRendererPlugin;
 
 		Map<DynLib*, UpdatePluginFunc> mPluginUpdateFunctions;

+ 24 - 8
BansheeCore/Include/BsCoreSceneManager.h

@@ -9,8 +9,7 @@ namespace BansheeEngine
 	/**
 	 * @brief	Manages all objects in the scene and provides various query methods
 	 * 			for finding objects. This is just the base class with basic query 
-	 *			functionality. You should override it with your own version that
-	 * 			implements a spatial data structure of your choice for faster queries.
+	 *			functionality. You should override it with your own version.
 	 */
 	class BS_CORE_EXPORT CoreSceneManager : public Module<CoreSceneManager>
 	{
@@ -48,18 +47,35 @@ namespace BansheeEngine
 		 */
 		void registerNewSO(const HSceneObject& node);
 
+	protected:
+		HSceneObject mRootNode;
+	};
+
+	/**
+	 * @brief	Handles creation of a scene manager.
+	 *
+	 * @note	Since scene manager implementations may vary it is expected that a concrete implementation
+	 *			of a scene manager will register its creation method using "setFactoryMethod" which will then
+	 *			later be used for creating the scene manager during application start up.
+	 */
+	class BS_CORE_EXPORT SceneManagerFactory
+	{
+	public:
 		/**
-		 * @brief	SceneObjects call this when they have a component added to them.
+		 * @brief	Creates a concrete scene manager, depending on the currently set factory method.
 		 */
-		virtual void notifyComponentAdded(const HComponent& component);
+		static void create();
 
 		/**
-		 * @brief	SceneObjects call this when they have a component removed from them.
+		 * @brief	Sets method that will be used for creating the scene manager when "create" gets called.
 		 */
-		virtual void notifyComponentRemoved(const HComponent& component);
+		static void setFactoryMethod(const std::function<void()>& method)
+		{
+			mFactoryMethod = method;
+		}
 
-	protected:
-		HSceneObject mRootNode;
+	private:
+		static std::function<void()> mFactoryMethod;
 	};
 
 	/**

+ 2 - 1
BansheeCore/Include/BsInput.h

@@ -100,7 +100,8 @@ namespace BansheeEngine
 		void _update();
 
 		/**
-		 * @brief	Returns value of the specified input axis in range [-1.0, 1.0].
+		 * @brief	Returns value of the specified input axis. Normally in range [-1.0, 1.0] but can be outside
+		 *			the range for devices with unbound axes (e.g. mouse).
 		 *
 		 * @param	type		Type of axis to query. Usually a type from InputAxis but can be a custom value.
 		 * @param	deviceIdx	Index of the device in case more than one is hooked up (0 - primary).

+ 2 - 2
BansheeCore/Include/BsSceneObject.h

@@ -8,6 +8,7 @@
 #include "BsCoreSceneManager.h"
 #include "BsGameObjectManager.h"
 #include "BsGameObject.h"
+#include "BsComponent.h"
 
 namespace BansheeEngine
 {
@@ -402,8 +403,7 @@ namespace BansheeEngine
 				GameObjectHandle<T>(GameObjectManager::instance().registerObject(gameObject));
 
 			mComponents.push_back(newComponent);
-
-			gCoreSceneManager().notifyComponentAdded(newComponent);	
+			newComponent->onInitialized();
 
 			return newComponent;
 		}

+ 21 - 0
BansheeCore/Include/BsSceneObjectRTTI.h

@@ -5,6 +5,7 @@
 #include "BsSceneObject.h"
 #include "BsGameObjectHandle.h"
 #include "BsGameObjectManager.h"
+#include "BsComponent.h"
 
 namespace BansheeEngine
 {
@@ -60,8 +61,28 @@ namespace BansheeEngine
 			DeserializationData deserializationData = any_cast<DeserializationData>(so->mRTTIData);
 
 			if (deserializationData.isDeserializationParent)
+			{
 				GameObjectManager::instance().endDeserialization();
 
+				// Initialize all components
+				Stack<HSceneObject> todo;
+				todo.push(so->mThisHandle);
+
+				while (!todo.empty())
+				{
+					HSceneObject curSO = todo.top();
+					todo.pop();
+
+					const Vector<HComponent>& components = curSO->getComponents();
+
+					for (auto& component : components)
+						component->onInitialized();
+
+					for (UINT32 i = 0; i < curSO->getNumChildren(); i++)
+						todo.push(curSO->getChild(i));
+				}
+			}
+
 			so->mRTTIData = nullptr;
 		}
 

+ 3 - 4
BansheeCore/Source/BsCoreApplication.cpp

@@ -60,7 +60,7 @@ namespace BansheeEngine
 
 	CoreApplication::CoreApplication(START_UP_DESC& desc)
 		:mPrimaryWindow(nullptr), mIsFrameRenderingFinished(true), mRunMainLoop(false), 
-		mSceneManagerPlugin(nullptr), mRendererPlugin(nullptr)
+		mRendererPlugin(nullptr)
 	{
 		signal(SIGABRT, handleAbort);
 
@@ -97,8 +97,8 @@ namespace BansheeEngine
 		RendererManager::startUp();
 
 		loadPlugin(desc.renderer, &mRendererPlugin);
-		loadPlugin(desc.sceneManager, &mSceneManagerPlugin);
 
+		SceneManagerFactory::create();
 		RendererManager::instance().setActive(desc.renderer);
 
 		ProfilerGPU::startUp();
@@ -125,7 +125,7 @@ namespace BansheeEngine
 		MeshManager::shutDown();
 		ProfilerGPU::shutDown();
 
-		shutdownPlugin(mSceneManagerPlugin);
+		CoreSceneManager::shutDown();
 
 		RendererManager::shutDown();
 		shutdownPlugin(mRendererPlugin);
@@ -142,7 +142,6 @@ namespace BansheeEngine
 		gCoreThread().update();
 		gCoreThread().submitAccessors(true);
 
-		unloadPlugin(mSceneManagerPlugin);
 		unloadPlugin(mRendererPlugin);
 
 		RenderAPIManager::shutDown();

+ 10 - 3
BansheeCore/Source/BsCoreSceneManager.cpp

@@ -5,6 +5,8 @@
 
 namespace BansheeEngine
 {
+	std::function<void()> SceneManagerFactory::mFactoryMethod;
+
 	CoreSceneManager::CoreSceneManager()
 	{
 		mRootNode = SceneObject::createInternal("SceneRoot");
@@ -52,11 +54,16 @@ namespace BansheeEngine
 			node->setParent(mRootNode);
 	}
 
-	void CoreSceneManager::notifyComponentAdded(const HComponent& component) { }
-	void CoreSceneManager::notifyComponentRemoved(const HComponent& component) { }
-
 	CoreSceneManager& gCoreSceneManager()
 	{
 		return CoreSceneManager::instance();
 	}
+
+	void SceneManagerFactory::create()
+	{
+		if (mFactoryMethod != nullptr)
+			mFactoryMethod();
+		else
+			BS_EXCEPT(InvalidStateException, "Failed to initialize scene manager because no valid factory method is set.");
+	}
 }

+ 0 - 4
BansheeCore/Source/BsSceneObject.cpp

@@ -69,7 +69,6 @@ namespace BansheeEngine
 
 		for(auto iter = mComponents.begin(); iter != mComponents.end(); ++iter)
 		{
-			gCoreSceneManager().notifyComponentRemoved((*iter));
 			(*iter)->onDestroyed();
 
 			if (immediate)
@@ -468,7 +467,6 @@ namespace BansheeEngine
 
 		if(iter != mComponents.end())
 		{
-			gCoreSceneManager().notifyComponentRemoved((*iter));
 			(*iter)->onDestroyed();
 			
 			mComponents.erase(iter);
@@ -509,8 +507,6 @@ namespace BansheeEngine
 		GameObjectHandle<Component> newComponent = GameObjectHandle<Component>(component);
 		newComponent->mParent = mThisHandle;
 		mComponents.push_back(newComponent);
-
-		gCoreSceneManager().notifyComponentAdded(newComponent);
 	}
 
 	RTTITypeBase* SceneObject::getRTTIStatic()

+ 3 - 3
BansheeEditor/Source/BsScenePicking.cpp

@@ -78,14 +78,14 @@ namespace BansheeEngine
 
 		Matrix4 viewProjMatrix = cam->getProjectionMatrixRS() * cam->getViewMatrix();
 
-		const Vector<SceneRenderableData>& renderables = SceneManager::instance().getAllRenderables();
+		const Map<RenderableHandler*, SceneRenderableData>& renderables = SceneManager::instance().getAllRenderables();
 		RenderableSet pickData(comparePickElement);
 		Map<UINT32, HSceneObject> idxToRenderable;
 
 		for (auto& renderableData : renderables)
 		{
-			RenderableHandlerPtr renderable = renderableData.renderable;
-			HSceneObject so = renderableData.sceneObject;
+			RenderableHandlerPtr renderable = renderableData.second.renderable;
+			HSceneObject so = renderableData.second.sceneObject;
 
 			if (!so->getActive())
 				continue;

+ 0 - 31
BansheeEngine.sln

@@ -66,7 +66,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BansheeEditorExec", "Banshe
 		{A4865386-A95B-41BE-B016-4674F6B4272E} = {A4865386-A95B-41BE-B016-4674F6B4272E}
 		{07B0C186-5173-46F2-BE26-7E4148BD0CCA} = {07B0C186-5173-46F2-BE26-7E4148BD0CCA}
 		{7F449698-73DF-4203-9F31-0877DBF01695} = {7F449698-73DF-4203-9F31-0877DBF01695}
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521} = {41CC18CE-139E-45A5-A9AA-336CBA2E1521}
 		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1} = {BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}
 		{796B6DFF-BA04-42B7-A43A-2B14D707A33A} = {796B6DFF-BA04-42B7-A43A-2B14D707A33A}
 	EndProjectSection
@@ -90,7 +89,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExampleProject", "ExamplePr
 		{AB6C9284-D1CB-4AAD-BA4B-8A9E81AD1A73} = {AB6C9284-D1CB-4AAD-BA4B-8A9E81AD1A73}
 		{07B0C186-5173-46F2-BE26-7E4148BD0CCA} = {07B0C186-5173-46F2-BE26-7E4148BD0CCA}
 		{7F449698-73DF-4203-9F31-0877DBF01695} = {7F449698-73DF-4203-9F31-0877DBF01695}
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521} = {41CC18CE-139E-45A5-A9AA-336CBA2E1521}
 		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1} = {BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}
 		{796B6DFF-BA04-42B7-A43A-2B14D707A33A} = {796B6DFF-BA04-42B7-A43A-2B14D707A33A}
 	EndProjectSection
@@ -106,13 +104,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BansheeCore", "BansheeCore\
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BansheeUtility", "BansheeUtility\BansheeUtility.vcxproj", "{CC7F9445-71C9-4559-9976-FF0A64DCB582}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BansheeSceneManager", "BansheeSceneManager\BansheeSceneManager.vcxproj", "{41CC18CE-139E-45A5-A9AA-336CBA2E1521}"
-	ProjectSection(ProjectDependencies) = postProject
-		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
-		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
-		{07B0C186-5173-46F2-BE26-7E4148BD0CCA} = {07B0C186-5173-46F2-BE26-7E4148BD0CCA}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BansheeRenderer", "BansheeRenderer\BansheeRenderer.vcxproj", "{08975177-4A13-4EE7-BB21-3BB92FB3F3CC}"
 	ProjectSection(ProjectDependencies) = postProject
 		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
@@ -424,27 +415,6 @@ Global
 		{CC7F9445-71C9-4559-9976-FF0A64DCB582}.Release|Win32.Build.0 = Release|Win32
 		{CC7F9445-71C9-4559-9976-FF0A64DCB582}.Release|x64.ActiveCfg = Release|x64
 		{CC7F9445-71C9-4559-9976-FF0A64DCB582}.Release|x64.Build.0 = Release|x64
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Debug|Any CPU.ActiveCfg = Debug|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Debug|Mixed Platforms.Build.0 = Debug|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Debug|Win32.ActiveCfg = Debug|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Debug|Win32.Build.0 = Debug|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Debug|x64.ActiveCfg = Debug|x64
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Debug|x64.Build.0 = Debug|x64
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.DebugRelease|Any CPU.ActiveCfg = DebugRelease|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.DebugRelease|Mixed Platforms.ActiveCfg = DebugRelease|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.DebugRelease|Mixed Platforms.Build.0 = DebugRelease|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.DebugRelease|Win32.ActiveCfg = DebugRelease|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.DebugRelease|Win32.Build.0 = DebugRelease|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.DebugRelease|x64.ActiveCfg = DebugRelease|x64
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.DebugRelease|x64.Build.0 = DebugRelease|x64
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Release|Any CPU.ActiveCfg = Release|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Release|Mixed Platforms.ActiveCfg = Release|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Release|Mixed Platforms.Build.0 = Release|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Release|Win32.ActiveCfg = Release|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Release|Win32.Build.0 = Release|Win32
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Release|x64.ActiveCfg = Release|x64
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521}.Release|x64.Build.0 = Release|x64
 		{08975177-4A13-4EE7-BB21-3BB92FB3F3CC}.Debug|Any CPU.ActiveCfg = Debug|Win32
 		{08975177-4A13-4EE7-BB21-3BB92FB3F3CC}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
 		{08975177-4A13-4EE7-BB21-3BB92FB3F3CC}.Debug|Mixed Platforms.Build.0 = Debug|Win32
@@ -625,7 +595,6 @@ Global
 		{2DA6824A-4D3A-4B59-8AE9-85D3C14074A3} = {363078CE-900A-4B1B-A408-601025EA0A23}
 		{11D4409F-3BF0-4074-B809-B959FB45B1B1} = {7E093EC6-24C6-4832-9482-2D8C0551D3B6}
 		{4E02D5FE-5A98-49C1-93FD-DF841A9FA3DB} = {7E093EC6-24C6-4832-9482-2D8C0551D3B6}
-		{41CC18CE-139E-45A5-A9AA-336CBA2E1521} = {32E4E2B7-1B4D-4B06-AD87-57CEE00BC247}
 		{08975177-4A13-4EE7-BB21-3BB92FB3F3CC} = {32E4E2B7-1B4D-4B06-AD87-57CEE00BC247}
 		{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1} = {32E4E2B7-1B4D-4B06-AD87-57CEE00BC247}
 		{F58FF869-2EA6-4FFF-AB84-328C531BA9D9} = {32E4E2B7-1B4D-4B06-AD87-57CEE00BC247}

+ 5 - 0
BansheeEngine/Include/BsCamera.h

@@ -302,6 +302,11 @@ namespace BansheeEngine
 	protected:
 		friend class SceneObject;
 
+		/**
+		 * @copydoc	Component::onDestroyed
+		 */
+		void onDestroyed();
+
 	public:
 		/**
 		 * @copydoc	Component::update

+ 5 - 0
BansheeEngine/Include/BsRenderable.h

@@ -77,6 +77,11 @@ namespace BansheeEngine
 
 		Renderable(const HSceneObject& parent);
 
+		/**
+		 * @copydoc	Component::onDestroyed
+		 */
+		void onDestroyed();
+
 	public:
 		/**
 		 * @copydoc	Component::update

+ 58 - 7
BansheeEngine/Include/BsSceneManager.h

@@ -10,6 +10,8 @@ namespace BansheeEngine
 	 */
 	struct SceneCameraData
 	{
+		SceneCameraData() { }
+
 		SceneCameraData(const CameraHandlerPtr& camera, const HSceneObject& sceneObject)
 			:camera(camera), sceneObject(sceneObject)
 		{ }
@@ -23,6 +25,8 @@ namespace BansheeEngine
 	 */
 	struct SceneRenderableData
 	{
+		SceneRenderableData() { }
+
 		SceneRenderableData(const RenderableHandlerPtr& renderable, const HSceneObject& sceneObject)
 			:renderable(renderable), sceneObject(sceneObject)
 		{ }
@@ -38,18 +42,64 @@ namespace BansheeEngine
 	class BS_EXPORT SceneManager : public CoreSceneManager
 	{
 	public:
-		SceneManager() {}
+		struct InitOnStart
+		{
+		public:
+			InitOnStart()
+			{
+				SceneManagerFactory::setFactoryMethod(&startUp);
+			}
+
+			static void startUp()
+			{
+				CoreSceneManager::startUp<SceneManager>();
+			}
+		};
+
+		SceneManager() { }
 		virtual ~SceneManager() {}
 
 		/**
 		 * @brief	Returns all cameras in the scene.
+		 *
+		 * @note	Internal method.
 		 */
-		virtual const Vector<SceneCameraData>& getAllCameras() const = 0;
+		const Map<CameraHandler*, SceneCameraData>& getAllCameras() const { return mCameras; }
 
 		/**
 		 * @brief	Returns all renderables in the scene.
+		 *
+		 * @note	Internal method.
+		 */
+		const Map<RenderableHandler*, SceneRenderableData>& getAllRenderables() const { return mRenderables; }
+
+		/**
+		 * @brief	Notifies the scene manager that a new renderable was created.
+		 * 
+		 * @note	Internal method.
+		 */
+		void _registerRenderable(const SPtr<RenderableHandler>& renderable, const HSceneObject& so);
+
+		/**
+		 * @brief	Notifies the scene manager that a renderable was removed.
+		 *
+		 * @note	Internal method.
 		 */
-		virtual const Vector<SceneRenderableData>& getAllRenderables() const = 0;
+		void _unregisterRenderable(const SPtr<RenderableHandler>& renderable);
+
+		/**
+		 * @brief	Notifies the scene manager that a new camera was created.
+		 *
+		 * @note	Internal method.
+		 */
+		void _registerCamera(const SPtr<CameraHandler>& camera, const HSceneObject& so);
+
+		/**
+		 * @brief	Notifies the scene manager that a camera was removed.
+		 *
+		 * @note	Internal method.
+		 */
+		void _unregisterCamera(const SPtr<CameraHandler>& camera);
 
 		/**
 		 * @copydoc	CoreSceneManager::instance
@@ -61,10 +111,11 @@ namespace BansheeEngine
 		 */
 		static SceneManager* instancePtr();
 
-		/**
-		 * @brief	Triggered whenever a renderable is removed from a SceneObject.
-		 */
-		Event<void(const RenderableHandlerPtr&)> onRenderableRemoved;
+	private:
+		Map<CameraHandler*, SceneCameraData> mCameras;
+		Map<RenderableHandler*, SceneRenderableData> mRenderables;
+
+		volatile static InitOnStart DoInitOnStart;
 	};
 
 	/**

+ 2 - 1
BansheeEngine/Include/BsVirtualInput.h

@@ -100,7 +100,8 @@ namespace BansheeEngine
 
 		/**
 		 * @brief	Returns normalized value for the specified input axis. 
-		 *			Returned value will be in [-1.0, 1.0] range.
+		 *			Returned value will usually be in [-1.0, 1.0] range, but can be outside
+		 *			the range for devices with unbound axes (e.g. mouse).
 		 *
 		 * @param	axis		Virtual axis identifier.
 		 * @param	deviceIdx	Optional device index in case multiple input devices are available.

+ 0 - 1
BansheeEngine/Source/BsApplication.cpp

@@ -23,7 +23,6 @@ namespace BansheeEngine
 		desc.primaryWindowDesc = primaryWindowDesc;
 
 		desc.input = "BansheeOISInput";
-		desc.sceneManager = "BansheeSceneManager";
 		desc.importers.push_back("BansheeFreeImgImporter");
 		desc.importers.push_back("BansheeFBXImporter");
 		desc.importers.push_back("BansheeFontImporter");

+ 7 - 0
BansheeEngine/Source/BsCamera.cpp

@@ -12,6 +12,7 @@
 #include "BsRenderAPI.h"
 #include "BsSceneObject.h"
 #include "BsDebug.h"
+#include "BsSceneManager.h"
 
 namespace BansheeEngine 
 {
@@ -19,6 +20,7 @@ namespace BansheeEngine
 		: Component(parent), mLastUpdateHash(std::numeric_limits<UINT32>::max())
     {
 		mInternal = CameraHandler::create(target, left, top, width, height);
+		gSceneManager()._registerCamera(mInternal, parent);
 
 		setName("Camera");
     }
@@ -61,6 +63,11 @@ namespace BansheeEngine
 		updateView();
 	}
 
+	void Camera::onDestroyed()
+	{
+		gSceneManager()._unregisterCamera(mInternal);
+	}
+
 	RTTITypeBase* Camera::getRTTIStatic()
 	{
 		return CameraRTTI::instance();

+ 7 - 0
BansheeEngine/Source/BsRenderable.cpp

@@ -6,6 +6,7 @@
 #include "BsMaterial.h"
 #include "BsRenderQueue.h"
 #include "BsBounds.h"
+#include "BsSceneManager.h"
 
 namespace BansheeEngine
 {
@@ -15,6 +16,7 @@ namespace BansheeEngine
 		setName("Renderable");
 
 		mInternal = RenderableHandler::create();
+		gSceneManager()._registerRenderable(mInternal, parent);
 	}
 
 	Bounds Renderable::getBounds() const
@@ -45,6 +47,11 @@ namespace BansheeEngine
 		}
 	}
 
+	void Renderable::onDestroyed()
+	{
+		gSceneManager()._unregisterRenderable(mInternal);
+	}
+
 	RTTITypeBase* Renderable::getRTTIStatic()
 	{
 		return RenderableRTTI::instance();

+ 22 - 0
BansheeEngine/Source/BsSceneManager.cpp

@@ -2,6 +2,28 @@
 
 namespace BansheeEngine
 {
+	volatile SceneManager::InitOnStart SceneManager::DoInitOnStart;
+
+	void SceneManager::_registerRenderable(const SPtr<RenderableHandler>& renderable, const HSceneObject& so)
+	{
+		mRenderables[renderable.get()] = SceneRenderableData(renderable, so);
+	}
+
+	void SceneManager::_unregisterRenderable(const SPtr<RenderableHandler>& renderable)
+	{
+		mRenderables.erase(renderable.get());
+	}
+
+	void SceneManager::_registerCamera(const SPtr<CameraHandler>& camera, const HSceneObject& so)
+	{
+		mCameras[camera.get()] = SceneCameraData(camera, so);
+	}
+
+	void SceneManager::_unregisterCamera(const SPtr<CameraHandler>& camera)
+	{
+		mCameras.erase(camera.get());
+	}
+
 	SceneManager& SceneManager::instance()
 	{
 		return static_cast<SceneManager&>(CoreSceneManager::instance());

+ 0 - 35
BansheeOISInput/Include/BsInputHandlerOIS.h

@@ -129,40 +129,6 @@ namespace BansheeEngine
 		 */
 		float smoothMouse(float value, UINT32 idx);
 
-		/**
-		 * @brief	Default dots per inch reported by the mouse. 
-		 *
-		 * @note	This should be retrieved from the mouse driver but I am not aware of any decent 
-		 *			way of doing it. What this means is that if the user has a mouse with a different 
-		 *			DPI then he will need to adjust sensitivity.
-		 */
-		static const UINT32 MOUSE_DPI;
-
-		/**
-		 * @brief	How much does the user need to move the mouse in order to max out the mouse axis
-		 *			(either positive or negative), in inches.
-		 */
-		static const float MOUSE_MAX;
-
-		/**
-		 * @brief	Number of seconds the mouse needs to reach the MOUSE_MAX value in, in order to
-		 *			max out the axis.
-		 */
-		static const float MOUSE_MAX_TIME;
-
-		/**
-		 * @brief	Minimum number of milliseconds that need to pass before mouse axes are updated again.
-		 *			
-		 * @note	At extremely high frame rates sampling the mouse too often will introduce jitter. This is because
-		 *			mouse will be sampled by the application faster than the hardware reports the samples. This means some
-		 *			of the samples will be reported as 0, while in truth mouse could be moving but it just hasn't been sampled.
-		 *			So we cannot tell if mouse is actually still, or moving but sample hasn't been updated, and must assume mouse
-		 *			is still, which causes jitter as one frame reports mouse as moving and another as still.
-		 *
-		 *			We could get around this if we knew the exact hardware sampling rate, but we don't.
-		 */
-		static const float MOUSE_MAX_SAMPLING_RATE;
-
 		OIS::InputManager* mInputManager;
 		OIS::Mouse*	mMouse;
 		OIS::Keyboard* mKeyboard;
@@ -174,7 +140,6 @@ namespace BansheeEngine
 		INT32 mMouseSampleAccumulator[2];
 		float mMouseSmoothedAxis[2];
 		UINT32 mLastMouseUpdateFrame;
-		float mMouseSampleCounter;
 
 		UINT64 mTimestampClockOffset;
 	};

+ 8 - 22
BansheeOISInput/Source/BsInputHandlerOIS.cpp

@@ -8,11 +8,6 @@
 
 namespace BansheeEngine
 {
-	const UINT32 InputHandlerOIS::MOUSE_DPI = 800;
-	const float InputHandlerOIS::MOUSE_MAX = 0.05f;
-	const float InputHandlerOIS::MOUSE_MAX_TIME = 0.020f; // 20 ms
-	const float InputHandlerOIS::MOUSE_MAX_SAMPLING_RATE = 0.006f; // 6ms
-
 	GamepadEventListener::GamepadEventListener(InputHandlerOIS* parentHandler, UINT32 joystickIdx)
 		:mParentHandler(parentHandler), mGamepadIdx(joystickIdx)
 	{ }
@@ -54,7 +49,7 @@ namespace BansheeEngine
 
 	InputHandlerOIS::InputHandlerOIS(unsigned int hWnd)
 		:mInputManager(nullptr), mKeyboard(nullptr), mMouse(nullptr), mTimestampClockOffset(0),
-		mLastMouseUpdateFrame(0), mMouseSampleCounter(0.0f)
+		mLastMouseUpdateFrame(0)
 	{
 		mMouseSampleAccumulator[0] = 0;
 		mMouseSampleAccumulator[1] = 0;
@@ -194,12 +189,6 @@ namespace BansheeEngine
 			gamepadData.gamepad->capture();
 		}
 
-		// Limit mouse sampling to a certain rate to avoid jitter at extremely high frame rates.
-		// (As the application might request samples faster than they are produced)
-		mMouseSampleCounter += gTime().getFrameDelta();
-		if (mMouseSampleCounter < MOUSE_MAX_SAMPLING_RATE)
-			return;
-
 		float rawXValue = 0.0f;
 		float rawYValue = 0.0f;
 
@@ -215,28 +204,25 @@ namespace BansheeEngine
 			rawYValue = (float)mMouseSampleAccumulator[1];
 		}
 
-		mMouseSampleAccumulator[0] = 0;
-		mMouseSampleAccumulator[1] = 0;
+		rawXValue *= 0.1f;
+		rawYValue *= 0.1f;
 
-		// Scale by time so that we are framerate independant: rawXValue = rawXValue * (MOUSE_MAX_TIME / gTime().getFrameDelta());
-		// Scale to valid [-1.0, 1.0] range: rawXValue / (MOUSE_DPI * MOUSE_MAX)
-		// This is just the combination of the two:
+		LOGWRN(toString(rawXValue) + " - " + toString(rawYValue));
 
-		float axisScale = ((MOUSE_DPI * MOUSE_MAX) / MOUSE_MAX_TIME) * mMouseSampleCounter;
+		mMouseSampleAccumulator[0] = 0;
+		mMouseSampleAccumulator[1] = 0;
 
 		RawAxisState xState;
-		xState.rel = -Math::clamp(rawXValue / axisScale, -1.0f, 1.0f);
+		xState.rel = -rawXValue;
 		xState.abs = xState.rel; // Abs value irrelevant for mouse
 
 		onAxisMoved(0, xState, (UINT32)InputAxis::MouseX);
 
 		RawAxisState yState;
-		yState.rel = -Math::clamp(rawYValue / axisScale, -1.0f, 1.0f);
+		yState.rel = -rawYValue;
 		yState.abs = yState.rel; // Abs value irrelevant for mouse
 		
 		onAxisMoved(0, yState, (UINT32)InputAxis::MouseY);
-
-		mMouseSampleCounter = 0.0f;
 	}
 
 	void InputHandlerOIS::_inputWindowChanged(const RenderWindow& win)

+ 3 - 3
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -161,11 +161,11 @@ namespace BansheeEngine
 	void BansheeRenderer::renderAll() 
 	{
 		// Populate direct draw lists
-		const Vector<SceneCameraData>& allCameras = gSceneManager().getAllCameras();
+		const Map<CameraHandler*, SceneCameraData>& allCameras = gSceneManager().getAllCameras();
 		for (auto& cameraData : allCameras)
 		{
-			CameraHandlerPtr camera = cameraData.camera;
-			HSceneObject cameraSO = cameraData.sceneObject;
+			CameraHandlerPtr camera = cameraData.second.camera;
+			HSceneObject cameraSO = cameraData.second.sceneObject;
 
 			DrawListPtr drawList = bs_shared_ptr<DrawList>();
 

+ 0 - 247
BansheeSceneManager/BansheeSceneManager.vcxproj

@@ -1,247 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="DebugRelease|Win32">
-      <Configuration>DebugRelease</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="DebugRelease|x64">
-      <Configuration>DebugRelease</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{41CC18CE-139E-45A5-A9AA-336CBA2E1521}</ProjectGuid>
-    <RootNamespace>CamelotOctreeSM</RootNamespace>
-    <ProjectName>BansheeSceneManager</ProjectName>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <OutDir>..\bin\x86\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
-    <OutDir>..\bin\$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <OutDir>..\bin\x86\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'">
-    <OutDir>..\bin\x86\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <OutDir>..\bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'">
-    <OutDir>..\bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>../BansheeUtility/Include;../BansheeCore/Include;../BansheeEngine/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_WINDLL;BS_SM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>..\lib\x86\$(Configuration);..\Dependencies\lib\x86\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>../BansheeUtility/Include;../BansheeCore/Include;../BansheeEngine/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_WINDLL;BS_SM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>..\lib\$(Platform)\$(Configuration);..\Dependencies\lib\x64\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
-      <ShowProgress>NotSet</ShowProgress>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../BansheeUtility/Include;../BansheeCore/Include;../BansheeEngine/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_WINDLL;BS_SM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>..\lib\x86\$(Configuration);..\Dependencies\lib\x86\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../BansheeUtility/Include;../BansheeCore/Include;../BansheeEngine/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_WINDLL;BS_SM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <MinimalRebuild>true</MinimalRebuild>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>..\lib\x86\$(Configuration);..\Dependencies\lib\x86\DebugRelease;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../BansheeUtility/Include;../BansheeCore/Include;../BansheeEngine/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_WINDLL;BS_SM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>..\lib\$(Platform)\$(Configuration);..\Dependencies\lib\x64\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../BansheeUtility/Include;../BansheeCore/Include;../BansheeEngine/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_WINDLL;BS_SM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <MinimalRebuild>true</MinimalRebuild>
-      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>..\lib\$(Platform)\$(Configuration);..\Dependencies\lib\x64\DebugRelease;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClInclude Include="Include\BsBansheeSceneManager.h" />
-    <ClInclude Include="Include\BsBansheeSMPrerequisites.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="Source\BsBansheeSceneManager.cpp" />
-    <ClCompile Include="Source\BsBansheeManagerPlugin.cpp" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>

+ 0 - 33
BansheeSceneManager/BansheeSceneManager.vcxproj.filters

@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="Include\BsBansheeSceneManager.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsBansheeSMPrerequisites.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="Source\BsBansheeSceneManager.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsBansheeManagerPlugin.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-</Project>

+ 0 - 19
BansheeSceneManager/Include/BsBansheeSMPrerequisites.h

@@ -1,19 +0,0 @@
-#pragma once
-
-#include "BsPrerequisites.h"
-
-#if (BS_PLATFORM == BS_PLATFORM_WIN32) && !defined(__MINGW32__)
-#	ifdef BS_SM_EXPORTS
-#		define BS_SM_EXPORT __declspec(dllexport)
-#	else
-#       if defined( __MINGW32__ )
-#           define BS_SM_EXPORT
-#       else
-#    		define BS_SM_EXPORT __declspec(dllimport)
-#       endif
-#	endif
-#elif defined ( BS_GCC_VISIBILITY )
-#    define BS_SM_EXPORT  __attribute__ ((visibility("default")))
-#else
-#    define BS_SM_EXPORT
-#endif

+ 0 - 44
BansheeSceneManager/Include/BsBansheeSceneManager.h

@@ -1,44 +0,0 @@
-#pragma once
-
-#include "BsBansheeSMPrerequisites.h"
-#include "BsSceneManager.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Default scene manager implementation. Allows you to query
-	 *			the scene graph for various uses.
-	 *
-	 * TODO - Update doc when I implement this properly
-	 */
-	class BS_SM_EXPORT BansheeSceneManager : public SceneManager
-	{
-	public:
-		BansheeSceneManager() {}
-		~BansheeSceneManager() {}
-
-		/**
-		 * @copydoc	SceneManager::getAllCameras
-		 */
-		const Vector<SceneCameraData>& getAllCameras() const { return mCachedCameras; }
-
-		/**
-		 * @copydoc	SceneManager::getAllRenderables
-		 */
-		const Vector<SceneRenderableData>& getAllRenderables() const { return mRenderables; }
-
-	private:
-		/**
-		 * @brief	Called by scene objects whenever a new component is added to the scene.
-		 */
-		void notifyComponentAdded(const HComponent& component);
-
-		/**
-		 * @brief	Called by scene objects whenever a new component is destroyed.
-		 */
-		void notifyComponentRemoved(const HComponent& component);
-
-		Vector<SceneCameraData> mCachedCameras;
-		Vector<SceneRenderableData> mRenderables;
-	};
-}

+ 0 - 40
BansheeSceneManager/Source/BsBansheeManagerPlugin.cpp

@@ -1,40 +0,0 @@
-#include "BsBansheeSMPrerequisites.h"
-#include "BsBansheeSceneManager.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Returns a name of the plugin.
-	 */
-	extern "C" BS_SM_EXPORT const String& getPluginName()
-	{
-		static String pluginName = "BansheeSceneManager";
-		return pluginName;
-	}
-
-	/**
-	 * @brief	Entry point to the plugin. Called by the engine when the plugin is loaded.
-	 */
-	extern "C" BS_SM_EXPORT void* loadPlugin()
-	{
-		SceneManager::startUp<BansheeSceneManager>();
-
-		return nullptr;
-	}
-
-	/**
-	 * @brief	Called by the engine when the plugin should be shut down and all of its resources should be released.
-	 */
-	extern "C" BS_SM_EXPORT void shutdownPlugin()
-	{
-		SceneManager::shutDown();
-	}
-
-	/**
-	 * @brief	Exit point of the plugin. Called by the engine just before the plugin is unloaded.
-	 */
-	extern "C" BS_SM_EXPORT void unloadPlugin()
-	{
-
-	}
-}

+ 0 - 68
BansheeSceneManager/Source/BsBansheeSceneManager.cpp

@@ -1,68 +0,0 @@
-#include "BsBansheeSceneManager.h"
-#include "BsComponent.h"
-#include "BsException.h"
-#include "BsSceneObject.h"
-#include "BsRenderable.h"
-#include "BsCamera.h"
-
-namespace BansheeEngine
-{
-	void BansheeSceneManager::notifyComponentAdded(const HComponent& component)
-	{
-		if(component->getTypeId() == TID_Camera)
-		{
-			HCamera camera = static_object_cast<Camera>(component);
-			CameraHandlerPtr cameraHandler = camera->_getHandler();
-
-			auto findIter = std::find_if(mCachedCameras.begin(), mCachedCameras.end(), 
-				[&](const SceneCameraData& x) { return x.camera == cameraHandler; });
-
-			if(findIter != mCachedCameras.end())
-			{
-				BS_EXCEPT(InternalErrorException, "Trying to add an already existing camera!");
-			}
-
-			mCachedCameras.push_back(SceneCameraData(cameraHandler, component->SO()));
-		}
-		else if(component->getTypeId() == TID_Renderable)
-		{
-			HRenderable renderable = static_object_cast<Renderable>(component);
-			RenderableHandlerPtr renderableHandler = renderable->_getHandler();
-
-			mRenderables.push_back(SceneRenderableData(renderableHandler, renderable->SO()));
-		}
-	}
-
-	void BansheeSceneManager::notifyComponentRemoved(const HComponent& component)
-	{
-		if(component->getTypeId() == TID_Camera)
-		{
-			HCamera camera = static_object_cast<Camera>(component);
-			CameraHandlerPtr cameraHandler = camera->_getHandler();
-
-			auto findIter = std::find_if(mCachedCameras.begin(), mCachedCameras.end(),
-				[&](const SceneCameraData& x) { return x.camera == cameraHandler; });
-
-			if(findIter == mCachedCameras.end())
-			{
-				BS_EXCEPT(InternalErrorException, "Cannot find specified camera!");
-			}
-
-			mCachedCameras.erase(findIter);
-		}
-		else if(component->getTypeId() == TID_Renderable)
-		{
-			HRenderable renderable = static_object_cast<Renderable>(component);
-			RenderableHandlerPtr renderableHandler = renderable->_getHandler();
-
-			// TODO - I should probably use some for of a hash set because searching through possibly thousands of renderables will be slow
-			auto findIter = std::find_if(mRenderables.begin(), mRenderables.end(),
-				[&](const SceneRenderableData& x) { return x.renderable == renderableHandler; });
-
-			if(findIter != mRenderables.end())
-				mRenderables.erase(findIter);
-
-			onRenderableRemoved(renderableHandler);
-		}
-	}
-}

+ 7 - 2
MBansheeEngine/Camera.cs

@@ -154,14 +154,19 @@ namespace BansheeEngine
         public Vector3 ProjectPoint(Vector3 value) { return handler.ProjectPoint(value); }
         public Vector3 UnprojectPoint(Vector3 value) { return handler.UnprojectPoint(value); }
 
-        public Camera()
+        private void OnInitialize()
         {
-            handler = new CameraHandler();
+            handler = new CameraHandler(sceneObject);
         }
 
         private void Update()
         {
             handler.UpdateView(sceneObject);
         }
+
+        private void OnDestroy()
+        {
+            handler.OnDestroy();
+        }
     }
 }

+ 15 - 3
MBansheeEngine/CameraHandler.cs

@@ -174,9 +174,13 @@ namespace BansheeEngine
 
         private RenderTarget _target;
 
-        public CameraHandler()
+        public CameraHandler(SceneObject sceneObject)
         {
-            Internal_Create(this);
+            IntPtr sceneObjPtr = IntPtr.Zero;
+            if (sceneObject != null)
+                sceneObjPtr = sceneObject.GetCachedPtr();
+
+            Internal_Create(this, sceneObjPtr);
         }
 
         internal void UpdateView(SceneObject sceneObject)
@@ -184,8 +188,13 @@ namespace BansheeEngine
             Internal_UpdateView(mCachedPtr, sceneObject.mCachedPtr);
         }
 
+        internal void OnDestroy()
+        {
+            Internal_OnDestroy(mCachedPtr);
+        }
+
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_Create(CameraHandler instance);
+        private static extern void Internal_Create(CameraHandler instance, IntPtr parentSO);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern float Internal_GetAspect(IntPtr instance);
@@ -310,5 +319,8 @@ namespace BansheeEngine
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_UpdateView(IntPtr instance, IntPtr parentSO);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_OnDestroy(IntPtr thisPtr);
     }
 }

+ 6 - 1
MBansheeEngine/Component.cs

@@ -7,13 +7,18 @@ namespace BansheeEngine
     {
         // Internal use only
         protected Component()
-        { }
+        {
+            Internal_CreateInstance(this);
+        }
 
         public SceneObject sceneObject
         {
             get { return Internal_GetSceneObject(mCachedPtr); }
         }
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        internal static extern SceneObject Internal_CreateInstance(Component instance);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal static extern Component Internal_AddComponent(SceneObject parent, Type type);
 

+ 9 - 1
SBansheeEngine/Include/BsManagedComponent.h

@@ -9,6 +9,8 @@ namespace BansheeEngine
 	class BS_SCR_BE_EXPORT ManagedComponent : public Component
 	{
 	public:
+		~ManagedComponent();
+
 		MonoObject* getManagedInstance() const { return mManagedInstance; }
 		MonoReflectionType* getRuntimeType() const { return mRuntimeType; }
 
@@ -17,7 +19,9 @@ namespace BansheeEngine
 		const String& getManagedFullTypeName() const { return mFullTypeName; }
 
 	private:
+		typedef void(__stdcall *OnInitializedThunkDef) (MonoObject*, MonoException**);
 		typedef void(__stdcall *UpdateThunkDef) (MonoObject*, MonoException**);
+		typedef void(__stdcall *OnDestroyedThunkDef) (MonoObject*, MonoException**);
 
 		MonoObject* mManagedInstance;
 		MonoReflectionType* mRuntimeType;
@@ -27,7 +31,9 @@ namespace BansheeEngine
 		String mTypeName;
 		String mFullTypeName;
 
+		OnInitializedThunkDef mOnInitializedThunk;
 		UpdateThunkDef mUpdateThunk;
+		OnDestroyedThunkDef mOnDestroyThunk;
 
 		/************************************************************************/
 		/* 							COMPONENT OVERRIDES                    		*/
@@ -35,12 +41,14 @@ namespace BansheeEngine
 
 	protected:
 		friend class SceneObject;
+		friend class ScriptComponent;
 
 		/** Standard constructor.
         */
 		ManagedComponent(const HSceneObject& parent, MonoReflectionType* runtimeType);
-		void construct(MonoObject* object, MonoReflectionType* runtimeType, MonoClass* monoClass);
+		void initialize(MonoObject* object, MonoReflectionType* runtimeType, MonoClass* monoClass);
 
+		void onInitialized();
 		void onDestroyed();
 
 	public:

+ 3 - 19
SBansheeEngine/Include/BsManagedComponentRTTI.h

@@ -8,6 +8,7 @@
 #include "BsManagedSerializableObject.h"
 #include "BsGameObjectManager.h"
 #include "BsScriptGameObjectManager.h"
+#include "BsScriptComponent.h"
 
 namespace BansheeEngine
 {
@@ -74,27 +75,10 @@ namespace BansheeEngine
 			MonoType* monoType = mono_class_get_type(monoClass);
 			MonoReflectionType* runtimeType = mono_type_get_object(MonoManager::instance().getDomain(), monoType);
 
-			// Find handle so we can create a script component
-			HManagedComponent componentHandle;
-			if (mc->mParent != nullptr)
-			{
-				const Vector<HComponent>& components = mc->mParent->getComponents();
-				for (auto& component : components)
-				{
-					if (component.get() == mc)
-					{
-						componentHandle = component;
-						break;
-					}
-				}
-			}
-
-			assert(componentHandle != nullptr); // It must exist as every component belongs to its parent SO
-
 			MonoClass* managedClass = MonoManager::instance().findClass(monoClass);
+			MonoObject* managedInstance = serializableObject->getManagedInstance();
 
-			mc->construct(serializableObject->getManagedInstance(), runtimeType, managedClass);
-			ScriptComponent* nativeInstance = ScriptGameObjectManager::instance().createScriptComponent(componentHandle);
+			mc->initialize(managedInstance, runtimeType, managedClass);
 		}
 
 		virtual const String& getRTTIName()

+ 3 - 2
SBansheeEngine/Include/BsScriptCameraHandler.h

@@ -21,12 +21,12 @@ namespace BansheeEngine
 		SPtr<CameraHandler> getInternal() const { return mCameraHandler; }
 
 	private:
-		ScriptCameraHandler(MonoObject* managedInstance);
+		ScriptCameraHandler(MonoObject* managedInstance, const HSceneObject& parentSO);
 		~ScriptCameraHandler();
 
 		void updateView(const HSceneObject& parent);
 
-		static void internal_Create(MonoObject* managedInstance);
+		static void internal_Create(MonoObject* managedInstance, ScriptSceneObject* parentSO);
 
 		static float internal_GetAspect(ScriptCameraHandler* instance);
 		static void internal_SetAspect(ScriptCameraHandler* instance, float value);
@@ -100,6 +100,7 @@ namespace BansheeEngine
 		static void internal_SetRenderTarget(ScriptCameraHandler* instance, ScriptRenderTarget* target);
 
 		static void internal_UpdateView(ScriptCameraHandler* instance, ScriptSceneObject* parent);
+		static void internal_OnDestroy(ScriptCameraHandler* instance);
 
 		SPtr<CameraHandler> mCameraHandler;
 		UINT32 mLastUpdateHash;

+ 4 - 1
SBansheeEngine/Include/BsScriptComponent.h

@@ -15,9 +15,12 @@ namespace BansheeEngine
 		virtual HGameObject getNativeHandle() const { return mManagedComponent; }
 		virtual void setNativeHandle(const HGameObject& gameObject);
 
+		void setManagedComponent(const GameObjectHandle<ManagedComponent>& managedComponent);
+
 	private:
 		friend class ScriptGameObjectManager;
 
+		static void internal_createInstance(MonoObject* instance);
 		static MonoObject* internal_addComponent(MonoObject* parentSceneObject, MonoReflectionType* type);
 		static MonoObject* internal_getComponent(MonoObject* parentSceneObject, MonoReflectionType* type);
 		static MonoArray* internal_getComponents(MonoObject* parentSceneObject);
@@ -26,7 +29,7 @@ namespace BansheeEngine
 
 		static bool checkIfDestroyed(const GameObjectHandleBase& handle);
 
-		ScriptComponent(MonoObject* instance, const GameObjectHandle<ManagedComponent>& managedComponent);
+		ScriptComponent(MonoObject* instance);
 		~ScriptComponent() {}
 
 		void _onManagedInstanceDeleted();

+ 1 - 1
SBansheeEngine/Include/BsScriptGameObjectManager.h

@@ -11,7 +11,7 @@ namespace BansheeEngine
 	public:
 		ScriptGameObjectManager();
 
-		ScriptComponent* createScriptComponent(const GameObjectHandle<ManagedComponent>& component);
+		void registerScriptComponent(ScriptComponent* nativeInstance, const GameObjectHandle<ManagedComponent>& component);
 		ScriptSceneObject* createScriptSceneObject(const HSceneObject& sceneObject);
 		ScriptSceneObject* createScriptSceneObject(MonoObject* existingInstance, const HSceneObject& sceneObject);
 

+ 68 - 7
SBansheeEngine/Source/BsManagedComponent.cpp

@@ -9,11 +9,12 @@
 namespace BansheeEngine
 {
 	ManagedComponent::ManagedComponent()
-		:mUpdateThunk(nullptr)
+		:mUpdateThunk(nullptr), mOnDestroyThunk(nullptr), mOnInitializedThunk(nullptr)
 	{ }
 
 	ManagedComponent::ManagedComponent(const HSceneObject& parent, MonoReflectionType* runtimeType)
-		:Component(parent), mManagedInstance(nullptr), mRuntimeType(runtimeType), mUpdateThunk(nullptr)
+		: Component(parent), mManagedInstance(nullptr), mRuntimeType(runtimeType), mUpdateThunk(nullptr), 
+		mOnDestroyThunk(nullptr), mOnInitializedThunk(nullptr)
 	{
 		MonoType* monoType = mono_reflection_type_get_type(mRuntimeType);
 		::MonoClass* monoClass = mono_type_get_class(monoType);
@@ -30,10 +31,19 @@ namespace BansheeEngine
 
 		setName(mTypeName);
 
-		construct(managedClass->createInstance(), runtimeType, managedClass);
+		initialize(managedClass->createInstance(), runtimeType, managedClass);
 	}
 
-	void ManagedComponent::construct(MonoObject* object, MonoReflectionType* runtimeType, MonoClass* monoClass)
+	ManagedComponent::~ManagedComponent()
+	{
+		if (mManagedInstance != nullptr)
+		{
+			mManagedInstance = nullptr;
+			mono_gchandle_free(mManagedHandle);
+		}
+	}
+
+	void ManagedComponent::initialize(MonoObject* object, MonoReflectionType* runtimeType, MonoClass* monoClass)
 	{
 		mFullTypeName = mNamespace + "." + mTypeName;
 
@@ -43,9 +53,17 @@ namespace BansheeEngine
 
 		if (monoClass != nullptr)
 		{
+			MonoMethod* onInitializedMethod = monoClass->getMethod("OnInitialize", 0);
+			if (onInitializedMethod != nullptr)
+				mOnInitializedThunk = (OnInitializedThunkDef)onInitializedMethod->getThunk();
+
 			MonoMethod* updateMethod = monoClass->getMethod("Update", 0);
 			if (updateMethod != nullptr)
 				mUpdateThunk = (UpdateThunkDef)updateMethod->getThunk();
+
+			MonoMethod* onDestroyMethod = monoClass->getMethod("OnDestroy", 0);
+			if (onDestroyMethod != nullptr)
+				mOnDestroyThunk = (OnDestroyedThunkDef)onDestroyMethod->getThunk();
 		}
 	}
 
@@ -63,12 +81,55 @@ namespace BansheeEngine
 		}
 	}
 
+	void ManagedComponent::onInitialized()
+	{
+		assert(mManagedInstance != nullptr);
+
+		ScriptComponent* nativeInstance = ScriptComponent::toNative(mManagedInstance);
+
+		// Find handle to self
+		HManagedComponent componentHandle;
+		if (mParent != nullptr)
+		{
+			const Vector<HComponent>& components = mParent->getComponents();
+			for (auto& component : components)
+			{
+				if (component.get() == this)
+				{
+					componentHandle = component;
+					break;
+				}
+			}
+		}
+
+		assert(componentHandle != nullptr);
+		ScriptGameObjectManager::instance().registerScriptComponent(nativeInstance, componentHandle);
+
+		if (mOnInitializedThunk != nullptr)
+		{
+			MonoException* exception = nullptr;
+
+			// Note: Not calling virtual methods. Can be easily done if needed but for now doing this
+			// for some extra speed.
+			mOnInitializedThunk(mManagedInstance, &exception);
+
+			MonoUtil::throwIfException(exception);
+		}
+	}
+
 	void ManagedComponent::onDestroyed()
 	{
-		if(mManagedInstance != nullptr)
+		assert(mManagedInstance != nullptr);
+
+		if (mOnDestroyThunk != nullptr)
 		{
-			mManagedInstance = nullptr;
-			mono_gchandle_free(mManagedHandle);
+			MonoException* exception = nullptr;
+
+			// Note: Not calling virtual methods. Can be easily done if needed but for now doing this
+			// for some extra speed.
+			mOnDestroyThunk(mManagedInstance, &exception);
+
+			MonoUtil::throwIfException(exception);
 		}
 	}
 

+ 2 - 3
SBansheeEngine/Source/BsManagedSerializableField.cpp

@@ -474,11 +474,10 @@ namespace BansheeEngine
 			}
 			else if(primitiveTypeInfo->mType == ScriptPrimitiveType::ComponentRef)
 			{
-				if(value)
+				if (value)
 				{
 					ScriptComponent* scriptComponent = ScriptGameObjectManager::instance().getScriptComponent(value);
-					if(scriptComponent == nullptr)
-						scriptComponent = ScriptGameObjectManager::instance().createScriptComponent(value);
+					assert(scriptComponent != nullptr);
 
 					return scriptComponent->getManagedInstance();
 				}

+ 6 - 20
SBansheeEngine/Source/BsRuntimeScriptObjects.cpp

@@ -91,10 +91,6 @@ namespace BansheeEngine
 		{
 			std::shared_ptr<ManagedSerializableObjectInfo> objInfo = curClassInfo.second;
 
-			String fullTypeName = objInfo->getFullTypeName();
-			assemblyInfo->mTypeNameToId[fullTypeName] = objInfo->mTypeId;
-			assemblyInfo->mObjectInfos[objInfo->mTypeId] = objInfo;
-
 			UINT32 mUniqueFieldId = 1;
 			const Vector<MonoField*>& fields = objInfo->mMonoClass->getAllFields();
 
@@ -277,27 +273,17 @@ namespace BansheeEngine
 			}
 			else
 			{
-				if(hasSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName()))
-				{
-					std::shared_ptr<ManagedSerializableTypeInfoObject> typeInfo = bs_shared_ptr<ManagedSerializableTypeInfoObject>();
-					typeInfo->mTypeNamespace = monoClass->getNamespace();
-					typeInfo->mTypeName = monoClass->getTypeName();
-					typeInfo->mValueType = false;
-
-					return typeInfo;
-				}
+				std::shared_ptr<ManagedSerializableObjectInfo> objInfo;
+				if (getSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName(), objInfo))
+					return objInfo->mTypeInfo;
 			}
 
 			break;
 		case MONO_TYPE_VALUETYPE:
-			if(hasSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName()))
 			{
-				std::shared_ptr<ManagedSerializableTypeInfoObject> typeInfo = bs_shared_ptr<ManagedSerializableTypeInfoObject>();
-				typeInfo->mTypeNamespace = monoClass->getNamespace();
-				typeInfo->mTypeName = monoClass->getTypeName();
-				typeInfo->mValueType = true;
-
-				return typeInfo;
+				std::shared_ptr<ManagedSerializableObjectInfo> objInfo;
+				if (getSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName(), objInfo))
+					return objInfo->mTypeInfo;
 			}
 
 			break;

+ 15 - 3
SBansheeEngine/Source/BsScriptCameraHandler.cpp

@@ -9,10 +9,11 @@
 #include "BsScriptSceneObject.h"
 #include "BsSceneObject.h"
 #include "BsScriptRenderTarget.h"
+#include "BsSceneManager.h"
 
 namespace BansheeEngine
 {
-	ScriptCameraHandler::ScriptCameraHandler(MonoObject* managedInstance)
+	ScriptCameraHandler::ScriptCameraHandler(MonoObject* managedInstance, const HSceneObject& parentSO)
 		:ScriptObject(managedInstance), mCameraHandler(nullptr), mLastUpdateHash(0)
 	{ 
 		ViewportPtr primaryViewport = gApplication().getPrimaryViewport();
@@ -22,6 +23,7 @@ namespace BansheeEngine
 			target = primaryViewport->getTarget();
 
 		mCameraHandler = CameraHandler::create(target);
+		gSceneManager()._registerCamera(mCameraHandler, parentSO);
 	}
 
 	ScriptCameraHandler::~ScriptCameraHandler()
@@ -105,6 +107,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetRenderTarget", &ScriptCameraHandler::internal_SetRenderTarget);
 
 		metaData.scriptClass->addInternalCall("Internal_UpdateView", &ScriptCameraHandler::internal_UpdateView);
+		metaData.scriptClass->addInternalCall("Internal_OnDestroy", &ScriptCameraHandler::internal_OnDestroy);
 	}
 
 	void ScriptCameraHandler::updateView(const HSceneObject& parent)
@@ -119,9 +122,13 @@ namespace BansheeEngine
 		}
 	}
 
-	void ScriptCameraHandler::internal_Create(MonoObject* managedInstance)
+	void ScriptCameraHandler::internal_Create(MonoObject* managedInstance, ScriptSceneObject* parentSO)
 	{
-		ScriptCameraHandler* nativeInstance = new (bs_alloc<ScriptCameraHandler>()) ScriptCameraHandler(managedInstance);
+		HSceneObject so;
+		if (parentSO != nullptr)
+			so = parentSO->getNativeHandle();
+
+		ScriptCameraHandler* nativeInstance = new (bs_alloc<ScriptCameraHandler>()) ScriptCameraHandler(managedInstance, so);
 	}
 
 	float ScriptCameraHandler::internal_GetAspect(ScriptCameraHandler* instance)
@@ -401,4 +408,9 @@ namespace BansheeEngine
 
 		instance->updateView(parentSO);
 	}
+
+	void ScriptCameraHandler::internal_OnDestroy(ScriptCameraHandler* instance)
+	{
+		gSceneManager()._unregisterCamera(instance->getInternal());
+	}
 }

+ 15 - 5
SBansheeEngine/Source/BsScriptComponent.cpp

@@ -12,12 +12,13 @@
 
 namespace BansheeEngine
 {
-	ScriptComponent::ScriptComponent(MonoObject* instance, const GameObjectHandle<ManagedComponent>& managedComponent)
-		:ScriptObject(instance), mManagedComponent(managedComponent)
+	ScriptComponent::ScriptComponent(MonoObject* instance)
+		:ScriptObject(instance)
 	{ }
 
 	void ScriptComponent::initRuntimeData()
 	{
+		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptComponent::internal_createInstance);
 		metaData.scriptClass->addInternalCall("Internal_AddComponent", &ScriptComponent::internal_addComponent);
 		metaData.scriptClass->addInternalCall("Internal_GetComponent", &ScriptComponent::internal_getComponent);
 		metaData.scriptClass->addInternalCall("Internal_GetComponents", &ScriptComponent::internal_getComponents);
@@ -25,6 +26,16 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetSceneObject", &ScriptComponent::internal_getSceneObject);
 	}
 
+	void ScriptComponent::setManagedComponent(const GameObjectHandle<ManagedComponent>& managedComponent)
+	{
+		mManagedComponent = managedComponent;
+	}
+
+	void ScriptComponent::internal_createInstance(MonoObject* instance)
+	{
+		ScriptComponent* nativeInstance = new (bs_alloc<ScriptComponent>()) ScriptComponent(instance);
+	}
+
 	MonoObject* ScriptComponent::internal_addComponent(MonoObject* parentSceneObject, MonoReflectionType* type)
 	{
 		ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(parentSceneObject);
@@ -50,9 +61,8 @@ namespace BansheeEngine
 		}
 
 		GameObjectHandle<ManagedComponent> mc = so->addComponent<ManagedComponent>(type);
-		ScriptComponent* nativeInstance = ScriptGameObjectManager::instance().createScriptComponent(mc);
-		
-		return nativeInstance->getManagedInstance();
+
+		return mc->getManagedInstance();
 	}
 
 	MonoObject* ScriptComponent::internal_getComponent(MonoObject* parentSceneObject, MonoReflectionType* type)

+ 2 - 4
SBansheeEngine/Source/BsScriptGameObjectManager.cpp

@@ -25,16 +25,14 @@ namespace BansheeEngine
 			BS_EXCEPT(InternalErrorException, "Cannot find managed SceneObject class.");
 	}
 
-	ScriptComponent* ScriptGameObjectManager::createScriptComponent(const GameObjectHandle<ManagedComponent>& component)
+	void ScriptGameObjectManager::registerScriptComponent(ScriptComponent* nativeInstance, const GameObjectHandle<ManagedComponent>& component)
 	{
 		auto findIter = mScriptGameObjects.find(component->getInstanceId());
 		if(findIter != mScriptGameObjects.end())
 			BS_EXCEPT(InvalidStateException, "Script component for this Component already exists.");
 
-		ScriptComponent* nativeInstance = new (bs_alloc<ScriptComponent>()) ScriptComponent(component->getManagedInstance(), component);
+		nativeInstance->setManagedComponent(component);
 		mScriptGameObjects[component->getInstanceId()] = nativeInstance;
-
-		return nativeInstance;
 	}
 
 	ScriptSceneObject* ScriptGameObjectManager::createScriptSceneObject(const HSceneObject& sceneObject)

+ 2 - 3
TODO.txt

@@ -13,12 +13,11 @@
 See GDrive/Resources doc for resources refactor
 
 Handle lines don't draw in front of geometry
+I think mouse delta isn't properly reset between mouse movement
+Gizmos don't start rendering until you click on screen
 
 I can get mono errors by checking g_print calls in goutput.c
 
-Screen grid isn't rendered
- - Managed camera isn't properly registered with scene manager so its render calls aren't registered
-Handles aren't properly rendered
 Icon gizmo seems to sometimes get struck to the side of the camera
 
 Other: