예제 #1
0
파일: remReplace.cs 프로젝트: kkdevs/sb3u
        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);
        }
예제 #2
0
파일: DirectX.cs 프로젝트: hejob/SB3Utility
            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();
                            }
                        }
                    }
                }
            }
예제 #3
0
 private void SetMaterial(Document.Instance instance, ImportedSubmesh submesh)
 {
     if (instance is Document.InstanceWithMaterialBind)
     {
         Document.BindMaterial bindMat = ((Document.InstanceWithMaterialBind)instance).bindMaterial;
         if ((bindMat.instanceMaterials != null) && (bindMat.instanceMaterials.Count > 0))
         {
             foreach (DictionaryEntry de in (IDictionary)(bindMat.instanceMaterials))
             {
                 Document.InstanceMaterial instanceMat = (Document.InstanceMaterial)de.Value;
                 submesh.Material = DecodeName(instanceMat.target.Fragment);
                 break;
             }
         }
     }
 }
예제 #4
0
            private static List <Texture2D> Export(string dest, Animator parser, List <MeshRenderer> meshes, bool worldCoords)
            {
                DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(dest));

                if (!dir.Exists)
                {
                    dir.Create();
                }

                ImageFileFormat preferredUncompressedFormat = (string)Properties.Settings.Default["ExportUncompressedAs"] == "BMP"
                                        ? ImageFileFormat.Bmp : (ImageFileFormat)(-1);

                Operations.UnityConverter conv         = new Operations.UnityConverter(parser, meshes, false, null, false, preferredUncompressedFormat, false);
                List <Material>           materialList = new List <Material>(meshes.Count);

                using (StreamWriter writer = new StreamWriter(dest, false))
                {
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        MeshRenderer meshRenderer = meshes[i];
                        ImportedMesh meshListSome = conv.MeshList[i];
                        for (int j = 0; j < meshListSome.SubmeshList.Count; j++)
                        {
                            Material mat = j < meshRenderer.m_Materials.Count ? meshRenderer.m_Materials[j].instance : null;
                            if (mat != null)
                            {
                                if (!materialList.Contains(mat))
                                {
                                    materialList.Add(mat);
                                }
                            }
                            else
                            {
                                Report.ReportLog("Warning: Mesh " + meshes[i].m_GameObject.instance.m_Name + " Object " + j + " has an invalid material");
                            }
                        }
                    }

                    writer.WriteLine("Metasequoia Document");
                    writer.WriteLine("Format Text Ver 1.0");
                    writer.WriteLine();
                    writer.WriteLine("Material " + materialList.Count + " {");
                    for (int matIdx = 0; matIdx < materialList.Count; matIdx++)
                    {
                        Material mat = materialList[matIdx];
                        string   s   = "\t\"" + mat.m_Name + "\" col(0.800 0.800 0.800 1.000) dif(0.500) amb(0.100) emi(0.500) spc(0.100) power(30.00)";
                        try
                        {
                            Texture2D tex = null;
                            if (mat.m_SavedProperties.m_TexEnvs.Count > 0)
                            {
                                tex = mat.m_SavedProperties.m_TexEnvs[0].Value.m_Texture.instance;
                                for (int i = 1; i < mat.m_SavedProperties.m_TexEnvs.Count; i++)
                                {
                                    var texProp = mat.m_SavedProperties.m_TexEnvs[i];
                                    if (texProp.Key.name == "_MainTex")
                                    {
                                        tex = texProp.Value.m_Texture.instance;
                                        break;
                                    }
                                }
                            }
                            if (tex != null)
                            {
                                string matTexName = tex.m_Name + "-" + tex.m_TextureFormat;
                                string extension  = tex.m_TextureFormat == TextureFormat.DXT1 || tex.m_TextureFormat == TextureFormat.DXT5 ? ".dds" : ".tga";
                                s += " tex(\"" + matTexName + extension + "\")";
                            }
                        }
                        catch { }
                        writer.WriteLine(s);
                    }
                    writer.WriteLine("}");

                    Random rand = new Random();
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        MeshRenderer mesh = meshes[i];
                        if (worldCoords)
                        {
                            Transform parent = meshes[i].m_GameObject.instance.FindLinkedComponent(typeof(Transform));
                            conv.WorldCoordinates(i, Transform.WorldTransform(parent));
                        }

                        string       meshName     = mesh.m_GameObject.instance.m_Name;
                        ImportedMesh meshListSome = conv.MeshList[i];
                        for (int j = 0; j < meshListSome.SubmeshList.Count; j++)
                        {
                            ImportedSubmesh meshObj   = meshListSome.SubmeshList[j];
                            Material        mat       = j < mesh.m_Materials.Count ? mesh.m_Materials[j].instance : null;
                            int             mqoMatIdx = -1;
                            if (mat != null)
                            {
                                mqoMatIdx = materialList.IndexOf(mat);
                            }
                            float[] color = new float[3];
                            for (int k = 0; k < color.Length; k++)
                            {
                                color[k] = (float)((rand.NextDouble() / 2) + 0.5);
                            }

                            string mqoName = meshName + "(Scale=1000)[" + j + "]";
                            if (worldCoords)
                            {
                                mqoName += "[W]";
                            }
                            writer.WriteLine("Object \"" + mqoName + "\" {");
                            writer.WriteLine("\tshading 1");
                            writer.WriteLine("\tcolor " + color[0].ToFloatString() + " " + color[1].ToFloatString() + " " + color[2].ToFloatString());
                            writer.WriteLine("\tcolor_type 1");

                            List <ImportedVertex> vertList = meshObj.VertexList;
                            List <ImportedFace>   faceList = meshObj.FaceList;
                            SB3Utility.Mqo.ExporterCommon.WriteMeshObject(writer, vertList, faceList, mqoMatIdx, null, 1000);
                            writer.WriteLine("}");
                        }
                    }
                    writer.WriteLine("Eof");
                }

                List <Texture2D> usedTextures = new List <Texture2D>(meshes.Count);

                foreach (Material mat in materialList)
                {
                    try
                    {
                        Texture2D matTex = mat.m_SavedProperties.m_TexEnvs[0].Value.m_Texture.instance;
                        for (int i = 1; i < mat.m_SavedProperties.m_TexEnvs.Count; i++)
                        {
                            var texProp = mat.m_SavedProperties.m_TexEnvs[i];
                            if (texProp.Key.name == "_MainTex")
                            {
                                matTex = texProp.Value.m_Texture.instance;
                                break;
                            }
                        }
                        if (matTex != null && !usedTextures.Contains(matTex))
                        {
                            usedTextures.Add(matTex);
                        }
                    }
                    catch { }
                }
                return(usedTextures);
            }
