Пример #1
0
        private void UpdateMeshInfoRecursively(FbxSDK.Node node, ref Matrix4 parentMatrix)
        {
            int childCount = node.GetChildCount();

            Matrix4 globalTransform = GetGlobalTransform(node, parentMatrix);

            FbxSDK.Mesh mesh = node.GetAttribute() as FbxSDK.Mesh;
            if (mesh != null)
            {
                Matrix4 meshTransform = GetGeometry(node) * globalTransform;

                MeshInfo meshInfo = FindMeshInfo(mesh);
                if (meshInfo == null)
                {
                    meshInfo = LoadMesh(mesh);
                }

                meshInfo.geometryToWorld = meshTransform;
            }

            for (int i = 0; i < childCount; ++i)
            {
                UpdateMeshInfoRecursively(node.GetChild(i), ref globalTransform);
            }
        }
Пример #2
0
        private void OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            var item = e.NewValue as TreeViewItem;

            CurSelected = null;
            if (item != null)
            {
                CurSelected = item.Tag as FbxSDK.Node;
            }
        }
Пример #3
0
        private Matrix4 GetGlobalTransform(FbxSDK.Node node, Matrix4?parentGlobalTransform = null)
        {
            Matrix4 globalTransform        = Matrix4.Identity;
            bool    isGlobalTransformReady = false;

            if (curPose != null)
            {
                int nodeIndex = curPose.Find(node);
                if (nodeIndex >= 0)
                {
                    Matrix4 poseMat = Converter.Convert(curPose.GetMatrix(nodeIndex));

                    if (curPose.IsBindPose() || !curPose.IsLocalMatrix(nodeIndex))
                    {
                        globalTransform = poseMat;
                    }
                    else
                    {
                        if (parentGlobalTransform.HasValue)
                        {
                            globalTransform = poseMat * parentGlobalTransform.Value;
                        }
                        else
                        {
                            if (node.GetParent() != null)
                            {
                                globalTransform = poseMat * GetGlobalTransform(node.GetParent());
                            }
                        }
                    }

                    isGlobalTransformReady = true;
                }
            }

            if (isGlobalTransformReady == false)
            {
                globalTransform = Converter.Convert(node.EvaluateGlobalTransform(curTime));
            }

            return(globalTransform);
        }
Пример #4
0
        public void AddNode(ItemCollection collection, FbxSDK.Node node)
        {
            TreeViewItem viewItem  = new TreeViewItem();
            string       name      = node.GetName();
            var          attribute = node.GetAttribute();

            if (attribute != null)
            {
                var attributeType = attribute.GetAttributeType();
                name += string.Format(" ({0})", attributeType);
            }

            viewItem.Header = name;
            viewItem.Tag    = node;

            for (int i = 0; i < node.GetChildCount(); ++i)
            {
                var child = node.GetChild(i);
                AddNode(viewItem.Items, child);
            }

            collection.Add(viewItem);
        }
Пример #5
0
 private Matrix4 GetGeometry(FbxSDK.Node node)
 {
     return(Converter.Convert(node.GetGeometryOffset()));
 }
