瀏覽代碼

Animation bone transforms now used by the core thread for rendering

BearishSun 9 年之前
父節點
當前提交
05266555e8

二進制
Data/Engine/GUISkin.asset


二進制
Data/Engine/Includes/DeferredLightPass.bslinc.asset


二進制
Data/Engine/Includes/SkinnedVertexInput.bslinc.asset


二進制
Data/Engine/ResourceManifest.asset


二進制
Data/Engine/Timestamp.asset


二進制
Data/Engine/arial.ttf.asset


+ 1 - 1
Data/Raw/Engine/Includes/DeferredLightPass.bslinc

@@ -2,7 +2,7 @@
 #include "$ENGINE$\PerCameraData.bslinc"
 #include "$ENGINE$\PerCameraData.bslinc"
 
 
 Parameters =
 Parameters =
-{		
+{
 	Sampler2D 	gGBufferASamp : alias("gGBufferATex");
 	Sampler2D 	gGBufferASamp : alias("gGBufferATex");
 	Sampler2D 	gGBufferBSamp : alias("gGBufferBTex");
 	Sampler2D 	gGBufferBSamp : alias("gGBufferBTex");
 	Sampler2D 	gDepthBufferSamp : alias("gDepthBufferTex");
 	Sampler2D 	gDepthBufferSamp : alias("gDepthBufferTex");

+ 5 - 0
Data/Raw/Engine/Includes/SkinnedVertexInput.bslinc

@@ -1,3 +1,8 @@
+Parameters =
+{
+	StructBuffer boneMatrices : auto("BoneMatrices");;
+}
+
 Technique =
 Technique =
 {
 {
 	Language = "HLSL11";
 	Language = "HLSL11";

+ 6 - 2
Source/BansheeCore/Include/BsAnimationManager.h

@@ -25,7 +25,10 @@ namespace BansheeEngine
 			UINT32 numBones;
 			UINT32 numBones;
 		};
 		};
 
 
+		/** Maps animation ID to a pose information structure, containing its global joint transforms. */
 		UnorderedMap<UINT64, PoseInfo> poseInfos;
 		UnorderedMap<UINT64, PoseInfo> poseInfos;
+
+		/** Global joint transforms for all skeletons in the scene. */
 		Vector<Matrix4> transforms;
 		Vector<Matrix4> transforms;
 	};
 	};
 
 
@@ -33,7 +36,7 @@ namespace BansheeEngine
 	 * Keeps track of all active animations, queues animation thread tasks and synchronizes data between simulation, core
 	 * Keeps track of all active animations, queues animation thread tasks and synchronizes data between simulation, core
 	 * and animation threads.
 	 * and animation threads.
 	 */
 	 */
