Browse Source

Refactored Renderable into RenderableHandler
Added RTTI for Camera and Viewport

Marko Pintera 11 years ago
parent
commit
ff8ed9021c
38 changed files with 833 additions and 406 deletions
  1. 1 0
      BansheeCore/BansheeCore.vcxproj
  2. 3 0
      BansheeCore/BansheeCore.vcxproj.filters
  3. 2 1
      BansheeCore/Include/BsCorePrerequisites.h
  4. 10 1
      BansheeCore/Include/BsViewport.h
  5. 62 0
      BansheeCore/Include/BsViewportRTTI.h
  6. 11 1
      BansheeCore/Source/BsViewport.cpp
  7. 7 6
      BansheeEditor/Source/BsScenePicking.cpp
  8. 4 1
      BansheeEngine/BansheeEngine.vcxproj
  9. 15 6
      BansheeEngine/BansheeEngine.vcxproj.filters
  10. 61 55
      BansheeEngine/Include/BsCamera.h
  11. 87 1
      BansheeEngine/Include/BsCameraHandlerRTTI.h
  12. 5 2
      BansheeEngine/Include/BsCameraRTTI.h
  13. 4 1
      BansheeEngine/Include/BsPrerequisites.h
  14. 34 78
      BansheeEngine/Include/BsRenderable.h
  15. 42 0
      BansheeEngine/Include/BsRenderableController.h
  16. 126 21
      BansheeEngine/Include/BsRenderableHandler.h
  17. 48 0
      BansheeEngine/Include/BsRenderableHandlerRTTI.h
  18. 1 1
      BansheeEngine/Include/BsRenderableProxy.h
  19. 3 13
      BansheeEngine/Include/BsRenderableRTTI.h
  20. 30 4
      BansheeEngine/Include/BsSceneManager.h
  21. 5 3
      BansheeEngine/Source/BsCamera.cpp
  22. 0 1
      BansheeEngine/Source/BsCameraHandler.cpp
  23. 8 154
      BansheeEngine/Source/BsRenderable.cpp
  24. 14 0
      BansheeEngine/Source/BsRenderableController.cpp
  25. 171 5
      BansheeEngine/Source/BsRenderableHandler.cpp
  26. 2 2
      BansheeRenderer/BansheeRenderer.vcxproj
  27. 2 2
      BansheeRenderer/BansheeRenderer.vcxproj.filters
  28. 3 3
      BansheeRenderer/Include/BsBansheeLitTexRenderableController.h
  29. 3 3
      BansheeRenderer/Include/BsBansheeRenderer.h
  30. 1 1
      BansheeRenderer/Include/BsBansheeRendererPrerequisites.h
  31. 7 7
      BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp
  32. 30 21
      BansheeRenderer/Source/BsBansheeRenderer.cpp
  33. 4 4
      BansheeSceneManager/Include/BsBansheeSceneManager.h
  34. 19 8
      BansheeSceneManager/Source/BsBansheeSceneManager.cpp
  35. 2 0
      BansheeUtility/Include/BsDegree.h
  36. 2 0
      BansheeUtility/Include/BsQuaternion.h
  37. 2 0
      BansheeUtility/Include/BsRadian.h
  38. 2 0
      BansheeUtility/Include/BsRect2.h

+ 1 - 0
BansheeCore/BansheeCore.vcxproj

@@ -413,6 +413,7 @@
     <ClInclude Include="Include\BsBlendState.h" />
     <ClInclude Include="Include\BsVertexDeclarationRTTI.h" />
     <ClInclude Include="Include\BsTechnique.h" />
+    <ClInclude Include="Include\BsViewportRTTI.h" />
     <ClInclude Include="Include\Win32\BsPlatformImpl.h" />
     <ClInclude Include="Include\Win32\BsWin32Defs.h" />
     <ClInclude Include="Include\Win32\BsPlatformWndProc.h" />

+ 3 - 0
BansheeCore/BansheeCore.vcxproj.filters

@@ -531,6 +531,9 @@
     <ClInclude Include="Include\BsRenderTargetManager.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsViewportRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsCoreApplication.cpp">

+ 2 - 1
BansheeCore/Include/BsCorePrerequisites.h

@@ -305,7 +305,8 @@ namespace BansheeEngine
 		TID_EmulatedParamBlock = 1069,
 		TID_TextureImportOptions = 1070,
 		TID_ResourceMetaData = 1071,
-		TID_GpuProgramInclude = 1072
+		TID_GpuProgramInclude = 1072,
+		TID_Viewport = 1073
 	};
 }
 

+ 10 - 1
BansheeCore/Include/BsViewport.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "BsCorePrerequisites.h"
+#include "BsIReflectable.h"
 #include "BsColor.h"
 #include "BsRect2I.h"
 #include "BsRect2.h"
@@ -15,7 +16,7 @@ namespace BansheeEngine
 	 *
 	 * @note	Thread safe unless noted otherwise.
 	 */
-	class BS_CORE_EXPORT Viewport
+	class BS_CORE_EXPORT Viewport : public IReflectable
     {
     public:       
 		Viewport();
@@ -185,5 +186,13 @@ namespace BansheeEngine
 		UINT32 mCoreDirtyFlags; /**< True when internal data has changed and core thread wasn't yet informed. */
 
 		static const Color DEFAULT_CLEAR_COLOR;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class ViewportRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
     };
 }

+ 62 - 0
BansheeCore/Include/BsViewportRTTI.h

@@ -0,0 +1,62 @@
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsViewport.h"
+
+namespace BansheeEngine
+{
+	class BS_CORE_EXPORT ViewportRTTI : public RTTIType<Viewport, IReflectable, ViewportRTTI>
+	{
+	private:
+		Rect2& getNormArea(Viewport* obj) { return obj->mNormArea; }
+		void setNormArea(Viewport* obj, Rect2& val) { obj->mNormArea = val; }
+
+		bool& getRequireColorClear(Viewport* obj) { return obj->mRequiresColorClear; }
+		void setRequireColorClear(Viewport* obj, bool& val) { obj->mRequiresColorClear = val; }
+
+		bool& getRequireDepthClear(Viewport* obj) { return obj->mRequiresDepthClear; }
+		void setRequireDepthClear(Viewport* obj, bool& val) { obj->mRequiresDepthClear = val; }
+
+		bool& getRequireStencilClear(Viewport* obj) { return obj->mRequiresStencilClear; }
+		void setRequireStencilClear(Viewport* obj, bool& val) { obj->mRequiresStencilClear = val; }
+
+		Color& getClearColor(Viewport* obj) { return obj->mClearColor; }
+		void setClearColor(Viewport* obj, Color& val) { obj->mClearColor = val; }
+
+		float& getDepthClearValue(Viewport* obj) { return obj->mDepthClearValue; }
+		void setDepthClearValue(Viewport* obj, float& val) { obj->mDepthClearValue = val; }
+
+		UINT16& getStencilClearValue(Viewport* obj) { return obj->mStencilClearValue; }
+		void setStencilClearValue(Viewport* obj, UINT16& val) { obj->mStencilClearValue = val; }
+
+		// TODO - Not saving a render target reference. Need to re-think the design on how to reference those. Likely as a handle to resource.
+	public:
+		ViewportRTTI()
+		{
+			addPlainField("mNormArea", 0, &ViewportRTTI::getNormArea, &ViewportRTTI::setNormArea);
+			addPlainField("mRequiresColorClear", 1, &ViewportRTTI::getRequireColorClear, &ViewportRTTI::setRequireColorClear);
+			addPlainField("mRequiresDepthClear", 2, &ViewportRTTI::getRequireDepthClear, &ViewportRTTI::setRequireDepthClear);
+			addPlainField("mRequiresStencilClear", 3, &ViewportRTTI::getRequireStencilClear, &ViewportRTTI::setRequireStencilClear);
+			addPlainField("mClearColor", 4, &ViewportRTTI::getClearColor, &ViewportRTTI::setClearColor);
+			addPlainField("mDepthClearValue", 5, &ViewportRTTI::getDepthClearValue, &ViewportRTTI::setDepthClearValue);
+			addPlainField("mStencilClearValue", 6, &ViewportRTTI::getStencilClearValue, &ViewportRTTI::setStencilClearValue);
+		}
+
+		virtual const String& getRTTIName()
+		{
+			static String name = "Viewport";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId()
+		{
+			return TID_Viewport;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		{
+			return bs_shared_ptr<Viewport>();
+		}
+	};
+}

+ 11 - 1
BansheeCore/Source/BsViewport.cpp

@@ -1,5 +1,5 @@
 #include "BsViewport.h"
-
+#include "BsViewportRTTI.h"
 #include "BsException.h"
 #include "BsRenderTarget.h"
 #include "BsMath.h"
@@ -93,4 +93,14 @@ namespace BansheeEngine
 	{
 		return *this;
 	}
+
+	RTTITypeBase* Viewport::getRTTIStatic()
+	{
+		return ViewportRTTI::instance();
+	}
+
+	RTTITypeBase* Viewport::getRTTI() const
+	{
+		return Viewport::getRTTIStatic();
+	}
 }

+ 7 - 6
BansheeEditor/Source/BsScenePicking.cpp

@@ -106,13 +106,14 @@ namespace BansheeEngine
 
 		Matrix4 viewProjMatrix = cam->getProjectionMatrixRS() * cam->getViewMatrix();
 
-		const Vector<HRenderable>& renderables = SceneManager::instance().getAllRenderables();
+		const Vector<SceneRenderableData>& renderables = SceneManager::instance().getAllRenderables();
 		RenderableSet pickData(comparePickElement);
-		Map<UINT32, HRenderable> idxToRenderable;
+		Map<UINT32, HSceneObject> idxToRenderable;
 
-		for (auto& renderable : renderables)
+		for (auto& renderableData : renderables)
 		{
-			HSceneObject so = renderable->SO();
+			RenderableHandlerPtr renderable = renderableData.renderable;
+			HSceneObject so = renderableData.sceneObject;
 
 			if (!so->getActive())
 				continue;
@@ -177,7 +178,7 @@ namespace BansheeEngine
 							}
 						}
 
-						idxToRenderable[idx] = renderable;
+						idxToRenderable[idx] = so;
 
 						Matrix4 wvpTransform = viewProjMatrix * worldTransform;
 						pickData.insert({ meshProxy, idx, wvpTransform, useAlphaShader, cullMode, mainTexture });
@@ -208,7 +209,7 @@ namespace BansheeEngine
 				auto iterFind = idxToRenderable.find(selectedObjectIdx);
 
 				if (iterFind != idxToRenderable.end())
