Пример #1
0
        public static List <ImportedFace> ImportedFaceList(List <odfFace> faceList)
        {
            List <ImportedFace> importedList = new List <ImportedFace>(faceList.Count);

            for (int i = 0; i < faceList.Count; i++)
            {
                ImportedFace importedFace = new ImportedFace();
                importedList.Add(importedFace);
                importedFace.VertexIndices = new int[3];
                for (int j = 0; j < 3; j++)
                {
                    importedFace.VertexIndices[j] = faceList[i].VertexIndices[j];
                }
            }
            return(importedList);
        }
Пример #2
0
        public static List <ImportedFace> ImportedFaceList(List <int> faceList)
        {
            int numFaces = faceList.Count / 3;
            List <ImportedFace> importedList = new List <ImportedFace>(numFaces);

            for (int i = 0; i < numFaces; i++)
            {
                ImportedFace importedFace = new ImportedFace();
                importedList.Add(importedFace);
                importedFace.VertexIndices = new int[3];
                for (int j = 0; j < 3; j++)
                {
                    importedFace.VertexIndices[j] = faceList[i * 3 + j];
                }
            }
            return(importedList);
        }
Пример #3
0
            private void ImportMesh(Section section, ImportedMesh meshList, SortedDictionary<string, byte> boneDic, List<bool> hasBonesList)
            {
                int vertIdxOffset = 0;
                foreach (ImportedSubmesh submesh in meshList.SubmeshList)
                {
                    vertIdxOffset += submesh.VertexList.Count;
                }

                LinkedListNode<object> node = section.data.First;
                int numVertices = ConvertInt32(node.Value);
                node = node.Next;
                DXVertex[] vertices = new DXVertex[numVertices];
                for (int i = 0; i < numVertices; i++)
                {
                    vertices[i] = new DXVertex();
                    float[] pos = new float[3];
                    for (int j = 0; j < pos.Length; j++)
                    {
                        pos[j] = ConvertFloat(node.Value);
                        node = node.Next;
                    }
                    pos[2] = -pos[2];
                    vertices[i].position = pos;
                }

                int numFaces = ConvertInt32(node.Value);
                node = node.Next;
                DXFace[] faces = new DXFace[numFaces];
                for (int i = 0; i < numFaces; i++)
                {
                    int numFaceVerts = ConvertInt32(node.Value);
                    node = node.Next;
                    if (numFaceVerts != 3)
                    {
                        throw new Exception("Meshes must be triangulated");
                    }

                    faces[i] = new DXFace();
                    faces[i].vertexIndices[0] = ConvertUInt16(node.Value);
                    node = node.Next;
                    faces[i].vertexIndices[2] = ConvertUInt16(node.Value);
                    node = node.Next;
                    faces[i].vertexIndices[1] = ConvertUInt16(node.Value);
                    node = node.Next;
                }

                string[] materials = new string[] { String.Empty };
                bool hasNormals = false;
                bool hasBones = false;
                bool hasUVs = false;
                List<KeyValuePair<byte, float>>[] boneAssignments = new List<KeyValuePair<byte, float>>[numVertices];
                for (int i = 0; i < boneAssignments.Length; i++)
                {
                    boneAssignments[i] = new List<KeyValuePair<byte, float>>();
                }
                foreach (Section child in section.children)
                {
                    if (child.type == "VertexDuplicationIndices")
                    {
                    }
                    else if (child.type == "MeshNormals")
                    {
                        hasNormals = true;
                        LinkedListNode<object> childNode = child.data.First;
                        int numNormals = ConvertInt32(childNode.Value);
                        childNode = childNode.Next;
                        if (numNormals != numVertices)
                        {
                            throw new Exception("Number of normals doesn't match the number of vertices");
                        }
                        foreach (DXVertex vert in vertices)
                        {
                            float[] norm = new float[3];
                            for (int i = 0; i < norm.Length; i++)
                            {
                                norm[i] = ConvertFloat(childNode.Value);
                                childNode = childNode.Next;
                            }
                            norm[2] = -norm[2];
                            vert.normal = norm;
                        }
                    }
                    else if (child.type == "MeshTextureCoords")
                    {
                        hasUVs = true;
                        LinkedListNode<object> childNode = child.data.First;
                        int numTexCoords = ConvertInt32(childNode.Value);
                        childNode = childNode.Next;
                        if (numTexCoords != numVertices)
                        {
                            throw new Exception("Number of texture coordinates doesn't match the number of vertices");
                        }
                        foreach (DXVertex vert in vertices)
                        {
                            float[] uv = new float[2];
                            for (int i = 0; i < uv.Length; i++)
                            {
                                uv[i] = ConvertFloat(childNode.Value);
                                childNode = childNode.Next;
                            }
                            vert.uv = uv;
                        }
                    }
                    else if (child.type == "MeshMaterialList")
                    {
                        materials = ImportMaterials(child, faces);
                    }
                    else if (child.type == "XSkinMeshHeader")
                    {
                        hasBones = true;
                    }
                    else if (child.type == "SkinWeights")
                    {
                        LinkedListNode<object> childNode = child.data.First;
                        string boneName = ConvertString(childNode.Value);
                        childNode = childNode.Next;
                        int numWeights = ConvertInt32(childNode.Value);
                        childNode = childNode.Next;
                        int[] vertIndices = new int[numWeights];
                        for (int i = 0; i < numWeights; i++)
                        {
                            vertIndices[i] = ConvertInt32(childNode.Value);
                            childNode = childNode.Next;
                        }
                        float[] weights = new float[numWeights];
                        for (int i = 0; i < numWeights; i++)
                        {
                            weights[i] = ConvertFloat(childNode.Value);
                            childNode = childNode.Next;
                        }

                        byte boneIdx;
                        if (!boneDic.TryGetValue(boneName, out boneIdx))
                        {
                            boneIdx = (byte)boneDic.Count;
                            boneDic.Add(boneName, boneIdx);

                            ImportedBone boneInfo = new ImportedBone();
                            meshList.BoneList.Add(boneInfo);
                            boneInfo.Name = boneName;

                            Matrix matrix = new Matrix();
                            for (int i = 0; i < 4; i++)
                            {
                                for (int j = 0; j < 4; j++)
                                {
                                    matrix[i, j] = ConvertFloat(childNode.Value);
                                    childNode = childNode.Next;
                                }
                            }
                            boneInfo.Matrix = RHToLHMatrix(matrix);
                        }

                        for (int i = 0; i < numWeights; i++)
                        {
                            boneAssignments[vertIndices[i]].Add(new KeyValuePair<byte, float>(boneIdx, weights[i]));
                        }
                    }
                    else
                    {
                        Report.ReportLog("Warning: unexpected section " + child.type);
                    }
                }

                if (hasBones)
                {
                    for (int i = 0; i < boneAssignments.Length; i++)
                    {
                        byte[] boneIndices = new byte[4];
                        float[] weights4 = new float[4];
                        for (int j = 0; (j < 4) && (j < boneAssignments[i].Count); j++)
                        {
                            boneIndices[j] = boneAssignments[i][j].Key;
                            weights4[j] = boneAssignments[i][j].Value;
                        }
                        for (int j = boneAssignments[i].Count; j < 4; j++)
                        {
                            boneIndices[j] = 0xFF;
                            weights4[j] = 0;
                        }

                        vertices[i].boneIndices = boneIndices;
                        vertices[i].weights = new float[] { weights4[0], weights4[1], weights4[2], weights4[3] };
                    }
                }

                SortedDictionary<ushort, ushort>[] vertexMaps = new SortedDictionary<ushort, ushort>[materials.Length];
                ImportedSubmesh[] submeshes = new ImportedSubmesh[materials.Length];
                for (int i = 0; i < materials.Length; i++)
                {
                    submeshes[i] = new ImportedSubmesh();
                    submeshes[i].Material = materials[i];
                    submeshes[i].VertexList = new List<ImportedVertex>(vertices.Length);
                    submeshes[i].FaceList = new List<ImportedFace>(faces.Length);
                    vertexMaps[i] = new SortedDictionary<ushort, ushort>();
                }

                foreach (DXFace dxFace in faces)
                {
                    ImportedSubmesh submesh = submeshes[dxFace.materialIndex];
                    ImportedFace face = new ImportedFace();
                    submesh.FaceList.Add(face);

                    ushort[] foundVertexIndices = new ushort[3];
                    for (int i = 0; i < dxFace.vertexIndices.Length; i++)
                    {
                        ushort dxVertIdx = dxFace.vertexIndices[i];
                        SortedDictionary<ushort, ushort> vertexMap = vertexMaps[dxFace.materialIndex];
                        if (!vertexMap.TryGetValue(dxVertIdx, out foundVertexIndices[i]))
                        {
                            DXVertex dxVert = vertices[dxVertIdx];
                            ImportedVertex vert = new ImportedVertex();
                            submesh.VertexList.Add(vert);
                            if (hasNormals)
                            {
                                vert.Normal = new Vector3(dxVert.normal[0], dxVert.normal[1], dxVert.normal[2]);
                            }
                            if (hasUVs)
                            {
                                vert.UV = (float[])dxVert.uv.Clone();
                            }
                            if (hasBones)
                            {
                                vert.BoneIndices = (byte[])dxVert.boneIndices.Clone();
                                vert.Weights = (float[])dxVert.weights.Clone();
                            }
                            vert.Position = new Vector3(dxVert.position[0], dxVert.position[1], dxVert.position[2]);
                            vertIdxOffset++;

                            foundVertexIndices[i] = (ushort)vertexMap.Count;
                            vertexMap.Add(dxVertIdx, foundVertexIndices[i]);
                        }
                    }

                    face.VertexIndices = new int[] { foundVertexIndices[0], foundVertexIndices[1], foundVertexIndices[2] };
                }

                foreach (ImportedSubmesh submesh in submeshes)
                {
                    if (submesh.VertexList.Count > 0)
                    {
                        submesh.VertexList.TrimExcess();
                        submesh.FaceList.TrimExcess();
                        submesh.Index = meshList.SubmeshList.Count;
                        meshList.SubmeshList.Add(submesh);
                        hasBonesList.Add(hasBones);

                        if (!hasNormals)
                        {
                            for (int i = 0; i < submesh.VertexList.Count; i++)
                            {
                                submesh.VertexList[i].Normal = new Vector3();
                            }
                        }
                    }
                }
            }