예제 #5
0
        public static odfMesh CreateMesh(WorkspaceMesh mesh, int subMeshFormat, 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];

            odfMesh newMesh = new odfMesh(new ObjectName(String.Empty, null), null, numSubmeshes);

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

                ImportedSubmesh submesh = mesh.SubmeshList[submeshIdx];

                odfSubmesh newSubmesh = new odfSubmesh(new ObjectName(String.Empty, null), null, subMeshFormat);
                newMesh.AddChild(newSubmesh);

                newSubmesh.MaterialId     = ObjectID.INVALID;
                materialNames[i]          = submesh.Material;
                indices[i]                = submesh.Index;
                worldCoords[i]            = submesh.WorldCoords;
                replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]);

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

                    newVertex.Normal      = vert.Normal;
                    newVertex.UV          = new Vector2(vert.UV[0], vert.UV[1]);
                    newVertex.Weights     = (float[])vert.Weights.Clone();
                    newVertex.BoneIndices = (byte[])vert.BoneIndices.Clone();
                    newVertex.Position    = vert.Position;
                    newVertexList.Add(newVertex);
                }
                newSubmesh.VertexList = newVertexList;

                List <ImportedFace> faceList    = submesh.FaceList;
                List <odfFace>      newFaceList = new List <odfFace>(faceList.Count);
                for (int j = 0; j < faceList.Count; j++)
                {
                    int[]   vertexIndices = faceList[j].VertexIndices;
                    odfFace newFace       = new odfFace();
                    newFace.VertexIndices = new ushort[3] {
                        (ushort)vertexIndices[0], (ushort)vertexIndices[1], (ushort)vertexIndices[2]
                    };
                    newFaceList.Add(newFace);
                }
                newSubmesh.FaceList = newFaceList;
            }

            return(newMesh);
        }