-	class AnimationManager : public Module<AnimationManager>
+	class BS_CORE_EXPORT AnimationManager : public Module<AnimationManager>
 	{
 	{
 	public:
 	public:
 		AnimationManager();
 		AnimationManager();
@@ -64,7 +67,8 @@ namespace BansheeEngine
 		/** 
 		/** 
 		 * Gets skeleton poses required by the renderer to display all the animations. This will block the animation thread
 		 * Gets skeleton poses required by the renderer to display all the animations. This will block the animation thread
 		 * if it has not yet finished, and it will also advance the read buffer index, meaning this shouldn't be called more
 		 * if it has not yet finished, and it will also advance the read buffer index, meaning this shouldn't be called more
-		 * than once per frame.
+		 * than once per frame. The returned data can be referenced, and is guaranteed to be valid for a single core-thread
+		 * frame.
 		 *
 		 *
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */

+ 18 - 18
Source/BansheeCore/Include/BsGpuParam.h

@@ -108,7 +108,7 @@ namespace BansheeEngine
 		 * Like with all GPU parameters, the actual GPU buffer will not be updated until rendering with material this 
 		 * Like with all GPU parameters, the actual GPU buffer will not be updated until rendering with material this 
 		 * parameter was created from starts on the core thread.
 		 * parameter was created from starts on the core thread.
 		 */
 		 */
-		void set(const T& value, UINT32 arrayIdx = 0);
+		void set(const T& value, UINT32 arrayIdx = 0) const;
 
 
 		/**
 		/**
 		 * Returns a value of a parameter at the specified array index. If parameter does not contain an array leave the 
 		 * Returns a value of a parameter at the specified array index. If parameter does not contain an array leave the 
@@ -116,13 +116,13 @@ namespace BansheeEngine
 		 *
 		 *
 		 * @note	No GPU reads are done. Data returned was cached when it was written. 
 		 * @note	No GPU reads are done. Data returned was cached when it was written. 
 		 */
 		 */
-		T get(UINT32 arrayIdx = 0);
+		T get(UINT32 arrayIdx = 0) const;
 
 
 		/** Returns meta-data about the parameter. */
 		/** Returns meta-data about the parameter. */
 		const GpuParamDataDesc& getDesc() const { return *mParamDesc; }
 		const GpuParamDataDesc& getDesc() const { return *mParamDesc; }
 
 
 		/** Checks if param is initialized. */
 		/** Checks if param is initialized. */
-		bool operator==(const nullptr_t &nullval) const
+		bool operator==(const nullptr_t& nullval) const
 		{
 		{
 			return mParamDesc == nullptr;
 			return mParamDesc == nullptr;
 		}
 		}
@@ -144,10 +144,10 @@ namespace BansheeEngine
 		TGpuParamStruct(GpuParamDataDesc* paramDesc, const GpuParamsType& parent);
 		TGpuParamStruct(GpuParamDataDesc* paramDesc, const GpuParamsType& parent);
 
 
 		/** @copydoc TGpuDataParam::set */
 		/** @copydoc TGpuDataParam::set */
-		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const;
 
 
 		/** @copydoc TGpuDataParam::get */
 		/** @copydoc TGpuDataParam::get */
-		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const;
 
 
 		/**	Returns the size of the struct in bytes. */
 		/**	Returns the size of the struct in bytes. */
 		UINT32 getElementSize() const;
 		UINT32 getElementSize() const;
@@ -156,7 +156,7 @@ namespace BansheeEngine
 		const GpuParamDataDesc& getDesc() const { return *mParamDesc; }
 		const GpuParamDataDesc& getDesc() const { return *mParamDesc; }
 
 
 		/**	Checks if param is initialized. */
 		/**	Checks if param is initialized. */
-		bool operator==(const nullptr_t &nullval) const
+		bool operator==(const nullptr_t& nullval) const
 		{
 		{
 			return mParamDesc == nullptr;
 			return mParamDesc == nullptr;
 		}
 		}
@@ -182,16 +182,16 @@ namespace BansheeEngine
 		TGpuParamTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 		TGpuParamTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 
 
 		/** @copydoc TGpuDataParam::set */
 		/** @copydoc TGpuDataParam::set */
-		void set(const TextureType& texture);
+		void set(const TextureType& texture) const;
 
 
 		/** @copydoc TGpuDataParam::get */
 		/** @copydoc TGpuDataParam::get */
-		TextureType get();
+		TextureType get() const;
 
 
 		/** @copydoc TGpuDataParam::getDesc */
 		/** @copydoc TGpuDataParam::getDesc */
 		const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
 		const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
 
 
 		/** Checks if param is initialized. */
 		/** Checks if param is initialized. */
-		bool operator==(const nullptr_t &nullval) const
+		bool operator==(const nullptr_t& nullval) const
 		{
 		{
 			return mParamDesc == nullptr;
 			return mParamDesc == nullptr;
 		}
 		}
@@ -217,16 +217,16 @@ namespace BansheeEngine
 		TGpuParamLoadStoreTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 		TGpuParamLoadStoreTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 
 
 		/** @copydoc TGpuDataParam::set */
 		/** @copydoc TGpuDataParam::set */
-		void set(const TextureType& texture, const TextureSurface& surface);
+		void set(const TextureType& texture, const TextureSurface& surface) const;
 
 
 		/** @copydoc TGpuDataParam::get */
 		/** @copydoc TGpuDataParam::get */
-		TextureType get();
+		TextureType get() const;
 
 
 		/** @copydoc TGpuDataParam::getDesc */
 		/** @copydoc TGpuDataParam::getDesc */
 		const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
 		const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
 
 
 		/**	Checks if param is initialized. */
 		/**	Checks if param is initialized. */
-		bool operator==(const nullptr_t &nullval) const
+		bool operator==(const nullptr_t& nullval) const
 		{
 		{
 			return mParamDesc == nullptr;
 			return mParamDesc == nullptr;
 		}
 		}
@@ -252,16 +252,16 @@ namespace BansheeEngine
 		TGpuParamBuffer(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 		TGpuParamBuffer(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 
 
 		/** @copydoc TGpuDataParam::set */
 		/** @copydoc TGpuDataParam::set */
-		void set(const BufferType& texture);
+		void set(const BufferType& texture) const;
 
 
 		/** @copydoc TGpuDataParam::get */
 		/** @copydoc TGpuDataParam::get */
-		BufferType get();
+		BufferType get() const;
 
 
 		/** @copydoc TGpuDataParam::getDesc */
 		/** @copydoc TGpuDataParam::getDesc */
 		const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
 		const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
 
 
 		/** Checks if param is initialized. */
 		/** Checks if param is initialized. */
-		bool operator==(const nullptr_t &nullval) const
+		bool operator==(const nullptr_t& nullval) const
 		{
 		{
 			return mParamDesc == nullptr;
 			return mParamDesc == nullptr;
 		}
 		}
@@ -287,16 +287,16 @@ namespace BansheeEngine
 		TGpuParamSampState(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 		TGpuParamSampState(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 
 
 		/** @copydoc TGpuDataParam::set */
 		/** @copydoc TGpuDataParam::set */
-		void set(const SamplerStateType& samplerState);
+		void set(const SamplerStateType& samplerState) const;
 
 
 		/** @copydoc TGpuDataParam::get */
 		/** @copydoc TGpuDataParam::get */
-		SamplerStateType get();
+		SamplerStateType get() const;
 
 
 		/** @copydoc TGpuDataParam::getDesc */
 		/** @copydoc TGpuDataParam::getDesc */
 		const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
 		const GpuParamObjectDesc& getDesc() const { return *mParamDesc; }
 
 
 		/**	Checks if param is initialized. */
 		/**	Checks if param is initialized. */
-		bool operator==(const nullptr_t &nullval) const
+		bool operator==(const nullptr_t& nullval) const
 		{
 		{
 			return mParamDesc == nullptr;
 			return mParamDesc == nullptr;
 		}
 		}

+ 27 - 24
Source/BansheeCore/Include/BsMaterialParam.h

@@ -43,10 +43,10 @@ namespace BansheeEngine
 		TMaterialDataParam() { }
 		TMaterialDataParam() { }
 
 
 		/** @copydoc TGpuDataParam::set */
 		/** @copydoc TGpuDataParam::set */
-		void set(const T& value, UINT32 arrayIdx = 0);
+		void set(const T& value, UINT32 arrayIdx = 0) const;
 
 
 		/** @copydoc TGpuDataParam::get */
 		/** @copydoc TGpuDataParam::get */
-		T get(UINT32 arrayIdx = 0);
+		T get(UINT32 arrayIdx = 0) const;
 
 
 	protected:
 	protected:
 		UINT32 mParamIndex;
 		UINT32 mParamIndex;
@@ -64,10 +64,10 @@ namespace BansheeEngine
 		TMaterialDataParam() { }
 		TMaterialDataParam() { }
 
 
 		/** @copydoc TGpuDataParam::set */
 		/** @copydoc TGpuDataParam::set */
-		void set(const T& value, UINT32 arrayIdx = 0);
+		void set(const T& value, UINT32 arrayIdx = 0) const;
 
 
 		/** @copydoc TGpuDataParam::get */
 		/** @copydoc TGpuDataParam::get */
-		T get(UINT32 arrayIdx = 0);
+		T get(UINT32 arrayIdx = 0) const;
 
 
 	protected:
 	protected:
 		SPtr<Vector<TGpuDataParam<T, true>>> mParams;
 		SPtr<Vector<TGpuDataParam<T, true>>> mParams;
@@ -88,10 +88,10 @@ namespace BansheeEngine
 		TMaterialParamStruct() { }
 		TMaterialParamStruct() { }
 
 
 		/** @copydoc TGpuParamStruct::set */
 		/** @copydoc TGpuParamStruct::set */
-		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const;
 
 
 		/** @copydoc TGpuParamStruct::get */
 		/** @copydoc TGpuParamStruct::get */
-		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const;
 
 
 		/** @copydoc TGpuParamStruct::getElementSize */
 		/** @copydoc TGpuParamStruct::getElementSize */
 		UINT32 getElementSize() const;
 		UINT32 getElementSize() const;
@@ -112,10 +112,10 @@ namespace BansheeEngine
 		TMaterialParamStruct() { }
 		TMaterialParamStruct() { }
 
 
 		/** @copydoc TGpuParamStruct::set */
 		/** @copydoc TGpuParamStruct::set */
-		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const;
 
 
 		/** @copydoc TGpuParamStruct::get */
 		/** @copydoc TGpuParamStruct::get */
-		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const;
 
 
 		/** @copydoc TGpuParamStruct::getElementSize */
 		/** @copydoc TGpuParamStruct::getElementSize */
 		UINT32 getElementSize() const;
 		UINT32 getElementSize() const;
@@ -139,10 +139,10 @@ namespace BansheeEngine
 		TMaterialParamTexture() { }
 		TMaterialParamTexture() { }
 
 
 		/** @copydoc GpuParamTexture::set */
 		/** @copydoc GpuParamTexture::set */
-		void set(const HTexture& texture);
+		void set(const HTexture& texture) const;
 
 
 		/** @copydoc GpuParamTexture::get */
 		/** @copydoc GpuParamTexture::get */
-		HTexture get();
+		HTexture get() const;
 
 
 	protected:
 	protected:
 		UINT32 mParamIndex;
 		UINT32 mParamIndex;
@@ -159,10 +159,10 @@ namespace BansheeEngine
 		TMaterialParamTexture() { }
 		TMaterialParamTexture() { }
 
 
 		/** @copydoc GpuParamTexture::set */
 		/** @copydoc GpuParamTexture::set */
-		void set(const SPtr<TextureCore>& texture);
+		void set(const SPtr<TextureCore>& texture) const;
 
 
 		/** @copydoc GpuParamTexture::get */
 		/** @copydoc GpuParamTexture::get */
-		SPtr<TextureCore> get();
+		SPtr<TextureCore> get() const;
 
 
 	protected:
 	protected:
 		SPtr<Vector<TGpuParamTexture<true>>> mParams;
 		SPtr<Vector<TGpuParamTexture<true>>> mParams;
@@ -183,10 +183,10 @@ namespace BansheeEngine
 		TMaterialParamLoadStoreTexture() { }
 		TMaterialParamLoadStoreTexture() { }
 
 
 		/** @copydoc GpuParamLoadStoreTexture::set */
 		/** @copydoc GpuParamLoadStoreTexture::set */
-		void set(const HTexture& texture, const TextureSurface& surface);
+		void set(const HTexture& texture, const TextureSurface& surface) const;
 
 
 		/** @copydoc GpuParamLoadStoreTexture::get */
 		/** @copydoc GpuParamLoadStoreTexture::get */
-		HTexture get();
+		HTexture get() const;
 
 
 	protected:
 	protected:
 		UINT32 mParamIndex;
 		UINT32 mParamIndex;
@@ -204,10 +204,10 @@ namespace BansheeEngine
 		TMaterialParamLoadStoreTexture() { }
 		TMaterialParamLoadStoreTexture() { }
 
 
 		/** @copydoc GpuParamLoadStoreTexture::set */
 		/** @copydoc GpuParamLoadStoreTexture::set */
-		void set(const SPtr<TextureCore>& texture, const TextureSurface& surface = TextureSurface());
+		void set(const SPtr<TextureCore>& texture, const TextureSurface& surface = TextureSurface()) const;
 
 
 		/** @copydoc GpuParamLoadStoreTexture::get */
 		/** @copydoc GpuParamLoadStoreTexture::get */
-		SPtr<TextureCore> get();
+		SPtr<TextureCore> get() const;
 
 
 	protected:
 	protected:
 		SPtr<Vector<TGpuParamLoadStoreTexture<true>>> mParams;
 		SPtr<Vector<TGpuParamLoadStoreTexture<true>>> mParams;
@@ -228,10 +228,10 @@ namespace BansheeEngine
 		TMaterialParamBuffer() { }
 		TMaterialParamBuffer() { }
 
 
 		/** @copydoc GpuParamBuffer::set */
 		/** @copydoc GpuParamBuffer::set */
-		void set(const SPtr<GpuBuffer>& buffer);
+		void set(const SPtr<GpuBuffer>& buffer) const;
 
 
 		/** @copydoc GpuParamBuffer::get */
 		/** @copydoc GpuParamBuffer::get */
-		SPtr<GpuBuffer> get();
+		SPtr<GpuBuffer> get() const;
 
 
 	protected:
 	protected:
 		UINT32 mParamIndex;
 		UINT32 mParamIndex;
@@ -248,10 +248,10 @@ namespace BansheeEngine
 		TMaterialParamBuffer() { }
 		TMaterialParamBuffer() { }
 
 
 		/** @copydoc GpuParamBuffer::set */
 		/** @copydoc GpuParamBuffer::set */
-		void set(const SPtr<GpuBufferCore>& buffer);
+		void set(const SPtr<GpuBufferCore>& buffer) const;
 
 
 		/** @copydoc GpuParamBuffer::get */
 		/** @copydoc GpuParamBuffer::get */
-		SPtr<GpuBufferCore> get();
+		SPtr<GpuBufferCore> get() const;
 
 
 	protected:
 	protected:
 		SPtr<Vector<TGpuParamBuffer<true>>> mParams;
 		SPtr<Vector<TGpuParamBuffer<true>>> mParams;
@@ -272,10 +272,10 @@ namespace BansheeEngine
 		TMaterialParamSampState() { }
 		TMaterialParamSampState() { }
 
 
 		/** @copydoc GpuParamSampState::set */
 		/** @copydoc GpuParamSampState::set */
-		void set(const SPtr<SamplerState>& sampState);
+		void set(const SPtr<SamplerState>& sampState) const;
 
 
 		/** @copydoc GpuParamSampState::get */
 		/** @copydoc GpuParamSampState::get */
-		SPtr<SamplerState> get();
+		SPtr<SamplerState> get() const;
 
 
 	protected:
 	protected:
 		UINT32 mParamIndex;
 		UINT32 mParamIndex;
@@ -292,10 +292,10 @@ namespace BansheeEngine
 		TMaterialParamSampState() { }
 		TMaterialParamSampState() { }
 
 
 		/** @copydoc GpuParamSampState::set */
 		/** @copydoc GpuParamSampState::set */
-		void set(const SPtr<SamplerStateCore>& sampState);
+		void set(const SPtr<SamplerStateCore>& sampState) const;
 
 
 		/** @copydoc GpuParamSampState::get */
 		/** @copydoc GpuParamSampState::get */
-		SPtr<SamplerStateCore> get();
+		SPtr<SamplerStateCore> get() const;
 
 
 	protected:
 	protected:
 		SPtr<Vector<TGpuParamSampState<true>>> mParams;
 		SPtr<Vector<TGpuParamSampState<true>>> mParams;
@@ -340,6 +340,9 @@ namespace BansheeEngine
 	typedef TMaterialParamLoadStoreTexture<false> MaterialParamLoadStoreTexture;
 	typedef TMaterialParamLoadStoreTexture<false> MaterialParamLoadStoreTexture;
 	typedef TMaterialParamLoadStoreTexture<true> MaterialParamLoadStoreTextureCore;
 	typedef TMaterialParamLoadStoreTexture<true> MaterialParamLoadStoreTextureCore;
 
 
+	typedef TMaterialParamBuffer<false> MaterialParamBuffer;
+	typedef TMaterialParamBuffer<true> MaterialParamBufferCore;
+
 	typedef TMaterialParamSampState<false> MaterialParamSampState;
 	typedef TMaterialParamSampState<false> MaterialParamSampState;
 	typedef TMaterialParamSampState<true> MaterialParamSampStateCore;
 	typedef TMaterialParamSampState<true> MaterialParamSampStateCore;
 
 

+ 12 - 12
Source/BansheeCore/Source/BsGpuParam.cpp

@@ -22,7 +22,7 @@ namespace BansheeEngine
 	{ }
 	{ }
 
 
 	template<class T, bool Core>
 	template<class T, bool Core>
-	void TGpuDataParam<T, Core>::set(const T& value, UINT32 arrayIdx)
+	void TGpuDataParam<T, Core>::set(const T& value, UINT32 arrayIdx) const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return;
 			return;
@@ -61,7 +61,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	template<class T, bool Core>
 	template<class T, bool Core>
-	T TGpuDataParam<T, Core>::get(UINT32 arrayIdx)
+	T TGpuDataParam<T, Core>::get(UINT32 arrayIdx) const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return T();
 			return T();
@@ -101,7 +101,7 @@ namespace BansheeEngine
 	{ }
 	{ }
 
 
 	template<bool Core>
 	template<bool Core>
-	void TGpuParamStruct<Core>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	void TGpuParamStruct<Core>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return;
 			return;
@@ -141,7 +141,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
-	void TGpuParamStruct<Core>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	void TGpuParamStruct<Core>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return;
 			return;
@@ -190,7 +190,7 @@ namespace BansheeEngine
 	{ }
 	{ }
 
 
 	template<bool Core>
 	template<bool Core>
-	void TGpuParamTexture<Core>::set(const TextureType& texture)
+	void TGpuParamTexture<Core>::set(const TextureType& texture) const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return;
 			return;
@@ -202,7 +202,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
-	typename TGpuParamTexture<Core>::TextureType TGpuParamTexture<Core>::get()
+	typename TGpuParamTexture<Core>::TextureType TGpuParamTexture<Core>::get() const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return TextureType();
 			return TextureType();
@@ -221,7 +221,7 @@ namespace BansheeEngine
 	{ }
 	{ }
 
 
 	template<bool Core>
 	template<bool Core>
-	void TGpuParamBuffer<Core>::set(const BufferType& texture)
+	void TGpuParamBuffer<Core>::set(const BufferType& texture) const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return;
 			return;
@@ -233,7 +233,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
-	typename TGpuParamBuffer<Core>::BufferType TGpuParamBuffer<Core>::get()
+	typename TGpuParamBuffer<Core>::BufferType TGpuParamBuffer<Core>::get() const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return BufferType();
 			return BufferType();
@@ -252,7 +252,7 @@ namespace BansheeEngine
 	{ }
 	{ }
 
 
 	template<bool Core>
 	template<bool Core>
-	void TGpuParamLoadStoreTexture<Core>::set(const TextureType& texture, const TextureSurface& surface)
+	void TGpuParamLoadStoreTexture<Core>::set(const TextureType& texture, const TextureSurface& surface) const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return;
 			return;
@@ -264,7 +264,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
-	typename TGpuParamLoadStoreTexture<Core>::TextureType TGpuParamLoadStoreTexture<Core>::get()
+	typename TGpuParamLoadStoreTexture<Core>::TextureType TGpuParamLoadStoreTexture<Core>::get() const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return TextureType();
 			return TextureType();
@@ -283,7 +283,7 @@ namespace BansheeEngine
 	{ }
 	{ }
 
 
 	template<bool Core>
 	template<bool Core>
-	void TGpuParamSampState<Core>::set(const SamplerStateType& samplerState)
+	void TGpuParamSampState<Core>::set(const SamplerStateType& samplerState) const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return;
 			return;
@@ -295,7 +295,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
-	typename TGpuParamSampState<Core>::SamplerStateType TGpuParamSampState<Core>::get()
+	typename TGpuParamSampState<Core>::SamplerStateType TGpuParamSampState<Core>::get() const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return SamplerStateType();
 			return SamplerStateType();

+ 24 - 24
Source/BansheeCore/Source/BsMaterialParam.cpp

@@ -30,7 +30,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	template<class T>
 	template<class T>
-	void TMaterialDataParam<T, false>::set(const T& value, UINT32 arrayIdx)
+	void TMaterialDataParam<T, false>::set(const T& value, UINT32 arrayIdx) const
 	{
 	{
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
 			return;
 			return;
@@ -52,7 +52,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	template<class T>
 	template<class T>
-	T TMaterialDataParam<T, false>::get(UINT32 arrayIdx)
+	T TMaterialDataParam<T, false>::get(UINT32 arrayIdx) const
 	{
 	{
 		T output = T();
 		T output = T();
 		if (mMaterialParams == nullptr || arrayIdx >= mArraySize)
 		if (mMaterialParams == nullptr || arrayIdx >= mArraySize)
@@ -68,7 +68,7 @@ namespace BansheeEngine
 	{ }
 	{ }
 
 
 	template<class T>
 	template<class T>
-	void TMaterialDataParam<T, true>::set(const T& value, UINT32 arrayIdx)
+	void TMaterialDataParam<T, true>::set(const T& value, UINT32 arrayIdx) const
 	{
 	{
 		if (mParams == nullptr)
 		if (mParams == nullptr)
 			return;
 			return;
@@ -78,7 +78,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	template<class T>
 	template<class T>
-	T TMaterialDataParam<T, true>::get(UINT32 arrayIdx)
+	T TMaterialDataParam<T, true>::get(UINT32 arrayIdx) const
 	{
 	{
 		if (mParams == nullptr || mParams->size() == 0)
 		if (mParams == nullptr || mParams->size() == 0)
 			return T();
 			return T();
@@ -106,7 +106,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void TMaterialParamStruct<false>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	void TMaterialParamStruct<false>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
 	{
 	{
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
 			return;
 			return;
@@ -127,7 +127,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void TMaterialParamStruct<false>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	void TMaterialParamStruct<false>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
 	{
 	{
 		if (mMaterialParams == nullptr || arrayIdx >= mArraySize)
 		if (mMaterialParams == nullptr || arrayIdx >= mArraySize)
 			return;
 			return;
@@ -144,7 +144,7 @@ namespace BansheeEngine
 		:mParams(params)
 		:mParams(params)
 	{ }
 	{ }
 
 
-	void TMaterialParamStruct<true>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	void TMaterialParamStruct<true>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
 	{
 	{
 		if (mParams == nullptr)
 		if (mParams == nullptr)
 			return;
 			return;
@@ -153,7 +153,7 @@ namespace BansheeEngine
 			param.set(value, sizeBytes, arrayIdx);
 			param.set(value, sizeBytes, arrayIdx);
 	}
 	}
 
 
-	void TMaterialParamStruct<true>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	void TMaterialParamStruct<true>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
 	{
 	{
 		if (mParams == nullptr || mParams->size() == 0)
 		if (mParams == nullptr || mParams->size() == 0)
 		{
 		{
@@ -191,7 +191,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void TMaterialParamTexture<false>::set(const HTexture& texture)
+	void TMaterialParamTexture<false>::set(const HTexture& texture) const
 	{
 	{
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
 			return;
 			return;
@@ -210,7 +210,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	HTexture TMaterialParamTexture<false>::get()
+	HTexture TMaterialParamTexture<false>::get() const
 	{
 	{
 		HTexture texture;
 		HTexture texture;
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
@@ -225,7 +225,7 @@ namespace BansheeEngine
 		:mParams(params)
 		:mParams(params)
 	{ }
 	{ }
 
 
-	void TMaterialParamTexture<true>::set(const SPtr<TextureCore>& texture)
+	void TMaterialParamTexture<true>::set(const SPtr<TextureCore>& texture) const
 	{
 	{
 		if (mParams == nullptr)
 		if (mParams == nullptr)
 			return;
 			return;
@@ -234,7 +234,7 @@ namespace BansheeEngine
 			param.set(texture);
 			param.set(texture);
 	}
 	}
 
 
-	SPtr<TextureCore> TMaterialParamTexture<true>::get()
+	SPtr<TextureCore> TMaterialParamTexture<true>::get() const
 	{
 	{
 		if (mParams == nullptr || mParams->size() == 0)
 		if (mParams == nullptr || mParams->size() == 0)
 			return SPtr<TextureCore>();
 			return SPtr<TextureCore>();
@@ -261,7 +261,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void TMaterialParamLoadStoreTexture<false>::set(const HTexture& texture, const TextureSurface& surface)
+	void TMaterialParamLoadStoreTexture<false>::set(const HTexture& texture, const TextureSurface& surface) const
 	{
 	{
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
 			return;
 			return;
@@ -275,7 +275,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	HTexture TMaterialParamLoadStoreTexture<false>::get()
+	HTexture TMaterialParamLoadStoreTexture<false>::get() const
 	{
 	{
 		HTexture texture;
 		HTexture texture;
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
@@ -291,7 +291,7 @@ namespace BansheeEngine
 		:mParams(params)
 		:mParams(params)
 	{ }
 	{ }
 
 
-	void TMaterialParamLoadStoreTexture<true>::set(const SPtr<TextureCore>& texture, const TextureSurface& surface)
+	void TMaterialParamLoadStoreTexture<true>::set(const SPtr<TextureCore>& texture, const TextureSurface& surface) const
 	{
 	{
 		if (mParams == nullptr)
 		if (mParams == nullptr)
 			return;
 			return;
@@ -300,7 +300,7 @@ namespace BansheeEngine
 			param.set(texture, surface);
 			param.set(texture, surface);
 	}
 	}
 
 
-	SPtr<TextureCore> TMaterialParamLoadStoreTexture<true>::get()
+	SPtr<TextureCore> TMaterialParamLoadStoreTexture<true>::get() const
 	{
 	{
 		if (mParams == nullptr || mParams->size() == 0)
 		if (mParams == nullptr || mParams->size() == 0)
 			return SPtr<TextureCore>();
 			return SPtr<TextureCore>();
@@ -327,7 +327,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void TMaterialParamBuffer<false>::set(const SPtr<GpuBuffer>& buffer)
+	void TMaterialParamBuffer<false>::set(const SPtr<GpuBuffer>& buffer) const
 	{
 	{
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
 			return;
 			return;
@@ -341,7 +341,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	SPtr<GpuBuffer> TMaterialParamBuffer<false>::get()
+	SPtr<GpuBuffer> TMaterialParamBuffer<false>::get() const
 	{
 	{
 		SPtr<GpuBuffer> buffer;
 		SPtr<GpuBuffer> buffer;
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
@@ -356,7 +356,7 @@ namespace BansheeEngine
 		:mParams(params)
 		:mParams(params)
 	{ }
 	{ }
 
 
-	void TMaterialParamBuffer<true>::set(const SPtr<GpuBufferCore>& buffer)
+	void TMaterialParamBuffer<true>::set(const SPtr<GpuBufferCore>& buffer) const
 	{
 	{
 		if (mParams == nullptr)
 		if (mParams == nullptr)
 			return;
 			return;
@@ -365,7 +365,7 @@ namespace BansheeEngine
 			param.set(buffer);
 			param.set(buffer);
 	}
 	}
 
 
-	SPtr<GpuBufferCore> TMaterialParamBuffer<true>::get()
+	SPtr<GpuBufferCore> TMaterialParamBuffer<true>::get() const
 	{
 	{
 		if (mParams == nullptr || mParams->size() == 0)
 		if (mParams == nullptr || mParams->size() == 0)
 			return SPtr<GpuBufferCore>();
 			return SPtr<GpuBufferCore>();
@@ -392,7 +392,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void TMaterialParamSampState<false>::set(const SPtr<SamplerState>& sampState)
+	void TMaterialParamSampState<false>::set(const SPtr<SamplerState>& sampState) const
 	{
 	{
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
 			return;
 			return;
@@ -411,7 +411,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	SPtr<SamplerState> TMaterialParamSampState<false>::get()
+	SPtr<SamplerState> TMaterialParamSampState<false>::get() const
 	{
 	{
 		SPtr<SamplerState> samplerState;
 		SPtr<SamplerState> samplerState;
 		if (mMaterialParams == nullptr)
 		if (mMaterialParams == nullptr)
@@ -425,7 +425,7 @@ namespace BansheeEngine
 		:mParams(params)
 		:mParams(params)
 	{ }
 	{ }
 
 
-	void TMaterialParamSampState<true>::set(const SPtr<SamplerStateCore>& sampState)
+	void TMaterialParamSampState<true>::set(const SPtr<SamplerStateCore>& sampState) const
 	{
 	{
 		if (mParams == nullptr)
 		if (mParams == nullptr)
 			return;
 			return;
@@ -434,7 +434,7 @@ namespace BansheeEngine
 			param.set(sampState);
 			param.set(sampState);
 	}
 	}
 
 
-	SPtr<SamplerStateCore> TMaterialParamSampState<true>::get()
+	SPtr<SamplerStateCore> TMaterialParamSampState<true>::get() const
 	{
 	{
 		if (mParams == nullptr || mParams->size() == 0)
 		if (mParams == nullptr || mParams->size() == 0)
 			return SPtr<SamplerStateCore>();
 			return SPtr<SamplerStateCore>();

+ 6 - 4
Source/RenderBeast/Include/BsObjectRendering.h

@@ -8,6 +8,7 @@
 #include "BsRenderableElement.h"
 #include "BsRenderableElement.h"
 #include "BsRendererMaterial.h"
 #include "BsRendererMaterial.h"
 #include "BsParamBlocks.h"
 #include "BsParamBlocks.h"
+#include "BsRendererObject.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -73,21 +74,22 @@ namespace BansheeEngine
 		ObjectRenderer();
 		ObjectRenderer();
 
 
 		/** Initializes the specified renderable element, making it ready to be used. */
 		/** Initializes the specified renderable element, making it ready to be used. */
-		void initElement(RenderableElement& element);
+		void initElement(BeastRenderableElement& element);
 
 
 		/** Updates global per frame parameter buffers with new values. To be called at the start of every frame. */
 		/** Updates global per frame parameter buffers with new values. To be called at the start of every frame. */
-		void updatePerFrameBuffers(float time);
+		void setParamFrameParams(float time);
 
 
 		/**
 		/**
 		 * Updates global per frame parameter buffers with new values. To be called at the start of rendering for every 
 		 * Updates global per frame parameter buffers with new values. To be called at the start of rendering for every 
 		 * camera.
 		 * camera.
 		 */
 		 */
-		void updatePerCameraBuffers(const CameraShaderData& cameraData);
+		void setPerCameraParams(const CameraShaderData& cameraData);
 
 
 		/**
 		/**
 		 * Updates object specific parameter buffers with new values. To be called whenever object specific values change.
 		 * Updates object specific parameter buffers with new values. To be called whenever object specific values change.
 		 */
 		 */
-		void updatePerObjectBuffers(const RenderableElement& element, const RenderableShaderData& data, const Matrix4& wvpMatrix);
+		void setPerObjectParams(const BeastRenderableElement& element, const RenderableShaderData& data,
+			const Matrix4& wvpMatrix, const SPtr<GpuBufferCore>& boneMatrices = nullptr);
 
 
 		/** Returns a buffer that stores per-camera parameters. */
 		/** Returns a buffer that stores per-camera parameters. */
 		const PerCameraParamBuffer& getPerCameraParams() const { return mPerCameraParams; }
 		const PerCameraParamBuffer& getPerCameraParams() const { return mPerCameraParams; }

+ 30 - 16
Source/RenderBeast/Include/BsRenderBeast.h

@@ -19,10 +19,13 @@ namespace BansheeEngine
 	 *  @{
 	 *  @{
 	 */
 	 */
 
 
+	struct RendererAnimationData;
+
 	/** Semantics that may be used for signaling the renderer for what is a certain shader parameter used for. */
 	/** Semantics that may be used for signaling the renderer for what is a certain shader parameter used for. */
 	static StringID RPS_GBufferA = "GBufferA";
 	static StringID RPS_GBufferA = "GBufferA";
 	static StringID RPS_GBufferB = "GBufferB";
 	static StringID RPS_GBufferB = "GBufferB";
 	static StringID RPS_GBufferDepth = "GBufferDepth";
 	static StringID RPS_GBufferDepth = "GBufferDepth";
+	static StringID RPS_BoneMatrices = "BoneMatrices";
 
 
 	/**
 	/**
 	 * Default renderer for Banshee. Performs frustum culling, sorting and renders objects in custom ways determine by
 	 * Default renderer for Banshee. Performs frustum culling, sorting and renders objects in custom ways determine by
@@ -32,15 +35,24 @@ namespace BansheeEngine
 	 */
 	 */
 	class RenderBeast : public Renderer
 	class RenderBeast : public Renderer
 	{
 	{
-		/**	Render data for a single render target. */
-		struct RenderTargetData
+		/** Renderer information specific to a single frame. */
+		struct RendererFrame
+		{
+			RendererFrame(float delta, const RendererAnimationData& animData);
+
+			float delta;
+			const RendererAnimationData& animData;
+		};
+
+		/**	Renderer information specific to a single render target. */
+		struct RendererRenderTarget
 		{
 		{
 			SPtr<RenderTargetCore> target;
 			SPtr<RenderTargetCore> target;
 			Vector<const CameraCore*> cameras;
 			Vector<const CameraCore*> cameras;
 		};
 		};
 
 
-		/**	Data used by the renderer for lights. */
-		struct LightData
+		/**	Renderer information specific to a single light. */
+		struct RendererLight
 		{
 		{
 			LightCore* internal;
 			LightCore* internal;
 		};
 		};
@@ -124,24 +136,24 @@ namespace BansheeEngine
 		/**
 		/**
 		 * Renders all objects visible by the provided camera.
 		 * Renders all objects visible by the provided camera.
 		 *
 		 *
-		 * @param[in]	rtData	Render target data containing the camera to render.
-		 * @param[in]	camIdx	Index of the camera to render.
-		 * @param[in]	delta	Time elapsed since the last frame.
+		 * @param[in]	frameInfo	Renderer information specific to this frame.
+		 * @param[in]	rtInfo		Render target information containing the camera to render.
+		 * @param[in]	camIdx		Index of the camera to render.
 		 * 					
 		 * 					
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		void render(RenderTargetData& rtData, UINT32 camIdx, float delta);
+		void render(const RendererFrame& frameInfo, RendererRenderTarget& rtInfo, UINT32 camIdx);
 
 
 		/**
 		/**
 		 * Renders all overlay callbacks attached to the provided camera.
 		 * Renders all overlay callbacks attached to the provided camera.
 		 *
 		 *
-		 * @param[in]	rtData	Render target data containing the camera to render.
-		 * @param[in]	camIdx	Index of the camera to render.
-		 * @param[in]	delta	Time elapsed since the last frame.
+		 * @param[in]	frameInfo	Renderer information specific to this frame.
+		 * @param[in]	rtInfo		Render target information containing the camera to render.
+		 * @param[in]	camIdx		Index of the camera to render.
 		 * 					
 		 * 					
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		void renderOverlay(RenderTargetData& rtData, UINT32 camIdx, float delta);
+		void renderOverlay(const RendererFrame& frameInfo, RendererRenderTarget& rtInfo, UINT32 camIdx);
 
 
 		/** 
 		/** 
 		 * Renders a single element of a renderable object. 
 		 * Renders a single element of a renderable object. 
@@ -150,9 +162,11 @@ namespace BansheeEngine
 		 * @param[in]	passIdx		Index of the material pass to render the element with.
 		 * @param[in]	passIdx		Index of the material pass to render the element with.
 		 * @param[in]	bindPass	If true the material pass will be bound for rendering, if false it is assumed it is
 		 * @param[in]	bindPass	If true the material pass will be bound for rendering, if false it is assumed it is
 		 *							already bound.
 		 *							already bound.
+		 * @param[in]	frameInfo	Renderer information specific to this frame.
 		 * @param[in]	viewProj	View projection matrix of the camera the element is being rendered with.
 		 * @param[in]	viewProj	View projection matrix of the camera the element is being rendered with.
 		 */
 		 */
-		void renderElement(const BeastRenderableElement& element, UINT32 passIdx, bool bindPass, const Matrix4& viewProj);
+		void renderElement(const BeastRenderableElement& element, UINT32 passIdx, bool bindPass, 
+			const RendererFrame& frameInfo, const Matrix4& viewProj);
 
 
 		/**	Creates data used by the renderer on the core thread. */
 		/**	Creates data used by the renderer on the core thread. */
 		void initializeCore();
 		void initializeCore();
@@ -180,7 +194,7 @@ namespace BansheeEngine
 		static void setPassParams(const SPtr<PassParametersCore>& passParams, const PassSamplerOverrides* samplerOverrides);
 		static void setPassParams(const SPtr<PassParametersCore>& passParams, const PassSamplerOverrides* samplerOverrides);
 
 
 		// Core thread only fields
 		// Core thread only fields
-		Vector<RenderTargetData> mRenderTargets;
+		Vector<RendererRenderTarget> mRenderTargets;
 		UnorderedMap<const CameraCore*, RendererCamera> mCameras;
 		UnorderedMap<const CameraCore*, RendererCamera> mCameras;
 		UnorderedMap<SPtr<MaterialCore>, MaterialSamplerOverrides*> mSamplerOverrides;
 		UnorderedMap<SPtr<MaterialCore>, MaterialSamplerOverrides*> mSamplerOverrides;
 
 
@@ -188,8 +202,8 @@ namespace BansheeEngine
 		Vector<RenderableShaderData> mRenderableShaderData;
 		Vector<RenderableShaderData> mRenderableShaderData;
 		Vector<Bounds> mWorldBounds;
 		Vector<Bounds> mWorldBounds;
 
 
-		Vector<LightData> mDirectionalLights;
-		Vector<LightData> mPointLights;
+		Vector<RendererLight> mDirectionalLights;
+		Vector<RendererLight> mPointLights;
 		Vector<Sphere> mLightWorldBounds;
 		Vector<Sphere> mLightWorldBounds;
 
 
 		SPtr<RenderBeastOptions> mCoreOptions;
 		SPtr<RenderBeastOptions> mCoreOptions;

+ 8 - 0
Source/RenderBeast/Include/BsRendererObject.h

@@ -29,6 +29,14 @@ namespace BansheeEngine
 
 
 		/**	Identifier of the owner renderable. */
 		/**	Identifier of the owner renderable. */
 		UINT32 renderableId;
 		UINT32 renderableId;
+
+		/** Identifier of the animation running on the renderable's mesh. -1 if no animation. */
+		UINT64 animationId;
+
+		/** 
+		 * Parameter for setting global bone pose transforms used for an element with skeletal animation, null otherwise. 
+		 */
+		MaterialParamBufferCore boneMatricesParam;
 	};
 	};
 
 
 	 /** Contains information about a Renderable, used by the Renderer. */
 	 /** Contains information about a Renderable, used by the Renderer. */

+ 23 - 65
Source/RenderBeast/Source/BsObjectRendering.cpp

@@ -11,7 +11,7 @@ namespace BansheeEngine
 	ObjectRenderer::ObjectRenderer()
 	ObjectRenderer::ObjectRenderer()
 	{ }
 	{ }
 
 
-	void ObjectRenderer::initElement(RenderableElement& element)
+	void ObjectRenderer::initElement(BeastRenderableElement& element)
 	{
 	{
 		SPtr<ShaderCore> shader = element.material->getShader();
 		SPtr<ShaderCore> shader = element.material->getShader();
 		if (shader == nullptr)
 		if (shader == nullptr)
@@ -35,76 +35,31 @@ namespace BansheeEngine
 				perObjectBlockName = paramBlockDesc.second.name;
 				perObjectBlockName = paramBlockDesc.second.name;
 		}
 		}
 
 
-		UINT32 numPasses = element.material->getNumPasses();
-		for (UINT32 i = 0; i < numPasses; i++)
-		{
-			SPtr<PassParametersCore> passParams = element.material->getPassParameters(i);
-
-			for (UINT32 j = 0; j < PassParametersCore::NUM_PARAMS; j++)
-			{
-				SPtr<GpuParamsCore> gpuParams = passParams->getParamByIdx(j);
-				if (gpuParams == nullptr)
-					continue;
-
-				const GpuParamDesc& paramsDesc = gpuParams->getParamDesc();
-
-				// Note: We only validate buffer size and not buffer contents. We should check the contents as well, but
-				// likely on a higher level rather than here.
-				
-				if (perFrameBlockName != "")
-				{
-					auto findIter = paramsDesc.paramBlocks.find(perFrameBlockName);
-					if (findIter != paramsDesc.paramBlocks.end())
-					{
-						if (findIter->second.blockSize == mPerFrameParams.getDesc().blockSize)
-						{
-							SPtr<GpuParamsCore> params = element.material->getPassParameters(i)->getParamByIdx(j);
-
-							UINT32 slotIdx = findIter->second.slot;
-							params->setParamBlockBuffer(slotIdx, mPerFrameParams.getBuffer());
-						}
-					}
-				}
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& bufferDescs = shader->getBufferParams();
+		String boneMatricesParamName;
 
 
-				if (perCameraBlockName != "")
-				{
-					auto findIter = paramsDesc.paramBlocks.find(perCameraBlockName);
-					if (findIter != paramsDesc.paramBlocks.end())
-					{
-						if (findIter->second.blockSize == mPerCameraParams.getDesc().blockSize)
-						{
-							SPtr<GpuParamsCore> params = element.material->getPassParameters(i)->getParamByIdx(j);
-
-							UINT32 slotIdx = findIter->second.slot;
-							params->setParamBlockBuffer(slotIdx, mPerCameraParams.getBuffer());
-						}
-					}
-				}
-
-				if (perObjectBlockName != "")
-				{
-					auto findIter = paramsDesc.paramBlocks.find(perObjectBlockName);
-					if (findIter != paramsDesc.paramBlocks.end())
-					{
-						if (findIter->second.blockSize == mPerObjectParams.getDesc().blockSize)
-						{
-							SPtr<GpuParamsCore> params = element.material->getPassParameters(i)->getParamByIdx(j);
-
-							UINT32 slotIdx = findIter->second.slot;
-							params->setParamBlockBuffer(slotIdx, mPerObjectParams.getBuffer());
-						}
-					}
-				}
-			}
+		for(auto& entry : bufferDescs)
+		{
+			if (entry.second.rendererSemantic == RPS_BoneMatrices)
+				boneMatricesParamName = entry.second.name;
 		}
 		}
+		
+		// Note: Perhaps perform buffer validation to ensure expected buffer has the same size and layout as the provided
+		// buffer, and show a warning otherwise. But this is perhaps better handled on a higher level.
+		element.material->setParamBlockBuffer(perFrameBlockName, mPerFrameParams.getBuffer());
+		element.material->setParamBlockBuffer(perCameraBlockName, mPerCameraParams.getBuffer());
+		element.material->setParamBlockBuffer(perObjectBlockName, mPerObjectParams.getBuffer());
+
+		if(!boneMatricesParamName.empty())
+			element.boneMatricesParam = element.material->getParamBuffer(boneMatricesParamName);
 	}
 	}
 
 
-	void ObjectRenderer::updatePerFrameBuffers(float time)
+	void ObjectRenderer::setParamFrameParams(float time)
 	{
 	{
 		mPerFrameParams.gTime.set(time);
 		mPerFrameParams.gTime.set(time);
 	}
 	}
 
 
-	void ObjectRenderer::updatePerCameraBuffers(const CameraShaderData& cameraData)
+	void ObjectRenderer::setPerCameraParams(const CameraShaderData& cameraData)
 	{
 	{
 		mPerCameraParams.gViewDir.set(cameraData.viewDir);
 		mPerCameraParams.gViewDir.set(cameraData.viewDir);
 		mPerCameraParams.gViewOrigin.set(cameraData.viewOrigin);
 		mPerCameraParams.gViewOrigin.set(cameraData.viewOrigin);
@@ -120,8 +75,8 @@ namespace BansheeEngine
 		mPerCameraParams.flushToGPU();
 		mPerCameraParams.flushToGPU();
 	}
 	}
 
 
-	void ObjectRenderer::updatePerObjectBuffers(const RenderableElement& element, const RenderableShaderData& data, 
-		const Matrix4& wvpMatrix)
+	void ObjectRenderer::setPerObjectParams(const BeastRenderableElement& element, const RenderableShaderData& data,
+		const Matrix4& wvpMatrix, const SPtr<GpuBufferCore>& boneMatrices)
 	{
 	{
 		// Note: If I kept all the values in the same structure maybe a simple memcpy directly into the constant buffer
 		// Note: If I kept all the values in the same structure maybe a simple memcpy directly into the constant buffer
 		// would be better (i.e. faster)?
 		// would be better (i.e. faster)?
@@ -131,6 +86,9 @@ namespace BansheeEngine
 		mPerObjectParams.gMatInvWorldNoScale.set(data.invWorldNoScaleTransform);
 		mPerObjectParams.gMatInvWorldNoScale.set(data.invWorldNoScaleTransform);
 		mPerObjectParams.gWorldDeterminantSign.set(data.worldDeterminantSign);
 		mPerObjectParams.gWorldDeterminantSign.set(data.worldDeterminantSign);
 		mPerObjectParams.gMatWorldViewProj.set(wvpMatrix);
 		mPerObjectParams.gMatWorldViewProj.set(wvpMatrix);
+
+		if(element.animationId != (UINT32)-1)
+			element.boneMatricesParam.set(boneMatrices);
 	}
 	}
 
 
 	void DefaultMaterial::_initDefines(ShaderDefines& defines)
 	void DefaultMaterial::_initDefines(ShaderDefines& defines)

+ 85 - 49
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -25,17 +25,21 @@
 #include "BsRenderTexturePool.h"
 #include "BsRenderTexturePool.h"
 #include "BsRenderTargets.h"
 #include "BsRenderTargets.h"
 #include "BsRendererUtility.h"
 #include "BsRendererUtility.h"
+#include "BsAnimationManager.h"
+#include "BsGpuBuffer.h"
 
 
 using namespace std::placeholders;
 using namespace std::placeholders;
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	RenderBeast::RendererFrame::RendererFrame(float delta, const RendererAnimationData& animData)
+		:delta(delta), animData(animData)
+	{ }
+
 	RenderBeast::RenderBeast()
 	RenderBeast::RenderBeast()
 		: mDefaultMaterial(nullptr), mPointLightInMat(nullptr), mPointLightOutMat(nullptr), mDirLightMat(nullptr)
 		: mDefaultMaterial(nullptr), mPointLightInMat(nullptr), mPointLightOutMat(nullptr), mDirLightMat(nullptr)
 		, mObjectRenderer(nullptr), mOptions(bs_shared_ptr_new<RenderBeastOptions>()), mOptionsDirty(true)
 		, mObjectRenderer(nullptr), mOptions(bs_shared_ptr_new<RenderBeastOptions>()), mOptionsDirty(true)
-	{
-
-	}
+	{ }
 
 
 	const StringID& RenderBeast::getName() const
 	const StringID& RenderBeast::getName() const
 	{
 	{
@@ -130,6 +134,7 @@ namespace BansheeEngine
 				renElement.mesh = mesh;
 				renElement.mesh = mesh;
 				renElement.subMesh = meshProps.getSubMesh(i);
 				renElement.subMesh = meshProps.getSubMesh(i);
 				renElement.renderableId = renderableId;
 				renElement.renderableId = renderableId;
+				renElement.animationId = renderable->getAnimationId();
 
 
 				renElement.material = renderable->getMaterial(i);
 				renElement.material = renderable->getMaterial(i);
 				if (renElement.material == nullptr)
 				if (renElement.material == nullptr)
@@ -250,9 +255,9 @@ namespace BansheeEngine
 			UINT32 lightId = (UINT32)mDirectionalLights.size();
 			UINT32 lightId = (UINT32)mDirectionalLights.size();
 			light->setRendererId(lightId);
 			light->setRendererId(lightId);
 
 
-			mDirectionalLights.push_back(LightData());
+			mDirectionalLights.push_back(RendererLight());
 
 
-			LightData& lightData = mDirectionalLights.back();
+			RendererLight& lightData = mDirectionalLights.back();
 			lightData.internal = light;
 			lightData.internal = light;
 		}
 		}
 		else
 		else
@@ -261,10 +266,10 @@ namespace BansheeEngine
 
 
 			light->setRendererId(lightId);
 			light->setRendererId(lightId);
 
 
-			mPointLights.push_back(LightData());
+			mPointLights.push_back(RendererLight());
 			mLightWorldBounds.push_back(light->getBounds());
 			mLightWorldBounds.push_back(light->getBounds());
 
 
-			LightData& lightData = mPointLights.back();
+			RendererLight& lightData = mPointLights.back();
 			lightData.internal = light;
 			lightData.internal = light;
 		}
 		}
 	}
 	}
@@ -355,7 +360,7 @@ namespace BansheeEngine
 		int rtChanged = 0; // 0 - No RT, 1 - RT found, 2 - RT changed
 		int rtChanged = 0; // 0 - No RT, 1 - RT found, 2 - RT changed
 		for (auto iterTarget = mRenderTargets.begin(); iterTarget != mRenderTargets.end(); ++iterTarget)
 		for (auto iterTarget = mRenderTargets.begin(); iterTarget != mRenderTargets.end(); ++iterTarget)
 		{
 		{
-			RenderTargetData& target = *iterTarget;
+			RendererRenderTarget& target = *iterTarget;
 			for (auto iterCam = target.cameras.begin(); iterCam != target.cameras.end(); ++iterCam)
 			for (auto iterCam = target.cameras.begin(); iterCam != target.cameras.end(); ++iterCam)
 			{
 			{
 				if (camera == *iterCam)
 				if (camera == *iterCam)
@@ -384,7 +389,7 @@ namespace BansheeEngine
 		if (renderTarget != nullptr && (rtChanged == 0 || rtChanged == 2))
 		if (renderTarget != nullptr && (rtChanged == 0 || rtChanged == 2))
 		{
 		{
 			auto findIter = std::find_if(mRenderTargets.begin(), mRenderTargets.end(),
 			auto findIter = std::find_if(mRenderTargets.begin(), mRenderTargets.end(),
-				[&](const RenderTargetData& x) { return x.target == renderTarget; });
+				[&](const RendererRenderTarget& x) { return x.target == renderTarget; });
 
 
 			if (findIter != mRenderTargets.end())
 			if (findIter != mRenderTargets.end())
 			{
 			{
@@ -392,8 +397,8 @@ namespace BansheeEngine
 			}
 			}
 			else
 			else
 			{
 			{
-				mRenderTargets.push_back(RenderTargetData());
-				RenderTargetData& renderTargetData = mRenderTargets.back();
+				mRenderTargets.push_back(RendererRenderTarget());
+				RendererRenderTarget& renderTargetData = mRenderTargets.back();
 
 
 				renderTargetData.target = renderTarget;
 				renderTargetData.target = renderTarget;
 				renderTargetData.cameras.push_back(camera);
 				renderTargetData.cameras.push_back(camera);
@@ -401,7 +406,7 @@ namespace BansheeEngine
 
 
 			// Sort render targets based on priority
 			// Sort render targets based on priority
 			auto cameraComparer = [&](const CameraCore* a, const CameraCore* b) { return a->getPriority() > b->getPriority(); };
 			auto cameraComparer = [&](const CameraCore* a, const CameraCore* b) { return a->getPriority() > b->getPriority(); };
-			auto renderTargetInfoComparer = [&](const RenderTargetData& a, const RenderTargetData& b)
+			auto renderTargetInfoComparer = [&](const RendererRenderTarget& a, const RendererRenderTarget& b)
 			{ return a.target->getProperties().getPriority() > b.target->getProperties().getPriority(); };
 			{ return a.target->getProperties().getPriority() > b.target->getProperties().getPriority(); };
 			std::sort(begin(mRenderTargets), end(mRenderTargets), renderTargetInfoComparer);
 			std::sort(begin(mRenderTargets), end(mRenderTargets), renderTargetInfoComparer);
 
 
@@ -469,17 +474,20 @@ namespace BansheeEngine
 		refreshSamplerOverrides();
 		refreshSamplerOverrides();
 
 
 		// Update global per-frame hardware buffers
 		// Update global per-frame hardware buffers
-		mObjectRenderer->updatePerFrameBuffers(time);
+		mObjectRenderer->setParamFrameParams(time);
 
 
 		// Generate render queues per camera
 		// Generate render queues per camera
 		for (auto& entry : mCameras)
 		for (auto& entry : mCameras)
 			entry.second.determineVisible(mRenderables, mWorldBounds);
 			entry.second.determineVisible(mRenderables, mWorldBounds);
 
 
+		const RendererAnimationData& animData = AnimationManager::instance().getRendererData();
+		RendererFrame frameInfo(delta, animData);
+
 		// Render everything, target by target
 		// Render everything, target by target
-		for (auto& renderTargetData : mRenderTargets)
+		for (auto& rtInfo : mRenderTargets)
 		{
 		{
-			SPtr<RenderTargetCore> target = renderTargetData.target;
-			Vector<const CameraCore*>& cameras = renderTargetData.cameras;
+			SPtr<RenderTargetCore> target = rtInfo.target;
+			Vector<const CameraCore*>& cameras = rtInfo.cameras;
 
 
 			RenderAPICore::instance().beginFrame();
 			RenderAPICore::instance().beginFrame();
 
 
@@ -488,9 +496,9 @@ namespace BansheeEngine
 			{
 			{
 				bool isOverlayCamera = cameras[i]->getFlags().isSet(CameraFlag::Overlay);
 				bool isOverlayCamera = cameras[i]->getFlags().isSet(CameraFlag::Overlay);
 				if (!isOverlayCamera)
 				if (!isOverlayCamera)
-					render(renderTargetData, i, delta);
+					render(frameInfo, rtInfo, i);
 				else
 				else
-					renderOverlay(renderTargetData, i, delta);
+					renderOverlay(frameInfo, rtInfo, i);
 			}
 			}
 
 
 			RenderAPICore::instance().endFrame();
 			RenderAPICore::instance().endFrame();
@@ -500,17 +508,17 @@ namespace BansheeEngine
 		gProfilerCPU().endSample("renderAllCore");
 		gProfilerCPU().endSample("renderAllCore");
 	}
 	}
 
 
-	void RenderBeast::render(RenderTargetData& rtData, UINT32 camIdx, float delta)
+	void RenderBeast::render(const RendererFrame& frameInfo, RendererRenderTarget& rtInfo, UINT32 camIdx)
 	{
 	{
 		gProfilerCPU().beginSample("Render");
 		gProfilerCPU().beginSample("Render");
 
 
-		const CameraCore* camera = rtData.cameras[camIdx];
+		const CameraCore* camera = rtInfo.cameras[camIdx];
 		RendererCamera& rendererCam = mCameras[camera];
 		RendererCamera& rendererCam = mCameras[camera];
 		CameraShaderData cameraShaderData = rendererCam.getShaderData();
 		CameraShaderData cameraShaderData = rendererCam.getShaderData();
 
 
 		assert(!camera->getFlags().isSet(CameraFlag::Overlay));
 		assert(!camera->getFlags().isSet(CameraFlag::Overlay));
 
 
-		mObjectRenderer->updatePerCameraBuffers(cameraShaderData);
+		mObjectRenderer->setPerCameraParams(cameraShaderData);
 		rendererCam.beginRendering(true);
 		rendererCam.beginRendering(true);
 
 
 		SPtr<RenderTargets> renderTargets = rendererCam.getRenderTargets();
 		SPtr<RenderTargets> renderTargets = rendererCam.getRenderTargets();
@@ -539,7 +547,7 @@ namespace BansheeEngine
 		for (auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
 		for (auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
 		{
 		{
 			BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
 			BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
-			renderElement(*renderElem, iter->passIdx, iter->applyPass, cameraShaderData.viewProj);
+			renderElement(*renderElem, iter->passIdx, iter->applyPass, frameInfo, cameraShaderData.viewProj);
 		}
 		}
 
 
 		renderTargets->bindSceneColor(true);
 		renderTargets->bindSceneColor(true);
@@ -610,7 +618,7 @@ namespace BansheeEngine
 		for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
 		for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
 		{
 		{
 			BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
 			BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
-			renderElement(*renderElem, iter->passIdx, iter->applyPass, cameraShaderData.viewProj);
+			renderElement(*renderElem, iter->passIdx, iter->applyPass, frameInfo, cameraShaderData.viewProj);
 		}
 		}
 
 
 		// Render non-overlay post-scene callbacks
 		// Render non-overlay post-scene callbacks
@@ -629,7 +637,7 @@ namespace BansheeEngine
 
 
 		// TODO - If GBuffer has multiple samples, I should resolve them before post-processing
 		// TODO - If GBuffer has multiple samples, I should resolve them before post-processing
 		PostProcessing::instance().postProcess(renderTargets->getSceneColorRT(),
 		PostProcessing::instance().postProcess(renderTargets->getSceneColorRT(),
-			camera, rendererCam.getPPInfo(), delta);
+			camera, rendererCam.getPPInfo(), frameInfo.delta);
 
 
 		// Render overlay post-scene callbacks
 		// Render overlay post-scene callbacks
 		if (iterCameraCallbacks != mRenderCallbacks.end())
 		if (iterCameraCallbacks != mRenderCallbacks.end())
@@ -650,30 +658,7 @@ namespace BansheeEngine
 		gProfilerCPU().endSample("Render");
 		gProfilerCPU().endSample("Render");
 	}
 	}
 
 
-	void RenderBeast::renderElement(const BeastRenderableElement& element, UINT32 passIdx, bool bindPass, 
-		const Matrix4& viewProj)
-	{
-		SPtr<MaterialCore> material = element.material;
-
-		UINT32 rendererId = element.renderableId;
-		Matrix4 worldViewProjMatrix = viewProj * mRenderableShaderData[rendererId].worldTransform;
-
-		mObjectRenderer->updatePerObjectBuffers(element, mRenderableShaderData[rendererId], worldViewProjMatrix);
-
-		if (bindPass)
-			RendererUtility::instance().setPass(material, passIdx, false);
-
-		SPtr<PassParametersCore> passParams = material->getPassParameters(passIdx);
-
-		if (element.samplerOverrides != nullptr)
-			setPassParams(passParams, &element.samplerOverrides->passes[passIdx]);
-		else
-			setPassParams(passParams, nullptr);
-
-		gRendererUtility().draw(element.mesh, element.subMesh);
-	}
-
-	void RenderBeast::renderOverlay(RenderTargetData& rtData, UINT32 camIdx, float delta)
+	void RenderBeast::renderOverlay(const RendererFrame& frameInfo, RendererRenderTarget& rtData, UINT32 camIdx)
 	{
 	{
 		gProfilerCPU().beginSample("RenderOverlay");
 		gProfilerCPU().beginSample("RenderOverlay");
 
 
@@ -684,7 +669,7 @@ namespace BansheeEngine
 		RendererCamera& rendererCam = mCameras[camera];
 		RendererCamera& rendererCam = mCameras[camera];
 		CameraShaderData cameraShaderData = rendererCam.getShaderData();
 		CameraShaderData cameraShaderData = rendererCam.getShaderData();
 
 
-		mObjectRenderer->updatePerCameraBuffers(cameraShaderData);
+		mObjectRenderer->setPerCameraParams(cameraShaderData);
 		rendererCam.beginRendering(false);
 		rendererCam.beginRendering(false);
 
 
 		SPtr<RenderTargetCore> target = rtData.target;
 		SPtr<RenderTargetCore> target = rtData.target;
@@ -732,6 +717,57 @@ namespace BansheeEngine
 		gProfilerCPU().endSample("RenderOverlay");
 		gProfilerCPU().endSample("RenderOverlay");
 	}
 	}
 	
 	
+	void RenderBeast::renderElement(const BeastRenderableElement& element, UINT32 passIdx, bool bindPass,
+		const RendererFrame& frameInfo, const Matrix4& viewProj)
+	{
+		SPtr<MaterialCore> material = element.material;
+
+		UINT32 rendererId = element.renderableId;
+		Matrix4 worldViewProjMatrix = viewProj * mRenderableShaderData[rendererId].worldTransform;
+
+		SPtr<GpuBufferCore> boneMatrices;
+		if(element.animationId != (UINT32)-1)
+		{
+			// Note: If multiple elements are using the same animation (not possible atm), this buffer should be created
+			// earlier and then shared by all elements
+
+			const RendererAnimationData& animData = frameInfo.animData;
+
+			auto iterFind = animData.poseInfos.find(element.animationId);
+			if(iterFind != animData.poseInfos.end())
+			{
+				const RendererAnimationData::PoseInfo& poseInfo = iterFind->second;
+
+				boneMatrices = GpuBufferCore::create(poseInfo.numBones * 3, 0, GBT_STANDARD, BF_32X4F, GBU_STATIC);
+				UINT8* dest = (UINT8*)boneMatrices->lock(0, poseInfo.numBones * 3 * sizeof(Vector4), GBL_WRITE_ONLY_DISCARD);
+
+				for(UINT32 i = 0; i < poseInfo.numBones; i++)
+				{
+					const Matrix4& transform = animData.transforms[poseInfo.startIdx + i];
+					memcpy(dest, &transform, 12 * sizeof(float)); // Assuming row-major format
+
+					dest += 12 * sizeof(float);
+				}
+
+				boneMatrices->unlock();
+			}
+		}
+
+		mObjectRenderer->setPerObjectParams(element, mRenderableShaderData[rendererId], worldViewProjMatrix, boneMatrices);
+
+		if (bindPass)
+			RendererUtility::instance().setPass(material, passIdx, false);
+
+		SPtr<PassParametersCore> passParams = material->getPassParameters(passIdx);
+
+		if (element.samplerOverrides != nullptr)
+			setPassParams(passParams, &element.samplerOverrides->passes[passIdx]);
+		else
+			setPassParams(passParams, nullptr);
+
+		gRendererUtility().draw(element.mesh, element.subMesh);
+	}
+
 	void RenderBeast::refreshSamplerOverrides(bool force)
 	void RenderBeast::refreshSamplerOverrides(bool force)
 	{
 	{
 		for (auto& entry : mSamplerOverrides)
 		for (auto& entry : mSamplerOverrides)