protected void LinkMeshToSkeleton(FbxScene scene, FbxNode meshNode, FbxNode skelRootNode) { FbxNode limb1 = skelRootNode.GetChild(0); FbxNode limb2 = limb1.GetChild(0); FbxCluster rootCluster = FbxCluster.Create(scene, "RootCluster"); rootCluster.SetLink(skelRootNode); rootCluster.SetLinkMode(FbxCluster.ELinkMode.eTotalOne); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { rootCluster.AddControlPointIndex(4 * i + j, 1.0 - 0.25 * i); } } FbxCluster limb1Cluster = FbxCluster.Create(scene, "Limb1Cluster"); limb1Cluster.SetLink(limb1); limb1Cluster.SetLinkMode(FbxCluster.ELinkMode.eTotalOne); for (int i = 1; i < 6; i++) { for (int j = 0; j < 4; j++) { limb1Cluster.AddControlPointIndex(4 * i + j, (i == 1 || i == 5 ? 0.25 : 0.5)); } } FbxCluster limb2Cluster = FbxCluster.Create(scene, "Limb2Cluster"); limb2Cluster.SetLink(limb2); limb2Cluster.SetLinkMode(FbxCluster.ELinkMode.eTotalOne); for (int i = 3; i < 7; i++) { for (int j = 0; j < 4; j++) { limb2Cluster.AddControlPointIndex(4 * i + j, 0.25 * (i - 2)); } } FbxAMatrix globalTransform = meshNode.EvaluateGlobalTransform(); rootCluster.SetTransformMatrix(globalTransform); limb1Cluster.SetTransformMatrix(globalTransform); limb2Cluster.SetTransformMatrix(globalTransform); rootCluster.SetTransformLinkMatrix(skelRootNode.EvaluateGlobalTransform()); limb1Cluster.SetTransformLinkMatrix(limb1.EvaluateGlobalTransform()); limb2Cluster.SetTransformLinkMatrix(limb2.EvaluateGlobalTransform()); FbxSkin skin = FbxSkin.Create(scene, "Skin"); skin.AddCluster(rootCluster); skin.AddCluster(limb1Cluster); skin.AddCluster(limb2Cluster); meshNode.GetMesh().AddDeformer(skin); }
override public void TestBasics(T fbxGeometry, FbxNodeAttribute.EType typ) { base.TestBasics(fbxGeometry, typ); int origCount = fbxGeometry.GetDeformerCount(); // test get blendshape deformer FbxBlendShape blendShape = FbxBlendShape.Create(Manager, "blendShape"); int index = fbxGeometry.AddDeformer(blendShape); Assert.GreaterOrEqual(index, 0); origCount++; // TODO: (UNI-19581): If we add the blendShape after the skin, then the below // tests fail. Assert.AreEqual(blendShape, fbxGeometry.GetBlendShapeDeformer(index)); Assert.AreEqual(blendShape, fbxGeometry.GetBlendShapeDeformer(index, null)); Assert.AreEqual(blendShape, fbxGeometry.GetDeformer(index, FbxDeformer.EDeformerType.eBlendShape)); Assert.AreEqual(1, fbxGeometry.GetDeformerCount(FbxDeformer.EDeformerType.eBlendShape)); // test add deformer FbxSkin skin = FbxSkin.Create(Manager, "skin"); int skinIndex = fbxGeometry.AddDeformer(skin); Assert.GreaterOrEqual(skinIndex, 0); Assert.AreEqual(skin, fbxGeometry.GetDeformer(skinIndex)); // test get invalid deformer index doesn't crash fbxGeometry.GetDeformer(-1, new FbxStatus()); fbxGeometry.GetDeformer(int.MaxValue, new FbxStatus()); // test get deformer null FbxStatus fbxGeometry.GetDeformer(0, null); // check right index but wrong type Assert.IsNull(fbxGeometry.GetDeformer(skinIndex, FbxDeformer.EDeformerType.eVertexCache, null)); Assert.AreEqual(origCount + 1, fbxGeometry.GetDeformerCount()); // test add null deformer Assert.That(() => fbxGeometry.AddDeformer(null), Throws.Exception.TypeOf <System.ArgumentNullException>()); // test add invalid deformer skin.Destroy(); Assert.That(() => fbxGeometry.AddDeformer(skin), Throws.Exception.TypeOf <System.ArgumentNullException>()); }
/// <summary> /// Export binding of mesh to skeleton /// </summary> protected void ExportSkin(MeshInfo meshInfo, FbxScene fbxScene, FbxMesh fbxMesh, FbxNode fbxRootNode, Dictionary <Transform, FbxNode> boneNodes) { SkinnedMeshRenderer unitySkinnedMeshRenderer = meshInfo.renderer as SkinnedMeshRenderer; FbxSkin fbxSkin = FbxSkin.Create(fbxScene, (meshInfo.unityObject.name + "_Skin")); FbxAMatrix fbxMeshMatrix = fbxRootNode.EvaluateGlobalTransform(); // keep track of the bone index -> fbx cluster mapping, so that we can add the bone weights afterwards Dictionary <int, FbxCluster> boneCluster = new Dictionary <int, FbxCluster> (); for (int i = 0; i < unitySkinnedMeshRenderer.bones.Length; i++) { FbxNode fbxBoneNode = boneNodes [unitySkinnedMeshRenderer.bones[i]]; // Create the deforming cluster FbxCluster fbxCluster = FbxCluster.Create(fbxScene, "BoneWeightCluster"); fbxCluster.SetLink(fbxBoneNode); fbxCluster.SetLinkMode(FbxCluster.ELinkMode.eTotalOne); boneCluster.Add(i, fbxCluster); // set the Transform and TransformLink matrix fbxCluster.SetTransformMatrix(fbxMeshMatrix); FbxAMatrix fbxLinkMatrix = fbxBoneNode.EvaluateGlobalTransform(); fbxCluster.SetTransformLinkMatrix(fbxLinkMatrix); // add the cluster to the skin fbxSkin.AddCluster(fbxCluster); } // set the vertex weights for each bone SetVertexWeights(meshInfo, boneCluster); // Add the skin to the mesh after the clusters have been added fbxMesh.AddDeformer(fbxSkin); }