-					results.push_back(iterFind->second->SO());
+					results.push_back(iterFind->second);
 			}
 			else
 			{

+ 4 - 1
BansheeEngine/BansheeEngine.vcxproj

@@ -231,6 +231,7 @@
     <ClCompile Include="Source\BsDrawHelper.cpp" />
     <ClCompile Include="Source\BsGUILayoutUtility.cpp" />
     <ClCompile Include="Source\BsInputConfiguration.cpp" />
+    <ClCompile Include="Source\BsRenderableController.cpp" />
     <ClCompile Include="Source\BsRenderableHandler.cpp" />
     <ClCompile Include="Source\BsRenderableProxy.cpp" />
     <ClCompile Include="Source\BsRenderQueue.cpp" />
@@ -240,6 +241,8 @@
     <ClInclude Include="Include\BsCameraHandlerRTTI.h" />
     <ClInclude Include="Include\BsCursor.h" />
     <ClInclude Include="Include\BsDrawHelper.h" />
+    <ClInclude Include="Include\BsRenderableHandler.h" />
+    <ClInclude Include="Include\BsRenderableHandlerRTTI.h" />
     <ClInclude Include="Include\BsShapeMeshes3D.h" />
     <ClInclude Include="Include\BsDragAndDropManager.h" />
     <ClInclude Include="Include\BsShapeMeshes2D.h" />
@@ -296,7 +299,7 @@
     <ClInclude Include="Include\BsImageSprite.h" />
     <ClInclude Include="Include\BsProfilerOverlay.h" />
     <ClInclude Include="Include\BsRectOffset.h" />
-    <ClInclude Include="Include\BsRenderableHandler.h" />
+    <ClInclude Include="Include\BsRenderableController.h" />
     <ClInclude Include="Include\BsRenderableProxy.h" />
     <ClInclude Include="Include\BsRenderQueue.h" />
     <ClInclude Include="Include\BsSceneManager.h" />

+ 15 - 6
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -255,9 +255,6 @@
     <ClInclude Include="Include\BsRenderQueue.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsRenderableHandler.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsGUILayoutUtility.h">
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
@@ -279,6 +276,15 @@
     <ClInclude Include="Include\BsCameraHandlerRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsRenderableController.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderableHandler.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderableHandlerRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -461,9 +467,6 @@
     <ClCompile Include="Source\BsRenderQueue.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsRenderableHandler.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsGUILayoutUtility.cpp">
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
@@ -479,5 +482,11 @@
     <ClCompile Include="Source\BsCameraHandler.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsRenderableController.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRenderableHandler.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 61 - 55
BansheeEngine/Include/BsCamera.h

@@ -21,114 +21,114 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	CameraHandler::getViewport
 		 */
-		ViewportPtr getViewport() const { return mInternal.getViewport(); }
+		ViewportPtr getViewport() const { return mInternal->getViewport(); }
 
 		/**
 		 * @copydoc	CameraHandler::setHorzFOV
 		 */
-		virtual void setHorzFOV(const Radian& fovy) { mInternal.setHorzFOV(fovy); }
+		virtual void setHorzFOV(const Radian& fovy) { mInternal->setHorzFOV(fovy); }
 
 		/**
 		 * @copydoc	CameraHandler::getHorzFOV
 		 */
-		virtual const Radian& getHorzFOV() const { return mInternal.getHorzFOV(); }
+		virtual const Radian& getHorzFOV() const { return mInternal->getHorzFOV(); }
 
 		/**
 		 * @copydoc	CameraHandler::setNearClipDistance
 		 */
-		virtual void setNearClipDistance(float nearDist) { mInternal.setNearClipDistance(nearDist); }
+		virtual void setNearClipDistance(float nearDist) { mInternal->setNearClipDistance(nearDist); }
 
 		/**
 		 * @copydoc	CameraHandler::getNearClipDistance
 		 */
-		virtual float getNearClipDistance() const { return mInternal.getNearClipDistance(); }
+		virtual float getNearClipDistance() const { return mInternal->getNearClipDistance(); }
 
 		/**
 		 * @copydoc	CameraHandler::setFarClipDistance
 		 */
-		virtual void setFarClipDistance(float farDist) { mInternal.setFarClipDistance(farDist); }
+		virtual void setFarClipDistance(float farDist) { mInternal->setFarClipDistance(farDist); }
 
 		/**
 		 * @copydoc	CameraHandler::getFarClipDistance
 		 */
-		virtual float getFarClipDistance() const { return mInternal.getFarClipDistance(); }
+		virtual float getFarClipDistance() const { return mInternal->getFarClipDistance(); }
 
 		/**
 		 * @copydoc	CameraHandler::setAspectRatio
 		 */
-		virtual void setAspectRatio(float ratio) { mInternal.setAspectRatio(ratio); }
+		virtual void setAspectRatio(float ratio) { mInternal->setAspectRatio(ratio); }
 
 		/**
 		 * @copydoc	CameraHandler::getAspectRatio
 		 */
-		virtual float getAspectRatio() const { return mInternal.getAspectRatio(); }
+		virtual float getAspectRatio() const { return mInternal->getAspectRatio(); }
 
 		/**
 		 * @copydoc	CameraHandler::setFrustumExtents
 		 */
 		virtual void setFrustumExtents(float left, float right, float top, float bottom)
 		{
-			mInternal.setFrustumExtents(left, right, top, bottom);
+			mInternal->setFrustumExtents(left, right, top, bottom);
 		}
 
 		/**
 		 * @copydoc	CameraHandler::resetFrustumExtents
 		 */
-		virtual void resetFrustumExtents() { mInternal.resetFrustumExtents(); }
+		virtual void resetFrustumExtents() { mInternal->resetFrustumExtents(); }
 
 		/**
 		 * @copydoc	CameraHandler::getFrustumExtents
 		 */
 		virtual void getFrustumExtents(float& outleft, float& outright, float& outtop, float& outbottom) const
 		{
-			mInternal.getFrustumExtents(outleft, outright, outtop, outbottom);
+			mInternal->getFrustumExtents(outleft, outright, outtop, outbottom);
 		}
 
 		/**
 		 * @copydoc	CameraHandler::getProjectionMatrixRS
 		 */
-		virtual const Matrix4& getProjectionMatrixRS() const { return mInternal.getProjectionMatrixRS(); }
+		virtual const Matrix4& getProjectionMatrixRS() const { return mInternal->getProjectionMatrixRS(); }
 
 		/**
 		 * @copydoc	CameraHandler::getProjectionMatrix
 		 */
-		virtual const Matrix4& getProjectionMatrix() const { return mInternal.getProjectionMatrix(); }
+		virtual const Matrix4& getProjectionMatrix() const { return mInternal->getProjectionMatrix(); }
 
 		/**
 		 * @copydoc	CameraHandler::getViewMatrix
 		 */
-		virtual const Matrix4& getViewMatrix() const { updateView(); return mInternal.getViewMatrix(); }
+		virtual const Matrix4& getViewMatrix() const { updateView(); return mInternal->getViewMatrix(); }
 
 		/**
 		 * @copydoc	CameraHandler::setCustomViewMatrix
 		 */
 		virtual void setCustomViewMatrix(bool enable, const Matrix4& viewMatrix = Matrix4::IDENTITY)
 		{
-			mInternal.setCustomViewMatrix(enable, viewMatrix);
+			mInternal->setCustomViewMatrix(enable, viewMatrix);
 		}
 
 		/**
 		 * @copydoc	CameraHandler::isCustomViewMatrixEnabled
 		 */
-		virtual bool isCustomViewMatrixEnabled() const { return mInternal.isCustomViewMatrixEnabled(); }
+		virtual bool isCustomViewMatrixEnabled() const { return mInternal->isCustomViewMatrixEnabled(); }
 		
 		/**
 		 * @copydoc	CameraHandler::setCustomProjectionMatrix
 		 */
 		virtual void setCustomProjectionMatrix(bool enable, const Matrix4& projectionMatrix = Matrix4::IDENTITY)
 		{
-			mInternal.setCustomProjectionMatrix(enable, projectionMatrix);
+			mInternal->setCustomProjectionMatrix(enable, projectionMatrix);
 		}
 
 		/**
 		 * @copydoc	CameraHandler::isCustomProjectionMatrixEnabled
 		 */
-		virtual bool isCustomProjectionMatrixEnabled() const { return mInternal.isCustomProjectionMatrixEnabled(); }
+		virtual bool isCustomProjectionMatrixEnabled() const { return mInternal->isCustomProjectionMatrixEnabled(); }
 
 		/**
 		 * @copydoc	CameraHandler::getFrustum
 		 */
-		virtual const ConvexVolume& getFrustum() const { return mInternal.getFrustum(); }
+		virtual const ConvexVolume& getFrustum() const { return mInternal->getFrustum(); }
 
 		/**
 		 * @copydoc	CameraHandler::getWorldFrustum
@@ -138,147 +138,153 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	CameraHandler::getBoundingBox
 		 */
-		const AABox& getBoundingBox() const { return mInternal.getBoundingBox(); }
+		const AABox& getBoundingBox() const { return mInternal->getBoundingBox(); }
 
 		/**
 		 * @copydoc	CameraHandler::setProjectionType
 		 */
-		virtual void setProjectionType(ProjectionType pt) { mInternal.setProjectionType(pt); }
+		virtual void setProjectionType(ProjectionType pt) { mInternal->setProjectionType(pt); }
 
 		/**
 		 * @copydoc	CameraHandler::getProjectionType
 		 */
-		virtual ProjectionType getProjectionType() const { return mInternal.getProjectionType(); }
+		virtual ProjectionType getProjectionType() const { return mInternal->getProjectionType(); }
 
 		/**
 		 * @copydoc	CameraHandler::setOrthoWindow
 		 */
-		virtual void setOrthoWindow(float w, float h) { mInternal.setOrthoWindow(w, h); }
+		virtual void setOrthoWindow(float w, float h) { mInternal->setOrthoWindow(w, h); }
 
 		/**
 		 * @copydoc	CameraHandler::setOrthoWindowHeight
 		 */
-		virtual void setOrthoWindowHeight(float h) { mInternal.setOrthoWindowHeight(h); }
+		virtual void setOrthoWindowHeight(float h) { mInternal->setOrthoWindowHeight(h); }
 
 		/**
 		 * @copydoc	CameraHandler::setOrthoWindowWidth
 		 */
-		virtual void setOrthoWindowWidth(float w) { mInternal.setOrthoWindowWidth(w); }
+		virtual void setOrthoWindowWidth(float w) { mInternal->setOrthoWindowWidth(w); }
 
 		/**
 		 * @copydoc	CameraHandler::getOrthoWindowHeight
 		 */
-		virtual float getOrthoWindowHeight() const { return mInternal.getOrthoWindowHeight(); }
+		virtual float getOrthoWindowHeight() const { return mInternal->getOrthoWindowHeight(); }
 
 		/**
 		 * @copydoc	CameraHandler::getOrthoWindowWidth
 		 */
-		virtual float getOrthoWindowWidth() const { return mInternal.getOrthoWindowWidth(); }
+		virtual float getOrthoWindowWidth() const { return mInternal->getOrthoWindowWidth(); }
 
 		/**
 		 * @copydoc	CameraHandler::setIgnoreSceneRenderables
 		 */
-		void setIgnoreSceneRenderables(bool value) { mInternal.setIgnoreSceneRenderables(value); }
+		void setIgnoreSceneRenderables(bool value) { mInternal->setIgnoreSceneRenderables(value); }
 
 		/**
 		 * @copydoc	CameraHandler::getIgnoreSceneRenderables
 		 */
-		bool getIgnoreSceneRenderables() const { return mInternal.getIgnoreSceneRenderables(); }
+		bool getIgnoreSceneRenderables() const { return mInternal->getIgnoreSceneRenderables(); }
 
 		/**
 		 * @copydoc	CameraHandler::getPriority
 		 */
-		INT32 getPriority() const { return mInternal.getPriority(); }
+		INT32 getPriority() const { return mInternal->getPriority(); }
 
 		/**
 		 * @copydoc	CameraHandler::setPriority
 		 */
-		void setPriority(INT32 priority) { mInternal.setPriority(priority); }
+		void setPriority(INT32 priority) { mInternal->setPriority(priority); }
 
 		/**
 		 * @copydoc	CameraHandler::getLayers
 		 */
-		UINT64 getLayers() const { return mInternal.getLayers(); }
+		UINT64 getLayers() const { return mInternal->getLayers(); }
 
 		/**
 		 * @copydoc	CameraHandler::setLayers
 		 */
-		void setLayers(UINT64 layers) { mInternal.setLayers(layers); }
+		void setLayers(UINT64 layers) { mInternal->setLayers(layers); }
 
 		/**
 		 * @copydoc	CameraHandler::worldToScreenPoint
 		 */
-		Vector2I worldToScreenPoint(const Vector3& worldPoint) const { updateView(); return mInternal.worldToScreenPoint(worldPoint); }
+		Vector2I worldToScreenPoint(const Vector3& worldPoint) const { updateView(); return mInternal->worldToScreenPoint(worldPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::worldToClipPoint
 		 */
-		Vector2 worldToClipPoint(const Vector3& worldPoint) const { updateView(); return mInternal.worldToClipPoint(worldPoint); }
+		Vector2 worldToClipPoint(const Vector3& worldPoint) const { updateView(); return mInternal->worldToClipPoint(worldPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::worldToViewPoint
 		 */
-		Vector3 worldToViewPoint(const Vector3& worldPoint) const { updateView(); return mInternal.worldToViewPoint(worldPoint); }
+		Vector3 worldToViewPoint(const Vector3& worldPoint) const { updateView(); return mInternal->worldToViewPoint(worldPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::screenToWorldPoint
 		 */
-		Vector3 screenToWorldPoint(const Vector2I& screenPoint) const { updateView(); return mInternal.screenToWorldPoint(screenPoint); }
+		Vector3 screenToWorldPoint(const Vector2I& screenPoint) const { updateView(); return mInternal->screenToWorldPoint(screenPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::screenToViewPoint
 		 */
-		Vector3 screenToViewPoint(const Vector2I& screenPoint) const { return mInternal.screenToViewPoint(screenPoint); }
+		Vector3 screenToViewPoint(const Vector2I& screenPoint) const { return mInternal->screenToViewPoint(screenPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::screenToClipPoint
 		 */
-		Vector2 screenToClipPoint(const Vector2I& screenPoint) const { return mInternal.screenToClipPoint(screenPoint); }
+		Vector2 screenToClipPoint(const Vector2I& screenPoint) const { return mInternal->screenToClipPoint(screenPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::viewToWorldPoint
 		 */
-		Vector3 viewToWorldPoint(const Vector3& viewPoint) const { updateView(); return mInternal.viewToWorldPoint(viewPoint); }
+		Vector3 viewToWorldPoint(const Vector3& viewPoint) const { updateView(); return mInternal->viewToWorldPoint(viewPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::viewToScreenPoint
 		 */
-		Vector2I viewToScreenPoint(const Vector3& viewPoint) const { return mInternal.viewToScreenPoint(viewPoint); }
+		Vector2I viewToScreenPoint(const Vector3& viewPoint) const { return mInternal->viewToScreenPoint(viewPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::viewToClipPoint
 		 */
-		Vector2 viewToClipPoint(const Vector3& viewPoint) const { return mInternal.viewToClipPoint(viewPoint); }
+		Vector2 viewToClipPoint(const Vector3& viewPoint) const { return mInternal->viewToClipPoint(viewPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::clipToWorldPoint
 		 */
-		Vector3 clipToWorldPoint(const Vector2& clipPoint) const { updateView(); return mInternal.clipToWorldPoint(clipPoint); }
+		Vector3 clipToWorldPoint(const Vector2& clipPoint) const { updateView(); return mInternal->clipToWorldPoint(clipPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::clipToViewPoint
 		 */
-		Vector3 clipToViewPoint(const Vector2& clipPoint) const { return mInternal.clipToViewPoint(clipPoint); }
+		Vector3 clipToViewPoint(const Vector2& clipPoint) const { return mInternal->clipToViewPoint(clipPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::clipToScreenPoint
 		 */
-		Vector2I clipToScreenPoint(const Vector2& clipPoint) const { return mInternal.clipToScreenPoint(clipPoint); }
+		Vector2I clipToScreenPoint(const Vector2& clipPoint) const { return mInternal->clipToScreenPoint(clipPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::screenPointToRay
 		 */
-		Ray screenPointToRay(const Vector2I& screenPoint) const { updateView(); return mInternal.screenPointToRay(screenPoint); }
+		Ray screenPointToRay(const Vector2I& screenPoint) const { updateView(); return mInternal->screenPointToRay(screenPoint); }
 
 		/**
 		 * @copydoc	CameraHandler::projectPoint
 		 */
-		Vector3 projectPoint(const Vector3& point) const { return mInternal.projectPoint(point); }
+		Vector3 projectPoint(const Vector3& point) const { return mInternal->projectPoint(point); }
 
 		/**
 		 * @copydoc	CameraHandler::unprojectPoint
 		 */
-		Vector3 unprojectPoint(const Vector3& point) const { return mInternal.unprojectPoint(point); }
+		Vector3 unprojectPoint(const Vector3& point) const { return mInternal->unprojectPoint(point); }
+
+		/**
+		 * @brief	Returns the internal camera handler that is used for
+		 *			majority of operations by this component.
+		 */
+		CameraHandlerPtr _getHandler() const { return mInternal; }
 
 		/************************************************************************/
 		/* 								CORE PROXY                      		*/
@@ -287,27 +293,27 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	CameraHandler::_isCoreDirty
 		 */
-		bool _isCoreDirty() const { return mInternal._isCoreDirty(); }
+		bool _isCoreDirty() const { return mInternal->_isCoreDirty(); }
 
 		/**
 		 * @copydoc	CameraHandler::_markCoreClean
 		 */
-		void _markCoreClean() { mInternal._markCoreClean(); }
+		void _markCoreClean() { mInternal->_markCoreClean(); }
 
 		/**
 		 * @copydoc	CameraHandler::_createProxy
 		 */
-		CameraProxyPtr _createProxy() const { updateView(); return mInternal._createProxy(); }
+		CameraProxyPtr _createProxy() const { updateView(); return mInternal->_createProxy(); }
 
 		/**
 		 * @copydoc	CameraHandler::_getActiveProxy
 		 */
-		CameraProxyPtr _getActiveProxy() const { return mInternal._getActiveProxy(); }
+		CameraProxyPtr _getActiveProxy() const { return mInternal->_getActiveProxy(); }
 
 		/**
 		 * @copydoc	CameraHandler::_setActiveProxy
 		 */
-		void _setActiveProxy(const CameraProxyPtr& proxy) { mInternal._setActiveProxy(proxy); }
+		void _setActiveProxy(const CameraProxyPtr& proxy) { mInternal->_setActiveProxy(proxy); }
 
     protected:
 		/**
@@ -316,7 +322,7 @@ namespace BansheeEngine
 		 */
 		void updateView() const;
 
-		mutable CameraHandler mInternal;
+		mutable CameraHandlerPtr mInternal;
 		mutable UINT32 mLastUpdateHash;
 
 		/************************************************************************/

+ 87 - 1
BansheeEngine/Include/BsCameraHandlerRTTI.h

@@ -9,11 +9,97 @@ namespace BansheeEngine
 	class BS_EXPORT CameraHandlerRTTI : public RTTIType <CameraHandler, IReflectable, CameraHandlerRTTI>
 	{
 	private:
+		ViewportPtr getViewport(CameraHandler* obj) { return obj->mViewport; }
+		void setViewport(CameraHandler* obj, ViewportPtr val) { obj->mViewport = val; }
+
+		UINT64& getLayers(CameraHandler* obj) { return obj->mLayers; }
+		void setLayers(CameraHandler* obj, UINT64& val) { obj->mLayers = val; }
+
+		Vector3& getPosition(CameraHandler* obj) { return obj->mPosition; }
+		void setPosition(CameraHandler* obj, Vector3& val) { obj->mPosition = val; }
+
+		Quaternion& getRotation(CameraHandler* obj) { return obj->mRotation; }
+		void setRotation(CameraHandler* obj, Quaternion& val) { obj->mRotation = val; }
+
+		ProjectionType& getProjType(CameraHandler* obj) { return obj->mProjType; }
+		void setProjType(CameraHandler* obj, ProjectionType& val) { obj->mProjType = val; }
+
+		Radian& getHorzFOV(CameraHandler* obj) { return obj->mHorzFOV; }
+		void setHorzFOV(CameraHandler* obj, Radian& val) { obj->mHorzFOV = val; }
+
+		float& getFarDist(CameraHandler* obj) { return obj->mFarDist; }
+		void setFarDist(CameraHandler* obj, float& val) { obj->mFarDist = val; }
+
+		float& getNearDist(CameraHandler* obj) { return obj->mNearDist; }
+		void setNearDist(CameraHandler* obj, float& val) { obj->mNearDist = val; }
+
+		float& getAspect(CameraHandler* obj) { return obj->mAspect; }
+		void setAspect(CameraHandler* obj, float& val) { obj->mAspect = val; }
+
+		float& getOrthoHeight(CameraHandler* obj) { return obj->mOrthoHeight; }
+		void setOrthoHeight(CameraHandler* obj, float& val) { obj->mOrthoHeight = val; }
+
+		INT32& getPriority(CameraHandler* obj) { return obj->mPriority; }
+		void setPriority(CameraHandler* obj, INT32& val) { obj->mPriority = val; }
+
+		bool& getCustomViewMatrix(CameraHandler* obj) { return obj->mCustomViewMatrix; }
+		void setCustomViewMatrix(CameraHandler* obj, bool& val) { obj->mCustomViewMatrix = val; }
+
+		bool& getCustomProjMatrix(CameraHandler* obj) { return obj->mCustomProjMatrix; }
+		void setCustomProjMatrix(CameraHandler* obj, bool& val) { obj->mCustomProjMatrix = val; }
+
+		bool& getFrustumManual(CameraHandler* obj) { return obj->mFrustumExtentsManuallySet; }
+		void setFrustumManual(CameraHandler* obj, bool& val) { obj->mFrustumExtentsManuallySet = val; }
+
+		bool& getIgnoreSceneRenderables(CameraHandler* obj) { return obj->mIgnoreSceneRenderables; }
+		void setIgnoreSceneRenderables(CameraHandler* obj, bool& val) { obj->mIgnoreSceneRenderables = val; }
+
+		Matrix4& getProjMatrix(CameraHandler* obj) { return obj->mProjMatrix; }
+		void setProjMatrix(CameraHandler* obj, Matrix4& val) { obj->mProjMatrix = val; }
+
+		Matrix4& getProjMatrixRS(CameraHandler* obj) { return obj->mProjMatrixRS; }
+		void setProjMatrixRS(CameraHandler* obj, Matrix4& val) { obj->mProjMatrixRS = val; }
+
+		Matrix4& getViewMatrix(CameraHandler* obj) { return obj->mViewMatrix; }
+		void setViewMatrix(CameraHandler* obj, Matrix4& val) { obj->mViewMatrix = val; }
+
+		float& getLeft(CameraHandler* obj) { return obj->mLeft; }
+		void setLeft(CameraHandler* obj, float& val) { obj->mLeft = val; }
+
+		float& getRight(CameraHandler* obj) { return obj->mRight; }
+		void setRight(CameraHandler* obj, float& val) { obj->mRight = val; }
+
+		float& getTop(CameraHandler* obj) { return obj->mTop; }
+		void setTop(CameraHandler* obj, float& val) { obj->mTop = val; }
+
+		float& getBottom(CameraHandler* obj) { return obj->mBottom; }
+		void setBottom(CameraHandler* obj, float& val) { obj->mBottom = val; }
 
 	public:
 		CameraHandlerRTTI()
 		{
-
+			addReflectablePtrField("mViewport", 0, &CameraHandlerRTTI::getViewport, &CameraHandlerRTTI::setViewport);
+			addPlainField("mLayers", 1, &CameraHandlerRTTI::getLayers, &CameraHandlerRTTI::setLayers);
+			addPlainField("mPosition", 2, &CameraHandlerRTTI::getPosition, &CameraHandlerRTTI::setPosition);
+			addPlainField("mRotation", 3, &CameraHandlerRTTI::getRotation, &CameraHandlerRTTI::setRotation);
+			addPlainField("mProjType", 4, &CameraHandlerRTTI::getProjType, &CameraHandlerRTTI::setProjType);
+			addPlainField("mHorzFOV", 5, &CameraHandlerRTTI::getHorzFOV, &CameraHandlerRTTI::setHorzFOV);
+			addPlainField("mFarDist", 6, &CameraHandlerRTTI::getFarDist, &CameraHandlerRTTI::setFarDist);
+			addPlainField("mNearDist", 7, &CameraHandlerRTTI::getNearDist, &CameraHandlerRTTI::setNearDist);
+			addPlainField("mAspect", 8, &CameraHandlerRTTI::getAspect, &CameraHandlerRTTI::setAspect);
+			addPlainField("mOrthoHeight", 9, &CameraHandlerRTTI::getOrthoHeight, &CameraHandlerRTTI::setOrthoHeight);
+			addPlainField("mPriority", 10, &CameraHandlerRTTI::getPriority, &CameraHandlerRTTI::setPriority);
+			addPlainField("mCustomViewMatrix", 11, &CameraHandlerRTTI::getCustomViewMatrix, &CameraHandlerRTTI::setCustomViewMatrix);
+			addPlainField("mCustomProjMatrix", 12, &CameraHandlerRTTI::getCustomProjMatrix, &CameraHandlerRTTI::setCustomProjMatrix);
+			addPlainField("mFrustumExtentsManuallySet", 13, &CameraHandlerRTTI::getFrustumManual, &CameraHandlerRTTI::setFrustumManual);
+			addPlainField("mIgnoreSceneRenderables", 14, &CameraHandlerRTTI::getIgnoreSceneRenderables, &CameraHandlerRTTI::setIgnoreSceneRenderables);
+			addPlainField("mProjMatrixRS", 15, &CameraHandlerRTTI::getProjMatrixRS, &CameraHandlerRTTI::setProjMatrixRS);
+			addPlainField("mProjMatrix", 16, &CameraHandlerRTTI::getProjMatrix, &CameraHandlerRTTI::setProjMatrix);
+			addPlainField("mViewMatrix", 17, &CameraHandlerRTTI::getViewMatrix, &CameraHandlerRTTI::setViewMatrix);
+			addPlainField("mLeft", 18, &CameraHandlerRTTI::getLeft, &CameraHandlerRTTI::setLeft);
+			addPlainField("mRight", 19, &CameraHandlerRTTI::getRight, &CameraHandlerRTTI::setRight);
+			addPlainField("mTop", 20, &CameraHandlerRTTI::getTop, &CameraHandlerRTTI::setTop);
+			addPlainField("mBottom", 21, &CameraHandlerRTTI::getBottom, &CameraHandlerRTTI::setBottom);
 		}
 
 		virtual const String& getRTTIName()

+ 5 - 2
BansheeEngine/Include/BsCameraRTTI.h

@@ -3,17 +3,20 @@
 #include "BsPrerequisites.h"
 #include "BsRTTIType.h"
 #include "BsCamera.h"
+#include "BsGameObjectRTTI.h"
 
 namespace BansheeEngine
 {
 	class BS_EXPORT CameraRTTI : public RTTIType<Camera, Component, CameraRTTI>
 	{
 	private:
+		CameraHandlerPtr getInternal(Camera* obj) { return obj->mInternal; }
+		void setInternal(Camera* obj, CameraHandlerPtr val) { obj->mInternal = val; }
 
 	public:
 		CameraRTTI()
 		{
-
+			addReflectablePtrField("mInternal", 0, &CameraRTTI::getInternal, &CameraRTTI::setInternal);
 		}
 
 		virtual const String& getRTTIName()
@@ -29,7 +32,7 @@ namespace BansheeEngine
 
 		virtual std::shared_ptr<IReflectable> newRTTIObject()
 		{
-			return bs_shared_ptr<Camera, PoolAlloc>(new (bs_alloc<Camera, PoolAlloc>()) Camera());
+			return GameObjectRTTI::createGameObject<Camera>();
 		}
 	};
 }

+ 4 - 1
BansheeEngine/Include/BsPrerequisites.h

@@ -77,10 +77,11 @@ namespace BansheeEngine
 	class GUIDropDownHitBox;
 
 	class RenderableProxy;
-	class RenderableHandler;
+	class RenderableController;
 	class ProfilerOverlay;
 	class DrawHelper;
 	class CameraHandler;
+	class RenderableHandler;
 
 	// 2D
 	class TextSprite;
@@ -101,6 +102,7 @@ namespace BansheeEngine
 	typedef std::shared_ptr<GUIToggleGroup> GUIToggleGroupPtr;
 	typedef std::shared_ptr<RenderableProxy> RenderableProxyPtr;
 	typedef std::shared_ptr<CameraHandler> CameraHandlerPtr;
+	typedef std::shared_ptr<RenderableHandler> RenderableHandlerPtr;
 
 	typedef GameObjectHandle<GUIWidget> HGUIWidget;
 	typedef GameObjectHandle<Camera> HCamera;
@@ -118,5 +120,6 @@ namespace BansheeEngine
 		TID_Renderable = 30001,
 		TID_SpriteTexture = 30002,
 		TID_CameraHandler = 30003,
+		TID_RenderableHandler = 30004
 	};
 }

+ 34 - 78
BansheeEngine/Include/BsRenderable.h

@@ -1,143 +1,99 @@
 #pragma once
 
 #include "BsPrerequisites.h"
+#include "BsRenderableHandler.h"
 #include "BsComponent.h"
-#include "BsRenderableProxy.h"
-#include "BsAABox.h"
-#include "BsGpuParam.h"
 
 namespace BansheeEngine
 {
 	/**
-	 * @brief	Renderable represents any visible object in the scene. It has a mesh,
-	 *			bounds and a set of materials. Renderer will render any Renderable objects
-	 *			visible by the camera.
+	 * @copydoc	RenderableHandler
 	 */
 	class BS_EXPORT Renderable : public Component
 	{
-		struct MeshData
-		{
-			MeshData() {}
-			MeshData(const HMesh& mesh);
-
-			HMesh mesh;
-			mutable bool isLoaded;
-		};
-
-		struct MaterialData
-		{
-			MaterialData() {}
-			MaterialData(const HMaterial& material);
-
-			HMaterial material;
-			mutable bool isLoaded;
-		};
-
 	public:
 		/**
-		 * @brief	Sets the mesh to render. All sub-meshes of the mesh will be rendered,
-		 *			and you may set individual materials for each sub-mesh.
+		 * @copydoc	RenderableHandler::setMesh
 		 */
-		void setMesh(HMesh mesh);
+		void setMesh(HMesh mesh) { mInternal->setMesh(mesh); }
 
 		/**
-		 * @brief	Sets a material that will be used for rendering a sub-mesh with
-		 *			the specified index. If a sub-mesh doesn't have a specific material set
-		 *			then the primary material will be used.
+		 * @copydoc	RenderableHandler::setMaterial
 		 */
-		void setMaterial(UINT32 idx, HMaterial material);
+		void setMaterial(UINT32 idx, HMaterial material) { mInternal->setMaterial(idx, material); }
 
 		/**
-		 * @brief	Sets the primary material to use for rendering. Any sub-mesh that 
-		 *			doesn't have an explicit material set will use this material.
-		 *
-		 * @note	This is equivalent to calling setMaterial(0, material).
+		 * @copydoc	RenderableHandler::setMaterial
 		 */
-		void setMaterial(HMaterial material);
+		void setMaterial(HMaterial material) { mInternal->setMaterial(material); }
 
 		/**
-		 * @brief	Sets the layer bitfield. Renderable layer must match camera layer
-		 *			in order for the camera to render the component.
+		 * @copydoc	RenderableHandler::setLayer
 		 */
-		void setLayer(UINT64 layer);
+		void setLayer(UINT64 layer) { mInternal->setLayer(layer); }
 
 		/**
-		 * @brief	Gets the layer bitfield. Renderable layer must match camera layer
-		 *			in order for the camera to render the component.
+		 * @copydoc	RenderableHandler::getLayer
 		 */
-		UINT64 getLayer() const { return mLayer; }
+		UINT64 getLayer() const { return mInternal->getLayer(); }
 
 		/**
-		 * @brief	Returns the mesh used for rendering.
+		 * @copydoc	RenderableHandler::getMesh
 		 */
-		HMesh getMesh() const { return mMeshData.mesh; }
+		HMesh getMesh() const { return mInternal->getMesh(); }
 
 		/**
-		 * @brief	Returns the material used for rendering a sub-mesh with
-		 *			the specified index.
+		 * @copydoc	RenderableHandler::getMaterial
 		 */
-		HMaterial getMaterial(UINT32 idx) const;
+		HMaterial getMaterial(UINT32 idx) const { return mInternal->getMaterial(idx); }
 
 		/**
 		 * @brief	Gets world bounds of the mesh rendered by this object.
 		 */
 		Bounds getBounds() const;
 
+		/**
+		 * @brief	Returns the internal renderable handler that is used for
+		 *			majority of operations by this component.
+		 */
+		RenderableHandlerPtr _getHandler() const { return mInternal; }
+
 		/************************************************************************/
 		/* 								CORE PROXY                      		*/
 		/************************************************************************/
 
 		/**
-		 * @brief	Checks is the core dirty flag set. This is used by external systems 
-		 *			to know when internal data has changed and core thread potentially needs to be notified.
+		 * @copydoc	RenderableHandler::_isCoreDirty
 		 */
-		bool _isCoreDirty() const;
+		bool _isCoreDirty() const { return mInternal->_isCoreDirty(); }
 
 		/**
-		 * @brief	Marks the core dirty flag as clean.
+		 * @copydoc	RenderableHandler::_markCoreClean
 		 */
-		void _markCoreClean();
+		void _markCoreClean() { mInternal->_markCoreClean(); }
 
 		/**
-		 * @brief	Marks the core data as dirty.
+		 * @copydoc	RenderableHandler::_markCoreDirty
 		 */
-		void _markCoreDirty() const { mCoreDirtyFlags = 0xFFFFFFFF; }
+		void _markCoreDirty() const { mInternal->_markCoreDirty(); }
 
 		/**
-		 * @brief	Creates a new core proxy from the currently set Renderable data. Core proxies ensure
-		 *			that the core thread has all the necessary Renderable data, while avoiding the need
-		 *			to manage Renderable itself on the core thread.
-		 *
-		 * @note	You generally need to update the core thread with a new proxy whenever core 
-		 *			dirty flag is set.
+		 * @copydoc	RenderableHandler::_createProxy
 		 */
 		RenderableProxyPtr _createProxy() const;
 
 		/**
-		 * @brief	Returns the currently active proxy object, if any.
-		 */
-		RenderableProxyPtr _getActiveProxy() const { return mActiveProxy; }
-
-		/**
-		 * @brief	Changes the currently active proxy object. 
+		 * @copydoc	RenderableHandler::_getActiveProxy
 		 */
-		void _setActiveProxy(const RenderableProxyPtr& proxy) { mActiveProxy = proxy; }
+		RenderableProxyPtr _getActiveProxy() const { return mInternal->_getActiveProxy();; }
 
-	private:
 		/**
-		 * @brief	Checks if any resources were loaded since last time. Marks the core data as dirty
-		 *			if they have (does nothing if all resources are already loaded).
+		 * @copydoc	RenderableHandler::_setActiveProxy
 		 */
-		void updateResourceLoadStates() const;
+		void _setActiveProxy(const RenderableProxyPtr& proxy) { mInternal->_setActiveProxy(proxy); }
 
 	private:
-		MeshData mMeshData;
-		Vector<MaterialData> mMaterialData;
-		UINT64 mLayer;
-		Vector<AABox> mWorldBounds;
-
-		RenderableProxyPtr mActiveProxy;
-		mutable UINT32 mCoreDirtyFlags;
+		RenderableHandlerPtr mInternal;
 
 		/************************************************************************/
 		/* 							COMPONENT OVERRIDES                    		*/

+ 42 - 0
BansheeEngine/Include/BsRenderableController.h

@@ -0,0 +1,42 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * Abstract class that provides an interface for initializing
+	 * renderable elements of a certain type, along with their GPU
+	 * parameter buffers.
+	 *
+	 * Essentially this class holds all the information that is needed for rendering
+	 * an element of a certain renderable type.
+	 *
+	 * @note	e.g. elements that have shadows would have a RenderableLitShadowHandler
+	 *			and elements that can be animated would have RenderableAnimatedHandler,
+	 *			or a combination of the two.	
+	 */
+	class BS_EXPORT RenderableController
+	{
+	public:
+		virtual ~RenderableController() {}
+
+		/**
+		 * @brief	Initializes the specified renderable element, making it ready
+		 *			to be used. Caller must ensure the renderable element actually
+		 *			supports this handler.
+		 */
+		virtual void initializeRenderElem(RenderableElement* element) = 0;
+
+		/**
+		 * @brief	Binds per object GPU parameter buffers to the provided element.
+		 */
+		virtual void bindPerObjectBuffers(const RenderableElement* element) = 0;
+
+		/**
+		 * @brief	Binds global GPU parameter buffers used for this Renderable 
+		 *			type to the provided element.
+		 */
+		virtual void bindGlobalBuffers(const RenderableElement* element);
+	};
+}

+ 126 - 21
BansheeEngine/Include/BsRenderableHandler.h

@@ -1,42 +1,147 @@
 #pragma once
 
 #include "BsPrerequisites.h"
+#include "BsIReflectable.h"
+#include "BsRenderableProxy.h"
+#include "BsAABox.h"
+#include "BsGpuParam.h"
 
 namespace BansheeEngine
 {
 	/**
-	 * Abstract class that provides an interface for initializing
-	 * renderable elements of a certain type, along with their GPU
-	 * parameter buffers.
-	 *
-	 * Essentially this class holds all the information that is needed for rendering
-	 * an element of a certain renderable type.
-	 *
-	 * @note	e.g. elements that have shadows would have a RenderableLitShadowHandler
-	 *			and elements that can be animated would have RenderableAnimatedHandler,
-	 *			or a combination of the two.	
+	 * @brief	Renderable represents any visible object in the scene. It has a mesh,
+	 *			bounds and a set of materials. Renderer will render any Renderable objects
+	 *			visible by the camera.
 	 */
-	class BS_EXPORT RenderableHandler
+	class BS_EXPORT RenderableHandler : public IReflectable
 	{
+		struct MeshData
+		{
+			MeshData() {}
+			MeshData(const HMesh& mesh);
+
+			HMesh mesh;
+			mutable bool isLoaded;
+		};
+
+		struct MaterialData
+		{
+			MaterialData() {}
+			MaterialData(const HMaterial& material);
+
+			HMaterial material;
+			mutable bool isLoaded;
+		};
+
 	public:
-		virtual ~RenderableHandler() {}
+		RenderableHandler();
+
+		/**
+		 * @brief	Sets the mesh to render. All sub-meshes of the mesh will be rendered,
+		 *			and you may set individual materials for each sub-mesh.
+		 */
+		void setMesh(HMesh mesh);
+
+		/**
+		 * @brief	Sets a material that will be used for rendering a sub-mesh with
+		 *			the specified index. If a sub-mesh doesn't have a specific material set
+		 *			then the primary material will be used.
+		 */
+		void setMaterial(UINT32 idx, HMaterial material);
+
+		/**
+		 * @brief	Sets the primary material to use for rendering. Any sub-mesh that 
+		 *			doesn't have an explicit material set will use this material.
+		 *
+		 * @note	This is equivalent to calling setMaterial(0, material).
+		 */
+		void setMaterial(HMaterial material);
+
+		/**
+		 * @brief	Sets the layer bitfield. Renderable layer must match camera layer
+		 *			in order for the camera to render the component.
+		 */
+		void setLayer(UINT64 layer);
+
+		/**
+		 * @brief	Gets the layer bitfield. Renderable layer must match camera layer
+		 *			in order for the camera to render the component.
+		 */
+		UINT64 getLayer() const { return mLayer; }
+
+		/**
+		 * @brief	Returns the mesh used for rendering.
+		 */
+		HMesh getMesh() const { return mMeshData.mesh; }
+
+		/**
+		 * @brief	Returns the material used for rendering a sub-mesh with
+		 *			the specified index.
+		 */
+		HMaterial getMaterial(UINT32 idx) const;
+
+		/************************************************************************/
+		/* 								CORE PROXY                      		*/
+		/************************************************************************/
+
+		/**
+		 * @brief	Checks is the core dirty flag set. This is used by external systems 
+		 *			to know when internal data has changed and core thread potentially needs to be notified.
+		 */
+		bool _isCoreDirty() const;
+
+		/**
+		 * @brief	Marks the core dirty flag as clean.
+		 */
+		void _markCoreClean();
 
 		/**
-		 * @brief	Initializes the specified renderable element, making it ready
-		 *			to be used. Caller must ensure the renderable element actually
-		 *			supports this handler.
+		 * @brief	Marks the core data as dirty.
 		 */
-		virtual void initializeRenderElem(RenderableElement* element) = 0;
+		void _markCoreDirty() const { mCoreDirtyFlags = 0xFFFFFFFF; }
 
 		/**
-		 * @brief	Binds per object GPU parameter buffers to the provided element.
+		 * @brief	Creates a new core proxy from the currently set Renderable data. Core proxies ensure
+		 *			that the core thread has all the necessary Renderable data, while avoiding the need
+		 *			to manage Renderable itself on the core thread.
+		 *
+		 * @note	You generally need to update the core thread with a new proxy whenever core 
+		 *			dirty flag is set.
 		 */
-		virtual void bindPerObjectBuffers(const RenderableElement* element) = 0;
+		RenderableProxyPtr _createProxy(const Matrix4& worldTransform) const;
 
 		/**
-		 * @brief	Binds global GPU parameter buffers used for this Renderable 
-		 *			type to the provided element.
+		 * @brief	Returns the currently active proxy object, if any.
 		 */
-		virtual void bindGlobalBuffers(const RenderableElement* element);
+		RenderableProxyPtr _getActiveProxy() const { return mActiveProxy; }
+
+		/**
+		 * @brief	Changes the currently active proxy object. 
+		 */
+		void _setActiveProxy(const RenderableProxyPtr& proxy) { mActiveProxy = proxy; }
+
+	private:
+		/**
+		 * @brief	Checks if any resources were loaded since last time. Marks the core data as dirty
+		 *			if they have (does nothing if all resources are already loaded).
+		 */
+		void updateResourceLoadStates() const;
+
+	private:
+		MeshData mMeshData;
+		Vector<MaterialData> mMaterialData;
+		UINT64 mLayer;
+		Vector<AABox> mWorldBounds;
+
+		RenderableProxyPtr mActiveProxy;
+		mutable UINT32 mCoreDirtyFlags;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class RenderableHandlerRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
 	};
 }

+ 48 - 0
BansheeEngine/Include/BsRenderableHandlerRTTI.h

@@ -0,0 +1,48 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsRenderableHandler.h"
+
+namespace BansheeEngine
+{
+	class BS_EXPORT RenderableHandlerRTTI : public RTTIType<RenderableHandler, IReflectable, RenderableHandlerRTTI>
+	{
+	private:
+		HMesh& getMesh(RenderableHandler* obj) { return obj->mMeshData.mesh; }
+		void setMesh(RenderableHandler* obj, HMesh& val) { obj->mMeshData.mesh = val; }
+
+		UINT64& getLayer(RenderableHandler* obj) { return obj->mLayer; }
+		void setLayer(RenderableHandler* obj, UINT64& val) { obj->mLayer = val; }
+
+		HMaterial& getMaterial(RenderableHandler* obj, UINT32 idx) { return obj->mMaterialData[idx].material; }
+		void setMaterial(RenderableHandler* obj, UINT32 idx, HMaterial& val) { obj->setMaterial(idx, val); }
+		UINT32 getNumMaterials(RenderableHandler* obj) { return (UINT32)obj->mMaterialData.size(); }
+		void setNumMaterials(RenderableHandler* obj, UINT32 num) { obj->mMaterialData.resize(num); }
+
+	public:
+		RenderableHandlerRTTI()
+		{
+			addReflectableField("mMesh", 0, &RenderableHandlerRTTI::getMesh, &RenderableHandlerRTTI::setMesh);
+			addPlainField("mLayer", 1, &RenderableHandlerRTTI::getLayer, &RenderableHandlerRTTI::setLayer);
+			addReflectableArrayField("mMaterials", 2, &RenderableHandlerRTTI::getMaterial, 
+				&RenderableHandlerRTTI::getNumMaterials, &RenderableHandlerRTTI::setMaterial, &RenderableHandlerRTTI::setNumMaterials);
+		}
+
+		virtual const String& getRTTIName()
+		{
+			static String name = "RenderableHandler";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId()
+		{
+			return TID_RenderableHandler;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		{
+			return bs_shared_ptr<RenderableHandler>();
+		}
+	};
+}

+ 1 - 1
BansheeEngine/Include/BsRenderableProxy.h

@@ -57,7 +57,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Handler responsible for initializing and updating this element.
 		 */
-		RenderableHandler* handler;
+		RenderableController* handler;
 
 		/**
 		 * @brief	Type that determines which type of RenderableHandler to use for this element.

+ 3 - 13
BansheeEngine/Include/BsRenderableRTTI.h

@@ -10,23 +10,13 @@ namespace BansheeEngine
 	class BS_EXPORT RenderableRTTI : public RTTIType<Renderable, Component, RenderableRTTI>
 	{
 	private:
-		HMesh& getMesh(Renderable* obj) { return obj->mMeshData.mesh; }
-		void setMesh(Renderable* obj, HMesh& val) { obj->mMeshData.mesh = val; } 
-
-		UINT64& getLayer(Renderable* obj) { return obj->mLayer; }
-		void setLayer(Renderable* obj, UINT64& val) { obj->mLayer = val; }
-
-		HMaterial& getMaterial(Renderable* obj, UINT32 idx) { return obj->mMaterialData[idx].material; }
-		void setMaterial(Renderable* obj, UINT32 idx, HMaterial& val) { obj->setMaterial(idx, val); }
-		UINT32 getNumMaterials(Renderable* obj) { return (UINT32)obj->mMaterialData.size(); }
-		void setNumMaterials(Renderable* obj, UINT32 num) { obj->mMaterialData.resize(num); }
+		RenderableHandlerPtr getInternal(Renderable* obj) { return obj->mInternal; }
+		void setInternal(Renderable* obj, RenderableHandlerPtr val) { obj->mInternal = val; }
 
 	public:
 		RenderableRTTI()
 		{
-			addReflectableField("mMesh", 0, &RenderableRTTI::getMesh, &RenderableRTTI::setMesh);
-			addPlainField("mLayer", 1, &RenderableRTTI::getLayer, &RenderableRTTI::setLayer);
-			addReflectableArrayField("mMaterials", 2, &RenderableRTTI::getMaterial, &RenderableRTTI::getNumMaterials, &RenderableRTTI::setMaterial, &RenderableRTTI::setNumMaterials);
+			addReflectablePtrField("mInternal", 0, &RenderableRTTI::getInternal, &RenderableRTTI::setInternal);
 		}
 
 		virtual const String& getRTTIName()

+ 30 - 4
BansheeEngine/Include/BsSceneManager.h

@@ -5,6 +5,32 @@
 
 namespace BansheeEngine
 {
+	/**
+	 * @brief	Contains information about a camera managed by the scene manager.
+	 */
+	struct SceneCameraData
+	{
+		SceneCameraData(const CameraHandlerPtr& camera, const HSceneObject& sceneObject)
+			:camera(camera), sceneObject(sceneObject)
+		{ }
+
+		CameraHandlerPtr camera;
+		HSceneObject sceneObject;
+	};
+
+	/**
+	 * @brief	Contains information about a renderable managed by the scene manager.
+	 */
+	struct SceneRenderableData
+	{
+		SceneRenderableData(const RenderableHandlerPtr& renderable, const HSceneObject& sceneObject)
+			:renderable(renderable), sceneObject(sceneObject)
+		{ }
+
+		RenderableHandlerPtr renderable;
+		HSceneObject sceneObject;
+	};
+
 	/**
 	 * @brief	Manages active SceneObjects and provides ways for querying
 	 *			and updating them or their components.
@@ -18,12 +44,12 @@ namespace BansheeEngine
 		/**
 		 * @brief	Returns all cameras in the scene.
 		 */
-		virtual const Vector<HCamera>& getAllCameras() const = 0;
+		virtual const Vector<SceneCameraData>& getAllCameras() const = 0;
 
 		/**
 		 * @brief	Returns all renderables in the scene.
 		 */
-		virtual const Vector<HRenderable>& getAllRenderables() const = 0;
+		virtual const Vector<SceneRenderableData>& getAllRenderables() const = 0;
 
 		/**
 		 * @brief	Updates dirty transforms on any scene objects with a Renderable component.
@@ -43,12 +69,12 @@ namespace BansheeEngine
 		/**
 		 * @brief	Triggered whenever a renderable is removed from a SceneObject.
 		 */
-		Event<void(const HRenderable&)> onRenderableRemoved;
+		Event<void(const RenderableHandlerPtr&)> onRenderableRemoved;
 
 		/**
 		 * @brief	Triggered whenever a camera is removed from a SceneObject.
 		 */
-		Event<void(const HCamera&)> onCameraRemoved;
+		Event<void(const CameraHandlerPtr&)> onCameraRemoved;
 	};
 
 	/**

+ 5 - 3
BansheeEngine/Source/BsCamera.cpp

@@ -16,8 +16,10 @@
 namespace BansheeEngine 
 {
 	Camera::Camera(const HSceneObject& parent, RenderTargetPtr target, float left, float top, float width, float height)
-		: Component(parent), mInternal(target, left, top, width, height), mLastUpdateHash(std::numeric_limits<UINT32>::max())
+		: Component(parent), mLastUpdateHash(std::numeric_limits<UINT32>::max())
     {
+		mInternal = bs_shared_ptr<CameraHandler>(target, left, top, width, height);
+
 		setName("Camera");
     }
 
@@ -46,8 +48,8 @@ namespace BansheeEngine
 		UINT32 curHash = SO()->getTransformHash();
 		if (curHash != mLastUpdateHash)
 		{
-			mInternal.setPosition(SO()->getWorldPosition());
-			mInternal.setRotation(SO()->getWorldRotation());
+			mInternal->setPosition(SO()->getWorldPosition());
+			mInternal->setRotation(SO()->getWorldRotation());
 
 			mLastUpdateHash = curHash;
 		}

+ 0 - 1
BansheeEngine/Source/BsCameraHandler.cpp

@@ -148,7 +148,6 @@ namespace BansheeEngine
 				top = mTop;
 				bottom = mBottom;
 			}
-
 			else if (mProjType == PT_PERSPECTIVE)
 			{
 				Radian thetaY(mHorzFOV * 0.5f);

+ 8 - 154
BansheeEngine/Source/BsRenderable.cpp

@@ -9,57 +9,19 @@
 
 namespace BansheeEngine
 {
-	Renderable::MeshData::MeshData(const HMesh& mesh)
-	{
-		this->mesh = mesh;
-		isLoaded = mesh.isLoaded();
-	}
-
-	Renderable::MaterialData::MaterialData(const HMaterial& material)
-	{
-		this->material = material;
-		isLoaded = material.isLoaded();
-	}
-
 	Renderable::Renderable(const HSceneObject& parent)
-		:Component(parent), mLayer(1), mCoreDirtyFlags(0xFFFFFFFF), mActiveProxy(nullptr)
+		:Component(parent)
 	{
 		setName("Renderable");
 
-		mMaterialData.resize(1);
-	}
-
-	void Renderable::setMesh(HMesh mesh)
-	{
-		mMeshData = mesh;
-		mMaterialData.resize(mesh->getNumSubMeshes());
-
-		_markCoreDirty();
-	}
-
-	void Renderable::setMaterial(UINT32 idx, HMaterial material)
-	{
-		mMaterialData[idx] = material;
-
-		_markCoreDirty();
-	}
-
-	void Renderable::setMaterial(HMaterial material)
-	{
-		setMaterial(0, material);
-	}
-
-	HMaterial Renderable::getMaterial(UINT32 idx) const
-	{ 
-		if (mMaterialData[idx].material != nullptr)
-			return mMaterialData[idx].material;
-		else
-			return mMaterialData[0].material;
+		mInternal = bs_shared_ptr<RenderableHandler>();
 	}
 
 	Bounds Renderable::getBounds() const
 	{
-		if (mMeshData.mesh == nullptr || !mMeshData.mesh.isLoaded())
+		HMesh mesh = mInternal->getMesh();
+
+		if (mesh == nullptr || !mesh.isLoaded())
 		{
 			Vector3 pos = SO()->getWorldPosition();
 
@@ -70,124 +32,16 @@ namespace BansheeEngine
 		}
 		else
 		{
-			Bounds bounds = mMeshData.mesh->getBounds();
+			Bounds bounds = mesh->getBounds();
 			bounds.transformAffine(SO()->getWorldTfrm());
 
 			return bounds;
 		}
 	}
 
-	void Renderable::setLayer(UINT64 layer)
-	{
-		bool isPow2 = layer && !((layer - 1) & layer);
-
-		if (!isPow2)
-			BS_EXCEPT(InvalidParametersException, "Invalid layer provided. Only one layer bit may be set.");
-
-		mLayer = layer;
-		_markCoreDirty();
-	}
-
-	bool Renderable::_isCoreDirty() const
+	RenderableProxyPtr Renderable::_createProxy() const 
 	{ 
-		updateResourceLoadStates();
-
-		for (auto& materialData : mMaterialData)
-		{
-			if (materialData.material != nullptr && materialData.material.isLoaded() && materialData.material->_isCoreDirty(MaterialDirtyFlag::Material))
-				return true;
-		}
-
-		if (mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded() && mMeshData.mesh->_isCoreDirty(MeshDirtyFlag::Mesh))
-			return true;
-
-		return mCoreDirtyFlags != 0; 
-	}
-
-	void Renderable::_markCoreClean()
-	{
-		for (auto& materialData : mMaterialData)
-		{
-			if (materialData.material != nullptr && materialData.material.isLoaded())
-				materialData.material->_markCoreClean(MaterialDirtyFlag::Material);
-		}
-
-		if (mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded())
-			mMeshData.mesh->_markCoreClean(MeshDirtyFlag::Mesh);
-
-		mCoreDirtyFlags = 0;
-	}
-
-	void Renderable::updateResourceLoadStates() const
-	{
-		if (!mMeshData.isLoaded && mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded())
-		{
-			mMeshData.isLoaded = true;
-
-			_markCoreDirty();
-		}
-
-		for (auto& materialData : mMaterialData)
-		{
-			if (!materialData.isLoaded && materialData.material != nullptr && materialData.material.isLoaded())
-			{
-				materialData.isLoaded = true;
-
-				_markCoreDirty();
-			}
-		}
-	}
-
-	RenderableProxyPtr Renderable::_createProxy() const
-	{
-		if (mMeshData.mesh == nullptr || !mMeshData.mesh.isLoaded())
-			return nullptr;
-
-		RenderableProxyPtr proxy = bs_shared_ptr<RenderableProxy>();
-
-		bool markMeshProxyClean = false;
-		for (UINT32 i = 0; i < mMeshData.mesh->getNumSubMeshes(); i++)
-		{
-			RenderableElement* renElement = bs_new<RenderableElement>();
-			renElement->layer = mLayer;
-			renElement->worldTransform = SO()->getWorldTfrm();
-
-			if (mMeshData.mesh->_isCoreDirty(MeshDirtyFlag::Proxy))
-			{
-				mMeshData.mesh->_setActiveProxy(i, mMeshData.mesh->_createProxy(i));
-				markMeshProxyClean = true;
-			}
-
-			renElement->mesh = mMeshData.mesh->_getActiveProxy(i);
-
-			HMaterial material;
-			if (mMaterialData[i].material != nullptr)
-				material = mMaterialData[i].material;
-			else
-				material = mMaterialData[0].material;
-
-			if (material == nullptr || !material.isLoaded())
-				material = BuiltinResources::instance().createDummyMaterial();
-
-			if (material->_isCoreDirty(MaterialDirtyFlag::Proxy))
-			{
-				material->_setActiveProxy(material->_createProxy());
-				material->_markCoreClean(MaterialDirtyFlag::Proxy);
-			}
-
-			renElement->material = material->_getActiveProxy();
-
-			proxy->renderableElements.push_back(renElement);
-		}
-
-		if (markMeshProxyClean)
-		{
-			mMeshData.mesh->_markCoreClean(MeshDirtyFlag::Proxy);
-		}
-
-		proxy->renderableType = RenType_LitTextured;
-
-		return proxy;
+		return mInternal->_createProxy(SO()->getWorldTfrm()); 
 	}
 
 	RTTITypeBase* Renderable::getRTTIStatic()

+ 14 - 0
BansheeEngine/Source/BsRenderableController.cpp

@@ -0,0 +1,14 @@
+#include "BsRenderableController.h"
+#include "BsRenderableProxy.h"
+#include "BsGpuParams.h"
+
+namespace BansheeEngine
+{
+	void RenderableController::bindGlobalBuffers(const RenderableElement* element)
+	{
+		for (auto& rendererBuffer : element->material->rendererBuffers)
+		{
+			element->material->params[rendererBuffer.paramsIdx]->setParamBlockBuffer(rendererBuffer.slotIdx, rendererBuffer.buffer);
+		}
+	}
+}

+ 171 - 5
BansheeEngine/Source/BsRenderableHandler.cpp

@@ -1,14 +1,180 @@
 #include "BsRenderableHandler.h"
-#include "BsRenderableProxy.h"
-#include "BsGpuParams.h"
+#include "BsRenderableHandlerRTTI.h"
+#include "BsSceneObject.h"
+#include "BsBuiltinResources.h"
+#include "BsMesh.h"
+#include "BsMaterial.h"
+#include "BsRenderQueue.h"
+#include "BsBounds.h"
 
 namespace BansheeEngine
 {
-	void RenderableHandler::bindGlobalBuffers(const RenderableElement* element)
+	RenderableHandler::MeshData::MeshData(const HMesh& mesh)
 	{
-		for (auto& rendererBuffer : element->material->rendererBuffers)
+		this->mesh = mesh;
+		isLoaded = mesh.isLoaded();
+	}
+
+	RenderableHandler::MaterialData::MaterialData(const HMaterial& material)
+	{
+		this->material = material;
+		isLoaded = material.isLoaded();
+	}
+
+	RenderableHandler::RenderableHandler()
+		:mLayer(1), mCoreDirtyFlags(0xFFFFFFFF), mActiveProxy(nullptr)
+	{
+		mMaterialData.resize(1);
+	}
+
+	void RenderableHandler::setMesh(HMesh mesh)
+	{
+		mMeshData = mesh;
+		mMaterialData.resize(mesh->getNumSubMeshes());
+
+		_markCoreDirty();
+	}
+
+	void RenderableHandler::setMaterial(UINT32 idx, HMaterial material)
+	{
+		mMaterialData[idx] = material;
+
+		_markCoreDirty();
+	}
+
+	void RenderableHandler::setMaterial(HMaterial material)
+	{
+		setMaterial(0, material);
+	}
+
+	HMaterial RenderableHandler::getMaterial(UINT32 idx) const
+	{
+		if (mMaterialData[idx].material != nullptr)
+			return mMaterialData[idx].material;
+		else
+			return mMaterialData[0].material;
+	}
+
+	void RenderableHandler::setLayer(UINT64 layer)
+	{
+		bool isPow2 = layer && !((layer - 1) & layer);
+
+		if (!isPow2)
+			BS_EXCEPT(InvalidParametersException, "Invalid layer provided. Only one layer bit may be set.");
+
+		mLayer = layer;
+		_markCoreDirty();
+	}
+
+	bool RenderableHandler::_isCoreDirty() const
+	{
+		updateResourceLoadStates();
+
+		for (auto& materialData : mMaterialData)
 		{
-			element->material->params[rendererBuffer.paramsIdx]->setParamBlockBuffer(rendererBuffer.slotIdx, rendererBuffer.buffer);
+			if (materialData.material != nullptr && materialData.material.isLoaded() && materialData.material->_isCoreDirty(MaterialDirtyFlag::Material))
+				return true;
 		}
+
+		if (mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded() && mMeshData.mesh->_isCoreDirty(MeshDirtyFlag::Mesh))
+			return true;
+
+		return mCoreDirtyFlags != 0;
+	}
+
+	void RenderableHandler::_markCoreClean()
+	{
+		for (auto& materialData : mMaterialData)
+		{
+			if (materialData.material != nullptr && materialData.material.isLoaded())
+				materialData.material->_markCoreClean(MaterialDirtyFlag::Material);
+		}
+
+		if (mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded())
+			mMeshData.mesh->_markCoreClean(MeshDirtyFlag::Mesh);
+
+		mCoreDirtyFlags = 0;
+	}
+
+	void RenderableHandler::updateResourceLoadStates() const
+	{
+		if (!mMeshData.isLoaded && mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded())
+		{
+			mMeshData.isLoaded = true;
+
+			_markCoreDirty();
+		}
+
+		for (auto& materialData : mMaterialData)
+		{
+			if (!materialData.isLoaded && materialData.material != nullptr && materialData.material.isLoaded())
+			{
+				materialData.isLoaded = true;
+
+				_markCoreDirty();
+			}
+		}
+	}
+
+	RenderableProxyPtr RenderableHandler::_createProxy(const Matrix4& worldTransform) const
+	{
+		if (mMeshData.mesh == nullptr || !mMeshData.mesh.isLoaded())
+			return nullptr;
+
+		RenderableProxyPtr proxy = bs_shared_ptr<RenderableProxy>();
+
+		bool markMeshProxyClean = false;
+		for (UINT32 i = 0; i < mMeshData.mesh->getNumSubMeshes(); i++)
+		{
+			RenderableElement* renElement = bs_new<RenderableElement>();
+			renElement->layer = mLayer;
+			renElement->worldTransform = worldTransform;
+
+			if (mMeshData.mesh->_isCoreDirty(MeshDirtyFlag::Proxy))
+			{
+				mMeshData.mesh->_setActiveProxy(i, mMeshData.mesh->_createProxy(i));
+				markMeshProxyClean = true;
+			}
+
+			renElement->mesh = mMeshData.mesh->_getActiveProxy(i);
+
+			HMaterial material;
+			if (mMaterialData[i].material != nullptr)
+				material = mMaterialData[i].material;
+			else
+				material = mMaterialData[0].material;
+
+			if (material == nullptr || !material.isLoaded())
+				material = BuiltinResources::instance().createDummyMaterial();
+
+			if (material->_isCoreDirty(MaterialDirtyFlag::Proxy))
+			{
+				material->_setActiveProxy(material->_createProxy());
+				material->_markCoreClean(MaterialDirtyFlag::Proxy);
+			}
+
+			renElement->material = material->_getActiveProxy();
+
+			proxy->renderableElements.push_back(renElement);
+		}
+
+		if (markMeshProxyClean)
+		{
+			mMeshData.mesh->_markCoreClean(MeshDirtyFlag::Proxy);
+		}
+
+		proxy->renderableType = RenType_LitTextured;
+
+		return proxy;
+	}
+
+	RTTITypeBase* RenderableHandler::getRTTIStatic()
+	{
+		return RenderableHandlerRTTI::instance();
+	}
+
+	RTTITypeBase* RenderableHandler::getRTTI() const
+	{
+		return RenderableHandler::getRTTIStatic();
 	}
 }

+ 2 - 2
BansheeRenderer/BansheeRenderer.vcxproj

@@ -233,13 +233,13 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClInclude Include="Include\BsBansheeLitTexRenderableHandler.h" />
+    <ClInclude Include="Include\BsBansheeLitTexRenderableController.h" />
     <ClInclude Include="Include\BsBansheeRenderer.h" />
     <ClInclude Include="Include\BsBansheeRendererFactory.h" />
     <ClInclude Include="Include\BsBansheeRendererPrerequisites.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="Source\BsBansheeLitTexRenderableHandler.cpp" />
+    <ClCompile Include="Source\BsBansheeLitTexRenderableController.cpp" />
     <ClCompile Include="Source\BsBansheeRenderer.cpp" />
     <ClCompile Include="Source\BsBansheeRendererFactory.cpp" />
     <ClCompile Include="Source\BsBansheeRendererPlugin.cpp" />

+ 2 - 2
BansheeRenderer/BansheeRenderer.vcxproj.filters

@@ -24,7 +24,7 @@
     <ClInclude Include="Include\BsBansheeRendererPrerequisites.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsBansheeLitTexRenderableHandler.h">
+    <ClInclude Include="Include\BsBansheeLitTexRenderableController.h">
       <Filter>Header Files</Filter>
     </ClInclude>
   </ItemGroup>
@@ -38,7 +38,7 @@
     <ClCompile Include="Source\BsBansheeRendererPlugin.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsBansheeLitTexRenderableHandler.cpp">
+    <ClCompile Include="Source\BsBansheeLitTexRenderableController.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>

+ 3 - 3
BansheeRenderer/Include/BsBansheeLitTexRenderableHandler.h → BansheeRenderer/Include/BsBansheeLitTexRenderableController.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include "BsBansheeRendererPrerequisites.h"
-#include "BsRenderableHandler.h"
+#include "BsRenderableController.h"
 #include "BsMaterialProxy.h"
 #include "BsGpuParamDesc.h"
 #include "BsGpuParam.h"
@@ -15,7 +15,7 @@ namespace BansheeEngine
 	 *
 	 * @note	This class is DEBUG ONLY. Until a better renderer is complete.
 	 */
-	class BS_BSRND_EXPORT LitTexRenderableHandler : public RenderableHandler
+	class BS_BSRND_EXPORT LitTexRenderableController : public RenderableController
 	{
 	public:
 		/**
@@ -31,7 +31,7 @@ namespace BansheeEngine
 			Vector<MaterialProxy::BufferBindInfo> perObjectBuffers;
 		};
 
-		LitTexRenderableHandler();
+		LitTexRenderableController();
 
 		/**
 		 * @copydoc	RenderableHandler::initializeRenderElem

+ 3 - 3
BansheeRenderer/Include/BsBansheeRenderer.h

@@ -156,13 +156,13 @@ namespace BansheeEngine
 		 * @brief	Called by the scene manager whenever a Renderable component has been
 		 *			removed from the scene.
 		 */
-		void renderableRemoved(const HRenderable& renderable);
+		void renderableRemoved(const RenderableHandlerPtr& renderable);
 
 		/**
 		 * @brief	Called by the scene manager whenever a Camera component has been
 		 *			removed from the scene.
 		 */
-		void cameraRemoved(const HCamera& camera);
+		void cameraRemoved(const CameraHandlerPtr& camera);
 
 		Vector<RenderableProxyPtr> mDeletedRenderableProxies;
 		Vector<CameraProxyPtr> mDeletedCameraProxies;
@@ -174,7 +174,7 @@ namespace BansheeEngine
 		Vector<Matrix4> mWorldTransforms;
 		Vector<Bounds> mWorldBounds;
 
-		LitTexRenderableHandler* mLitTexHandler;
+		LitTexRenderableController* mLitTexHandler;
 
 		HEvent mRenderableRemovedConn;
 		HEvent mCameraRemovedConn;

+ 1 - 1
BansheeRenderer/Include/BsBansheeRendererPrerequisites.h

@@ -20,5 +20,5 @@
 
 namespace BansheeEngine
 {
-	class LitTexRenderableHandler;
+	class LitTexRenderableController;
 }

+ 7 - 7
BansheeRenderer/Source/BsBansheeLitTexRenderableHandler.cpp → BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp

@@ -1,4 +1,4 @@
-#include "BsBansheeLitTexRenderableHandler.h"
+#include "BsBansheeLitTexRenderableController.h"
 #include "BsRenderableProxy.h"
 #include "BsShader.h"
 #include "BsShaderProxy.h"
@@ -12,7 +12,7 @@
 
 namespace BansheeEngine
 {
-	LitTexRenderableHandler::LitTexRenderableHandler()
+	LitTexRenderableController::LitTexRenderableController()
 	{
 		defaultShader = createDefaultShader();
 
@@ -123,7 +123,7 @@ namespace BansheeEngine
 		lightDirParam.set(Vector4(0.707f, 0.707f, 0.707f, 0.0f));
 	}
 
-	void LitTexRenderableHandler::initializeRenderElem(RenderableElement* element)
+	void LitTexRenderableController::initializeRenderElem(RenderableElement* element)
 	{
 		static auto paramsMatch = [](const GpuParamDataDesc& a, const GpuParamDataDesc& b)
 		{
@@ -233,7 +233,7 @@ namespace BansheeEngine
 		bindGlobalBuffers(element);
 	}
 
-	void LitTexRenderableHandler::bindPerObjectBuffers(const RenderableElement* element)
+	void LitTexRenderableController::bindPerObjectBuffers(const RenderableElement* element)
 	{
 		const PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element->rendererData);
 		for (auto& perObjectBuffer : rendererData->perObjectBuffers)
@@ -244,7 +244,7 @@ namespace BansheeEngine
 		}
 	}
 
-	void LitTexRenderableHandler::updateGlobalBuffers(float time)
+	void LitTexRenderableController::updateGlobalBuffers(float time)
 	{
 		timeParam.set(time);
 
@@ -252,7 +252,7 @@ namespace BansheeEngine
 		perFrameParams->updateHardwareBuffers();
 	}
 
-	void LitTexRenderableHandler::updatePerObjectBuffers(RenderableElement* element, const Matrix4& wvpMatrix)
+	void LitTexRenderableController::updatePerObjectBuffers(RenderableElement* element, const Matrix4& wvpMatrix)
 	{
 		PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element->rendererData);
 
@@ -267,7 +267,7 @@ namespace BansheeEngine
 		}
 	}
 
-	ShaderPtr LitTexRenderableHandler::createDefaultShader()
+	ShaderPtr LitTexRenderableController::createDefaultShader()
 	{
 		String rsName = RenderSystem::instance().getName();
 

+ 30 - 21
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -25,7 +25,7 @@
 #include "BsGpuParamBlockBuffer.h"
 #include "BsShader.h"
 #include "BsShaderProxy.h"
-#include "BsBansheeLitTexRenderableHandler.h"
+#include "BsBansheeLitTexRenderableController.h"
 #include "BsTime.h"
 #include "BsFrameAlloc.h"
 
@@ -55,7 +55,7 @@ namespace BansheeEngine
 	{
 		Renderer::_onActivated();
 
-		mLitTexHandler = bs_new<LitTexRenderableHandler>();
+		mLitTexHandler = bs_new<LitTexRenderableController>();
 	}
 
 	void BansheeRenderer::_onDeactivated()
@@ -180,7 +180,7 @@ namespace BansheeEngine
 		proxy->calcWorldFrustum();
 	}
 
-	void BansheeRenderer::renderableRemoved(const HRenderable& renderable)
+	void BansheeRenderer::renderableRemoved(const RenderableHandlerPtr& renderable)
 	{
 		if (renderable->_getActiveProxy() != nullptr)
 		{
@@ -188,7 +188,7 @@ namespace BansheeEngine
 		}
 	}
 
-	void BansheeRenderer::cameraRemoved(const HCamera& camera)
+	void BansheeRenderer::cameraRemoved(const CameraHandlerPtr& camera)
 	{
 		if (camera->_getActiveProxy() != nullptr)
 		{
@@ -208,39 +208,42 @@ namespace BansheeEngine
 		}
 
 		// Add or update Renderable proxies
-		const Vector<HRenderable>& allRenderables = gSceneManager().getAllRenderables();
+		const Vector<SceneRenderableData>& allRenderables = gSceneManager().getAllRenderables();
 		Vector<HSceneObject> dirtySceneObjects;
-		Vector<HRenderable> dirtyRenderables;
+		Vector<RenderableHandlerPtr> dirtyRenderables;
 
 		FrameAlloc* frameAlloc = gCoreThread().getFrameAlloc();
-		for (auto& renderable : allRenderables)
+		for (auto& renderableData : allRenderables)
 		{
+			RenderableHandlerPtr renderable = renderableData.renderable;
+			HSceneObject renderableSO = renderableData.sceneObject;
+
 			bool addedNewProxy = false;
 			RenderableProxyPtr proxy = renderable->_getActiveProxy();
 
-			if (renderable->SO()->getActive())
+			if (renderableSO->getActive())
 			{
 				if (renderable->_isCoreDirty())
 				{
 					if (proxy != nullptr)
 						gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::removeRenderableProxy, this, proxy));
 
-					proxy = renderable->_createProxy();
+					proxy = renderable->_createProxy(renderableSO->getWorldTfrm());
 					renderable->_setActiveProxy(proxy);
 
 					if (proxy != nullptr)
 						gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::addRenderableProxy, this, proxy));
 
 					dirtyRenderables.push_back(renderable);
-					dirtySceneObjects.push_back(renderable->SO());
+					dirtySceneObjects.push_back(renderableSO);
 					addedNewProxy = true;
 				}
-				else if (renderable->SO()->_isCoreDirty())
+				else if (renderableSO->_isCoreDirty())
 				{
 					if (proxy != nullptr)
-						gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateRenderableProxy, this, proxy, renderable->SO()->getWorldTfrm()));
+						gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateRenderableProxy, this, proxy, renderableSO->getWorldTfrm()));
 
-					dirtySceneObjects.push_back(renderable->SO());
+					dirtySceneObjects.push_back(renderableSO);
 				}
 
 				if (!addedNewProxy && proxy != nullptr)
@@ -284,9 +287,12 @@ namespace BansheeEngine
 		}
 
 		// Add or update Camera proxies
-		const Vector<HCamera>& allCameras = gSceneManager().getAllCameras();
-		for (auto& camera : allCameras)
+		const Vector<SceneCameraData>& allCameras = gSceneManager().getAllCameras();
+		for (auto& cameraData : allCameras)
 		{
+			CameraHandlerPtr camera = cameraData.camera;
+			HSceneObject cameraSO = cameraData.sceneObject;
+
 			if (camera->_isCoreDirty())
 			{
 				CameraProxyPtr proxy = camera->_getActiveProxy();
@@ -300,17 +306,17 @@ namespace BansheeEngine
 				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::addCameraProxy, this, proxy));
 
 				camera->_markCoreClean();
-				dirtySceneObjects.push_back(camera->SO());
+				dirtySceneObjects.push_back(cameraSO);
 			}
-			else if (camera->SO()->_isCoreDirty())
+			else if (cameraSO->_isCoreDirty())
 			{
 				CameraProxyPtr proxy = camera->_getActiveProxy();
 				assert(proxy != nullptr);
 
 				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateCameraProxy, this, 
-					proxy, camera->SO()->getWorldPosition(), camera->SO()->getWorldTfrm(), camera->getViewMatrix()));
+					proxy, cameraSO->getWorldPosition(), cameraSO->getWorldTfrm(), camera->getViewMatrix()));
 
-				dirtySceneObjects.push_back(camera->SO());
+				dirtySceneObjects.push_back(cameraSO);
 			}
 		}
 
@@ -321,8 +327,11 @@ namespace BansheeEngine
 		}
 
 		// Populate direct draw lists
-		for (auto& camera : allCameras)
+		for (auto& cameraData : allCameras)
 		{
+			CameraHandlerPtr camera = cameraData.camera;
+			HSceneObject cameraSO = cameraData.sceneObject;
+
 			DrawListPtr drawList = bs_shared_ptr<DrawList>();
 
 			// Get GUI render operations
@@ -382,7 +391,7 @@ namespace BansheeEngine
 						materialProxy, dirtyParams));
 				}
 
-				float distanceToCamera = (camera->SO()->getPosition() - drawOp.worldPosition).length();
+				float distanceToCamera = (cameraSO->getPosition() - drawOp.worldPosition).length();
 				renderQueue->add(materialProxy, meshProxy, distanceToCamera);
 			}
 

+ 4 - 4
BansheeSceneManager/Include/BsBansheeSceneManager.h

@@ -20,12 +20,12 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	SceneManager::getAllCameras
 		 */
-		const Vector<HCamera>& getAllCameras() const { return mCachedCameras; }
+		const Vector<SceneCameraData>& getAllCameras() const { return mCachedCameras; }
 
 		/**
 		 * @copydoc	SceneManager::getAllRenderables
 		 */
-		const Vector<HRenderable>& getAllRenderables() const { return mRenderables; }
+		const Vector<SceneRenderableData>& getAllRenderables() const { return mRenderables; }
 
 		/**
 		 * @copydoc	SceneManager
@@ -43,7 +43,7 @@ namespace BansheeEngine
 		 */
 		void notifyComponentRemoved(const HComponent& component);
 
-		Vector<HCamera> mCachedCameras;
-		Vector<HRenderable> mRenderables;
+		Vector<SceneCameraData> mCachedCameras;
+		Vector<SceneRenderableData> mRenderables;
 	};
 }

+ 19 - 8
BansheeSceneManager/Source/BsBansheeSceneManager.cpp

@@ -17,7 +17,7 @@ namespace BansheeEngine
 
 		for(auto& iter : mRenderables)
 		{
-			iter->SO()->updateTransformsIfDirty();
+			iter.sceneObject->updateTransformsIfDirty();
 		}
 	}
 
@@ -26,19 +26,24 @@ namespace BansheeEngine
 		if(component->getTypeId() == TID_Camera)
 		{
 			HCamera camera = static_object_cast<Camera>(component);
-			auto findIter = std::find(mCachedCameras.begin(), mCachedCameras.end(), camera);
+			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(camera);
+			mCachedCameras.push_back(SceneCameraData(cameraHandler, component->SO()));
 		}
 		else if(component->getTypeId() == TID_Renderable)
 		{
 			HRenderable renderable = static_object_cast<Renderable>(component);
-			mRenderables.push_back(renderable);
+			RenderableHandlerPtr renderableHandler = renderable->_getHandler();
+
+			mRenderables.push_back(SceneRenderableData(renderableHandler, renderable->SO()));
 		}
 	}
 
@@ -47,7 +52,10 @@ namespace BansheeEngine
 		if(component->getTypeId() == TID_Camera)
 		{
 			HCamera camera = static_object_cast<Camera>(component);
-			auto findIter = std::find(mCachedCameras.begin(), mCachedCameras.end(), camera);
+			CameraHandlerPtr cameraHandler = camera->_getHandler();
+
+			auto findIter = std::find_if(mCachedCameras.begin(), mCachedCameras.end(),
+				[&](const SceneCameraData& x) { return x.camera == cameraHandler; });
 
 			if(findIter == mCachedCameras.end())
 			{
@@ -56,18 +64,21 @@ namespace BansheeEngine
 
 			mCachedCameras.erase(findIter);
 
-			onCameraRemoved(camera);
+			onCameraRemoved(cameraHandler);
 		}
 		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(mRenderables.begin(), mRenderables.end(), renderable);
+			auto findIter = std::find_if(mRenderables.begin(), mRenderables.end(),
+				[&](const SceneRenderableData& x) { return x.renderable == renderableHandler; });
+
 			if(findIter != mRenderables.end())
 				mRenderables.erase(findIter);
 
-			onRenderableRemoved(renderable);
+			onRenderableRemoved(renderableHandler);
 		}
 	}
 }

+ 2 - 0
BansheeUtility/Include/BsDegree.h

@@ -55,4 +55,6 @@ namespace BansheeEngine
 		bool operator>= (const Degree& d) const { return mDeg >= d.mDeg; }
 		bool operator>  (const Degree& d) const { return mDeg >  d.mDeg; }
 	};
+
+	BS_ALLOW_MEMCPY_SERIALIZATION(Degree);
 }

+ 2 - 0
BansheeUtility/Include/BsQuaternion.h

@@ -279,4 +279,6 @@ namespace BansheeEngine
 		private:
 			static const EulerAngleOrderData EA_LOOKUP[6];
     };
+
+	BS_ALLOW_MEMCPY_SERIALIZATION(Quaternion);
 }

+ 2 - 0
BansheeUtility/Include/BsRadian.h

@@ -55,4 +55,6 @@ namespace BansheeEngine
 		bool operator>= (const Radian& r) const { return mRad >= r.mRad; }
 		bool operator>  (const Radian& r) const { return mRad >  r.mRad; }
 	};
+
+	BS_ALLOW_MEMCPY_SERIALIZATION(Radian);
 }

+ 2 - 0
BansheeUtility/Include/BsRect2.h

@@ -61,4 +61,6 @@ namespace BansheeEngine
 
 		static const Rect2 EMPTY;
 	};
+
+	BS_ALLOW_MEMCPY_SERIALIZATION(Rect2);
 }