Procházet zdrojové kódy

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 před 11 roky
rodič
revize
d0c583e20c
43 změnil soubory, kde provedl 346 přidání a 653 odebrání
  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: