Parcourir la source

Renderer can now handle morph animation

BearishSun il y a 9 ans
Parent
commit
014bac08b8

+ 16 - 16
Data/Raw/Editor/Includes/SelectionBase.bslinc

@@ -33,14 +33,14 @@ Technique : base("SelectionBase") =
 };
 };
 
 
 Technique 
 Technique 
-#if USE_BLEND_SHAPES
-	#if USE_SKELETON
+#ifdef USE_BLEND_SHAPES
+	#ifdef USE_SKELETON
 	 : base("SelectionSkinnedMorph")
 	 : base("SelectionSkinnedMorph")
 	#else
 	#else
 	 : base("SelectionMorph")
 	 : base("SelectionMorph")
 	#endif
 	#endif
 #else
 #else
-	#if USE_SKELETON
+	#ifdef USE_SKELETON
 	 : base("SelectionSkinned")
 	 : base("SelectionSkinned")
 	#else
 	#else
 	 : base("Selection")
 	 : base("Selection")
@@ -56,12 +56,12 @@ Technique
 		{
 		{
 			float3 position : POSITION;
 			float3 position : POSITION;
 			
 			
-			#if USE_SKELETON
+			#ifdef USE_SKELETON
 				uint4 blendIndices : BLENDINDICES;
 				uint4 blendIndices : BLENDINDICES;
 				float4 blendWeights : BLENDWEIGHT;
 				float4 blendWeights : BLENDWEIGHT;
 			#endif
 			#endif
 			
 			
-			#if USE_BLEND_SHAPES
+			#ifdef USE_BLEND_SHAPES
 				float3 deltaPosition : POSITION1;
 				float3 deltaPosition : POSITION1;
 				float4 deltaNormal : NORMAL1;
 				float4 deltaNormal : NORMAL1;
 			#endif
 			#endif
@@ -69,7 +69,7 @@ Technique
 	
 	
 		float4x4 matWorldViewProj;
 		float4x4 matWorldViewProj;
 	
 	
-#if USE_SKELETON
+#ifdef USE_SKELETON
 		StructuredBuffer<float4> boneMatrices;
 		StructuredBuffer<float4> boneMatrices;
 		
 		
 		float3x4 getBoneMatrix(uint idx)
 		float3x4 getBoneMatrix(uint idx)
@@ -94,13 +94,13 @@ Technique
 		
 		
 		void main(VertexInput input, out float4 oPosition : SV_Position)
 		void main(VertexInput input, out float4 oPosition : SV_Position)
 		{
 		{
-#if USE_BLEND_SHAPES
+#ifdef USE_BLEND_SHAPES
 			float4 position = float4(input.position + input.deltaPosition, 1.0f);
 			float4 position = float4(input.position + input.deltaPosition, 1.0f);
 #else
 #else
 			float4 position = float4(input.position, 1.0f);
 			float4 position = float4(input.position, 1.0f);
 #endif
 #endif
 		
 		
-#if USE_SKELETON
+#ifdef USE_SKELETON
 			float3x4 blendMatrix = getBlendMatrix(input);
 			float3x4 blendMatrix = getBlendMatrix(input);
 			position = float4(mul(blendMatrix, position), 1.0f);
 			position = float4(mul(blendMatrix, position), 1.0f);
 #endif
 #endif
@@ -139,14 +139,14 @@ Technique : base("SelectionBase") =
 };
 };
 
 
 Technique
 Technique
-#if USE_BLEND_SHAPES
-	#if USE_SKELETON
+#ifdef USE_BLEND_SHAPES
+	#ifdef USE_SKELETON
 	 : base("SelectionSkinnedMorph")
 	 : base("SelectionSkinnedMorph")
 	#else
 	#else
 	 : base("SelectionMorph")
 	 : base("SelectionMorph")
 	#endif
 	#endif
 #else
 #else
-	#if USE_SKELETON
+	#ifdef USE_SKELETON
 	 : base("SelectionSkinned")
 	 : base("SelectionSkinned")
 	#else
 	#else
 	 : base("Selection")
 	 : base("Selection")
@@ -162,12 +162,12 @@ Technique
 
 
 		in vec3 bs_position;
 		in vec3 bs_position;
 	
 	
-		#if USE_SKELETON
+		#ifdef USE_SKELETON
 			in uvec4 bs_blendindices;
 			in uvec4 bs_blendindices;
 			in vec4 bs_blendweights;
 			in vec4 bs_blendweights;
 		#endif
 		#endif
 			
 			
-		#if USE_BLEND_SHAPES
+		#ifdef USE_BLEND_SHAPES
 			in vec3 bs_position1;
 			in vec3 bs_position1;
 			in vec4 bs_normal1;
 			in vec4 bs_normal1;
 		#endif
 		#endif
@@ -177,7 +177,7 @@ Technique
 			vec4 gl_Position;
 			vec4 gl_Position;
 		};
 		};
 		
 		
-#if USE_SKELETON
+#ifdef USE_SKELETON
 		uniform samplerBuffer boneMatrices;
 		uniform samplerBuffer boneMatrices;
 		
 		
 		void getBoneMatrix(uint idx, out mat4x3 result)
 		void getBoneMatrix(uint idx, out mat4x3 result)
@@ -211,13 +211,13 @@ Technique
 		
 		
 		void main()
 		void main()
 		{
 		{
-#if USE_BLEND_SHAPES
+#ifdef USE_BLEND_SHAPES
 			vec4 position = vec4(bs_position + bs_position1, 1.0f);
 			vec4 position = vec4(bs_position + bs_position1, 1.0f);
 #else
 #else
 			vec4 position = vec4(bs_position, 1.0f);
 			vec4 position = vec4(bs_position, 1.0f);
 #endif		
 #endif		
 		
 		
-#if USE_SKELETON
+#ifdef USE_SKELETON
 			mat3x4 blendMatrix;
 			mat3x4 blendMatrix;
 			getBlendMatrix(blendMatrix);
 			getBlendMatrix(blendMatrix);
 			
 			

+ 38 - 188
Data/Raw/Editor/Shaders/Selection.bsl

@@ -1,215 +1,65 @@
-Parameters =
+#include "$EDITOR$\SelectionBase.bslinc"
+
+#define USE_SKELETON
+#include "$EDITOR$\SelectionBase.bslinc"
+#undef USE_SKELETON
+
+#define USE_BLEND_SHAPES
+#include "$EDITOR$\SelectionBase.bslinc"
+
+#define USE_SKELETON
+#include "$EDITOR$\SelectionBase.bslinc"
+
+Technique 
+ : inherits("Selection") =
 {
 {
-	mat4x4			matWorldViewProj;
-	float4			selColor;
-	StructBuffer 	boneMatrices;
+	Language = "HLSL11";
 };
 };
 
 
-Technique : base("SelectionBase") =
+Technique 
+ : inherits("SelectionSkinned") =
 {
 {
 	Language = "HLSL11";
 	Language = "HLSL11";
-	
-	Pass =
-	{
-		Fill = WIRE;
-		DepthBias = 0.00001f;
-		
-		Target =
-		{
-			Blend = true;
-			Color = { SRCA, SRCIA, ADD };
-		};
-
-		Fragment =
-		{
-			float4 selColor;
-
-			float4 main(in float4 inPos : SV_Position) : SV_Target
-			{
-				return selColor;
-			}
-		};
-	};
+	Tags = { "Skinned" };
 };
 };
 
 
-Technique : inherits("SelectionBase") = 
+Technique 
+ : inherits("SelectionMorph") =
 {
 {
 	Language = "HLSL11";
 	Language = "HLSL11";
-
-	Vertex =
-	{
-		float4x4 matWorldViewProj;
-
-		void main(
-		in float3 inPos : POSITION,
-		out float4 oPosition : SV_Position)
-		{
-			oPosition = mul(matWorldViewProj, float4(inPos.xyz, 1));
-		}
-	};
+	Tags = { "Morph" };
 };
 };
 
 
-Technique : inherits("SelectionBase") = 
+Technique 
+ : inherits("SelectionSkinnedMorph") =
 {
 {
 	Language = "HLSL11";
 	Language = "HLSL11";
-	Tags = { "Skinned" };
-	
-	Vertex =
-	{
-		struct VertexInput
-		{
-			float3 position : POSITION;
-			uint4 blendIndices : BLENDINDICES;
-			float4 blendWeights : BLENDWEIGHT;
-			
-			#if USE_BLEND_SHAPES
-				float3 deltaPosition : POSITION1;
-				float4 deltaNormal : NORMAL1;
-			#endif
-		};	
-	
-		StructuredBuffer<float4> boneMatrices;
-		float4x4 matWorldViewProj;
-
-		float3x4 getBoneMatrix(uint idx)
-		{
-			float4 row0 = boneMatrices[idx * 3 + 0];
-			float4 row1 = boneMatrices[idx * 3 + 1];
-			float4 row2 = boneMatrices[idx * 3 + 2];
-			
-			return float3x4(row0, row1, row2);
-		}
-		
-		float3x4 getBlendMatrix(VertexInput input)
-		{
-			float3x4 result = input.blendWeights.x * getBoneMatrix(input.blendIndices.x);
-			result += input.blendWeights.y * getBoneMatrix(input.blendIndices.y);
-			result += input.blendWeights.z * getBoneMatrix(input.blendIndices.z);
-			result += input.blendWeights.w * getBoneMatrix(input.blendIndices.w);
-			
-			return result;
-		}		
-		
-		void main(VertexInput input, out float4 oPosition : SV_Position)
-		{
-			float3x4 blendMatrix = getBlendMatrix(input);
-			float4 position = float4(mul(blendMatrix, float4(input.position, 1.0f)), 1.0f);
-			oPosition = mul(matWorldViewProj, position);
-		}
-	};
+	Tags = { "SkinnedMorph" };
 };
 };
 
 
-Technique : base("SelectionBase") =
+Technique 
+ : inherits("Selection") =
 {
 {
 	Language = "GLSL";
 	Language = "GLSL";
-	
-	Pass =
-	{
-		Fill = WIRE;
-		DepthBias = 0.00001f;
-		
-		Target =
-		{
-			Blend = true;
-			Color = { SRCA, SRCIA, ADD };
-		};
-		
-		Fragment =
-		{
-			uniform vec4 selColor;
-			out vec4 fragColor;
-
-			void main()
-			{
-				fragColor = selColor;
-			}
-		};
-	};
 };
 };
 
 
-Technique : inherits("SelectionBase") = 
+Technique 
+ : inherits("SelectionSkinned") =
 {
 {
 	Language = "GLSL";
 	Language = "GLSL";
-
-	Vertex =
-	{
-		uniform mat4 matWorldViewProj;
-
-		in vec3 bs_position;
-
-		out gl_PerVertex
-		{
-			vec4 gl_Position;
-		};
-		
-		void main()
-		{
-			gl_Position = matWorldViewProj * vec4(bs_position.xyz, 1);
-		}
-	};
+	Tags = { "Skinned" };
 };
 };
 
 
-Technique : inherits("SelectionBase") = 
+Technique 
+ : inherits("SelectionMorph") =
 {
 {
 	Language = "GLSL";
 	Language = "GLSL";
-	Tags = { "Skinned" };
-	
-	Vertex =
-	{
-		uniform mat4 matWorldViewProj;
+	Tags = { "Morph" };
+};
 
 
-		in vec3 bs_position;
-	
-		in uvec4 bs_blendindices;
-		in vec4 bs_blendweights;
-			
-		#if USE_BLEND_SHAPES
-			in vec3 bs_position1;
-			in vec4 bs_normal1;
-		#endif
-		
-		uniform samplerBuffer boneMatrices;
-		
-		out gl_PerVertex
-		{
-			vec4 gl_Position;
-		};
-		
-		void getBoneMatrix(uint idx, out mat4x3 result)
-		{
-			mat3x4 temp;
-		
-			temp[0] = texelFetch(boneMatrices, idx * 3 + 0);
-			temp[1] = texelFetch(boneMatrices, idx * 3 + 1);
-			temp[2] = texelFetch(boneMatrices, idx * 3 + 2);
-			
-			result = transpose(temp);				
-		}
-		
-		void getBlendMatrix(out mat4x3 result)
-		{
-			mat4x3 boneMatrix;
-			
-			getBoneMatrix(bs_blendindices.x, out boneMatrix);
-			result = bs_blendweights.x * boneMatrix;
-			
-			getBoneMatrix(bs_blendindices.y, out boneMatrix);
-			result += bs_blendweights.y * boneMatrix;
-			
-			getBoneMatrix(bs_blendindices.z, out boneMatrix);
-			result += bs_blendweights.z * boneMatrix;
-			
-			getBoneMatrix(bs_blendindices.w, out boneMatrix);
-			result += bs_blendweights.w * boneMatrix;
-		}
-		
-		void main()
-		{
-			mat3x4 blendMatrix;
-			getBlendMatrix(blendMatrix);
-			
-			vec4 position = vec4(blendMatrix * vec4(bs_position, 1.0f), 1.0f);
-			gl_Position = matWorldViewProj * position;
-		}
-	};
+Technique 
+ : inherits("SelectionSkinnedMorph") =
+{
+	Language = "GLSL";
+	Tags = { "SkinnedMorph" };
 };
 };

+ 3 - 0
Data/Raw/Engine/Includes/DeferredBasePass.bslinc

@@ -2,6 +2,9 @@
 #include "$ENGINE$\PerCameraData.bslinc"
 #include "$ENGINE$\PerCameraData.bslinc"
 #include "$ENGINE$\PerObjectData.bslinc"
 #include "$ENGINE$\PerObjectData.bslinc"
 
 
+#include "$ENGINE$\SkinnedVertexInput.bslinc"
+#include "$ENGINE$\NormalVertexInput.bslinc"
+#define USE_BLEND_SHAPES
 #include "$ENGINE$\SkinnedVertexInput.bslinc"
 #include "$ENGINE$\SkinnedVertexInput.bslinc"
 #include "$ENGINE$\NormalVertexInput.bslinc"
 #include "$ENGINE$\NormalVertexInput.bslinc"
 
 

+ 25 - 25
Data/Raw/Engine/Includes/NormalVertexInput.bslinc

@@ -1,5 +1,5 @@
 Technique
 Technique
-#if USE_BLEND_SHAPES
+#ifdef USE_BLEND_SHAPES
 	 : base("MorphVertexInput") =
 	 : base("MorphVertexInput") =
 #else
 #else
 	 : base("NormalVertexInput") =
 	 : base("NormalVertexInput") =
@@ -18,11 +18,6 @@ Technique
 				
 				
 				float3 tangentToWorldZ : NORMAL; // Note: Half-precision could be used
 				float3 tangentToWorldZ : NORMAL; // Note: Half-precision could be used
 				float4 tangentToWorldX : TANGENT; // Note: Half-precision could be used
 				float4 tangentToWorldX : TANGENT; // Note: Half-precision could be used
-				
-				#if USE_BLEND_SHAPES
-					float3 deltaPosition : POSITION1;
-					float4 deltaNormal : NORMAL1;
-				#endif
 			};
 			};
 		};
 		};
 
 
@@ -34,6 +29,11 @@ Technique
 				float3 normal : NORMAL; // Note: Half-precision could be used
 				float3 normal : NORMAL; // Note: Half-precision could be used
 				float4 tangent : TANGENT; // Note: Half-precision could be used
 				float4 tangent : TANGENT; // Note: Half-precision could be used
 				float2 uv0 : TEXCOORD0;
 				float2 uv0 : TEXCOORD0;
+				
+				#ifdef USE_BLEND_SHAPES
+					float3 deltaPosition : POSITION1;
+					float4 deltaNormal : NORMAL1;
+				#endif				
 			};
 			};
 			
 			
 			struct VertexIntermediate
 			struct VertexIntermediate
@@ -47,19 +47,19 @@ Technique
 			float3x3 getTangentToLocal(VertexInput input, out float tangentSign)
 			float3x3 getTangentToLocal(VertexInput input, out float tangentSign)
 			{
 			{
 				float3 normal = input.normal * 2.0f - 1.0f;
 				float3 normal = input.normal * 2.0f - 1.0f;
-				float4 tangent = input.tangent * 2.0f - 1.0f;
+				float3 tangent = input.tangent.xyz * 2.0f - 1.0f;
 				
 				
-				#if USE_BLEND_SHAPES
-					float3 deltaNormal = input.deltaNormal.xyz * 2.0f - 1.0f;
+				#ifdef USE_BLEND_SHAPES
+					float3 deltaNormal = (input.deltaNormal.xyz * 2.0f - 1.0f) * 2.0f;
 					normal = normalize(normal + deltaNormal * input.deltaNormal.w);
 					normal = normalize(normal + deltaNormal * input.deltaNormal.w);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
 				#endif
 				#endif
 				
 				
-				float3 bitangent = cross(normal, tangent.xyz) * tangent.w;
-				tangentSign = tangent.w * gWorldDeterminantSign;
+				float3 bitangent = cross(normal, tangent) * input.tangent.w;
+				tangentSign = input.tangent.w * gWorldDeterminantSign;
 				
 				
 				// Note: Maybe it's better to store everything in row vector format?
 				// Note: Maybe it's better to store everything in row vector format?
-				float3x3 result = float3x3(tangent.xyz, bitangent, normal);
+				float3x3 result = float3x3(tangent, bitangent, normal);
 				result = transpose(result);
 				result = transpose(result);
 												
 												
 				return result;
 				return result;
@@ -81,7 +81,7 @@ Technique
 			
 			
 			float4 getVertexWorldPosition(VertexInput input, VertexIntermediate intermediate)
 			float4 getVertexWorldPosition(VertexInput input, VertexIntermediate intermediate)
 			{
 			{
-				#if USE_BLEND_SHAPES
+				#ifdef USE_BLEND_SHAPES
 					float4 position = float4(input.position + input.deltaPosition, 1.0f);
 					float4 position = float4(input.position + input.deltaPosition, 1.0f);
 				#else
 				#else
 					float4 position = float4(input.position, 1.0f);
 					float4 position = float4(input.position, 1.0f);
@@ -102,7 +102,7 @@ Technique
 };
 };
 
 
 Technique
 Technique
-#if USE_BLEND_SHAPES
+#ifdef USE_BLEND_SHAPES
 	 : base("MorphVertexInput") =
 	 : base("MorphVertexInput") =
 #else
 #else
 	 : base("NormalVertexInput") =
 	 : base("NormalVertexInput") =
@@ -126,7 +126,7 @@ Technique
 			in vec4 bs_tangent;
 			in vec4 bs_tangent;
 			in vec2 bs_texcoord0;
 			in vec2 bs_texcoord0;
 		
 		
-			#if USE_BLEND_SHAPES
+			#ifdef USE_BLEND_SHAPES
 				in vec3 bs_position1;
 				in vec3 bs_position1;
 				in vec4 bs_normal1;
 				in vec4 bs_normal1;
 			#endif
 			#endif
@@ -142,12 +142,11 @@ Technique
 				vec4 gl_Position;
 				vec4 gl_Position;
 			};
 			};
 							
 							
-			void getTangentToLocal(vec3 normal, vec4 tangent, out float tangentSign, out mat3 tangentToLocal)
+			void getTangentToLocal(vec3 normal, vec3 tangent, float tangentSign, out mat3 tangentToLocal)
 			{
 			{
-				vec3 bitangent = cross(normal, tangent.xyz) * tangent.w;
-				tangentSign = tangent.w * gWorldDeterminantSign;
-				
-				tangentToLocal[0] = tangent.xyz;
+				vec3 bitangent = cross(normal, tangent) * tangentSign;
+
+				tangentToLocal[0] = tangent;
 				tangentToLocal[1] = bitangent;
 				tangentToLocal[1] = bitangent;
 				tangentToLocal[2] = normal;
 				tangentToLocal[2] = normal;
 			}
 			}