Пример #4
0
        public static remMesh CreateMesh(WorkspaceMesh mesh, out string[] materialNames, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption)
        {
            int numUncheckedSubmeshes = 0;

            foreach (ImportedSubmesh submesh in mesh.SubmeshList)
            {
                if (!mesh.isSubmeshEnabled(submesh))
                {
                    numUncheckedSubmeshes++;
                }
            }
            int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes;

            materialNames          = new string[numSubmeshes];
            indices                = new int[numSubmeshes];
            worldCoords            = new bool[numSubmeshes];
            replaceSubmeshesOption = new bool[numSubmeshes];

            remMesh newMesh = new remMesh(numSubmeshes);

            newMesh.name = new remId(mesh.Name);

            List <remVertex> newVertices  = new List <remVertex>();
            List <int>       newFaces     = new List <int>();
            List <int>       newFaceMarks = new List <int>();

            for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++)
            {
                while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx]))
                {
                    submeshIdx++;
                }

                ImportedSubmesh submesh = mesh.SubmeshList[submeshIdx];

                newMesh.AddMaterial(new remId(submesh.Material));
                materialNames[i]          = submesh.Material;
                indices[i]                = submesh.Index;
                worldCoords[i]            = submesh.WorldCoords;
                replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(submesh);

                List <ImportedFace> faceList = submesh.FaceList;
                newFaces.Capacity += faceList.Count * 3;
                int[] faceMarks = new int[faceList.Count];
                for (int j = 0; j < faceList.Count; j++)
                {
                    ImportedFace face = faceList[j];
                    for (int k = 0; k < 3; k++)
                    {
                        newFaces.Add(face.VertexIndices[k] + newVertices.Count);
                    }
                    faceMarks[j] = i;
                }
                newFaceMarks.AddRange(faceMarks);

                List <ImportedVertex> vertexList = submesh.VertexList;
                newVertices.Capacity += vertexList.Count;
                for (int j = 0; j < vertexList.Count; j++)
                {
                    ImportedVertex vert      = vertexList[j];
                    remVertex      newVertex = new remVertex();

                    if (submesh.WorldCoords)
                    {
                        newVertex.Position = vert.Position;
                        newVertex.Normal   = vert.Normal;
                    }
                    else
                    {
                        newVertex.Position = new Vector3(vert.Position.X, -vert.Position.Z, vert.Position.Y);
                        newVertex.Normal   = new Vector3(vert.Normal.X, -vert.Normal.Z, vert.Normal.Y);
                    }
                    newVertex.UV = new Vector2(vert.UV[0], vert.UV[1]);
                    newVertices.Add(newVertex);
                }
            }
            newMesh.vertices  = newVertices.ToArray();
            newMesh.faces     = newFaces.ToArray();
            newMesh.faceMarks = newFaceMarks.ToArray();

            return(newMesh);
        }
