예제 #1
0
        private static void SearchHierarchy(ImportedFrame rootFrame, List <ImportedMesh> meshList, HashSet <string> exportFrames)
        {
            var frameStack = new Stack <ImportedFrame>();

            frameStack.Push(rootFrame);

            while (frameStack.Count > 0)
            {
                var frame = frameStack.Pop();

                var meshListSome = ImportedHelpers.FindMesh(frame.Path, meshList);

                if (meshListSome != null)
                {
                    var parent = frame;

                    while (parent != null)
                    {
                        exportFrames.Add(parent.Path);
                        parent = parent.Parent;
                    }

                    var boneList = meshListSome.BoneList;

                    if (boneList != null)
                    {
                        foreach (var bone in boneList)
                        {
                            if (!exportFrames.Contains(bone.Path))
                            {
                                var boneParent = rootFrame.FindFrameByPath(bone.Path);

                                while (boneParent != null)
                                {
                                    exportFrames.Add(boneParent.Path);
                                    boneParent = boneParent.Parent;
                                }
                            }
                        }
                    }
                }

                for (var i = frame.Count - 1; i >= 0; i -= 1)
                {
                    frameStack.Push(frame[i]);
                }
            }
        }
예제 #2
0
        private void ExportMesh(ImportedFrame rootFrame, List <ImportedMaterial> materialList, List <ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, bool exportSkins)
        {
            var boneList       = importedMesh.BoneList;
            var totalBoneCount = 0;
            var hasBones       = false;

            if (exportSkins && boneList?.Count > 0)
            {
                totalBoneCount = boneList.Count;
                hasBones       = true;
            }

            var pClusterArray = IntPtr.Zero;

            try
            {
                if (hasBones)
                {
                    pClusterArray = AsFbxMeshCreateClusterArray(totalBoneCount);

                    foreach (var bone in boneList)
                    {
                        if (bone.Path != null)
                        {
                            var frame    = rootFrame.FindFrameByPath(bone.Path);
                            var boneNode = _frameToNode[frame];

                            var cluster = AsFbxMeshCreateCluster(_pContext, boneNode);

                            AsFbxMeshAddCluster(pClusterArray, cluster);
                        }
                        else
                        {
                            AsFbxMeshAddCluster(pClusterArray, IntPtr.Zero);
                        }
                    }
                }

                var mesh = AsFbxMeshCreateMesh(_pContext, frameNode);

                var totalVertexCount = 0;

                foreach (var m in importedMesh.SubmeshList)
                {
                    totalVertexCount += m.VertexList.Count;
                }

                AsFbxMeshInitControlPoints(mesh, totalVertexCount);

                if (importedMesh.hasNormal)
                {
                    AsFbxMeshCreateElementNormal(mesh);
                }

                if (importedMesh.hasUV[0])
                {
                    AsFbxMeshCreateDiffuseUV(mesh, 0);
                }

                if (importedMesh.hasUV[1])
                {
                    AsFbxMeshCreateNormalMapUV(mesh, 1);
                }

                if (importedMesh.hasTangent)
                {
                    AsFbxMeshCreateElementTangent(mesh);
                }

                if (importedMesh.hasColor)
                {
                    AsFbxMeshCreateElementVertexColor(mesh);
                }

                AsFbxMeshCreateElementMaterial(mesh);

                var firstVertex = 0;

                foreach (var meshObj in importedMesh.SubmeshList)
                {
                    var materialIndex = 0;
                    var mat           = ImportedHelpers.FindMaterial(meshObj.Material, materialList);

                    if (mat != null)
                    {
                        var    foundMat = _createdMaterials.FindIndex(kv => kv.Key == mat.Name);
                        IntPtr pMat;

                        if (foundMat >= 0)
                        {
                            pMat = _createdMaterials[foundMat].Value;
                        }
                        else
                        {
                            var diffuse    = mat.Diffuse;
                            var ambient    = mat.Ambient;
                            var emissive   = mat.Emissive;
                            var specular   = mat.Specular;
                            var reflection = mat.Reflection;

                            pMat = AsFbxCreateMaterial(_pContext, mat.Name, in diffuse, in ambient, in emissive, in specular, in reflection, mat.Shininess, mat.Transparency);

                            _createdMaterials.Add(new KeyValuePair <string, IntPtr>(mat.Name, pMat));
                        }

                        materialIndex = AsFbxAddMaterialToFrame(frameNode, pMat);

                        var hasTexture = false;

                        foreach (var texture in mat.Textures)
                        {
                            var tex      = ImportedHelpers.FindTexture(texture.Name, textureList);
                            var pTexture = ExportTexture(tex);

                            if (pTexture != IntPtr.Zero)
                            {
                                switch (texture.Dest)
                                {
                                case 0:
                                case 1:
                                case 2:
                                case 3:
                                {
                                    AsFbxLinkTexture(texture.Dest, pTexture, pMat, texture.Offset.X, texture.Offset.Y, texture.Scale.X, texture.Scale.Y);
                                    hasTexture = true;
                                    break;
                                }

                                default:
                                    break;
                                }
                            }
                        }

                        if (hasTexture)
                        {
                            AsFbxSetFrameShadingModeToTextureShading(frameNode);
                        }
                    }

                    var vertexList = meshObj.VertexList;

                    var vertexCount = vertexList.Count;

                    for (var j = 0; j < vertexCount; j += 1)
                    {
                        var importedVertex = vertexList[j];

                        var vertex = importedVertex.Vertex;
                        AsFbxMeshSetControlPoint(mesh, j + firstVertex, vertex.X, vertex.Y, vertex.Z);

                        if (importedMesh.hasNormal)
                        {
                            var normal = importedVertex.Normal;
                            AsFbxMeshElementNormalAdd(mesh, 0, normal.X, normal.Y, normal.Z);
                        }

                        for (var uvIndex = 0; uvIndex < 2; uvIndex += 1)
                        {
                            if (importedMesh.hasUV[uvIndex])
                            {
                                var uv = importedVertex.UV[uvIndex];
                                AsFbxMeshElementUVAdd(mesh, uvIndex, uv[0], uv[1]);
                            }
                        }

                        if (importedMesh.hasTangent)
                        {
                            var tangent = importedVertex.Tangent;
                            AsFbxMeshElementTangentAdd(mesh, 0, tangent.X, tangent.Y, tangent.Z, tangent.W);
                        }

                        if (importedMesh.hasColor)
                        {
                            var color = importedVertex.Color;
                            AsFbxMeshElementVertexColorAdd(mesh, 0, color.R, color.G, color.B, color.A);
                        }

                        if (hasBones && importedVertex.BoneIndices != null)
                        {
                            var boneIndices = importedVertex.BoneIndices;
                            var boneWeights = importedVertex.Weights;

                            for (var k = 0; k < 4; k += 1)
                            {
                                if (boneIndices[k] < totalBoneCount && boneWeights[k] > 0)
                                {
                                    AsFbxMeshSetBoneWeight(pClusterArray, boneIndices[k], j + firstVertex, boneWeights[k]);
                                }
                            }
                        }
                    }

                    foreach (var face in meshObj.FaceList)
                    {
                        var index0 = face.VertexIndices[0] + firstVertex;
                        var index1 = face.VertexIndices[1] + firstVertex;
                        var index2 = face.VertexIndices[2] + firstVertex;

                        AsFbxMeshAddPolygon(mesh, materialIndex, index0, index1, index2);
                    }

                    firstVertex += vertexCount;
                }

                if (hasBones)
                {
                    IntPtr pSkinContext = IntPtr.Zero;

                    try
                    {
                        pSkinContext = AsFbxMeshCreateSkinContext(_pContext, frameNode);

                        unsafe
                        {
                            var boneMatrix = stackalloc float[16];

                            for (var j = 0; j < totalBoneCount; j += 1)
                            {
                                if (!FbxClusterArray_HasItemAt(pClusterArray, j))
                                {
                                    continue;
                                }

                                var m = boneList[j].Matrix;

                                CopyMatrix4x4(in m, boneMatrix);

                                AsFbxMeshSkinAddCluster(pSkinContext, pClusterArray, j, boneMatrix);
                            }
                        }

                        AsFbxMeshAddDeformer(pSkinContext, mesh);
                    }
                    finally
                    {
                        AsFbxMeshDisposeSkinContext(ref pSkinContext);
                    }
                }
            }
            finally
            {
                AsFbxMeshDisposeClusterArray(ref pClusterArray);
            }
        }