@@ -155,17 +154,18 @@ Technique
 			void getVertexWorldPosition(VertexIntermediate intermediate, out vec4 result)
 			void getVertexWorldPosition(VertexIntermediate intermediate, out vec4 result)
 			{
 			{
 				vec3 normal = bs_normal * 2.0f - 1.0f;
 				vec3 normal = bs_normal * 2.0f - 1.0f;
-				vec4 tangent = bs_tangent * 2.0f - 1.0f;
+				vec3 tangent = bs_tangent.xyz * 2.0f - 1.0f;
 			
 			
-				#if USE_BLEND_SHAPES
-					vec3 deltaNormal = bs_normal1.xyz * 2.0f - 1.0f;
+				#ifdef USE_BLEND_SHAPES
+					vec3 deltaNormal = (bs_normal1.xyz * 2.0f - 1.0f) * 2.0f;
 					normal = normalize(normal + deltaNormal * bs_normal1.w);
 					normal = normalize(normal + deltaNormal * bs_normal1.w);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
 				#endif
 				#endif
 			
 			
-				float tangentSign;
+				float tangentSign = bs_tangent.w;
 				mat3 tangentToLocal;
 				mat3 tangentToLocal;
 				getTangentToLocal(normal, tangent, tangentSign, tangentToLocal);
 				getTangentToLocal(normal, tangent, tangentSign, tangentToLocal);
+				tangentSign *= gWorldDeterminantSign;
 				
 				
 				mat3 tangentToWorld = mat3(gMatWorldNoScale) * tangentToLocal;
 				mat3 tangentToWorld = mat3(gMatWorldNoScale) * tangentToLocal;
 				result.worldNormal = tangentToWorld[2]; // Normal basis vector
 				result.worldNormal = tangentToWorld[2]; // Normal basis vector
@@ -174,7 +174,7 @@ Technique
 			
 			
 			void getVertexWorldPosition(out vec4 result)
 			void getVertexWorldPosition(out vec4 result)
 			{
 			{
-				#if USE_BLEND_SHAPES
+				#ifdef USE_BLEND_SHAPES
 					vec4 position = vec4(bs_position + bs_position1, 1.0f);
 					vec4 position = vec4(bs_position + bs_position1, 1.0f);
 				#else
 				#else
 					vec4 position = vec4(bs_position, 1.0f);
 					vec4 position = vec4(bs_position, 1.0f);

+ 11 - 10
Data/Raw/Engine/Includes/SkinnedVertexInput.bslinc

@@ -4,7 +4,7 @@ Parameters =
 };
 };
 
 
 Technique 
 Technique 
-#if USE_BLEND_SHAPES
+#ifdef USE_BLEND_SHAPES
 	: base("SkinnedMorphVertexInput") =
 	: base("SkinnedMorphVertexInput") =
 #else
 #else
 	: base("SkinnedVertexInput") =
 	: base("SkinnedVertexInput") =
@@ -39,7 +39,7 @@ Technique
 				uint4 blendIndices : BLENDINDICES;
 				uint4 blendIndices : BLENDINDICES;
 				float4 blendWeights : BLENDWEIGHT;
 				float4 blendWeights : BLENDWEIGHT;
 				
 				
-				#if USE_BLEND_SHAPES
+				#ifdef USE_BLEND_SHAPES
 					float3 deltaPosition : POSITION1;
 					float3 deltaPosition : POSITION1;
 					float4 deltaNormal : NORMAL1;
 					float4 deltaNormal : NORMAL1;
 				#endif
 				#endif
@@ -79,8 +79,8 @@ Technique
 				float3 normal = input.normal * 2.0f - 1.0f;
 				float3 normal = input.normal * 2.0f - 1.0f;
 				float3 tangent = input.tangent.xyz * 2.0f - 1.0f;
 				float3 tangent = input.tangent.xyz * 2.0f - 1.0f;
 				
 				
-				#if USE_BLEND_SHAPES
-					float3 deltaNormal = input.deltaNormal.xyz * 2.0f - 1.0f;
+				#ifdef USE_BLEND_SHAPES
+					float3 deltaNormal = (input.deltaNormal.xyz * 2.0f - 1.0f) * 2.0f;
 					normal = normalize(normal + deltaNormal * input.deltaNormal.w);
 					normal = normalize(normal + deltaNormal * input.deltaNormal.w);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
 				#endif
 				#endif
@@ -115,7 +115,7 @@ Technique
 			
 			
 			float4 getVertexWorldPosition(VertexInput input, VertexIntermediate intermediate)
 			float4 getVertexWorldPosition(VertexInput input, VertexIntermediate intermediate)
 			{
 			{
-				#if USE_BLEND_SHAPES
+				#ifdef USE_BLEND_SHAPES
 					float4 position = float4(input.position + input.deltaPosition, 1.0f);
 					float4 position = float4(input.position + input.deltaPosition, 1.0f);
 				#else
 				#else
 					float4 position = float4(input.position, 1.0f);
 					float4 position = float4(input.position, 1.0f);
@@ -136,7 +136,8 @@ Technique
 	};
 	};
 };
 };
 
 
-#if USE_BLEND_SHAPES
+Technique
+#ifdef USE_BLEND_SHAPES
 	: base("SkinnedMorphVertexInput") =
 	: base("SkinnedMorphVertexInput") =
 #else
 #else
 	: base("SkinnedVertexInput") =
 	: base("SkinnedVertexInput") =
@@ -163,7 +164,7 @@ Technique
 			in uvec4 bs_blendindices;
 			in uvec4 bs_blendindices;
 			in vec4 bs_blendweights;
 			in vec4 bs_blendweights;
 				
 				
-			#if USE_BLEND_SHAPES
+			#ifdef USE_BLEND_SHAPES
 				in vec3 bs_position1;
 				in vec3 bs_position1;
 				in vec4 bs_normal1;
 				in vec4 bs_normal1;
 			#endif
 			#endif
@@ -218,8 +219,8 @@ Technique
 				vec3 normal = bs_normal * 2.0f - 1.0f;
 				vec3 normal = bs_normal * 2.0f - 1.0f;
 				vec3 tangent = bs_tangent.xyz * 2.0f - 1.0f;
 				vec3 tangent = bs_tangent.xyz * 2.0f - 1.0f;
 				
 				
-				#if USE_BLEND_SHAPES
-					vec3 deltaNormal = bs_normal1.xyz * 2.0f - 1.0f;
+				#ifdef USE_BLEND_SHAPES
+					vec3 deltaNormal = (bs_normal1.xyz * 2.0f - 1.0f) * 2.0f;
 					normal = normalize(normal + deltaNormal * bs_normal1.w);
 					normal = normalize(normal + deltaNormal * bs_normal1.w);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
 					tangent = normalize(tangent - dot(tangent, normal) * normal);
 				#endif
 				#endif
