2
0
Эх сурвалжийг харах

Bind poses now properly account for the fact that node transforms are baked into mesh vertices

BearishSun 9 жил өмнө
parent
commit
1c1ef5afac

+ 28 - 4
Source/BansheeFBXImporter/Source/BsFBXImporter.cpp

@@ -1030,6 +1030,7 @@ namespace BansheeEngine
 
 
 			importMesh->referencedBy.push_back(parentNode);
 			importMesh->referencedBy.push_back(parentNode);
 			importMesh->fbxMesh = mesh;
 			importMesh->fbxMesh = mesh;
+
 			outputScene.meshMap[mesh] = (UINT32)outputScene.meshes.size() - 1;
 			outputScene.meshMap[mesh] = (UINT32)outputScene.meshes.size() - 1;
 		}
 		}
 
 
@@ -1302,7 +1303,18 @@ namespace BansheeEngine
 		Vector<FBXBoneInfluence>& influences = mesh.boneInfluences;
 		Vector<FBXBoneInfluence>& influences = mesh.boneInfluences;
 		influences.resize(mesh.positions.size());
 		influences.resize(mesh.positions.size());
 
 
-		Matrix4 importScale = Matrix4::scaling(options.importScale);
+		Matrix4 invBakedTransform;
+		if (mesh.referencedBy.size() > 0)
+		{
+			Matrix4 importScale = Matrix4::scaling(options.importScale);
+			Matrix4 bakedTransform = mesh.referencedBy[0]->worldTransform * importScale;
+
+			invBakedTransform = bakedTransform.inverseAffine();
+			invBakedTransform.inverseAffine();
+		}
+		else
+			invBakedTransform = Matrix4::IDENTITY;
+		
 		UnorderedSet<FbxNode*> existingBones;
 		UnorderedSet<FbxNode*> existingBones;
 		UINT32 boneCount = (UINT32)skin->GetClusterCount();
 		UINT32 boneCount = (UINT32)skin->GetClusterCount();
 		for (UINT32 i = 0; i < boneCount; i++)
 		for (UINT32 i = 0; i < boneCount; i++)
@@ -1326,9 +1338,21 @@ namespace BansheeEngine
 			FbxAMatrix linkTransform;
 			FbxAMatrix linkTransform;
 			cluster->GetTransformLinkMatrix(linkTransform);
 			cluster->GetTransformLinkMatrix(linkTransform);
 
 
-			FbxAMatrix bindPose = linkTransform.Inverse() * clusterTransform;
-			bone.bindPose = FBXToNativeType(bindPose);
-			bone.bindPose = (bone.node->worldTransform * importScale) * bone.bindPose;
+			// For nodes attached to meshes we bake their transform directly into mesh vertices. We need to remove that
+			// transform
+
+			if(mesh.referencedBy.size() > 1)
+			{
+				// Note: If this becomes a relevant issue (unlikely), then I will have to duplicate skeleton bones for
+				// each such mesh, since they will all require their own bind poses. Animation curves will also need to be
+				// handled specially (likely by allowing them to be applied to multiple bones at once). The other option is
+				// not to bake the node transform into mesh vertices and handle it on a Scene Object level.
+				LOGWRN("Skinned mesh has multiple different instances. This is not supported.");
+			}
+
+			FbxAMatrix invLinkTransform = linkTransform.Inverse() * clusterTransform;
+			bone.bindPose = FBXToNativeType(invLinkTransform) * invBakedTransform;
+			//bone.bindPose = bone.bindPose * FBXToNativeType(clusterTransform);
 
 
 			bool isDuplicate = !existingBones.insert(link).second;
 			bool isDuplicate = !existingBones.insert(link).second;
 			bool isAdditive = cluster->GetLinkMode() == FbxCluster::eAdditive;
 			bool isAdditive = cluster->GetLinkMode() == FbxCluster::eAdditive;