Example #1
0
        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);
        }
Example #2
0
        public void TestAddCluster()
        {
            var fbxSkin    = CreateObject("skin");
            var fbxCluster = FbxCluster.Create(Manager, "cluster");

            bool result = fbxSkin.AddCluster(fbxCluster);

            Assert.IsTrue(result);
            Assert.AreEqual(fbxSkin.GetCluster(0), fbxCluster);

            // test adding null cluster
            Assert.That(() => { fbxSkin.AddCluster(null); }, Throws.Exception.TypeOf <System.ArgumentNullException>());

            // add invalid cluster
            var fbxCluster2 = FbxCluster.Create(Manager, "cluster2");

            fbxCluster2.Dispose();
            Assert.That(() => { fbxSkin.AddCluster(fbxCluster2); }, Throws.Exception.TypeOf <System.ArgumentNullException>());
        }
Example #3
0
            /// <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);
            }
Example #4
0
        protected override FbxSkin GenerateFbx()
        {
            MeshExportData meshData = Souls.meshData.SoulsData;

            ICollection <BoneIndexToWeightPair> rawBoneDeformerData = new List <BoneIndexToWeightPair>();

            for (int vertexIndex = 0; vertexIndex < meshData.mesh.Vertices.Count; ++vertexIndex)
            {
                FLVER.Vertex vertex = meshData.mesh.Vertices[vertexIndex];

                const int maxVertexDeformations = 4;
                for (int vertexDeformationIndex = 0; vertexDeformationIndex < maxVertexDeformations; ++vertexDeformationIndex)
                {
                    BoneIndexToWeightPair weightData = new BoneIndexToWeightPair()
                    {
                        flverBoneIndex = vertex.BoneIndices[vertexDeformationIndex],
                        boneWeight     = vertex.BoneWeights[vertexDeformationIndex],
                        vertexIndex    = vertexIndex
                    };

                    if (weightData.flverBoneIndex > 0 && weightData.boneWeight > 0)
                    {
                        rawBoneDeformerData.Add(weightData);
                    }
                }
            }

            foreach (var ddd in rawBoneDeformerData.GroupBy(boneDeformerData => boneDeformerData.vertexIndex).Select(boneDeformedGroup => (vertexIndex: boneDeformedGroup.Key, affectingBonesCount: boneDeformedGroup.Count())).Where((ddd) => ddd.affectingBonesCount > 4))
            {
                System.Console.WriteLine($"Vertex {ddd.vertexIndex} : {ddd.affectingBonesCount}");
            }

            foreach (var ddd in rawBoneDeformerData.GroupBy(boneDeformedData => boneDeformedData.flverBoneIndex).Select(boneDeformerGroup => (boneIndex: boneDeformerGroup.Key, affectingVerticesCount: boneDeformerGroup.Count(), uniqueAffectingVerticesCount: boneDeformerGroup.Select(boneDeformerData => boneDeformerData.vertexIndex).Distinct().Count())))
            {
                if (ddd.affectingVerticesCount != ddd.uniqueAffectingVerticesCount)
                {
                    System.Console.WriteLine($"Bone {ddd.boneIndex} : vertices {ddd.affectingVerticesCount} : unique {ddd.uniqueAffectingVerticesCount}");
                }
            }

            FbxSkin skin = FbxSkin.Create(Owner, meshData.meshRoot.Name + "_Skin");

            System.Console.WriteLine($"Generating {meshData.meshRoot.Name}");

            foreach (var deformerData in rawBoneDeformerData.ToLookup(boneDeformerData => boneDeformerData.flverBoneIndex))
            {
                FLVER2 flver = Souls.flver;

                FLVER.Bone flverBone = flver.Bones[deformerData.Key];

                DsBoneData boneData = Souls.skeleton.boneDatas.Single(boneData => boneData.flverBone == flverBone);

                //System.Console.WriteLine($"Exporting {deformerData.Key} : {flverBone.Name} with {deformerData.Count(weight=>weight.boneWeight > 0)} vertices");

                FbxCluster boneCluster = FbxCluster.Create(skin, meshData.meshRoot.Name + "_" + boneData.exportData.SoulsData.Name + "_Cluster");

                boneCluster.SetLink(boneData.exportData.FbxNode);
                boneCluster.SetLinkMode(FbxCluster.ELinkMode.eTotalOne);
                boneCluster.SetControlPointIWCount(deformerData.Count());
                boneCluster.SetTransformMatrix(Souls.meshData.FbxNode.EvaluateGlobalTransform());
                boneCluster.SetTransformLinkMatrix(boneData.exportData.FbxNode.EvaluateGlobalTransform());
                foreach (BoneIndexToWeightPair boneWeightPair in deformerData)
                {
                    boneCluster.AddControlPointIndex(boneWeightPair.vertexIndex, boneWeightPair.boneWeight);

                    //Console.WriteLine("Bone {0} has vertex {1} with weight {2}", flverBone.Name, boneWeightPair.vertexIndex, boneWeightPair.boneWeight);
                }

                skin.AddCluster(boneCluster);
            }

            //foreach (var dd in rawBoneDeformerData.GroupBy(biwp => biwp.vertexIndex).Where(group => group.Count() > 2))
            //{
            //System.Console.WriteLine($"Vertex {dd.Key} : {dd.Count()}");
            //}

            //var set = new HashSet<int>();
            //for (int vertexIndex = 0; vertexIndex < meshData.mesh.Vertices.Count; ++vertexIndex)
            //{
            //    if (!rawBoneDeformerData.Any(x=>x.vertexIndex == vertexIndex))
            //    {
            //        set.Add(vertexIndex);
            //    }
            //}

            //System.Console.WriteLine($"Total {set.Count} unweighted nodes");

            return(skin);
        }