@@ -250,7 +251,7 @@ Technique
 			
 			
 			void getVertexWorldPosition(VertexIntermediate intermediate, out vec4 result)
 			void getVertexWorldPosition(VertexIntermediate intermediate, out vec4 result)
 			{
 			{
-				#if USE_BLEND_SHAPES
+				#ifdef USE_BLEND_SHAPES
 					vec4 position = vec4(bs_position + bs_position1, 1.0f);
 					vec4 position = vec4(bs_position + bs_position1, 1.0f);
 				#else
 				#else
 					vec4 position = vec4(bs_position, 1.0f);
 					vec4 position = vec4(bs_position, 1.0f);

+ 10 - 11
Source/BansheeEditor/Source/BsSelectionRenderer.cpp

@@ -127,7 +127,10 @@ namespace BansheeEngine
 
 
 			SPtr<GpuParamsCore> vertParams = mParams[i]->getGpuParams(GPT_VERTEX_PROGRAM);
 			SPtr<GpuParamsCore> vertParams = mParams[i]->getGpuParams(GPT_VERTEX_PROGRAM);
 			vertParams->getParam("matWorldViewProj", mMatWorldViewProj[i]);
 			vertParams->getParam("matWorldViewProj", mMatWorldViewProj[i]);
-			vertParams->getBufferParam("boneMatrices", mBoneMatrices[i]);
+
+			RenderableAnimType animType = (RenderableAnimType)i;
+			if(animType == RenderableAnimType::Skinned || animType == RenderableAnimType::SkinnedMorph)
+				vertParams->getBufferParam("boneMatrices", mBoneMatrices[i]);
 
 
 			SPtr<GpuParamsCore> fragParams = mParams[i]->getGpuParams(GPT_FRAGMENT_PROGRAM);
 			SPtr<GpuParamsCore> fragParams = mParams[i]->getGpuParams(GPT_FRAGMENT_PROGRAM);
 			fragParams->getParam("selColor", mColor[i]);
 			fragParams->getParam("selColor", mColor[i]);
@@ -168,12 +171,16 @@ namespace BansheeEngine
 			if (mesh == nullptr)
 			if (mesh == nullptr)
 				continue;
 				continue;
 
 
+			SPtr<GpuBufferCore> boneMatrixBuffer = renderable->getBoneMatrixBuffer();
+			SPtr<VertexBufferCore> morphShapeBuffer = renderable->getMorphShapeBuffer();
+
 			Matrix4 worldViewProjMat = viewProjMat * renderable->getTransform();
 			Matrix4 worldViewProjMat = viewProjMat * renderable->getTransform();
 			UINT32 techniqueIdx = mTechniqueIndices[(int)renderable->getAnimType()];
 			UINT32 techniqueIdx = mTechniqueIndices[(int)renderable->getAnimType()];
 
 
 			mMatWorldViewProj[techniqueIdx].set(worldViewProjMat);
 			mMatWorldViewProj[techniqueIdx].set(worldViewProjMat);
 			mColor[techniqueIdx].set(SELECTION_COLOR);
 			mColor[techniqueIdx].set(SELECTION_COLOR);
-			
+			mBoneMatrices[techniqueIdx].set(boneMatrixBuffer);
+
 			gRendererUtility().setPass(mMaterial, 0, techniqueIdx);
 			gRendererUtility().setPass(mMaterial, 0, techniqueIdx);
 			gRendererUtility().setPassParams(mParams[techniqueIdx], 0);
 			gRendererUtility().setPassParams(mParams[techniqueIdx], 0);
 
 
@@ -181,15 +188,7 @@ namespace BansheeEngine
 			UINT32 renderableId = renderable->getRendererId();
 			UINT32 renderableId = renderable->getRendererId();
 
 
 			for(UINT32 i = 0; i < numSubmeshes; i++)
 			for(UINT32 i = 0; i < numSubmeshes; i++)
-			{
-				const RenderableElement* renderableElem = renderer->getRenderableElem(renderableId, i);
-				if (renderableElem == nullptr)
-					continue;
-
-				mBoneMatrices[techniqueIdx].set(renderableElem->boneMatrixBuffer);
-
-				gRendererUtility().drawMorph(mesh, mesh->getProperties().getSubMesh(i), renderableElem->morphShapeBuffer);
-			}
+				gRendererUtility().drawMorph(mesh, mesh->getProperties().getSubMesh(i), morphShapeBuffer);
 		}
 		}
 	}
 	}
 }
 }

+ 21 - 0
Source/BansheeEngine/Include/BsRenderable.h

@@ -11,6 +11,8 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	struct RendererAnimationData;
+
 	/** @addtogroup Implementation
 	/** @addtogroup Implementation
 	 *  @{
 	 *  @{
 	 */
 	 */
@@ -191,6 +193,18 @@ namespace BansheeEngine
 		/** Returns the identifier of the animation, if this object is animated using skeleton or blend shape animation. */
 		/** Returns the identifier of the animation, if this object is animated using skeleton or blend shape animation. */
 		UINT64 getAnimationId() const { return mAnimationId; }
 		UINT64 getAnimationId() const { return mAnimationId; }
 
 
+		/** 
+		 * Updates internal animation buffers from the contents of the provided animation data object. Does nothing if
+		 * renderable is not affected by animation.
+		 */
+		void updateAnimationBuffers(const RendererAnimationData& animData);
+
+		/** Returns the GPU buffer containing element's bone matrices, if it has any. */
+		const SPtr<GpuBufferCore>& getBoneMatrixBuffer() const { return mBoneMatrixBuffer; }
+
+		/** Returns the vertex buffer containing element's morph shape vertices, if it has any. */
+		const SPtr<VertexBufferCore>& getMorphShapeBuffer() const { return mMorphShapeBuffer; }
+
 	protected:
 	protected:
 		friend class Renderable;
 		friend class Renderable;
 
 
@@ -202,8 +216,15 @@ namespace BansheeEngine
 		/** @copydoc CoreObject::syncToCore */
 		/** @copydoc CoreObject::syncToCore */
 		void syncToCore(const CoreSyncData& data) override;
 		void syncToCore(const CoreSyncData& data) override;
 
 
+		/** Creates any buffers required for renderable animation. Should be called whenever animation properties change. */
+		void createAnimationBuffers();
+
 		UINT32 mRendererId;
 		UINT32 mRendererId;
 		UINT64 mAnimationId;
 		UINT64 mAnimationId;
+		UINT32 mMorphShapeVersion;
+
+		SPtr<GpuBufferCore> mBoneMatrixBuffer;
+		SPtr<VertexBufferCore> mMorphShapeBuffer;
 	};
 	};
 
 
 	/** @copydoc TRenderable */
 	/** @copydoc TRenderable */

+ 0 - 6
Source/BansheeEngine/Include/BsRenderableElement.h

@@ -23,12 +23,6 @@ namespace BansheeEngine
 
 
 		/**	Material to render the mesh with. */
 		/**	Material to render the mesh with. */
 		SPtr<MaterialCore> material;
 		SPtr<MaterialCore> material;
-
-		/** GPU buffer containing element's bone matrices, if it requires any. */
-		SPtr<GpuBufferCore> boneMatrixBuffer;
-
-		/** Vertex buffer containing element's morph shape vertices, if it has any. */
-		SPtr<VertexBufferCore> morphShapeBuffer;
 	};
 	};
 
 
 	/** @} */
 	/** @} */

+ 0 - 6
Source/BansheeEngine/Include/BsRenderer.h

@@ -58,12 +58,6 @@ namespace BansheeEngine
 		 * @note	Core thread.
 		 * @note	Core thread.
 		 */
 		 */
 		virtual void notifyLightRemoved(LightCore* light) { }
 		virtual void notifyLightRemoved(LightCore* light) { }
-
-		/**
-		 * Attempts to retrieve a renderable element for a renderable with the specified renderable ID, and a sub-mesh
-		 * index of the mesh. Returns null if element cannot be found. Returned value is transient and should be stored.
-		 */
-		virtual const RenderableElement* getRenderableElem(UINT32 id, UINT32 subMeshIdx) = 0;
 	};
 	};
 
 
 	/**	Provides easy access to Renderer. */
 	/**	Provides easy access to Renderer. */

+ 107 - 4
Source/BansheeEngine/Source/BsRenderable.cpp

@@ -11,7 +11,9 @@
 #include "BsRenderer.h"
 #include "BsRenderer.h"
 #include "BsAnimation.h"
 #include "BsAnimation.h"
 #include "BsFrameAlloc.h"
 #include "BsFrameAlloc.h"
-#include "BsDebug.h"
+#include "BsMorphShapes.h"
+#include "BsGpuBuffer.h"
+#include "BsAnimationManager.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -147,7 +149,7 @@ namespace BansheeEngine
 	template class TRenderable < true >;
 	template class TRenderable < true >;
 
 
 	RenderableCore::RenderableCore() 
 	RenderableCore::RenderableCore() 