Пример #5
0
            private ImportedSubmesh ImportGeometry(Document.Geometry geo, ref int vertInfoIdx)
            {
                ImportedSubmesh submesh = null;
                try
                {
                    bool hasNormalInput = false;
                    Document.Input positionInput = null;
                    Document.Input normalInput = null;
                    Document.Input texcoordInput = null;
                    for (int i = 0; i < geo.mesh.vertices.inputs.Count; i++)
                    {
                        switch (geo.mesh.vertices.inputs[i].semantic)
                        {
                            case "POSITION":
                                positionInput = geo.mesh.vertices.inputs[i];
                                break;
                            case "NORMAL":
                                normalInput = geo.mesh.vertices.inputs[i];
                                break;
                            case "TEXCOORD":
                                texcoordInput = geo.mesh.vertices.inputs[i];
                                break;
                        }
                    }
                    if (positionInput == null)
                    {
                        throw new Exception("No POSITION vertex input in " + geo.id);
                    }

                    int numVerts = ((Document.Source)positionInput.source).accessor.count;
                    List<ImportedVertex> vertList = new List<ImportedVertex>(numVerts);
                    for (int i = 0; i < numVerts; i++)
                    {
                        ImportedVertex vert = new ImportedVertex();
                        vertList.Add(vert);
                        vert.Normal = new Vector3(0, 0, 0);
                        vert.UV = new float[] { 0, 0 };
                        vert.BoneIndices = new byte[] { 0, 0, 0, 0 };
                        vert.Weights = new float[] { 0, 0, 0, 0 };
                        if (Z_UP)
                        {
                            vert.Position = new Vector3(
                                GetSourceValue(positionInput, 0, i),
                                GetSourceValue(positionInput, 2, i),
                                -GetSourceValue(positionInput, 1, i));
                        }
                        else
                        {
                            vert.Position = new Vector3(
                                GetSourceValue(positionInput, 0, i),
                                GetSourceValue(positionInput, 1, i),
                                GetSourceValue(positionInput, 2, i));
                        }
                        if (normalInput != null)
                        {
                            hasNormalInput = true;
                            if (Z_UP)
                            {
                                vert.Normal = new Vector3(
                                    GetSourceValue(normalInput, 0, i),
                                    GetSourceValue(normalInput, 2, i),
                                    -GetSourceValue(normalInput, 1, i));
                            }
                            else
                            {
                                vert.Normal = new Vector3(
                                    GetSourceValue(normalInput, 0, i),
                                    GetSourceValue(normalInput, 1, i),
                                    GetSourceValue(normalInput, 2, i));
                            }
                        }
                        if (texcoordInput == null)
                        {
                            vert.UV = new float[2];
                        }
                        else
                        {
                            if (IsBlender)
                            {
                                vert.UV = new float[] {
                                    GetSourceValue(texcoordInput, 0, i),
                                    -GetSourceValue(texcoordInput, 1, i) };
                            }
                            else
                            {
                                vert.UV = new float[] {
                                    GetSourceValue(texcoordInput, 0, i),
                                    1.0f - GetSourceValue(texcoordInput, 1, i) };
                            }
                        }
                        vertInfoIdx++;
                    }

                    List<ImportedFace> faceList = new List<ImportedFace>();
                    foreach (Document.Primitive primitive in geo.mesh.primitives)
                    {
                        if (primitive is Document.Triangle)
                        {
                            Document.Input vertexInput = null;
                            List<Document.Input> normalInputs = new List<Document.Input>();
                            List<Document.Input> textureInputs = new List<Document.Input>();
                            foreach (Document.Input input in primitive.Inputs)
                            {
                                switch (input.semantic)
                                {
                                    case "VERTEX":
                                        vertexInput = input;
                                        break;
                                    case "NORMAL":
                                        hasNormalInput = true;
                                        normalInputs.Add(input);
                                        break;
                                    case "TEXCOORD":
                                        textureInputs.Add(input);
                                        break;
                                }
                            }

                            if (vertexInput != null)
                            {
                                for (int faceIdx = 0; faceIdx < primitive.count; faceIdx++)
                                {
                                    ushort[] faceVerts = new ushort[3];
                                    for (int i = 0; i < 3; i++)
                                    {
                                        int pIdx = (faceIdx * 3) + i;
                                        int vertIdx = GetPValue(vertexInput, primitive, pIdx);
                                        faceVerts[i] = (ushort)vertIdx;

                                        ImportedVertex vert = vertList[vertIdx];
                                        for (int j = 0; j < normalInputs.Count; j++)
                                        {
                                            int p = GetPValue(normalInputs[j], primitive, pIdx);
                                            if (Z_UP)
                                            {
                                                vert.Normal = new Vector3(
                                                    GetSourceValue(normalInputs[j], 0, p),
                                                    GetSourceValue(normalInputs[j], 2, p),
                                                    -GetSourceValue(normalInputs[j], 1, p));
                                            }
                                            else
                                            {
                                                vert.Normal = new Vector3(
                                                    GetSourceValue(normalInputs[j], 0, p),
                                                    GetSourceValue(normalInputs[j], 1, p),
                                                    GetSourceValue(normalInputs[j], 2, p));
                                            }
                                        }
                                        for (int j = 0; j < textureInputs.Count; j++)
                                        {
                                            int p = GetPValue(textureInputs[j], primitive, pIdx);
                                            if (IsBlender)
                                            {
                                                vert.UV = new float[] {
                                                    GetSourceValue(textureInputs[j], 0, p),
                                                    -GetSourceValue(textureInputs[j], 1, p) };
                                            }
                                            else
                                            {
                                                vert.UV = new float[] {
                                                    GetSourceValue(textureInputs[j], 0, p),
                                                    1.0f - GetSourceValue(textureInputs[j], 1, p) };
                                            }
                                        }
                                    }
                                    ImportedFace face = new ImportedFace();
                                    faceList.Add(face);
                                    face.VertexIndices = new int[3] { faceVerts[0], faceVerts[1], faceVerts[2] };
                                }
                            }
                        }
                    }

                    submesh = new ImportedSubmesh();
                    submesh.VertexList = vertList;
                    submesh.FaceList = faceList;

                    if (!hasNormalInput)
                    {
                        for (int i = 0; i < submesh.VertexList.Count; i++)
                        {
                            submesh.VertexList[i].Normal = new Vector3();
                        }
                    }
                }
                catch (Exception e)
                {
                    Report.ReportLog("Error importing " + geo.id + ": " + e.Message);
                }
                return submesh;
            }
