Пример #1
0
        private static List <UltimateVertex> CreateVertices(MESH mesh, ISBSkeleton Skeleton, MeshObject meshObject, SSBHVertexAccessor vertexAccessor, uint[] vertexIndices)
        {
            // Read attribute values.
            var positions       = vertexAccessor.ReadAttribute("Position0", 0, meshObject.VertexCount, meshObject);
            var normals         = vertexAccessor.ReadAttribute("Normal0", 0, meshObject.VertexCount, meshObject);
            var tangents        = vertexAccessor.ReadAttribute("Tangent0", 0, meshObject.VertexCount, meshObject);
            var map1Values      = vertexAccessor.ReadAttribute("map1", 0, meshObject.VertexCount, meshObject);
            var uvSetValues     = vertexAccessor.ReadAttribute("uvSet", 0, meshObject.VertexCount, meshObject);
            var uvSet1Values    = vertexAccessor.ReadAttribute("uvSet1", 0, meshObject.VertexCount, meshObject);
            var bake1Values     = vertexAccessor.ReadAttribute("bake1", 0, meshObject.VertexCount, meshObject);
            var colorSet1Values = vertexAccessor.ReadAttribute("colorSet1", 0, meshObject.VertexCount, meshObject);
            var colorSet5Values = vertexAccessor.ReadAttribute("colorSet5", 0, meshObject.VertexCount, meshObject);

            var generatedBitangents = GenerateBitangents(vertexIndices, positions, map1Values);

            var riggingAccessor = new SSBHRiggingAccessor(mesh);
            var influences      = riggingAccessor.ReadRiggingBuffer(meshObject.Name, (int)meshObject.SubMeshIndex);
            var indexByBoneName = new Dictionary <string, int>();

            if (Skeleton != null)
            {
                var Bones = Skeleton.Bones;
                for (int i = 0; i < Bones.Length; i++)
                {
                    indexByBoneName.Add(Bones[i].Name, i);
                }
            }

            GetRiggingData(positions, influences, indexByBoneName, out IVec4[] boneIndices, out Vector4[] boneWeights);
Пример #2
0
        private static List <UltimateVertex> CreateVertices(MESH mesh, ISBSkeleton Skeleton, MeshObject meshObject, SSBHVertexAccessor vertexAccessor, uint[] vertexIndices)
        {
            // Read attribute values.
            var positions        = vertexAccessor.ReadAttribute("Position0", 0, meshObject.VertexCount, meshObject);
            var normals          = vertexAccessor.ReadAttribute("Normal0", 0, meshObject.VertexCount, meshObject);
            var tangents         = vertexAccessor.ReadAttribute("Tangent0", 0, meshObject.VertexCount, meshObject);
            var map1Values       = vertexAccessor.ReadAttribute("map1", 0, meshObject.VertexCount, meshObject);
            var uvSetValues      = vertexAccessor.ReadAttribute("uvSet", 0, meshObject.VertexCount, meshObject);
            var uvSet1Values     = vertexAccessor.ReadAttribute("uvSet1", 0, meshObject.VertexCount, meshObject);
            var uvSet2Values     = vertexAccessor.ReadAttribute("uvSet2", 0, meshObject.VertexCount, meshObject);
            var bake1Values      = vertexAccessor.ReadAttribute("bake1", 0, meshObject.VertexCount, meshObject);
            var colorSet1Values  = vertexAccessor.ReadAttribute("colorSet1", 0, meshObject.VertexCount, meshObject);
            var colorSet2Values  = vertexAccessor.ReadAttribute("colorSet2", 0, meshObject.VertexCount, meshObject);
            var colorSet21Values = vertexAccessor.ReadAttribute("colorSet21", 0, meshObject.VertexCount, meshObject);
            var colorSet22Values = vertexAccessor.ReadAttribute("colorSet22", 0, meshObject.VertexCount, meshObject);
            var colorSet23Values = vertexAccessor.ReadAttribute("colorSet23", 0, meshObject.VertexCount, meshObject);
            var colorSet3Values  = vertexAccessor.ReadAttribute("colorSet3", 0, meshObject.VertexCount, meshObject);
            var colorSet4Values  = vertexAccessor.ReadAttribute("colorSet4", 0, meshObject.VertexCount, meshObject);
            var colorSet5Values  = vertexAccessor.ReadAttribute("colorSet5", 0, meshObject.VertexCount, meshObject);
            var colorSet6Values  = vertexAccessor.ReadAttribute("colorSet6", 0, meshObject.VertexCount, meshObject);
            var colorSet7Values  = vertexAccessor.ReadAttribute("colorSet7", 0, meshObject.VertexCount, meshObject);

            // Generate bitangents.
            // TODO: Use vec4 tangents instead.
            var positionVectors = GetVectors3d(positions);
            var normalVectors   = GetVectors3d(normals);
            var map1Vectors     = GetVectors2d(map1Values);

            SFGraphics.Utils.TriangleListUtils.CalculateTangentsBitangents(positionVectors, normalVectors, map1Vectors, (int[])(object)vertexIndices, out Vector3[] tangentVectors, out Vector3[] bitangentVectors);
Пример #3
0
    static Mesh mesh(int N = 4)
    {
        Node[,] nodes_2D = new Node[2, N + 1];
        Vector3 dir   = Vector3.up,
                start = Vector3.right;

        float a_s = 360f / N;

        for (int x = 0; x <= 1; x += 1)
        {
            Vector3 o = dir * x;

            for (int y = 0; y <= N; y += 1)
            {
                Vector3 v = Z.Rotate(start, -dir, a_s * y);
                nodes_2D[x, y] = new Node()
                {
                    pos  = o + v,
                    wrap = new Vector2(x, 0)
                };
            }
        }

        return(MESH.mesh(nodes_2D));
    }
Пример #4
0
        public void Read(FileReader reader)
        {
            reader.ReadSignature(4, "GMX2");
            reader.SetByteOrder(true);
            HeaderSize = reader.ReadUInt32();

            while (reader.Position < reader.BaseStream.Length)
            {
                long pos = reader.Position;

                string Magic       = reader.ReadString(4);
                uint   SectionSize = reader.ReadUInt32();

                reader.SeekBegin(pos);
                switch (Magic)
                {
                case "PADX":
                    PADX padding = new PADX();
                    padding.Read(reader);
                    break;

                case "INDX":
                    INDX indexGrp = new INDX();
                    indexGrp.Read(reader, GetLastMesh());
                    GetLastMesh().IndexGroup = indexGrp;
                    break;

                case "VMAP":
                    VMAP vmap = new VMAP();
                    vmap.Read(reader);
                    GetLastMesh().VMapGroup = vmap;
                    break;

                case "MESH":
                    MESH mesh = new MESH();
                    mesh.Read(reader);
                    Meshes.Add(mesh);

                    Console.WriteLine($"MESH {mesh.VertexCount} {mesh.FaceCount} {mesh.SkinningFlags} {mesh.VertexSize}");
                    break;

                case "VERT":
                    VERT vert = new VERT();
                    vert.Read(reader, GetLastMesh());
                    GetLastMesh().VertexGroup = vert;
                    break;

                case "ENDX":
                    reader.ReadSignature(4, "ENDX");
                    uint EndSectionSize = reader.ReadUInt32();
                    break;

                default:
                    throw new Exception("Unknown section! " + Magic);
                }

                reader.SeekBegin(pos + SectionSize);
            }
            Console.WriteLine("MESHES " + Meshes.Count);
        }
Пример #5
0
 public void Write(FileWriter writer, MESH mesh)
 {
     writer.WriteSignature("VERT");
     writer.Write(Vertices.Count * mesh.VertexSize + 8);
     for (int v = 0; v < mesh.VertexCount; v++)
     {
         if (mesh.VertexSize == 32)
         {
             writer.Write(Vertices[v].pos);
             writer.Write(Vertices[v].nrm);
             writer.Write(Vertices[v].uv0);
         }
         else if (mesh.VertexSize == 36)
         {
             writer.Write(Unknowns[v]);
             writer.Write(Vertices[v].pos);
             writer.Write(-Vertices[v].nrm);
             writer.Write(Vertices[v].uv0);
         }
         else
         {
             throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}");
         }
     }
 }
Пример #6
0
        // ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
        //----------------------------------------------------------------------------------------------------
        //----------------------------------------------------------------------------------------------------
        // ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■



        //====================================================================================================
        // ■ START
        //====================================================================================================
        void Start()
        {
            var filter = GameObject.MeshFilter;
            var mesh   = filter.sharedMesh;

            var indexArray  = mesh.GetIndices();
            var vertexArray = mesh.GetVertices();

            var indexList = new List <int>();

            for (int i = 0; i < indexArray.Length / 3; i++)
            {
                indexList.Add(indexArray[i * 3 + 0]);
                indexList.Add(indexArray[i * 3 + 1]);

                indexList.Add(indexArray[i * 3 + 1]);
                indexList.Add(indexArray[i * 3 + 2]);

                indexList.Add(indexArray[i * 3 + 2]);
                indexList.Add(indexArray[i * 3 + 0]);
            }

            var newMesh = new MESH();

            newMesh.SetVertices(vertexArray);
            newMesh.SetLineIndices(indexList.ToArray());

            filter.mesh = newMesh;
        }
Пример #7
0
        /// <summary>
        /// Creates a new vertex accessor for given mesh file
        /// </summary>
        /// <param name="meshFile"></param>
        public SSBHVertexAccessor(MESH meshFile)
        {
            if (meshFile == null)
            {
                return;
            }

            this.meshFile = meshFile;
        }
Пример #8
0
 public override void Open(string Path)
 {
     if (SSBH.TryParseSSBHFile(Path, out ISSBH_File ssbhFile))
     {
         if (ssbhFile is MESH)
         {
             mesh = (MESH)ssbhFile;
         }
     }
 }
Пример #9
0
            public void Read(FileReader reader, MESH mesh)
            {
                reader.ReadSignature(4, "INDX");
                uint SectionSize = reader.ReadUInt32();

                Indices = new ushort[mesh.FaceCount];
                for (int i = 0; i < mesh.FaceCount; i++)
                {
                    Indices[i] = reader.ReadUInt16();
                }
            }
Пример #10
0
        //====================================================================================================
        // ■ CREATE MESH
        //====================================================================================================
        void CreateMesh()
        {
            if (ExplosionMesh == null)
            {
                ExplosionMesh = new MESH();
            }
            else
            {
                ExplosionMesh.Clear();
            }

            var vertexArray = new float3[PointCount * 2];
            var indexArray  = new int[(PointCount + 1) * 6];

            //Vertex
            for (int i = 0; i < PointCount; i++)
            {
                var p1 = ExplosionSize * PointArray[i];
                p1.z = PlanetRadius;
                p1   = math.normalize(p1) * PlanetRadius;

                var p2 = ExplosionSize * (1 + ExplosionWidth) * PointArray[i];
                p2.z = PlanetRadius;
                p2   = math.normalize(p2) * PlanetRadius;

                vertexArray[2 * i + 0] = p1;
                vertexArray[2 * i + 1] = p2;
            }

            //Index
            for (int i = 0; i < PointCount; i++)
            {
                var p0 = i * 2 + 0;
                var p1 = i * 2 + 1;

                var p2 = ((i + 1) % PointCount) * 2 + 0;
                var p3 = ((i + 1) % PointCount) * 2 + 1;

                indexArray[i * 6 + 0] = p0;
                indexArray[i * 6 + 1] = p1;
                indexArray[i * 6 + 2] = p3;
                indexArray[i * 6 + 3] = p3;
                indexArray[i * 6 + 4] = p2;
                indexArray[i * 6 + 5] = p0;
            }

            ExplosionMesh.vertices = vertexArray;
            ExplosionMesh.SetTriangleIndices(indexArray);

            GameObject.MeshFilter.sharedMesh = ExplosionMesh;
        }
Пример #11
0
        public SSBHVertexAccessor(MESH meshFile)
        {
            if (meshFile == null)
            {
                return;
            }

            this.meshFile = meshFile;

            buffers = new BinaryReader[meshFile.VertexBuffers.Length];
            for (int i = 0; i < meshFile.VertexBuffers.Length; i++)
            {
                buffers[i] = new BinaryReader(new MemoryStream(meshFile.VertexBuffers[i].Buffer));
            }
            indexBuffer = new BinaryReader(new MemoryStream(meshFile.PolygonBuffer));
        }
Пример #12
0
        private void MESH()
        {
            FileInfo fi = new FileInfo(textBoxFile5.Text);

            if (!fi.Exists)
            {
                richTextBoxStatus.Text = "File [" + fi.FullName + "] does not exist.\r\n";
                return;
            }

            using (MESH mesh = new MESH(fi))
            {
                mesh.CSSPDHIChanged += CSSPDHIChanged;
                mesh.ReadFile();
                mesh.CSSPDHIChanged -= CSSPDHIChanged;
            }
        }
Пример #13
0
        public override void Open()
        {
            string ADJB = System.IO.Path.GetDirectoryName(AbsolutePath) + "/model.adjb";

            System.Console.WriteLine(ADJB);
            if (File.Exists(ADJB))
            {
                ExtendedMesh = new ADJB();
                ExtendedMesh.Read(ADJB);
            }

            if (SSBH.TryParseSSBHFile(AbsolutePath, out ISSBH_File ssbhFile))
            {
                if (ssbhFile is MESH)
                {
                    mesh = (MESH)ssbhFile;
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Creates a vertex accessor from given MESH filepath
        /// </summary>
        /// <param name="FilePath"></param>
        public SSBHVertexAccessor(string meshFilePath)
        {
            if (SSBH.TryParseSSBHFile(meshFilePath, out ISSBH_File file))
            {
                if (file == null)
                {
                    throw new FileNotFoundException("File was null");
                }

                if (file is MESH mesh)
                {
                    meshFile = mesh;
                }
                else
                {
                    throw new FormatException("Given file was not a MESH file");
                }
            }
        }
Пример #15
0
        static MESH CreateMesh(int boneCount)
        {
            var mesh = new MESH("skinned mesh");

            mesh.VertexPreprocessor.SetValidationPreprocessors();

            var prim = mesh.UsePrimitive(new SharpGLTF.Materials.MaterialBuilder("Default"));

            var a0 = default(VERTEX);
            var a1 = default(VERTEX);
            var a2 = default(VERTEX);
            var a3 = default(VERTEX);

            for (int i = 0; i < boneCount; ++i)
            {
                var b0 = new VERTEX(new Vector3(-5, i * 10, -5), Vector4.One, (i, 1));
                var b1 = new VERTEX(new Vector3(+5, i * 10, -5), Vector4.One, (i, 1));
                var b2 = new VERTEX(new Vector3(+5, i * 10, +5), Vector4.One, (i, 1));
                var b3 = new VERTEX(new Vector3(-5, i * 10, +5), Vector4.One, (i, 1));

                if (i == 0)
                {
                    prim.AddQuadrangle(b0, b1, b2, b3);
                }
                else
                {
                    prim.AddQuadrangle(b0, b1, a1, a0);
                    prim.AddQuadrangle(b1, b2, a2, a1);
                    prim.AddQuadrangle(b2, b3, a3, a2);
                    prim.AddQuadrangle(b3, b0, a0, a3);
                }

                a0 = b0;
                a1 = b1;
                a2 = b2;
                a3 = b3;
            }

            prim.AddQuadrangle(a3, a2, a1, a0);

            return(mesh);
        }
Пример #16
0
 public void Write(FileWriter writer, MESH mesh)
 {
     writer.WriteSignature("VERT");
     writer.Write(Vertices.Count * mesh.VertexSize + 8);
     for (int v = 0; v < mesh.VertexCount; v++)
     {
         if (mesh.VertexSize == 32)
         {
             writer.Write(Vertices[v].Position);
             writer.Write(Vertices[v].Normal);
             writer.Write(Vertices[v].TexCoord0);
         }
         else if (mesh.VertexSize == 36 && mesh.SkinningFlags != 0)
         {
             writer.Write(Vertices[v].MatrixID);
             writer.Write(Vertices[v].Position);
             writer.Write(Vertices[v].Normal);
             writer.Write(Vertices[v].TexCoord0);
         }
         else if (mesh.SkinningFlags != 0 && mesh.SkinningFlags != 0)
         {
             writer.Write(Vertices[v].MatrixID);
             writer.Write(Vertices[v].Position);
             writer.Write(Vertices[v].Normal);
             writer.Write((byte)Vertices[v].Color.X);
             writer.Write((byte)Vertices[v].Color.Y);
             writer.Write((byte)Vertices[v].Color.Z);
             writer.Write((byte)Vertices[v].Color.W);
             writer.Write(Vertices[v].TexCoord0);
         }
         else
         {
             throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}");
         }
     }
 }
Пример #17
0
        public IOModel GetIOModel()
        {
            IOModel outModel = new IOModel();

            MESH meshFile     = null;
            MATL materialFile = null;

            foreach (FileNode n in Parent.Nodes)
            {
                if (n.Text.Equals(_model.MeshString))
                {
                    meshFile = ((NUMSHB_Node)n).mesh;
                }
                if (n.Text.Equals(_model.SkeletonFileName))
                {
                    outModel.Skeleton = (RSkeleton)((SKEL_Node)n).GetRenderableNode();
                }
                if (n.Text.Equals(_model.MaterialFileNames[0].MaterialFileName))
                {
                    materialFile = ((MATL_Node)n).Material;
                }
            }

            Dictionary <string, int> indexByBoneName = new Dictionary <string, int>();

            if (outModel.Skeleton != null)
            {
                for (int i = 0; i < outModel.Skeleton.Bones.Count; i++)
                {
                    indexByBoneName.Add(outModel.Skeleton.Bones[i].Name, i);
                }
            }

            Dictionary <string, int> materialNameToIndex = new Dictionary <string, int>();

            if (materialFile != null)
            {
                int materialIndex = 0;
                foreach (var entry in materialFile.Entries)
                {
                    materialNameToIndex.Add(entry.MaterialLabel, materialIndex++);
                    IOMaterial material = new IOMaterial();
                    material.Name = entry.MaterialLabel;
                    outModel.Materials.Add(material);

                    foreach (var attr in entry.Attributes)
                    {
                        if (attr.ParamID == MatlEnums.ParamId.Texture0)
                        {
                            IOTexture dif = new IOTexture();
                            dif.Name = attr.DataObject.ToString();
                            material.DiffuseTexture = dif;
                        }
                    }
                }
            }

            if (meshFile != null)
            {
                SSBHVertexAccessor vertexAccessor = new SSBHVertexAccessor(meshFile);
                {
                    SSBHRiggingAccessor riggingAccessor = new SSBHRiggingAccessor(meshFile);
                    foreach (MeshObject obj in meshFile.Objects)
                    {
                        IOMesh outMesh = new IOMesh()
                        {
                            Name = obj.Name,
                        };
                        outModel.Meshes.Add(outMesh);

                        // get material
                        if (materialFile != null)
                        {
                            foreach (var entry in _model.ModelEntries)
                            {
                                if (entry.MeshName.Equals(obj.Name) && entry.SubIndex == obj.SubMeshIndex)
                                {
                                    outMesh.MaterialIndex = materialNameToIndex[entry.MaterialName];
                                    break;
                                }
                            }
                        }

                        IOVertex[] vertices = new IOVertex[obj.VertexCount];
                        for (int i = 0; i < vertices.Length; i++)
                        {
                            vertices[i] = new IOVertex();
                        }

                        foreach (MeshAttribute attr in obj.Attributes)
                        {
                            SSBHVertexAttribute[] values = vertexAccessor.ReadAttribute(attr.AttributeStrings[0].Name, 0, obj.VertexCount, obj);

                            if (attr.AttributeStrings[0].Name.Equals("Position0"))
                            {
                                outMesh.HasPositions = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Position = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("Normal0"))
                            {
                                outMesh.HasNormals = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Normal = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }

                            // Flip UVs vertically for export.
                            if (attr.AttributeStrings[0].Name.Equals("map1"))
                            {
                                outMesh.HasUV0 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV0 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet"))
                            {
                                outMesh.HasUV1 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV1 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet1"))
                            {
                                outMesh.HasUV2 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV2 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet2"))
                            {
                                outMesh.HasUV3 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV3 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("colorSet1"))
                            {
                                outMesh.HasColor = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Color = new OpenTK.Vector4(values[i].X, values[i].Y, values[i].Z, values[i].W) / 127f;
                                }
                            }
                        }

                        // Fix SingleBinds
                        if (outModel.Skeleton != null && !obj.ParentBoneName.Equals(""))
                        {
                            int parentIndex = outModel.Skeleton.GetBoneIndex(obj.ParentBoneName);
                            if (parentIndex != -1)
                            {
                                for (int i = 0; i < vertices.Length; i++)
                                {
                                    vertices[i].Position      = OpenTK.Vector3.TransformPosition(vertices[i].Position, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].Normal        = OpenTK.Vector3.TransformNormal(vertices[i].Normal, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].BoneIndices.X = indexByBoneName[obj.ParentBoneName];
                                    vertices[i].BoneWeights.X = 1;
                                    outMesh.HasBoneWeights    = true;
                                }
                            }
                        }

                        // Apply Rigging
                        SSBHVertexInfluence[] influences = riggingAccessor.ReadRiggingBuffer(obj.Name, (int)obj.SubMeshIndex);

                        foreach (SSBHVertexInfluence influence in influences)
                        {
                            outMesh.HasBoneWeights = true;

                            // Some influences refer to bones that don't exist in the skeleton.
                            // _eff bones?
                            if (!indexByBoneName.ContainsKey(influence.BoneName))
                            {
                                continue;
                            }

                            if (vertices[influence.VertexIndex].BoneWeights.X == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.X = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.X = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Y == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Y = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Y = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Z == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Z = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Z = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.W == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.W = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.W = influence.Weight;
                            }
                        }

                        outMesh.Vertices.AddRange(vertices);
                        outMesh.Indices.AddRange(vertexAccessor.ReadIndices(0, obj.IndexCount, obj));
                    }
                }
            }


            return(outModel);
        }
Пример #18
0
            public void Read(FileReader reader, MESH mesh)
            {
                reader.ReadSignature(4, "VERT");
                uint SectionSize = reader.ReadUInt32();

                if (mesh.VertexSize == 32)
                {
                    for (int v = 0; v < mesh.VertexCount; v++)
                    {
                        Vertex vert = new Vertex();
                        vert.Position  = reader.ReadVec3();
                        vert.Normal    = reader.ReadVec3();
                        vert.TexCoord0 = reader.ReadVec2();
                        Vertices.Add(vert);
                    }
                }
                else if (mesh.VertexSize == 12)
                {
                    for (int v = 0; v < mesh.VertexCount; v++)
                    {
                        Vertex vert = new Vertex();
                        vert.Position = reader.ReadVec3();
                        Vertices.Add(vert);
                    }
                }
                else if (mesh.VertexSize == 20)
                {
                    for (int v = 0; v < mesh.VertexCount; v++)
                    {
                        Vertex vert = new Vertex();
                        vert.Position  = reader.ReadVec3();
                        vert.TexCoord0 = reader.ReadVec2();
                        Vertices.Add(vert);
                    }
                }
                else if (mesh.VertexSize == 24)
                {
                    for (int v = 0; v < mesh.VertexCount; v++)
                    {
                        Vertex vert = new Vertex();
                        vert.Position = reader.ReadVec3();
                        vert.Normal   = reader.ReadVec3();
                        Vertices.Add(vert);
                    }
                }
                else if (mesh.VertexSize == 36)
                {
                    for (int v = 0; v < mesh.VertexCount; v++)
                    {
                        Vertex vert = new Vertex();
                        if (mesh.SkinningFlags != 0)
                        {
                            vert.MatrixID  = reader.ReadUInt32();
                            vert.Position  = reader.ReadVec3();
                            vert.Normal    = reader.ReadVec3();
                            vert.TexCoord0 = reader.ReadVec2();
                        }
                        else
                        {
                            vert.Position  = reader.ReadVec3();
                            vert.Normal    = reader.ReadVec3();
                            vert.Color     = ColorUtility.ToVector4(reader.ReadBytes(4));
                            vert.TexCoord0 = reader.ReadVec2();
                        }

                        Vertices.Add(vert);
                    }
                }
                else if (mesh.VertexSize == 40)
                {
                    for (int v = 0; v < mesh.VertexCount; v++)
                    {
                        Vertex vert = new Vertex();
                        if (mesh.SkinningFlags != 0)
                        {
                            vert.MatrixID  = reader.ReadUInt32(); //Bone index?
                            vert.Position  = reader.ReadVec3();
                            vert.Normal    = reader.ReadVec3();
                            vert.Color     = ColorUtility.ToVector4(reader.ReadBytes(4));
                            vert.TexCoord0 = reader.ReadVec2();
                        }
                        else
                        {
                            throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}");
                        }


                        Vertices.Add(vert);
                    }
                }
                else if (mesh.VertexSize == 44)
                {
                    for (int v = 0; v < mesh.VertexCount; v++)
                    {
                        Vertex vert = new Vertex();
                        vert.Position  = reader.ReadVec3();
                        vert.Normal    = reader.ReadVec3();
                        vert.Color     = ColorUtility.ToVector4(reader.ReadBytes(4));
                        vert.TexCoord0 = reader.ReadVec2();
                        vert.TexCoord1 = reader.ReadVec2();

                        Vertices.Add(vert);
                    }
                }
                else
                {
                    throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}");
                }
            }
Пример #19
0
        public bool ExportMeshWithMaterials(Stream meshStream, FileInfo outfile, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds, bool isGLBinary = true, bool LodFilter = true)
        {
            if (matRepo == null)
            {
                throw new Exception("Material Repository Path is not set, Please select a folder in the Material Repository Settings where your textures will output, Generating the complete dump is not required.");
            }

            var cr2w = _wolvenkitFileService.TryReadRED4File(meshStream);

            if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
            {
                return(false);
            }
            DirectoryInfo outDir = new DirectoryInfo(Path.Combine(outfile.DirectoryName, Path.GetFileNameWithoutExtension(outfile.FullName)));

            MESH.MeshBones meshBones = new MESH.MeshBones();

            meshBones.boneCount = cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First().BoneNames.Count;

            if (meshBones.boneCount != 0)    // for rigid meshes
            {
                meshBones.Names     = RIG.GetboneNames(cr2w);
                meshBones.WorldPosn = MESH.GetMeshBonesPosn(cr2w);
            }
            RawArmature Rig = MESH.GetNonParentedRig(meshBones);

            MemoryStream ms       = MESH.GetMeshBufferStream(meshStream, cr2w);
            MeshesInfo   meshinfo = MESH.GetMeshesinfo(cr2w);

            List <RawMeshContainer> expMeshes = MESH.ContainRawMesh(ms, meshinfo, LodFilter);

            if (meshBones.boneCount == 0)    // for rigid meshes
            {
                for (int i = 0; i < expMeshes.Count; i++)
                {
                    expMeshes[i].weightcount = 0;
                }
            }
            MESH.UpdateMeshJoints(ref expMeshes, Rig, meshBones);

            ModelRoot model = MESH.RawMeshesToGLTF(expMeshes, Rig);

            if (!outDir.Exists)
            {
                Directory.CreateDirectory(outDir.FullName);
            }

            ParseMaterials(cr2w, meshStream, outDir, archives, matRepo, eUncookExtension);

            if (isGLBinary)
            {
                model.SaveGLB(outfile.FullName);
            }
            else
            {
                model.SaveGLTF(outfile.FullName);
            }

            meshStream.Dispose();
            meshStream.Close();

            return(true);
        }
Пример #20
0
        //====================================================================================================
        // ■ CREATE MESH
        //====================================================================================================
        void CreateMesh()
        {
            if (PointList.Count >= 2)
            {
                if (WallMesh == null)
                {
                    WallMesh = new MESH();
                }
                else
                {
                    WallMesh.Clear();
                }

                int count = PointList.Count;

                var vertexArray = new float3[count * 4];
                var indexArray  = new int[(count - 1) * 18 + 12];

                //Vertex
                for (int i = 0; i < count; i++)
                {
                    var    p = PointList[i];
                    float3 tangent;

                    if (i - 1 >= 0)
                    {
                        var t = PointList[i - 1].Position;
                        tangent = math.normalize(p.Position - t);
                    }
                    else
                    {
                        var t = PointList[i + 1].Position;
                        tangent = math.normalize(t - p.Position);
                    }

                    var center = math.normalize(p.Position);

                    var normal = math.normalize(math.cross(tangent, center));

                    var gridPosition = p.Position - center * GridDistance;

                    vertexArray[4 * i + 0] = gridPosition - normal * WallWidth;
                    vertexArray[4 * i + 1] = gridPosition + center * WallHeight - normal * WallWidth;
                    vertexArray[4 * i + 2] = gridPosition + center * WallHeight + normal * WallWidth;
                    vertexArray[4 * i + 3] = gridPosition + normal * WallWidth;
                }

                //Index
                for (int i = 0; i < count - 1; i++)
                {
                    var p0 = i * 4 + 0;
                    var p1 = i * 4 + 1;
                    var p2 = i * 4 + 2;
                    var p3 = i * 4 + 3;

                    var p4 = (i + 1) * 4 + 0;
                    var p5 = (i + 1) * 4 + 1;
                    var p6 = (i + 1) * 4 + 2;
                    var p7 = (i + 1) * 4 + 3;

                    indexArray[i * 18 + 0] = p4;
                    indexArray[i * 18 + 1] = p5;
                    indexArray[i * 18 + 2] = p1;
                    indexArray[i * 18 + 3] = p1;
                    indexArray[i * 18 + 4] = p0;
                    indexArray[i * 18 + 5] = p4;

                    indexArray[i * 18 + 6]  = p1;
                    indexArray[i * 18 + 7]  = p5;
                    indexArray[i * 18 + 8]  = p6;
                    indexArray[i * 18 + 9]  = p6;
                    indexArray[i * 18 + 10] = p2;
                    indexArray[i * 18 + 11] = p1;

                    indexArray[i * 18 + 12] = p3;
                    indexArray[i * 18 + 13] = p2;
                    indexArray[i * 18 + 14] = p6;
                    indexArray[i * 18 + 15] = p6;
                    indexArray[i * 18 + 16] = p7;
                    indexArray[i * 18 + 17] = p3;
                }

                //begin, end close
                var v0 = 0 * 4 + 0;
                var v1 = 0 * 4 + 1;
                var v2 = 0 * 4 + 2;
                var v3 = 0 * 4 + 3;

                var v4 = (count - 1) * 4 + 0;
                var v5 = (count - 1) * 4 + 1;
                var v6 = (count - 1) * 4 + 2;
                var v7 = (count - 1) * 4 + 3;

                int j = count - 1;
                indexArray[j * 18 + 0] = v0;
                indexArray[j * 18 + 1] = v1;
                indexArray[j * 18 + 2] = v2;
                indexArray[j * 18 + 3] = v2;
                indexArray[j * 18 + 4] = v3;
                indexArray[j * 18 + 5] = v0;

                indexArray[j * 18 + 6]  = v7;
                indexArray[j * 18 + 7]  = v6;
                indexArray[j * 18 + 8]  = v5;
                indexArray[j * 18 + 9]  = v5;
                indexArray[j * 18 + 10] = v4;
                indexArray[j * 18 + 11] = v7;

                WallMesh.vertices = vertexArray;
                WallMesh.SetTriangleIndices(indexArray);

                GameObject.MeshFilter.sharedMesh = WallMesh;
            }
        }
Пример #21
0
        private static void ContainedMeshToGLTF(List <RawMeshContainer> meshes, FileInfo outfile)
        {
            var scene = new SharpGLTF.Scenes.SceneBuilder();

            int mIndex = -1;

            foreach (var mesh in meshes)
            {
                ++mIndex;
                long indCount = mesh.indices.Length;
                var  expmesh  = new MESH(string.Format(Path.GetFileNameWithoutExtension(outfile.FullName) + "_mesh_{0}", mIndex));

                var prim = expmesh.UsePrimitive(new MaterialBuilder("Default"));
                for (long i = 0; i < indCount; i += 3)
                {
                    uint idx0 = mesh.indices[i + 1];
                    uint idx1 = mesh.indices[i];
                    uint idx2 = mesh.indices[i + 2];

                    //VPNT
                    Vec3 p_0 = new Vec3(mesh.vertices[idx0].X, mesh.vertices[idx0].Y, mesh.vertices[idx0].Z);
                    Vec3 n_0 = new Vec3(mesh.normals[idx0].X, mesh.normals[idx0].Y, mesh.normals[idx0].Z);
                    Vec4 t_0 = new Vec4(new Vec3(mesh.tangents[idx0].X, mesh.tangents[idx0].Y, mesh.tangents[idx0].Z), 1);

                    Vec3 p_1 = new Vec3(mesh.vertices[idx1].X, mesh.vertices[idx1].Y, mesh.vertices[idx1].Z);
                    Vec3 n_1 = new Vec3(mesh.normals[idx1].X, mesh.normals[idx1].Y, mesh.normals[idx1].Z);
                    Vec4 t_1 = new Vec4(new Vec3(mesh.tangents[idx1].X, mesh.tangents[idx1].Y, mesh.tangents[idx1].Z), 1);

                    Vec3 p_2 = new Vec3(mesh.vertices[idx2].X, mesh.vertices[idx2].Y, mesh.vertices[idx2].Z);
                    Vec3 n_2 = new Vec3(mesh.normals[idx2].X, mesh.normals[idx2].Y, mesh.normals[idx2].Z);
                    Vec4 t_2 = new Vec4(new Vec3(mesh.tangents[idx2].X, mesh.tangents[idx2].Y, mesh.tangents[idx2].Z), 1);

                    //VCT
                    Vec2 tx0_0 = new Vec2(mesh.tx0coords[idx0].X, mesh.tx0coords[idx0].Y);
                    Vec2 tx1_0 = new Vec2(mesh.tx1coords[idx0].X, mesh.tx1coords[idx0].Y);

                    Vec2 tx0_1 = new Vec2(mesh.tx0coords[idx1].X, mesh.tx0coords[idx1].Y);
                    Vec2 tx1_1 = new Vec2(mesh.tx1coords[idx1].X, mesh.tx1coords[idx1].Y);

                    Vec2 tx0_2 = new Vec2(mesh.tx0coords[idx2].X, mesh.tx0coords[idx2].Y);
                    Vec2 tx1_2 = new Vec2(mesh.tx1coords[idx2].X, mesh.tx1coords[idx2].Y);

                    Vec4 col_0 = new Vec4(mesh.colors[idx0].X, mesh.colors[idx0].Y, mesh.colors[idx0].Z, mesh.colors[idx0].W);
                    Vec4 col_1 = new Vec4(mesh.colors[idx1].X, mesh.colors[idx1].Y, mesh.colors[idx1].Z, mesh.colors[idx1].W);
                    Vec4 col_2 = new Vec4(mesh.colors[idx2].X, mesh.colors[idx2].Y, mesh.colors[idx2].Z, mesh.colors[idx2].W);

                    // vertex build
                    var v0 = new VERTEX(new VPNT(p_0, n_0, t_0), new VCT(col_0, tx0_0, tx1_0));
                    var v1 = new VERTEX(new VPNT(p_1, n_1, t_1), new VCT(col_1, tx0_1, tx1_1));
                    var v2 = new VERTEX(new VPNT(p_2, n_2, t_2), new VCT(col_2, tx0_2, tx1_2));

                    // triangle build
                    prim.AddTriangle(v0, v1, v2);
                }
                scene.AddRigidMesh(expmesh, System.Numerics.Matrix4x4.Identity);
            }

            var model = scene.ToGltf2();

            model.SaveGLB(Path.GetFullPath(outfile.FullName).Replace(".mesh", ".glb"));
        }
Пример #22
0
    public static Mesh mesh(int N = 32)
    {
        #region Ball

        /*
         * Vector3 a = Vector3.right,
         * b = Vector3.up,
         * K = -Vector3.forward;
         *
         * Node[,] nodes_2D = new Node[N + 1, N + 1];
         * float A_s = 180f / N,
         *    a_s = 2f * A_s;
         *
         * for (int y = 0; y <= N; y += 1)
         * {
         *  Vector3 V = Z.Rotate(-b, K, y * A_s);
         *  float _x = Z.dot(V, a),
         *        _y = Z.dot(V, b);
         *
         *  for (int x = 0; x <= N; x += 1)
         *  {
         *      Vector3 pos = Z.Rotate(a, b, x * a_s);
         *
         *      nodes_2D[x, y] = new Node()
         *      {
         *          pos = pos * _x + b * _y,
         *          wrap = new Vector2(x, y) / N
         *      };
         *  }
         * }
         */
        #endregion


        float[] R = new float[3]
        {
            0f, 0.7f, 1f
        };
        int l = R.Length - 1;

        Node[,] nodes_2D = new Node[l + 1, N + 1];

        Vector3 k     = Vector3.forward,
                start = Vector3.up;
        float a_s     = 360f / N;

        for (int x = 0; x <= l; x += 1)
        {
            for (int y = 0; y <= N; y += 1)
            {
                Vector3 pos = Z.Rotate(start, -k, a_s * y);

                nodes_2D[x, y] = new Node()
                {
                    pos  = pos * R[x],
                    wrap = new Vector2(x, 0) / l
                };
            }
        }

        return(MESH.mesh(nodes_2D));
    }
Пример #23
0
        /// <summary>
        /// Creates and returns a mesh file
        /// </summary>
        /// <returns></returns>
        public MESH GetMeshFile()
        {
            MESH mesh = new MESH
            {
                //TODO: bounding box stuff
                // Rigging
                Objects = new MeshObject[meshes.Count]
            };

            // create mesh objects and buffers
            BinaryWriter             vertexBuffer1     = new BinaryWriter(new MemoryStream());
            BinaryWriter             vertexBuffer2     = new BinaryWriter(new MemoryStream()); // there are actually 4 buffers, but only 2 seem to be used
            BinaryWriter             indexBuffer       = new BinaryWriter(new MemoryStream());
            int                      finalBufferOffset = 0;
            int                      meshIndex         = 0;
            Dictionary <string, int> MeshGroups        = new Dictionary <string, int>();
            List <MeshRiggingGroup>  RiggingGroups     = new List <MeshRiggingGroup>();

            foreach (var tempmesh in meshes)
            {
                MeshObject mo = new MeshObject
                {
                    Name = tempmesh.Name
                };
                if (MeshGroups.ContainsKey(mo.Name))
                {
                    MeshGroups[mo.Name] += 1;
                }
                else
                {
                    MeshGroups.Add(mo.Name, 0);
                }

                mo.SubMeshIndex         = MeshGroups[mo.Name];
                mo.BoundingSphereX      = tempmesh.BoundingSphere.X;
                mo.BoundingSphereY      = tempmesh.BoundingSphere.Y;
                mo.BoundingSphereZ      = tempmesh.BoundingSphere.Z;
                mo.BoundingSphereRadius = tempmesh.BoundingSphere.W;

                mo.MaxBoundingBoxX = tempmesh.BBMax.X;
                mo.MaxBoundingBoxY = tempmesh.BBMax.Y;
                mo.MaxBoundingBoxZ = tempmesh.BBMax.Z;
                mo.MinBoundingBoxX = tempmesh.BBMin.X;
                mo.MinBoundingBoxY = tempmesh.BBMin.Y;
                mo.MinBoundingBoxZ = tempmesh.BBMin.Z;

                mo.OBBCenterX = tempmesh.OBBCenter.X;
                mo.OBBCenterY = tempmesh.OBBCenter.Y;
                mo.OBBCenterZ = tempmesh.OBBCenter.Z;

                mo.OBBSizeX = tempmesh.OBBSize.X;
                mo.OBBSizeY = tempmesh.OBBSize.Y;
                mo.OBBSizeZ = tempmesh.OBBSize.Z;

                mo.M11 = tempmesh.OBBMatrix3x3[0];
                mo.M12 = tempmesh.OBBMatrix3x3[1];
                mo.M13 = tempmesh.OBBMatrix3x3[2];
                mo.M21 = tempmesh.OBBMatrix3x3[3];
                mo.M22 = tempmesh.OBBMatrix3x3[4];
                mo.M23 = tempmesh.OBBMatrix3x3[5];
                mo.M31 = tempmesh.OBBMatrix3x3[6];
                mo.M32 = tempmesh.OBBMatrix3x3[7];
                mo.M33 = tempmesh.OBBMatrix3x3[8];


                // Create Rigging
                RiggingGroups.Add(SSBHRiggingCompiler.CreateRiggingGroup(mo.Name, (int)mo.SubMeshIndex, tempmesh.Influences.ToArray()));

                // set object
                mesh.Objects[meshIndex++] = mo;

                mo.ParentBoneName = tempmesh.ParentBone;
                if (tempmesh.Influences.Count > 0 && (tempmesh.ParentBone == null || tempmesh.ParentBone.Equals("")))
                {
                    mo.HasRigging = 1;
                }

                int Stride1 = 0;
                int Stride2 = 0;

                mo.VertexOffset  = (int)vertexBuffer1.BaseStream.Length;
                mo.VertexOffset2 = (int)vertexBuffer2.BaseStream.Length;
                mo.ElementOffset = (uint)indexBuffer.BaseStream.Length;

                // gather strides
                mo.Attributes = new MeshAttribute[tempmesh.VertexData.Count];
                int attributeIndex = 0;
                foreach (var keypair in tempmesh.VertexData)
                {
                    MeshAttribute attr = new MeshAttribute
                    {
                        Name             = GetAttributeName(keypair.Key),
                        Index            = GetAttributeIndex(keypair.Key),
                        BufferIndex      = GetBufferIndex(keypair.Key),
                        DataType         = GetAttributeDataType(keypair.Key),
                        BufferOffset     = (GetBufferIndex(keypair.Key) == 0) ? Stride1 : Stride2,
                        AttributeStrings = new MeshAttributeString[] { new MeshAttributeString()
                                                                       {
                                                                           Name = keypair.Key.ToString()
                                                                       } }
                    };
                    mo.Attributes[attributeIndex++] = attr;

                    if (GetBufferIndex(keypair.Key) == 0)
                    {
                        Stride1 += GetAttributeSize(keypair.Key) * GetAttributeDataSize(keypair.Key);
                    }
                    else
                    {
                        Stride2 += GetAttributeSize(keypair.Key) * GetAttributeDataSize(keypair.Key);
                    }
                }

                // now that strides are known...
                long Buffer1Start = vertexBuffer1.BaseStream.Length;
                long Buffer2Start = vertexBuffer2.BaseStream.Length;
                vertexBuffer1.Write(new byte[Stride1 * tempmesh.VertexCount]);
                vertexBuffer2.Write(new byte[Stride2 * tempmesh.VertexCount]);
                attributeIndex = 0;
                foreach (var keypair in tempmesh.VertexData)
                {
                    var     attr         = mo.Attributes[attributeIndex++];
                    float[] Data         = keypair.Value;
                    var     buffer       = attr.BufferIndex == 0 ? vertexBuffer1 : vertexBuffer2;
                    int     bufferOffset = (int)(attr.BufferIndex == 0 ? Buffer1Start : Buffer2Start);
                    int     stride       = (attr.BufferIndex == 0 ? Stride1 : Stride2);
                    int     size         = GetAttributeSize(keypair.Key);
                    for (int vertexIndex = 0; vertexIndex < tempmesh.VertexCount; vertexIndex++)
                    {
                        buffer.Seek(bufferOffset + stride * vertexIndex + attr.BufferOffset, SeekOrigin.Begin);
                        for (int j = 0; j < size; j++)
                        {
                            WriteType(buffer, attr.DataType, Data[vertexIndex * size + j]);
                        }
                    }
                    // seek to end just to make sure
                    buffer.Seek((int)buffer.BaseStream.Length, SeekOrigin.Begin);
                }

                mo.FinalBufferOffset = finalBufferOffset;
                finalBufferOffset   += (4 + Stride1) * tempmesh.VertexCount;
                mo.VertexCount       = tempmesh.VertexCount;
                mo.IndexCount        = tempmesh.Indices.Count;
                mo.Stride            = Stride1;
                mo.Stride2           = Stride2;

                // write index buffer
                if (tempmesh.VertexCount > ushort.MaxValue)
                {
                    mo.DrawElementType = 1;
                    foreach (var i in tempmesh.Indices)
                    {
                        indexBuffer.Write(i);
                    }
                }
                else
                {
                    foreach (var i in tempmesh.Indices)
                    {
                        indexBuffer.Write((ushort)i);
                    }
                }
            }

            mesh.PolygonIndexSize = indexBuffer.BaseStream.Length;
            mesh.BufferSizes      = new int[] { (int)vertexBuffer1.BaseStream.Length, (int)vertexBuffer2.BaseStream.Length, 0, 0 };
            mesh.PolygonBuffer    = ((MemoryStream)indexBuffer.BaseStream).ToArray();
            Console.WriteLine(mesh.PolygonBuffer.Length + " " + indexBuffer.BaseStream.Length);
            mesh.VertexBuffers = new MeshBuffer[]
            {
                new MeshBuffer()
                {
                    Buffer = ((MemoryStream)vertexBuffer1.BaseStream).ToArray()
                },
                new MeshBuffer()
                {
                    Buffer = ((MemoryStream)vertexBuffer2.BaseStream).ToArray()
                },
                new MeshBuffer()
                {
                    Buffer = new byte[0]
                },
                new MeshBuffer()
                {
                    Buffer = new byte[0]
                }
            };

            mesh.RiggingBuffers = RiggingGroups.ToArray().OrderBy(o => o.Name, StringComparer.Ordinal).ToArray();

            vertexBuffer1.Close();
            vertexBuffer2.Close();
            indexBuffer.Close();

            return(mesh);
        }
Пример #24
0
        public bool ExportMorphTargets(Stream targetStream, FileInfo outfile, List <Archive> archives, bool isGLBinary = true)
        {
            var cr2w = _wolvenkitFileService.TryReadRED4File(targetStream);

            if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
            {
                return(false);
            }

            RawArmature             Rig        = null;
            MemoryStream            meshbuffer = MESH.GetMeshBufferStream(targetStream, cr2w);
            MeshesInfo              meshinfo   = MESH.GetMeshesinfo(cr2w);
            List <RawMeshContainer> expMeshes  = MESH.ContainRawMesh(meshbuffer, meshinfo, true);
            int subMeshC = expMeshes.Count;

            var    buffers      = cr2w.Buffers;
            var    blob         = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMorphTargetMeshBlob>().First();
            string baseMeshPath = cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().First().BaseMesh.DepotPath;
            ulong  hash         = FNV1A64HashAlgorithm.HashString(baseMeshPath);

            foreach (Archive ar in archives)
            {
                if (ar.Files.ContainsKey(hash))
                {
                    var meshStream = new MemoryStream();
                    ModTools.ExtractSingleToStream(ar, hash, meshStream);
                    var meshCr2w = _wolvenkitFileService.TryReadRED4File(meshStream);

                    if (meshCr2w == null || !meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !meshCr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
                    {
                        break;
                    }

                    MESH.MeshBones meshBones = new MESH.MeshBones();
                    meshBones.boneCount = meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First().BoneNames.Count;
                    if (meshBones.boneCount != 0)    // for rigid meshes
                    {
                        meshBones.Names     = RIG.GetboneNames(meshCr2w);
                        meshBones.WorldPosn = MESH.GetMeshBonesPosn(meshCr2w);
                    }

                    Rig = MESH.GetNonParentedRig(meshBones);

                    MemoryStream ms = MESH.GetMeshBufferStream(meshStream, meshCr2w);
                    meshinfo  = MESH.GetMeshesinfo(meshCr2w);
                    expMeshes = MESH.ContainRawMesh(ms, meshinfo, true);
                    subMeshC  = expMeshes.Count;
                    if (meshBones.boneCount == 0)    // for rigid meshes
                    {
                        for (int i = 0; i < expMeshes.Count; i++)
                        {
                            expMeshes[i].weightcount = 0;
                        }
                    }
                    MESH.UpdateMeshJoints(ref expMeshes, Rig, meshBones);

                    break;
                }
            }

            MemoryStream diffsbuffer   = new MemoryStream();
            MemoryStream mappingbuffer = new MemoryStream();
            MemoryStream texbuffer     = new MemoryStream();

            if (blob.DiffsBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.DiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(diffsbuffer, buffers[blob.DiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.DiffsBuffer.Buffer.Value - 1].MemSize);
            }

            if (blob.MappingBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.MappingBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(mappingbuffer, buffers[blob.MappingBuffer.Buffer.Value - 1].DiskSize, buffers[blob.MappingBuffer.Buffer.Value - 1].MemSize);
            }

            if (blob.TextureDiffsBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(texbuffer, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].MemSize);
            }

            TargetsInfo targetsInfo = GetTargetInfos(cr2w, subMeshC);

            List <RawTargetContainer[]> expTargets = new List <RawTargetContainer[]>();

            for (int i = 0; i < targetsInfo.NumTargets; i++)
            {
                UInt32[] temp_NumVertexDiffsInEachChunk        = new UInt32[subMeshC];
                UInt32[] temp_NumVertexDiffsMappingInEachChunk = new UInt32[subMeshC];
                for (int e = 0; e < subMeshC; e++)
                {
                    temp_NumVertexDiffsInEachChunk[e]        = targetsInfo.NumVertexDiffsInEachChunk[i, e];
                    temp_NumVertexDiffsMappingInEachChunk[e] = targetsInfo.NumVertexDiffsMappingInEachChunk[i, e];
                }
                expTargets.Add(ContainRawTargets(diffsbuffer, mappingbuffer, temp_NumVertexDiffsInEachChunk, temp_NumVertexDiffsMappingInEachChunk, targetsInfo.TargetStartsInVertexDiffs[i], targetsInfo.TargetStartsInVertexDiffsMapping[i], targetsInfo.TargetPositionDiffOffset[i], targetsInfo.TargetPositionDiffScale[i], subMeshC));
            }

            string[] names = new string[targetsInfo.NumTargets];
            for (int i = 0; i < targetsInfo.NumTargets; i++)
            {
                names[i] = targetsInfo.Names[i] + "_" + targetsInfo.RegionNames[i];
            }

            List <MemoryStream> textureStreams = ContainTextureStreams(cr2w, texbuffer);
            ModelRoot           model          = RawTargetsToGLTF(expMeshes, expTargets, names, Rig);

            if (WolvenTesting.IsTesting)
            {
                return(true);
            }
            model.Extras = SharpGLTF.IO.JsonContent.Serialize(new { BaseMesh = targetsInfo.BaseMesh });
            if (isGLBinary)
            {
                model.SaveGLB(outfile.FullName);
            }
            else
            {
                model.SaveGLTF(outfile.FullName);
            }

            var dir = new DirectoryInfo(outfile.FullName.Replace(Path.GetExtension(outfile.FullName), string.Empty) + "_Textures");

            if (textureStreams.Count > 0)
            {
                Directory.CreateDirectory(dir.FullName);
            }

            for (int i = 0; i < textureStreams.Count; i++)
            {
                File.WriteAllBytes(dir.FullName + "\\" + Path.GetFileNameWithoutExtension(outfile.FullName) + i + ".dds", textureStreams[i].ToArray());
            }

            targetStream.Dispose();
            targetStream.Close();

            return(true);
        }
Пример #25
0
 /// <summary>
 /// Creates a rigging accessor from a mesh file
 /// </summary>
 /// <param name="meshFile"></param>
 public SSBHRiggingAccessor(MESH meshFile)
 {
     this.meshFile = meshFile;
 }
Пример #26
0
 public SSBHRiggingAccessor(MESH MeshFile)
 {
     this.MeshFile = MeshFile;
 }
Пример #27
0
        public IOModel GetIOModel()
        {
            IOModel outModel = new IOModel();

            MESH meshFile = null;

            foreach (FileNode n in Parent.Nodes)
            {
                if (n.Text.Equals(_model.MeshString))
                {
                    meshFile = ((NUMSHB_Node)n).mesh;
                }
                if (n.Text.Equals(_model.SkeletonFileName))
                {
                    outModel.Skeleton = (RSkeleton)((SKEL_Node)n).GetRenderableNode();
                }
            }

            Dictionary <string, int> indexByBoneName = new Dictionary <string, int>();

            if (outModel.Skeleton != null)
            {
                for (int i = 0; i < outModel.Skeleton.Bones.Count; i++)
                {
                    indexByBoneName.Add(outModel.Skeleton.Bones[i].Name, i);
                }
            }

            if (meshFile != null)
            {
                using (SSBHVertexAccessor vertexAccessor = new SSBHVertexAccessor(meshFile))
                {
                    SSBHRiggingAccessor riggingAccessor = new SSBHRiggingAccessor(meshFile);
                    foreach (MeshObject obj in meshFile.Objects)
                    {
                        IOMesh outMesh = new IOMesh()
                        {
                            Name = obj.Name,
                        };
                        outModel.Meshes.Add(outMesh);

                        IOVertex[] vertices = new IOVertex[obj.VertexCount];
                        for (int i = 0; i < vertices.Length; i++)
                        {
                            vertices[i] = new IOVertex();
                        }

                        foreach (MeshAttribute attr in obj.Attributes)
                        {
                            SSBHVertexAttribute[] values = vertexAccessor.ReadAttribute(attr.AttributeStrings[0].Name, 0, obj.VertexCount, obj);

                            if (attr.AttributeStrings[0].Name.Equals("Position0"))
                            {
                                outMesh.HasPositions = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Position = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("Normal0"))
                            {
                                outMesh.HasNormals = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Normal = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("map1"))
                            {
                                outMesh.HasUV0 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV0 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet"))
                            {
                                outMesh.HasUV1 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV1 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet1"))
                            {
                                outMesh.HasUV2 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV2 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet2"))
                            {
                                outMesh.HasUV3 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV3 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("colorSet1"))
                            {
                                outMesh.HasColor = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Color = new OpenTK.Vector4(values[i].X, values[i].Y, values[i].Z, values[i].W);
                                }
                            }
                        }

                        // Fix SingleBinds
                        if (outModel.Skeleton != null && !obj.ParentBoneName.Equals(""))
                        {
                            int parentIndex = outModel.Skeleton.GetBoneIndex(obj.ParentBoneName);
                            if (parentIndex != -1)
                            {
                                for (int i = 0; i < vertices.Length; i++)
                                {
                                    vertices[i].Position      = OpenTK.Vector3.TransformPosition(vertices[i].Position, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].Normal        = OpenTK.Vector3.TransformNormal(vertices[i].Normal, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].BoneIndices.X = indexByBoneName[obj.ParentBoneName];
                                    vertices[i].BoneWeights.X = 1;
                                }
                            }
                        }

                        // Apply Rigging
                        SSBHVertexInfluence[] influences = riggingAccessor.ReadRiggingBuffer(obj.Name, (int)obj.SubMeshIndex);

                        foreach (SSBHVertexInfluence influence in influences)
                        {
                            // Some influences refer to bones that don't exist in the skeleton.
                            // _eff bones?
                            if (!indexByBoneName.ContainsKey(influence.BoneName))
                            {
                                continue;
                            }

                            if (vertices[influence.VertexIndex].BoneWeights.X == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.X = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.X = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Y == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Y = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Y = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Z == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Z = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Z = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.W == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.W = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.W = influence.Weight;
                            }
                        }

                        outMesh.Vertices.AddRange(vertices);
                        outMesh.Indices.AddRange(vertexAccessor.ReadIndices(0, obj.IndexCount, obj));
                    }
                }
            }


            return(outModel);
        }
Пример #28
0
                public void Read(FileReader reader, MESH mesh)
                {
                    reader.ReadSignature(4, "VERT");
                    uint SectionSize = reader.ReadUInt32();

                    if (mesh.VertexSize == 32)
                    {
                        for (int v = 0; v < mesh.VertexCount; v++)
                        {
                            Vertex vert = new Vertex();
                            vert.pos = reader.ReadVec3();
                            vert.nrm = reader.ReadVec3();
                            vert.uv0 = reader.ReadVec2();
                            Vertices.Add(vert);
                        }
                    }
                    else if (mesh.VertexSize == 12)
                    {
                        for (int v = 0; v < mesh.VertexCount; v++)
                        {
                            Vertex vert = new Vertex();
                            vert.pos = reader.ReadVec3();
                            Vertices.Add(vert);
                        }
                    }
                    else if (mesh.VertexSize == 20)
                    {
                        for (int v = 0; v < mesh.VertexCount; v++)
                        {
                            Vertex vert = new Vertex();
                            vert.pos = reader.ReadVec3();
                            vert.uv0 = reader.ReadVec2();
                            Vertices.Add(vert);
                        }
                    }
                    else if (mesh.VertexSize == 24)
                    {
                        for (int v = 0; v < mesh.VertexCount; v++)
                        {
                            Vertex vert = new Vertex();
                            vert.pos = reader.ReadVec3();
                            vert.nrm = reader.ReadVec3();
                            Vertices.Add(vert);
                        }
                    }
                    else if (mesh.VertexSize == 36)
                    {
                        for (int v = 0; v < mesh.VertexCount; v++)
                        {
                            Vertex vert = new Vertex();
                            if (mesh.Unknown1 != 0)
                            {
                                uint Unknown = reader.ReadUInt32(); //Bone index?
                                vert.pos = reader.ReadVec3();
                                vert.nrm = reader.ReadVec3();
                                vert.uv0 = reader.ReadVec2();
                                Unknowns.Add(Unknown);
                            }
                            else
                            {
                                vert.pos = reader.ReadVec3();
                                vert.nrm = reader.ReadVec3();
                                vert.col = ColorUtility.ToVector4(reader.ReadBytes(4));
                                vert.uv0 = reader.ReadVec2();
                            }

                            Vertices.Add(vert);
                        }
                    }
                    else if (mesh.VertexSize == 40)
                    {
                        for (int v = 0; v < mesh.VertexCount; v++)
                        {
                            Vertex vert = new Vertex();
                            if (mesh.Unknown1 != 0)
                            {
                                uint Unknown = reader.ReadUInt32(); //Bone index?
                                vert.pos = reader.ReadVec3();
                                vert.nrm = reader.ReadVec3();
                                vert.col = ColorUtility.ToVector4(reader.ReadBytes(4));
                                vert.uv0 = reader.ReadVec2();
                            }
                            else
                            {
                                throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}");
                            }

                            Vertices.Add(vert);
                        }
                    }
                    else if (mesh.VertexSize == 44)
                    {
                        for (int v = 0; v < mesh.VertexCount; v++)
                        {
                            Vertex vert = new Vertex();
                            vert.pos = reader.ReadVec3();
                            vert.nrm = reader.ReadVec3();
                            vert.col = ColorUtility.ToVector4(reader.ReadBytes(4));
                            vert.uv0 = reader.ReadVec2();
                            vert.uv1 = reader.ReadVec2();

                            Vertices.Add(vert);
                        }
                    }
                    else
                    {
                        throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}");
                    }
                }