Пример #6
0
        private MeshInfo LoadMesh(FbxSDK.Mesh mesh)
        {
            MeshInfo meshInfo = new MeshInfo();

            meshInfoList.Add(meshInfo);
            meshInfo.mesh = mesh;
            meshInfo.node = mesh.GetNode();
            int polygonCount       = mesh.GetPolygonCount();
            int controlPointsCount = mesh.GetControlPointsCount();

            meshInfo.polygonCount       = polygonCount;
            meshInfo.controlPointsCount = controlPointsCount;
            meshInfo.nextSkinningIndex  = new int[controlPointsCount];
            meshInfo.boneTrasforms      = new Matrix4[MaxBoneCount];

            int vertexArray = GL.GenVertexArray();

            meshInfo.vertexArray = vertexArray;

            GL.BindVertexArray(vertexArray);

            int vertexBuffer = GL.GenBuffer();

            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);

            int elementBuffer = GL.GenBuffer();

            GL.BindBuffer(BufferTarget.ElementArrayBuffer, elementBuffer);

            VertexData[] vertexBufferData        = new VertexData[controlPointsCount];
            int[]        vertexBufferBoneCounter = new int[controlPointsCount];

            for (int i = 0; i < controlPointsCount; ++i)
            {
                Vector3 coordinate = Converter.Convert(mesh.GetControlPoint(i));

                vertexBufferData[i] = new VertexData()
                {
                    x = coordinate.X,
                    y = coordinate.Y,
                    z = coordinate.Z
                };
            }

            int  skinDeformerCount = mesh.GetSkinDeformerCount();
            byte boneIndex         = 0;

            for (int i = 0; i < skinDeformerCount; ++i)
            {
                FbxSDK.Skin skin = mesh.GetSkinDeformer(i);

                var skinningType = skin.GetSkinningType();

                if (skinningType == FbxSDK.SkinningType.Linear || skinningType == FbxSDK.SkinningType.Rigid)
                {
                    int clusterCount = skin.GetClusterCount();

                    for (int j = 0; j < clusterCount; ++j)
                    {
                        FbxSDK.Cluster cluster = skin.GetCluster(j);
                        FbxSDK.Node    link    = cluster.GetLink();

                        if (link == null)
                        {
                            continue;
                        }

                        if (cluster.HasAssociateModel())
                        {
                            DebugUtil.WriteLine("No support for associate model.");
                        }

                        int  indexCount  = cluster.GetControlIndicesCount();
                        bool isValidBone = false;

                        for (int k = 0; k < indexCount; ++k)
                        {
                            int   controlPointIndex  = cluster.GetControlPointIndex(k);
                            float controlPointWeight = (float)cluster.GetControlPointWeight(k);

                            if (vertexBufferBoneCounter[controlPointIndex] == 16)
                            {
                                continue;
                            }

                            isValidBone = true;
                            int fieldIndex = vertexBufferBoneCounter[controlPointIndex];
                            VertexData.SetBoneInfo(ref vertexBufferData[controlPointIndex], fieldIndex, boneIndex, controlPointWeight);
                            ++vertexBufferBoneCounter[controlPointIndex];
                        }

                        if (isValidBone)
                        {
                            boneInfoList.Add(new BoneInfo()
                            {
                                cluster       = cluster,
                                boneIndex     = boneIndex,
                                ownerMeshInfo = meshInfo
                            });

                            ++boneIndex;
                        }
                    }
                }
                else
                {
                    DebugUtil.WriteLine("No support for dual quaternion and blend."); // TODO : Dual Quaternion rigging
                }
            }

            int[] indices = new int[polygonCount * 3];

            for (int i = 0; i < polygonCount; ++i)
            {
                indices[3 * i]     = mesh.GetControlPointIndex(i, 0);
                indices[3 * i + 1] = mesh.GetControlPointIndex(i, 1);
                indices[3 * i + 2] = mesh.GetControlPointIndex(i, 2);
            }

            GL.BufferData(BufferTarget.ArrayBuffer, vertexBufferData.Length * VertexData.GetSize(), vertexBufferData, BufferUsageHint.StaticDraw);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, VertexData.GetSize(), 0);
            GL.EnableVertexAttribArray(0);

            for (int i = 0; i < 4; ++i)
            {
                int attribIndexIndex = i + 1;
                GL.VertexAttribIPointer(attribIndexIndex, 4, VertexAttribIntegerType.UnsignedByte, VertexData.GetSize(), new IntPtr(VertexData.GetBoneIndexPos(i)));
                GL.EnableVertexAttribArray(attribIndexIndex);
            }

            for (int i = 0; i < 4; ++i)
            {
                int attribIndexIndex = i + 5;
                GL.VertexAttribPointer(attribIndexIndex, 4, VertexAttribPointerType.Float, false, VertexData.GetSize(), VertexData.GetBoneWeightPos(i));
                GL.EnableVertexAttribArray(attribIndexIndex);
            }

            GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(int), indices, BufferUsageHint.StaticDraw);
            GL.BindVertexArray(0);

            return(meshInfo);
        }
Пример #7
0
 public void SetNode(FbxSDK.Node rootNode)
 {
     treeView.Items.Clear();
     AddNode(treeView.Items, rootNode);
 }