예제 #6
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;
            }
예제 #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
파일: Fbx.cs 프로젝트: hejob/SB3Utility
            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];
                            }
                        }
                    }
                }
            }
예제 #9
0
파일: Fbx.cs 프로젝트: hejob/SB3Utility
            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);
                }
            }
예제 #10
0
파일: Fbx.cs 프로젝트: kkdevs/sb3u
            private void ConvertMeshes(List <remMesh> meshes, remParser parser)
            {
                MeshList     = new List <ImportedMesh>(meshes.Count);
                MaterialList = new List <ImportedMaterial>(meshes.Count);
                TextureList  = new List <ImportedTexture>(parser.MATC.Count);
                foreach (remMesh mesh in meshes)
                {
                    ImportedMesh iMesh = new ImportedMesh();
                    MeshList.Add(iMesh);
                    iMesh.BoneList = new List <ImportedBone>();
                    Dictionary <remId, byte> boneDic = new Dictionary <remId, byte>();
                    remSkin  skin          = rem.FindSkin(mesh.name, parser.SKIC);
                    rem.Mesh convertedMesh = new rem.Mesh(mesh, skin);
                    iMesh.SubmeshList = new List <ImportedSubmesh>(convertedMesh.Count);
                    remBone       meshFrame = rem.FindFrame(mesh.frame, parser.BONC.rootFrame);
                    ImportedFrame iFrame    = ImportedHelpers.FindFrame(mesh.frame, FrameList[0]);
                    float         s         = (float)Math.Round(Math.Abs(meshFrame.matrix.M11), 5);
                    iFrame.Name = iMesh.Name = mesh.name + (s != 1f ? "(Scale=" + s.ToString() + ")" : String.Empty);
                    foreach (rem.Submesh submesh in convertedMesh)
                    {
                        ImportedSubmesh iSubmesh = new ImportedSubmesh();
                        iMesh.SubmeshList.Add(iSubmesh);
                        remMaterial mat = rem.FindMaterial(submesh.MaterialName, parser.MATC);
                        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  = new Color4(mat.diffuse);
                                iMat.Ambient  = new Color4(mat.ambient);
                                iMat.Specular = new Color4(mat.specular);
                                iMat.Emissive = new Color4(mat.emissive);
                                iMat.Power    = mat.specularPower;

                                iMat.Textures = new string[4] {
                                    String.Empty, String.Empty, String.Empty, String.Empty
                                };
                                if (mat.texture != null)
                                {
                                    iMat.Textures[0] = mat.texture;
                                    if (ImportedHelpers.FindTexture(iMat.Textures[0], TextureList) == null)
                                    {
                                        try
                                        {
                                            ImportedTexture iTex = rem.ImportedTexture(mat.texture, parser.RemPath, true);
                                            TextureList.Add(iTex);
                                        }
                                        catch
                                        {
                                            Report.ReportLog("cant read texture " + iMat.Textures[0]);
                                        }
                                    }
                                }
                            }
                        }

                        List <Tuple <byte, float> >[] iSkin = new List <Tuple <byte, float> > [submesh.numVertices];
                        for (int i = 0; i < submesh.numVertices; i++)
                        {
                            iSkin[i] = new List <Tuple <byte, float> >(4);
                        }
                        List <remBoneWeights> boneList = submesh.BoneList;
                        if (boneList != null)
                        {
                            if (iMesh.BoneList.Capacity < boneList.Count)
                            {
                                iMesh.BoneList.Capacity += boneList.Count;
                            }
                            foreach (remBoneWeights boneWeights in boneList)
                            {
                                byte idx;
                                if (!boneDic.TryGetValue(boneWeights.bone, out idx))
                                {
                                    ImportedBone iBone = new ImportedBone();
                                    iMesh.BoneList.Add(iBone);
                                    iBone.Name = boneWeights.bone;
                                    Vector3    scale, translate;
                                    Quaternion rotate;
                                    meshFrame.matrix.Decompose(out scale, out rotate, out translate);
                                    scale.X      = Math.Abs(scale.X);
                                    scale.Y      = Math.Abs(scale.Y);
                                    scale.Z      = Math.Abs(scale.Z);
                                    iBone.Matrix = Matrix.Scaling(1f, 1f, -1f) * Matrix.Invert(meshFrame.matrix) * Matrix.Scaling(scale) * boneWeights.matrix;
                                    boneDic.Add(boneWeights.bone, idx = (byte)boneDic.Count);
                                }
                                for (int i = 0; i < boneWeights.numVertIdxWts; i++)
                                {
                                    iSkin[boneWeights.vertexIndices[i]].Add(new Tuple <byte, float>(idx, boneWeights.vertexWeights[i]));
                                }
                            }
                        }

                        iSubmesh.VertexList = new List <ImportedVertex>(submesh.numVertices);
                        for (int i = 0; i < submesh.numVertices; i++)
                        {
                            remVertex      vert  = submesh.VertexList[i];
                            ImportedVertex iVert = new ImportedVertex();
                            iSubmesh.VertexList.Add(iVert);
                            iVert.Position    = new Vector3(vert.Position.X, vert.Position.Z, -vert.Position.Y);
                            iVert.Normal      = new Vector3(vert.Normal.X, vert.Normal.Z, -vert.Normal.Y);
                            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 < iSkin[i].Count)
                                {
                                    Tuple <byte, float> vertIdxWeight = iSkin[i][j];
                                    iVert.BoneIndices[j] = vertIdxWeight.Item1;
                                    iVert.Weights[j]     = vertIdxWeight.Item2;
                                }
                                else
                                {
                                    iVert.BoneIndices[j] = 0xFF;
                                }
                            }
                        }

                        iSubmesh.FaceList = rem.ImportedFaceList(submesh.FaceList);
                    }
                }
            }