-		:mRendererId(0), mAnimationId((UINT64)-1)
+		:mRendererId(0), mAnimationId((UINT64)-1), mMorphShapeVersion(0)
 	{
 	{
 	}
 	}
 
 
@@ -194,6 +196,105 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	void RenderableCore::createAnimationBuffers()
+	{
+		if (mAnimType == RenderableAnimType::Skinned || mAnimType == RenderableAnimType::SkinnedMorph)
+		{
+			SPtr<Skeleton> skeleton = mMesh->getSkeleton();
+			UINT32 numBones = skeleton != nullptr ? skeleton->getNumBones() : 0;
+
+			if (numBones > 0)
+			{
+				SPtr<GpuBufferCore> buffer = GpuBufferCore::create(numBones * 3, 0, GBT_STANDARD, BF_32X4F, GBU_DYNAMIC);
+				UINT8* dest = (UINT8*)buffer->lock(0, numBones * 3 * sizeof(Vector4), GBL_WRITE_ONLY_DISCARD);
+
+				// Initialize bone transforms to identity, so the object renders properly even if no animation is animating it
+				for (UINT32 i = 0; i < numBones; i++)
+				{
+					memcpy(dest, &Matrix4::IDENTITY, 12 * sizeof(float)); // Assuming row-major format
+
+					dest += 12 * sizeof(float);
+				}
+
+				buffer->unlock();
+
+				mBoneMatrixBuffer = buffer;
+			}
+			else
+				mBoneMatrixBuffer = nullptr;
+		}
+		else
+			mBoneMatrixBuffer = nullptr;
+
+		if (mAnimType == RenderableAnimType::Morph || mAnimType == RenderableAnimType::SkinnedMorph)
+		{
+			SPtr<MorphShapes> morphShapes = mMesh->getMorphShapes();
+
+			UINT32 vertexSize = sizeof(Vector3) + sizeof(Vector4);
+			UINT32 numVertices = morphShapes->getNumVertices();
+
+			SPtr<VertexBufferCore> vertexBuffer = VertexBufferCore::create(vertexSize, numVertices, GBU_DYNAMIC);
+
+			UINT32 totalSize = vertexSize * numVertices;
+			UINT8* dest = (UINT8*)vertexBuffer->lock(0, totalSize, GBL_WRITE_ONLY_DISCARD);
+			memset(dest, 0, totalSize);
+			vertexBuffer->unlock();
+
+			mMorphShapeBuffer = vertexBuffer;
+		}
+		else
+			mMorphShapeBuffer = nullptr;
+
+		mMorphShapeVersion = 0;
+	}
+
+	void RenderableCore::updateAnimationBuffers(const RendererAnimationData& animData)
+	{
+		if (mAnimationId == (UINT64)-1)
+			return;
+
+		const RendererAnimationData::AnimInfo* animInfo = nullptr;
+
+		auto iterFind = animData.infos.find(mAnimationId);
+		if (iterFind != animData.infos.end())
+			animInfo = &iterFind->second;
+
+		if (animInfo == nullptr)
+			return;
+
+		if (mAnimType == RenderableAnimType::Skinned || mAnimType == RenderableAnimType::SkinnedMorph)
+		{
+			const RendererAnimationData::PoseInfo& poseInfo = animInfo->poseInfo;
+
+			// Note: If multiple elements are using the same animation (not possible atm), this buffer should be shared by
+			// all such elements
+			UINT8* dest = (UINT8*)mBoneMatrixBuffer->lock(0, poseInfo.numBones * 3 * sizeof(Vector4), GBL_WRITE_ONLY_DISCARD);
+			for (UINT32 j = 0; j < poseInfo.numBones; j++)
+			{
+				const Matrix4& transform = animData.transforms[poseInfo.startIdx + j];
+				memcpy(dest, &transform, 12 * sizeof(float)); // Assuming row-major format
+
+				dest += 12 * sizeof(float);
+			}
+
+			mBoneMatrixBuffer->unlock();
+		}
+
+		if (mAnimType == RenderableAnimType::Morph || mAnimType == RenderableAnimType::SkinnedMorph)
+		{
+			if (mMorphShapeVersion < animInfo->morphShapeInfo.version)
+			{
+				SPtr<MeshData> meshData = animInfo->morphShapeInfo.meshData;
+
+				UINT32 bufferSize = meshData->getSize();
+				UINT8* data = meshData->getData();
+
+				mMorphShapeBuffer->writeData(0, bufferSize, data, BufferWriteType::Discard);
+				mMorphShapeVersion = animInfo->morphShapeInfo.version;
+			}
+		}
+	}
+
 	void RenderableCore::syncToCore(const CoreSyncData& data)
 	void RenderableCore::syncToCore(const CoreSyncData& data)
 	{
 	{
 		char* dataPtr = (char*)data.getBuffer();
 		char* dataPtr = (char*)data.getBuffer();
@@ -212,8 +313,8 @@ namespace BansheeEngine
 		dataPtr = rttiReadElem(mTransformNoScale, dataPtr);
 		dataPtr = rttiReadElem(mTransformNoScale, dataPtr);
 		dataPtr = rttiReadElem(mPosition, dataPtr);
 		dataPtr = rttiReadElem(mPosition, dataPtr);
 		dataPtr = rttiReadElem(mIsActive, dataPtr);
 		dataPtr = rttiReadElem(mIsActive, dataPtr);
-		dataPtr = rttiReadElem(mAnimType, dataPtr);
 		dataPtr = rttiReadElem(mAnimationId, dataPtr);
 		dataPtr = rttiReadElem(mAnimationId, dataPtr);
+		dataPtr = rttiReadElem(mAnimType, dataPtr);
 		dataPtr = rttiReadElem(dirtyFlags, dataPtr);
 		dataPtr = rttiReadElem(dirtyFlags, dataPtr);
 
 
 		SPtr<MeshCore>* mesh = (SPtr<MeshCore>*)dataPtr;
 		SPtr<MeshCore>* mesh = (SPtr<MeshCore>*)dataPtr;
@@ -236,6 +337,8 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
+			createAnimationBuffers();
+
 			if (oldIsActive != mIsActive)
 			if (oldIsActive != mIsActive)
 			{
 			{
 				if (mIsActive)
 				if (mIsActive)
@@ -410,8 +513,8 @@ namespace BansheeEngine
 			rttiGetElemSize(mTransformNoScale) +
 			rttiGetElemSize(mTransformNoScale) +
 			rttiGetElemSize(mPosition) +
 			rttiGetElemSize(mPosition) +
 			rttiGetElemSize(mIsActive) +
 			rttiGetElemSize(mIsActive) +
+			rttiGetElemSize(animationId) +
 			rttiGetElemSize(mAnimType) + 
 			rttiGetElemSize(mAnimType) + 
-			rttiGetElemSize(animationId) + 
 			rttiGetElemSize(getCoreDirtyFlags()) +
 			rttiGetElemSize(getCoreDirtyFlags()) +
 			sizeof(SPtr<MeshCore>) + 
 			sizeof(SPtr<MeshCore>) + 
 			numMaterials * sizeof(SPtr<MaterialCore>);
 			numMaterials * sizeof(SPtr<MaterialCore>);

+ 8 - 8
Source/BansheeEngine/Source/BsRendererUtility.cpp

@@ -165,9 +165,6 @@ namespace BansheeEngine
 			rapi.setRasterizerState(pass->getRasterizerState());
 			rapi.setRasterizerState(pass->getRasterizerState());
 		else
 		else
 			rapi.setRasterizerState(RasterizerStateCore::getDefault());
 			rapi.setRasterizerState(RasterizerStateCore::getDefault());
-
-		SPtr<VertexDeclarationCore> shaderDecl = pass->getVertexProgram()->getInputDeclaration();
-		rapi.setVertexDeclaration(shaderDecl);
 	}
 	}
 
 
 	void RendererUtility::setComputePass(const SPtr<MaterialCore>& material, UINT32 passIdx)
 	void RendererUtility::setComputePass(const SPtr<MaterialCore>& material, UINT32 passIdx)
@@ -258,9 +255,11 @@ namespace BansheeEngine
 
 
 	void RendererUtility::draw(const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh, UINT32 numInstances)
 	void RendererUtility::draw(const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh, UINT32 numInstances)
 	{
 	{
-		RenderAPICore& rs = RenderAPICore::instance();
+		RenderAPICore& rapi = RenderAPICore::instance();
 		SPtr<VertexData> vertexData = mesh->getVertexData();
 		SPtr<VertexData> vertexData = mesh->getVertexData();
 
 
+		rapi.setVertexDeclaration(mesh->getVertexData()->vertexDeclaration);
+
 		auto& vertexBuffers = vertexData->getBuffers();
 		auto& vertexBuffers = vertexData->getBuffers();
 		if (vertexBuffers.size() > 0)
 		if (vertexBuffers.size() > 0)
 		{
 		{
@@ -282,16 +281,16 @@ namespace BansheeEngine
 				buffers[iter->first - startSlot] = iter->second;
 				buffers[iter->first - startSlot] = iter->second;
 			}
 			}
 
 
-			rs.setVertexBuffers(startSlot, buffers, endSlot - startSlot + 1);
+			rapi.setVertexBuffers(startSlot, buffers, endSlot - startSlot + 1);
 		}
 		}
 
 
 		SPtr<IndexBufferCore> indexBuffer = mesh->getIndexBuffer();
 		SPtr<IndexBufferCore> indexBuffer = mesh->getIndexBuffer();
-		rs.setIndexBuffer(indexBuffer);
+		rapi.setIndexBuffer(indexBuffer);
 
 
-		rs.setDrawOperation(subMesh.drawOp);
+		rapi.setDrawOperation(subMesh.drawOp);
 
 
 		UINT32 indexCount = subMesh.indexCount;
 		UINT32 indexCount = subMesh.indexCount;
-		rs.drawIndexed(subMesh.indexOffset + mesh->getIndexOffset(), indexCount, mesh->getVertexOffset(), 
+		rapi.drawIndexed(subMesh.indexOffset + mesh->getIndexOffset(), indexCount, mesh->getVertexOffset(), 
 			vertexData->vertexCount, numInstances);
 			vertexData->vertexCount, numInstances);
 
 
 		mesh->_notifyUsedOnGPU();
 		mesh->_notifyUsedOnGPU();
@@ -304,6 +303,7 @@ namespace BansheeEngine
 		RenderAPICore& rapi = RenderAPICore::instance();
 		RenderAPICore& rapi = RenderAPICore::instance();
 
 
 		SPtr<VertexData> vertexData = mesh->getVertexData();
 		SPtr<VertexData> vertexData = mesh->getVertexData();
+		rapi.setVertexDeclaration(mesh->getVertexData()->vertexDeclaration); // TODO - Set valid declaration
 
 
 		auto& meshBuffers = vertexData->getBuffers();
 		auto& meshBuffers = vertexData->getBuffers();
 		SPtr<VertexBufferCore> allBuffers[MAX_BOUND_VERTEX_BUFFERS];
 		SPtr<VertexBufferCore> allBuffers[MAX_BOUND_VERTEX_BUFFERS];

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

@@ -87,12 +87,6 @@ namespace BansheeEngine
 		 */
 		 */
 		void setPerCameraParams(const CameraShaderData& cameraData);
 		void setPerCameraParams(const CameraShaderData& cameraData);
 
 
-		/** 
-		 * Updates any bone or morph vertex buffers used by the element. Should be called once every frame before rendering,
-		 * or whenever animation changes. 
-		 */
-		void updateAnimationBuffers(const BeastRenderableElement& element, const RendererAnimationData& animData);
-
 		/**
 		/**
 		 * 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.
 		 */
 		 */

+ 0 - 3
Source/RenderBeast/Include/BsRenderBeast.h

@@ -117,9 +117,6 @@ namespace BansheeEngine
 		/** @copydoc Renderer::notifyRenderableRemoved */
 		/** @copydoc Renderer::notifyRenderableRemoved */
 		void notifyRenderableRemoved(RenderableCore* renderable) override;
 		void notifyRenderableRemoved(RenderableCore* renderable) override;
 
 
-		/** @copydoc Renderer::getRenderableElem */
-		const RenderableElement* getRenderableElem(UINT32 id, UINT32 subMeshIdx) override;
-
 		/** 
 		/** 
 		 * Updates (or adds) renderer specific data for the specified camera. Should be called whenever camera properties
 		 * Updates (or adds) renderer specific data for the specified camera. Should be called whenever camera properties
 		 * change. 
 		 * change. 

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

@@ -48,6 +48,12 @@ namespace BansheeEngine
 		 */
 		 */
 		MaterialParamBufferCore boneMatricesParam;
 		MaterialParamBufferCore boneMatricesParam;
 
 
+		/** GPU buffer containing element's bone matrices, if it requires any. */
+		SPtr<GpuBufferCore> boneMatrixBuffer;
+
+		/** Vertex buffer containing element's morph shape vertices, if it has any. */
+		SPtr<VertexBufferCore> morphShapeBuffer;
+
 		/** Version of the morph shape vertices in the buffer. */
 		/** Version of the morph shape vertices in the buffer. */
 		mutable UINT32 morphShapeVersion;
 		mutable UINT32 morphShapeVersion;
 	};
 	};