Пример #6
0
            private void ConvertMeshes(List<odfMesh> meshes, odfParser parser)
            {
                MeshList = new List<ImportedMesh>(meshes.Count);
                MaterialList = new List<ImportedMaterial>(meshes.Count);
                TextureList = new List<ImportedTexture>(parser.TextureSection != null ? parser.TextureSection.Count : 0);
                foreach (odfMesh mesh in meshes)
                {
                    ImportedMesh iMesh = new ImportedMesh();
                    MeshList.Add(iMesh);
                    iMesh.Name = odf.FindMeshFrame(mesh.Id, parser.FrameSection.RootFrame).Name;
                    iMesh.BoneList = new List<ImportedBone>();
                    Dictionary<ObjectID, byte> boneDic = new Dictionary<ObjectID, byte>();
                    iMesh.SubmeshList = new List<ImportedSubmesh>(mesh.Count);
                    foreach (odfSubmesh submesh in mesh)
                    {
                        ImportedSubmesh iSubmesh = new ImportedSubmesh();
                        iMesh.SubmeshList.Add(iSubmesh);
                        odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection);
                        if (mat != null)
                        {
                            iSubmesh.Material = mat.Name;
                            ImportedMaterial iMat = ImportedHelpers.FindMaterial(iSubmesh.Material, MaterialList);
                            if (iMat == null)
                            {
                                iMat = new ImportedMaterial();
                                MaterialList.Add(iMat);
                                iMat.Name = iSubmesh.Material;
                                iMat.Diffuse = mat.Diffuse;
                                iMat.Ambient = mat.Ambient;
                                iMat.Specular = mat.Specular;
                                iMat.Emissive = mat.Emissive;
                                iMat.Power = mat.SpecularPower;

                                iMat.Textures = new string[4];
                                for (int i = 0; i < 4; i++)
                                {
                                    if (submesh.TextureIds[i] != ObjectID.INVALID)
                                    {
                                        odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[i], parser.TextureSection);
                                        iMat.Textures[i] =  tex.Name;
                                        if (ImportedHelpers.FindTexture(iMat.Textures[i], TextureList) == null)
                                        {
                                            try
                                            {
                                                odfTextureFile texFile = new odfTextureFile(iMat.Textures[i], Path.GetDirectoryName(parser.ODFPath) + @"\" + iMat.Textures[i]);
                                                MemoryStream memStream;
                                                int filesize = 0;
                                                using (BinaryReader reader = texFile.DecryptFile(ref filesize))
                                                {
                                                    memStream = new MemoryStream(reader.ReadBytes(filesize));
                                                }
                                                ImportedTexture iTex = new ImportedTexture(memStream, iMat.Textures[i]);
                                                TextureList.Add(iTex);
                                            }
                                            catch
                                            {
                                                Report.ReportLog("cant read texture " + iMat.Textures[i]);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        iMat.Textures[i] = String.Empty;
                                    }
                                }
                            }
                        }

                        List<Tuple<byte, float>>[] skin = new List<Tuple<byte, float>>[submesh.NumVertices];
                        for (int i = 0; i < submesh.NumVertices; i++)
                        {
                            skin[i] = new List<Tuple<byte, float>>(4);
                        }
                        odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
                        if (boneList != null)
                        {
                            if (iMesh.BoneList.Capacity < boneList.Count)
                            {
                                iMesh.BoneList.Capacity += boneList.Count;
                            }
                            foreach (odfBone bone in boneList)
                            {
                                byte idx;
                                if (!boneDic.TryGetValue(bone.FrameId, out idx))
                                {
                                    ImportedBone iBone = new ImportedBone();
                                    iMesh.BoneList.Add(iBone);
                                    iBone.Name = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
                                    iBone.Matrix = bone.Matrix;
                                    boneDic.Add(bone.FrameId, idx = (byte)boneDic.Count);
                                }
                                for (int i = 0; i < bone.NumberIndices; i++)
                                {
                                    skin[bone.VertexIndexArray[i]].Add(new Tuple<byte, float>(idx, bone.WeightArray[i]));
                                }
                            }
                        }

                        iSubmesh.VertexList = new List<ImportedVertex>(submesh.NumVertices);
                        for (int i = 0; i < submesh.NumVertices; i++)
                        {
                            odfVertex vert = submesh.VertexList[i];
                            ImportedVertex iVert = new ImportedVertex();
                            iSubmesh.VertexList.Add(iVert);
                            iVert.Position = vert.Position;
                            iVert.Normal = vert.Normal;
                            iVert.UV = new float[] { vert.UV[0], vert.UV[1] };
                            iVert.BoneIndices = new byte[4];
                            iVert.Weights = new float[4];
                            for (int j = 0; j < 4; j++)
                            {
                                if (j < skin[i].Count)
                                {
                                    Tuple<byte, float> vertIdxWeight = skin[i][j];
                                    iVert.BoneIndices[j] = vertIdxWeight.Item1;
                                    iVert.Weights[j] = vertIdxWeight.Item2;
                                }
                                else
                                {
                                    iVert.BoneIndices[j] = 0xFF;
                                }
                            }
                        }

                        iSubmesh.FaceList = new List<ImportedFace>(submesh.NumVertexIndices / 3);
                        foreach (odfFace face in submesh.FaceList)
                        {
                            ImportedFace iFace = new ImportedFace();
                            iSubmesh.FaceList.Add(iFace);
                            iFace.VertexIndices = new int[3];
                            for (int i = 0; i < 3; i++)
                            {
                                iFace.VertexIndices[i] = face.VertexIndices[i];
                            }
                        }
                    }
                }
            }
Пример #7
0
            private void ConvertMeshRenderers(List <MeshRenderer> meshList, bool skins, bool morphs)
            {
                MeshList     = new List <ImportedMesh>(meshList.Count);
                MaterialList = new List <ImportedMaterial>(meshList.Count);
                TextureList  = new List <ImportedTexture>(meshList.Count);
                MorphList    = new List <ImportedMorph>(meshList.Count);
                foreach (MeshRenderer meshR in meshList)
                {
                    Mesh mesh = Operations.GetMesh(meshR);
                    if (mesh == null)
                    {
                        Report.ReportLog("skipping " + meshR.m_GameObject.instance.m_Name + " - no mesh");
                        continue;
                    }

                    ImportedMesh iMesh         = new ImportedMesh();
                    Transform    meshTransform = meshR.m_GameObject.instance.FindLinkedComponent(UnityClassID.Transform);
                    iMesh.Name        = meshTransform.GetTransformPath();
                    iMesh.SubmeshList = new List <ImportedSubmesh>(mesh.m_SubMeshes.Count);
                    using (BinaryReader vertReader = new BinaryReader(new MemoryStream(mesh.m_VertexData.m_DataSize)),
                           indexReader = new BinaryReader(new MemoryStream(mesh.m_IndexBuffer)))
                    {
                        for (int i = 0; i < mesh.m_SubMeshes.Count; i++)
                        {
                            SubMesh         submesh  = mesh.m_SubMeshes[i];
                            ImportedSubmesh iSubmesh = new ImportedSubmesh();
                            iSubmesh.Index   = i;
                            iSubmesh.Visible = true;

                            Material mat = meshR.m_Materials[i].instance;
                            ConvertMaterial(mat);
                            iSubmesh.Material = mat.m_Name;

                            iSubmesh.VertexList = new List <ImportedVertex>((int)submesh.vertexCount);
                            for (int str = 0; str < mesh.m_VertexData.m_Streams.Count; str++)
                            {
                                StreamInfo sInfo = mesh.m_VertexData.m_Streams[str];
                                if (sInfo.channelMask == 0)
                                {
                                    continue;
                                }

                                for (int j = 0; j < mesh.m_SubMeshes[i].vertexCount; j++)
                                {
                                    ImportedVertex iVertex;
                                    if (iSubmesh.VertexList.Count < mesh.m_SubMeshes[i].vertexCount)
                                    {
                                        iVertex = new ImportedVertex();
                                        iSubmesh.VertexList.Add(iVertex);
                                    }
                                    else
                                    {
                                        iVertex = iSubmesh.VertexList[j];
                                    }

                                    for (int chn = 0; chn < mesh.m_VertexData.m_Channels.Count; chn++)
                                    {
                                        ChannelInfo cInfo = mesh.m_VertexData.m_Channels[chn];
                                        if ((sInfo.channelMask & (1 << chn)) == 0)
                                        {
                                            continue;
                                        }

                                        vertReader.BaseStream.Position = sInfo.offset + (submesh.firstVertex + j) * sInfo.stride + cInfo.offset;
                                        switch (chn)
                                        {
                                        case 0:
                                            iVertex.Position = new SlimDX.Vector3(-vertReader.ReadSingle(), vertReader.ReadSingle(), vertReader.ReadSingle());
                                            break;

                                        case 1:
                                            iVertex.Normal = new SlimDX.Vector3(-vertReader.ReadSingle(), vertReader.ReadSingle(), vertReader.ReadSingle());
                                            break;

                                        case 3:
                                            iVertex.UV = new float[2] {
                                                vertReader.ReadSingle(), vertReader.ReadSingle()
                                            };
                                            break;

                                        case 5:
                                            iVertex.Tangent = new SlimDX.Vector4(-vertReader.ReadSingle(), vertReader.ReadSingle(), vertReader.ReadSingle(), -vertReader.ReadSingle());
                                            break;
                                        }
                                    }

                                    if (skins && iVertex.BoneIndices == null && mesh.m_Skin.Count > 0)
                                    {
                                        BoneInfluence inf = mesh.m_Skin[(int)submesh.firstVertex + j];
                                        iVertex.BoneIndices = new byte[inf.boneIndex.Length];
                                        for (int k = 0; k < iVertex.BoneIndices.Length; k++)
                                        {
                                            iVertex.BoneIndices[k] = (byte)inf.boneIndex[k];
                                        }
                                        iVertex.Weights = (float[])inf.weight.Clone();
                                    }
                                }
                            }

                            int numFaces = (int)(submesh.indexCount / 3);
                            iSubmesh.FaceList = new List <ImportedFace>(numFaces);
                            indexReader.BaseStream.Position = submesh.firstByte;
                            for (int j = 0; j < numFaces; j++)
                            {
                                ImportedFace face = new ImportedFace();
                                face.VertexIndices    = new int[3];
                                face.VertexIndices[0] = indexReader.ReadUInt16() - (int)submesh.firstVertex;
                                face.VertexIndices[2] = indexReader.ReadUInt16() - (int)submesh.firstVertex;
                                face.VertexIndices[1] = indexReader.ReadUInt16() - (int)submesh.firstVertex;
                                iSubmesh.FaceList.Add(face);
                            }

                            iMesh.SubmeshList.Add(iSubmesh);
                        }
                    }

                    if (skins && meshR is SkinnedMeshRenderer)
                    {
                        SkinnedMeshRenderer sMesh = (SkinnedMeshRenderer)meshR;
                        if (sMesh.m_Bones.Count >= 256)
                        {
                            throw new Exception("Too many bones (" + mesh.m_BindPose.Count + ")");
                        }
                        if (sMesh.m_Bones.Count != mesh.m_BindPose.Count || sMesh.m_Bones.Count != mesh.m_BoneNameHashes.Count)
                        {
                            throw new Exception("Mismatching number of bones bind pose=" + mesh.m_BindPose.Count + " hashes=" + mesh.m_BoneNameHashes.Count + " numBones=" + sMesh.m_Bones.Count);
                        }
                        iMesh.BoneList = new List <ImportedBone>(sMesh.m_Bones.Count);
                        for (int i = 0; i < sMesh.m_Bones.Count; i++)
                        {
                            ImportedBone bone     = new ImportedBone();
                            uint         boneHash = mesh.m_BoneNameHashes[i];
                            bone.Name = avatar.FindBoneName(boneHash);

                            Matrix     m = Matrix.Transpose(mesh.m_BindPose[i]);
                            Vector3    s, t;
                            Quaternion q;
                            m.Decompose(out s, out q, out t);
                            t.X *= -1;
                            Vector3 euler = FbxUtility.QuaternionToEuler(q);
                            euler.Y    *= -1;
                            euler.Z    *= -1;
                            q           = FbxUtility.EulerToQuaternion(euler);
                            bone.Matrix = Matrix.Scaling(s) * Matrix.RotationQuaternion(q) * Matrix.Translation(t);

                            iMesh.BoneList.Add(bone);
                        }
                    }

                    if (morphs && mesh.m_Shapes.shapes.Count > 0)
                    {
                        ImportedMorph morph = new ImportedMorph();
                        morph.Name         = iMesh.Name;
                        morph.ClipName     = Operations.BlendShapeName(mesh);
                        morph.KeyframeList = new List <ImportedMorphKeyframe>(mesh.m_Shapes.shapes.Count);
                        for (int i = 0; i < mesh.m_Shapes.shapes.Count; i++)
                        {
                            ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe();
                            keyframe.Name                 = Operations.BlendShapeKeyframeName(mesh, i);
                            keyframe.VertexList           = new List <ImportedVertex>((int)mesh.m_Shapes.shapes[i].vertexCount);
                            keyframe.MorphedVertexIndices = new List <ushort>((int)mesh.m_Shapes.shapes[i].vertexCount);
                            int lastVertIndex = (int)(mesh.m_Shapes.shapes[i].firstVertex + mesh.m_Shapes.shapes[i].vertexCount);
                            for (int j = (int)mesh.m_Shapes.shapes[i].firstVertex; j < lastVertIndex; j++)
                            {
                                BlendShapeVertex morphVert = mesh.m_Shapes.vertices[j];
                                ImportedVertex   vert      = GetSourceVertex(iMesh.SubmeshList, (int)morphVert.index);
                                ImportedVertex   destVert  = new ImportedVertex();
                                Vector3          morphPos  = morphVert.vertex;
                                morphPos.X       *= -1;
                                destVert.Position = vert.Position + morphPos;
                                Vector3 morphNormal = morphVert.normal;
                                morphNormal.X  *= -1;
                                destVert.Normal = morphNormal;
                                Vector4 morphTangent = new Vector4(morphVert.tangent, 0);
                                morphTangent.X  *= -1;
                                destVert.Tangent = morphTangent;
                                keyframe.VertexList.Add(destVert);
                                keyframe.MorphedVertexIndices.Add((ushort)morphVert.index);
                            }
                            morph.KeyframeList.Add(keyframe);
                        }
                        MorphList.Add(morph);
                    }

                    MeshList.Add(iMesh);
                }
            }
Пример #8
0
            private void ConvertMeshRenderers(List<MeshRenderer> meshList, bool skins, bool morphs)
            {
                MeshList = new List<ImportedMesh>(meshList.Count);
                MaterialList = new List<ImportedMaterial>(meshList.Count);
                TextureList = new List<ImportedTexture>(meshList.Count);
                MorphList = new List<ImportedMorph>(meshList.Count);
                foreach (MeshRenderer meshR in meshList)
                {
                    Mesh mesh = Operations.GetMesh(meshR);
                    if (mesh == null)
                    {
                        Report.ReportLog("skipping " + meshR.m_GameObject.instance.m_Name + " - no mesh");
                        continue;
                    }

                    ImportedMesh iMesh = new ImportedMesh();
                    Transform meshTransform = meshR.m_GameObject.instance.FindLinkedComponent(UnityClassID.Transform);
                    iMesh.Name = meshTransform.GetTransformPath();
                    iMesh.SubmeshList = new List<ImportedSubmesh>(mesh.m_SubMeshes.Count);
                    using (BinaryReader vertReader = new BinaryReader(new MemoryStream(mesh.m_VertexData.m_DataSize)),
                        indexReader = new BinaryReader(new MemoryStream(mesh.m_IndexBuffer)))
                    {
                        for (int i = 0; i < mesh.m_SubMeshes.Count; i++)
                        {
                            SubMesh submesh = mesh.m_SubMeshes[i];
                            ImportedSubmesh iSubmesh = new ImportedSubmesh();
                            iSubmesh.Index = i;
                            iSubmesh.Visible = true;

                            Material mat = meshR.m_Materials[i].instance;
                            ConvertMaterial(mat);
                            iSubmesh.Material = mat.m_Name;

                            iSubmesh.VertexList = new List<ImportedVertex>((int)submesh.vertexCount);
                            for (int str = 0; str < mesh.m_VertexData.m_Streams.Count; str++)
                            {
                                StreamInfo sInfo = mesh.m_VertexData.m_Streams[str];
                                if (sInfo.channelMask == 0)
                                {
                                    continue;
                                }

                                for (int j = 0; j < mesh.m_SubMeshes[i].vertexCount; j++)
                                {
                                    ImportedVertex iVertex;
                                    if (iSubmesh.VertexList.Count < mesh.m_SubMeshes[i].vertexCount)
                                    {
                                        iVertex = new ImportedVertex();
                                        iSubmesh.VertexList.Add(iVertex);
                                    }
                                    else
                                    {
                                        iVertex = iSubmesh.VertexList[j];
                                    }

                                    for (int chn = 0; chn < mesh.m_VertexData.m_Channels.Count; chn++)
                                    {
                                        ChannelInfo cInfo = mesh.m_VertexData.m_Channels[chn];
                                        if ((sInfo.channelMask & (1 << chn)) == 0)
                                        {
                                            continue;
                                        }

                                        vertReader.BaseStream.Position = sInfo.offset + (submesh.firstVertex + j) * sInfo.stride + cInfo.offset;
                                        switch (chn)
                                        {
                                        case 0:
                                            iVertex.Position = new SlimDX.Vector3(-vertReader.ReadSingle(), vertReader.ReadSingle(), vertReader.ReadSingle());
                                            break;
                                        case 1:
                                            iVertex.Normal = new SlimDX.Vector3(-vertReader.ReadSingle(), vertReader.ReadSingle(), vertReader.ReadSingle());
                                            break;
                                        case 3:
                                            iVertex.UV = new float[2] { vertReader.ReadSingle(), vertReader.ReadSingle() };
                                            break;
                                        case 5:
                                            iVertex.Tangent = new SlimDX.Vector4(-vertReader.ReadSingle(), vertReader.ReadSingle(), vertReader.ReadSingle(), -vertReader.ReadSingle());
                                            break;
                                        }
                                    }

                                    if (skins && iVertex.BoneIndices == null && mesh.m_Skin.Count > 0)
                                    {
                                        BoneInfluence inf = mesh.m_Skin[(int)submesh.firstVertex + j];
                                        iVertex.BoneIndices = new byte[inf.boneIndex.Length];
                                        for (int k = 0; k < iVertex.BoneIndices.Length; k++)
                                        {
                                            iVertex.BoneIndices[k] = (byte)inf.boneIndex[k];
                                        }
                                        iVertex.Weights = (float[])inf.weight.Clone();
                                    }
                                }
                            }

                            int numFaces = (int)(submesh.indexCount / 3);
                            iSubmesh.FaceList = new List<ImportedFace>(numFaces);
                            indexReader.BaseStream.Position = submesh.firstByte;
                            for (int j = 0; j < numFaces; j++)
                            {
                                ImportedFace face = new ImportedFace();
                                face.VertexIndices = new int[3];
                                face.VertexIndices[0] = indexReader.ReadUInt16() - (int)submesh.firstVertex;
                                face.VertexIndices[2] = indexReader.ReadUInt16() - (int)submesh.firstVertex;
                                face.VertexIndices[1] = indexReader.ReadUInt16() - (int)submesh.firstVertex;
                                iSubmesh.FaceList.Add(face);
                            }

                            iMesh.SubmeshList.Add(iSubmesh);
                        }
                    }

                    if (skins && meshR is SkinnedMeshRenderer)
                    {
                        SkinnedMeshRenderer sMesh = (SkinnedMeshRenderer)meshR;
                        if (sMesh.m_Bones.Count >= 256)
                        {
                            throw new Exception("Too many bones (" + mesh.m_BindPose.Count + ")");
                        }
                        if (sMesh.m_Bones.Count != mesh.m_BindPose.Count || sMesh.m_Bones.Count != mesh.m_BoneNameHashes.Count)
                        {
                            throw new Exception("Mismatching number of bones bind pose=" + mesh.m_BindPose.Count + " hashes=" + mesh.m_BoneNameHashes.Count + " numBones=" + sMesh.m_Bones.Count);
                        }
                        iMesh.BoneList = new List<ImportedBone>(sMesh.m_Bones.Count);
                        for (int i = 0; i < sMesh.m_Bones.Count; i++)
                        {
                            ImportedBone bone = new ImportedBone();
                            uint boneHash = mesh.m_BoneNameHashes[i];
                            bone.Name = avatar.FindBoneName(boneHash);

                            Matrix m = Matrix.Transpose(mesh.m_BindPose[i]);
                            Vector3 s, t;
                            Quaternion q;
                            m.Decompose(out s, out q, out t);
                            t.X *= -1;
                            Vector3 euler = FbxUtility.QuaternionToEuler(q);
                            euler.Y *= -1;
                            euler.Z *= -1;
                            q = FbxUtility.EulerToQuaternion(euler);
                            bone.Matrix = Matrix.Scaling(s) * Matrix.RotationQuaternion(q) * Matrix.Translation(t);

                            iMesh.BoneList.Add(bone);
                        }
                    }

                    if (morphs && mesh.m_Shapes.shapes.Count > 0)
                    {
                        ImportedMorph morph = new ImportedMorph();
                        morph.Name = iMesh.Name;
                        morph.ClipName = Operations.BlendShapeName(mesh);
                        morph.KeyframeList = new List<ImportedMorphKeyframe>(mesh.m_Shapes.shapes.Count);
                        for (int i = 0; i < mesh.m_Shapes.shapes.Count; i++)
                        {
                            ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe();
                            keyframe.Name = Operations.BlendShapeKeyframeName(mesh, i);
                            keyframe.VertexList = new List<ImportedVertex>((int)mesh.m_Shapes.shapes[i].vertexCount);
                            keyframe.MorphedVertexIndices = new List<ushort>((int)mesh.m_Shapes.shapes[i].vertexCount);
                            int lastVertIndex = (int)(mesh.m_Shapes.shapes[i].firstVertex + mesh.m_Shapes.shapes[i].vertexCount);
                            for (int j = (int)mesh.m_Shapes.shapes[i].firstVertex; j < lastVertIndex; j++)
                            {
                                BlendShapeVertex morphVert = mesh.m_Shapes.vertices[j];
                                ImportedVertex vert = GetSourceVertex(iMesh.SubmeshList, (int)morphVert.index);
                                ImportedVertex destVert = new ImportedVertex();
                                Vector3 morphPos = morphVert.vertex;
                                morphPos.X *= -1;
                                destVert.Position = vert.Position + morphPos;
                                Vector3 morphNormal = morphVert.normal;
                                morphNormal.X *= -1;
                                destVert.Normal = morphNormal;
                                Vector4 morphTangent = new Vector4(morphVert.tangent, 0);
                                morphTangent.X *= -1;
                                destVert.Tangent = morphTangent;
                                keyframe.VertexList.Add(destVert);
                                keyframe.MorphedVertexIndices.Add((ushort)morphVert.index);
                            }
                            morph.KeyframeList.Add(keyframe);
                        }
                        MorphList.Add(morph);
                    }

                    MeshList.Add(iMesh);
                }
            }
Пример #9
0
Файл: Fbx.cs Проект: kkdevs/sb3u
            private void ConvertMeshes(List <odfMesh> meshes, odfParser parser)
            {
                MeshList     = new List <ImportedMesh>(meshes.Count);
                MaterialList = new List <ImportedMaterial>(meshes.Count);
                TextureList  = new List <ImportedTexture>(parser.TextureSection != null ? parser.TextureSection.Count : 0);
                foreach (odfMesh mesh in meshes)
                {
                    ImportedMesh iMesh = new ImportedMesh();
                    MeshList.Add(iMesh);
                    iMesh.Name     = odf.FindMeshFrame(mesh.Id, parser.FrameSection.RootFrame).Name;
                    iMesh.BoneList = new List <ImportedBone>();
                    Dictionary <ObjectID, byte> boneDic = new Dictionary <ObjectID, byte>();
                    iMesh.SubmeshList = new List <ImportedSubmesh>(mesh.Count);
                    foreach (odfSubmesh submesh in mesh)
                    {
                        ImportedSubmesh iSubmesh = new ImportedSubmesh();
                        iMesh.SubmeshList.Add(iSubmesh);
                        odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection);
                        if (mat != null)
                        {
                            iSubmesh.Material = mat.Name;
                            ImportedMaterial iMat = ImportedHelpers.FindMaterial(iSubmesh.Material, MaterialList);
                            if (iMat == null)
                            {
                                iMat = new ImportedMaterial();
                                MaterialList.Add(iMat);
                                iMat.Name     = iSubmesh.Material;
                                iMat.Diffuse  = mat.Diffuse;
                                iMat.Ambient  = mat.Ambient;
                                iMat.Specular = mat.Specular;
                                iMat.Emissive = mat.Emissive;
                                iMat.Power    = mat.SpecularPower;

                                iMat.Textures = new string[4];
                                for (int i = 0; i < 4; i++)
                                {
                                    if (submesh.TextureIds[i] != ObjectID.INVALID)
                                    {
                                        odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[i], parser.TextureSection);
                                        iMat.Textures[i] = tex.Name;
                                        if (ImportedHelpers.FindTexture(iMat.Textures[i], TextureList) == null)
                                        {
                                            try
                                            {
                                                odfTextureFile texFile = new odfTextureFile(iMat.Textures[i], Path.GetDirectoryName(parser.ODFPath) + @"\" + iMat.Textures[i]);
                                                MemoryStream   memStream;
                                                int            filesize = 0;
                                                using (BinaryReader reader = texFile.DecryptFile(ref filesize))
                                                {
                                                    memStream = new MemoryStream(reader.ReadBytes(filesize));
                                                }
                                                ImportedTexture iTex = new ImportedTexture(memStream, iMat.Textures[i]);
                                                TextureList.Add(iTex);
                                            }
                                            catch
                                            {
                                                Report.ReportLog("cant read texture " + iMat.Textures[i]);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        iMat.Textures[i] = String.Empty;
                                    }
                                }
                            }
                        }

                        List <Tuple <byte, float> >[] skin = new List <Tuple <byte, float> > [submesh.NumVertices];
                        for (int i = 0; i < submesh.NumVertices; i++)
                        {
                            skin[i] = new List <Tuple <byte, float> >(4);
                        }
                        odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
                        if (boneList != null)
                        {
                            if (iMesh.BoneList.Capacity < boneList.Count)
                            {
                                iMesh.BoneList.Capacity += boneList.Count;
                            }
                            foreach (odfBone bone in boneList)
                            {
                                byte idx;
                                if (!boneDic.TryGetValue(bone.FrameId, out idx))
                                {
                                    ImportedBone iBone = new ImportedBone();
                                    iMesh.BoneList.Add(iBone);
                                    iBone.Name   = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
                                    iBone.Matrix = bone.Matrix;
                                    boneDic.Add(bone.FrameId, idx = (byte)boneDic.Count);
                                }
                                for (int i = 0; i < bone.NumberIndices; i++)
                                {
                                    skin[bone.VertexIndexArray[i]].Add(new Tuple <byte, float>(idx, bone.WeightArray[i]));
                                }
                            }
                        }

                        iSubmesh.VertexList = new List <ImportedVertex>(submesh.NumVertices);
                        for (int i = 0; i < submesh.NumVertices; i++)
                        {
                            odfVertex      vert  = submesh.VertexList[i];
                            ImportedVertex iVert = new ImportedVertex();
                            iSubmesh.VertexList.Add(iVert);
                            iVert.Position    = vert.Position;
                            iVert.Normal      = vert.Normal;
                            iVert.UV          = new float[] { vert.UV[0], vert.UV[1] };
                            iVert.BoneIndices = new byte[4];
                            iVert.Weights     = new float[4];
                            for (int j = 0; j < 4; j++)
                            {
                                if (j < skin[i].Count)
                                {
                                    Tuple <byte, float> vertIdxWeight = skin[i][j];
                                    iVert.BoneIndices[j] = vertIdxWeight.Item1;
                                    iVert.Weights[j]     = vertIdxWeight.Item2;
                                }
                                else
                                {
                                    iVert.BoneIndices[j] = 0xFF;
                                }
                            }
                        }

                        iSubmesh.FaceList = new List <ImportedFace>(submesh.NumVertexIndices / 3);
                        foreach (odfFace face in submesh.FaceList)
                        {
                            ImportedFace iFace = new ImportedFace();
                            iSubmesh.FaceList.Add(iFace);
                            iFace.VertexIndices = new int[3];
                            for (int i = 0; i < 3; i++)
                            {
                                iFace.VertexIndices[i] = face.VertexIndices[i];
                            }
                        }
                    }
                }
            }