예제 #11
0
 public void setSubmeshReplacingOriginal(ImportedSubmesh submesh, bool replaceOriginal)
 {
     AdditionalSubmeshOptions options;
     if (this.SubmeshOptions.TryGetValue(submesh, out options))
     {
         options.ReplaceOriginal = replaceOriginal;
         return;
     }
     throw new Exception("Submesh not found");
 }
예제 #12
0
 public void setSubmeshEnabled(ImportedSubmesh submesh, bool enabled)
 {
     AdditionalSubmeshOptions options;
     if (this.SubmeshOptions.TryGetValue(submesh, out options))
     {
         options.Enabled = enabled;
         return;
     }
     throw new Exception("Submesh not found");
 }
예제 #13
0
 public bool isSubmeshReplacingOriginal(ImportedSubmesh submesh)
 {
     AdditionalSubmeshOptions options;
     if (this.SubmeshOptions.TryGetValue(submesh, out options))
     {
         return options.ReplaceOriginal;
     }
     throw new Exception("Submesh not found");
 }
예제 #14
0
 public bool isSubmeshEnabled(ImportedSubmesh submesh)
 {
     AdditionalSubmeshOptions options;
     if (this.SubmeshOptions.TryGetValue(submesh, out options))
     {
         return options.Enabled;
     }
     throw new Exception("Submesh not found");
 }
예제 #15
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];
                            }
                        }
                    }
                }
            }