+ 0 - 92
Source/RenderBeast/Source/BsObjectRendering.cpp

@@ -54,98 +54,6 @@ namespace BansheeEngine
 			// Note: Bone matrices should be shared between all sub-meshes, so maybe it's better to create this buffer
 			// Note: Bone matrices should be shared between all sub-meshes, so maybe it's better to create this buffer
 			// on a per-Renderable basis, rather than per-element?
 			// on a per-Renderable basis, rather than per-element?
 			element.boneMatricesParam = element.material->getParamBuffer(boneMatricesParamName);
 			element.boneMatricesParam = element.material->getParamBuffer(boneMatricesParamName);
-
-			SPtr<Skeleton> skeleton = element.mesh->getSkeleton();
-			UINT32 numBones = skeleton != nullptr ? skeleton->getNumBones() : 0;
-
-			if (numBones > 0)
-			{
-				SPtr<GpuBufferCore> buffer = GpuBufferCore::create(numBones * 3, 0, GBT_STANDARD, BF_32X4F, GBU_DYNAMIC);
-				UINT8* dest = (UINT8*)buffer->lock(0, numBones * 3 * sizeof(Vector4), GBL_WRITE_ONLY_DISCARD);
-
-				// Initialize bone transforms to identity, so the object renders properly even if no animation is animating it
-				for (UINT32 i = 0; i < numBones; i++)
-				{
-					memcpy(dest, &Matrix4::IDENTITY, 12 * sizeof(float)); // Assuming row-major format
-
-					dest += 12 * sizeof(float);
-				}
-
-				buffer->unlock();
-
-				element.boneMatrixBuffer = buffer;
-			}
-		}
-
-		if (element.animType == RenderableAnimType::Morph || element.animType == RenderableAnimType::SkinnedMorph)
-		{
-			// Note: Morph vertices should be shared between all sub-meshes, so maybe it's better to create this buffer
-			// on a per-Renderable basis, rather than per-element?
-
-			SPtr<MorphShapes> morphShapes = element.mesh->getMorphShapes();
-
-			UINT32 vertexSize = sizeof(Vector3) + sizeof(Vector4);
-			UINT32 numVertices = morphShapes->getNumVertices();
-
-			SPtr<VertexBufferCore> vertexBuffer = VertexBufferCore::create(vertexSize, numVertices, GBU_DYNAMIC);
-
-			UINT32 totalSize = vertexSize * numVertices;
-			UINT8* dest = (UINT8*)vertexBuffer->lock(0, totalSize, GBL_WRITE_ONLY_DISCARD);
-			memset(dest, 0, totalSize);
-			vertexBuffer->unlock();
-
-			element.morphShapeBuffer = vertexBuffer;
-		}
-	}
-
-	void ObjectRenderer::updateAnimationBuffers(const BeastRenderableElement& element, const RendererAnimationData& animData)
-	{
-		if (element.animationId == (UINT64)-1)
-			return;
-
-		const RendererAnimationData::AnimInfo* animInfo = nullptr;
-
-		auto iterFind = animData.infos.find(element.animationId);
-		if (iterFind != animData.infos.end())
-			animInfo = &iterFind->second;
-
-		if (animInfo == nullptr)
-			return;
-
-		if (element.animType == RenderableAnimType::Skinned || element.animType == RenderableAnimType::SkinnedMorph)
-		{
-			const RendererAnimationData::PoseInfo& poseInfo = animInfo->poseInfo;
-
-			// Note: If multiple elements are using the same animation (not possible atm), this buffer should be shared by
-			// all such elements
-			SPtr<GpuBufferCore> boneMatrices = element.boneMatrixBuffer;
-
-			UINT8* dest = (UINT8*)boneMatrices->lock(0, poseInfo.numBones * 3 * sizeof(Vector4), GBL_WRITE_ONLY_DISCARD);
-			for (UINT32 j = 0; j < poseInfo.numBones; j++)
-			{
-				const Matrix4& transform = animData.transforms[poseInfo.startIdx + j];
-				memcpy(dest, &transform, 12 * sizeof(float)); // Assuming row-major format
-
-				dest += 12 * sizeof(float);
-			}
-
-			boneMatrices->unlock();
-		}
-
-		if (element.animType == RenderableAnimType::Morph || element.animType == RenderableAnimType::SkinnedMorph)
-		{
-			if (element.morphShapeVersion < animInfo->morphShapeInfo.version)
-			{
-				SPtr<MeshData> meshData = animInfo->morphShapeInfo.meshData;
-				SPtr<VertexBufferCore> vertexBuffer = element.morphShapeBuffer;
-
-				UINT32 bufferSize = meshData->getSize();
-				UINT8* data = meshData->getData();
-
-				vertexBuffer->writeData(0, bufferSize, data, BufferWriteType::Discard);
-
-				element.morphShapeVersion = animInfo->morphShapeInfo.version;
-			}
 		}
 		}
 	}
 	}
 
 

