Пример #1
0
        private void LoadGmdFile(GmdFile gmdFile)
        {
            Name = gmdFile.Name;

            Textures = gmdFile.Textures.Select(tex => tex.Name).ToArray();

            Materials = gmdFile.Materials.Select(mat =>
            {
                return(new Material
                {
                    Id = mat.Id,
                    Shader = gmdFile.Shaders[mat.ShaderIndex].ToString(),
                    Textures = mat.TextureIndices.Select(texIdx =>
                    {
                        if (texIdx >= 0 && texIdx < Textures.Length)
                        {
                            return Textures[texIdx];
                        }

                        return null;
                    }).ToArray()
                });
            }).ToArray();

            var bones = new Bone[gmdFile.BoneTransforms.Length];

            foreach (var bt in gmdFile.BoneTransforms)
            {
                if (GmdUtils.GetParentBone(bt, gmdFile.BoneTransforms) == null)
                {
                    LoadBone(bt, null, gmdFile, bones);
                }
            }

            Bones = bones.ToArray();


            var nameList = new List <string>();
            var meshes   = new List <Mesh>();

            foreach (var gmdMesh in gmdFile.Meshes)
            {
                var mesh = new Mesh();
                meshes.Add(mesh);

                // Console.WriteLine($"------------");

                foreach (var gmdSub in gmdFile.Submeshes.Where(s => s.MeshIndex == gmdMesh.MeshId))
                {
                    var submesh = new Submesh();
                    mesh.Submeshes.Add(submesh);

                    submesh.Id        = gmdSub.Id;
                    submesh.Name      = GetSubmeshName(Bones[gmdSub.BoneNo].Name, nameList);
                    submesh.Transform = Bones[gmdSub.BoneNo].WorldMatrix;
                    submesh.Material  = Materials[gmdSub.MaterialIndex];
                    submesh.Vertices  = ReadVertices(gmdSub, gmdMesh, gmdFile);
                    submesh.Triangles = new int[gmdSub.IndicesCount / 3, 3];

                    // Console.WriteLine(submesh.Name.PadRight(25, ' ')
                    //                   + submesh.Material.Shader.PadRight(25, ' ')
                    //                   + $"{gmdMesh.HasFlag1} {gmdMesh.HasFlag2} {gmdMesh.HasFlag3}");

                    var offset = gmdSub.IndicesOffset;
                    for (int i = 0; i < gmdSub.IndicesCount / 3; i++)
                    {
                        submesh.Triangles[i, 0] = gmdFile.Indices[offset + i * 3].Value - gmdSub.BufferOffset2;
                        submesh.Triangles[i, 1] = gmdFile.Indices[offset + i * 3 + 1].Value - gmdSub.BufferOffset2;
                        submesh.Triangles[i, 2] = gmdFile.Indices[offset + i * 3 + 2].Value - gmdSub.BufferOffset2;
                    }
                }
            }

            Meshes = meshes.ToArray();
        }
Пример #2
0
        private int WriteVertices(BinaryWriter writer, Submesh submesh, int flagCount, List <int> boneIndices)
        {
            var startPosition = writer.BaseStream.Position;

            foreach (var v in submesh.Vertices)
            {
                GmdUtils.WriteVector3(v.Position, writer);

                if (v.BoneIndices != null)
                {
                    writer.Write((byte)(v.BoneWeights[0] * 255));
                    writer.Write((byte)(v.BoneWeights[1] * 255));
                    writer.Write((byte)(v.BoneWeights[2] * 255));
                    writer.Write((byte)(v.BoneWeights[3] * 255));

                    writer.Write((byte)(boneIndices.IndexOf(v.BoneIndices[0])));
                    writer.Write((byte)(boneIndices.IndexOf(v.BoneIndices[1])));
                    writer.Write((byte)(boneIndices.IndexOf(v.BoneIndices[2])));
                    writer.Write((byte)(boneIndices.IndexOf(v.BoneIndices[3])));
                }

                GmdUtils.WriteNormal(v.Normal, writer);
                writer.Write((byte)0);

                for (int i = 0; i < flagCount; i++)
                {
                    writer.Write((byte)255);
                    writer.Write((byte)255);
                    writer.Write((byte)255);
                    writer.Write((byte)255);
                }

                // writer.Write(100);
                // writer.Write((byte)0);
                // if ((mesh.Format >> 12 & 7L) == 7L)
                // {
                //     writer.Write(0);
                // }
                //
                // if ((mesh.Format >> 21 & 7L) == 7L)
                // {
                //     writer.Write(0);
                // }
                //
                // if ((mesh.Format >> 24 & 7L) == 7L)
                // {
                //     writer.Write(0);
                // }
                writer.Write(Half.GetBits(new Half(v.Uv0.X)));
                writer.Write(Half.GetBits(new Half(1 - v.Uv0.Y)));

                if (v.Uv1.HasValue)
                {
                    writer.Write(Half.GetBits(new Half(v.Uv1.Value.X)));
                    writer.Write(Half.GetBits(new Half(1 - v.Uv1.Value.Y)));
                }

                if (v.Uv2.HasValue)
                {
                    writer.Write(Half.GetBits(new Half(v.Uv2.Value.X)));
                    writer.Write(Half.GetBits(new Half(1 - v.Uv2.Value.Y)));
                }

                if (v.Uv3.HasValue)
                {
                    writer.Write(Half.GetBits(new Half(v.Uv3.Value.X)));
                    writer.Write(Half.GetBits(new Half(1 - v.Uv3.Value.Y)));
                }
            }

            var endPosition = writer.BaseStream.Position;

            // Stride
            return((int)((endPosition - startPosition) / submesh.Vertices.Length));
        }