+ 4 - 14
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -142,6 +142,8 @@ namespace BansheeEngine
 				renElement.animType = renderable->getAnimType();
 				renElement.animType = renderable->getAnimType();
 				renElement.animationId = renderable->getAnimationId();
 				renElement.animationId = renderable->getAnimationId();
 				renElement.morphShapeVersion = 0;
 				renElement.morphShapeVersion = 0;
+				renElement.morphShapeBuffer = renderable->getMorphShapeBuffer();
+				renElement.boneMatrixBuffer = renderable->getBoneMatrixBuffer();
 
 
 				renElement.material = renderable->getMaterial(i);
 				renElement.material = renderable->getMaterial(i);
 				if (renElement.material == nullptr)
 				if (renElement.material == nullptr)
@@ -415,17 +417,6 @@ namespace BansheeEngine
 		updateCameraData(camera, true);
 		updateCameraData(camera, true);
 	}
 	}
 
 
-	const RenderableElement* RenderBeast::getRenderableElem(UINT32 id, UINT32 subMeshIdx)
-	{
-		if (id >= (UINT32)mRenderables.size())
-			return nullptr;
-
-		if (subMeshIdx >= (UINT32)mRenderables[id].elements.size())
-			return nullptr;
-
-		return &mRenderables[id].elements[subMeshIdx];
-	}
-
 	SPtr<PostProcessSettings> RenderBeast::createPostProcessSettings() const
 	SPtr<PostProcessSettings> RenderBeast::createPostProcessSettings() const
 	{
 	{
 		return bs_shared_ptr_new<StandardPostProcessSettings>();
 		return bs_shared_ptr_new<StandardPostProcessSettings>();
@@ -574,15 +565,14 @@ namespace BansheeEngine
 		const RendererAnimationData& animData = AnimationManager::instance().getRendererData();
 		const RendererAnimationData& animData = AnimationManager::instance().getRendererData();
 		RendererFrame frameInfo(delta, animData);
 		RendererFrame frameInfo(delta, animData);
 
 
-		// Update bone matrix buffers
+		// Update bone matrix and morph shape GPU buffers
 		UINT32 numRenderables = (UINT32)mRenderables.size();
 		UINT32 numRenderables = (UINT32)mRenderables.size();
 		for (UINT32 i = 0; i < numRenderables; i++)
 		for (UINT32 i = 0; i < numRenderables; i++)
 		{
 		{
 			if (!mVisibility[i])
 			if (!mVisibility[i])
 				continue;
 				continue;
 
 
-			for (auto& element : mRenderables[i].elements)
-				mObjectRenderer->updateAnimationBuffers(element, animData);
+			mRenderables[i].renderable->updateAnimationBuffers(animData);
 
 
 			// TODO - Also move per-object buffer updates here (will require worldViewProj matrix to be moved to a separate buffer (or a push constant))
 			// TODO - Also move per-object buffer updates here (will require worldViewProj matrix to be moved to a separate buffer (or a push constant))
 			// TODO - Before uploading bone matrices and per-object data, check if it has actually been changed since last frame (most objects will be static)
 			// TODO - Before uploading bone matrices and per-object data, check if it has actually been changed since last frame (most objects will be static)