Beispiel #1
0
        public void IsValidTest(byte[] header, int length, bool expected) => new MemoryStream()
        .Using(stream =>
        {
            stream.Write(header, 0, header.Length);
            stream.SetLength(length);

            Assert.Equal(expected, Tm2.IsValid(stream));
        });
Beispiel #2
0
        public void IsWritingBackCorrectly(string fileName) => File.OpenRead($"Imaging/res/{fileName}.tm2").Using(x =>
                                                                                                                  Helpers.AssertStream(x, stream =>
        {
            var images = Tm2.Read(stream);

            var newStream = new MemoryStream();
            Tm2.Write(newStream, images);

            return(newStream);
        }));
Beispiel #3
0
        public static void Write(Stream stream, Pmp pmp)
        {
            stream.Position = 0;
            BinaryMapping.WriteObject <Header>(stream, pmp.header);

            for (int i = 0; i < pmp.objectInfo.Count; i++)
            {
                BinaryMapping.WriteObject <ObjectInfo>(stream, pmp.objectInfo[i]);
            }

            List <Pmo> nPmoList = pmp.PmoList;

            nPmoList.Sort((l, r) => l.PMO_StartPosition.CompareTo(r.PMO_StartPosition));

            for (int p = 0; p < nPmoList.Count; p++)
            {
                uint off = (uint)stream.Position;
                stream.Seek(0x44 + (p * 0x30), SeekOrigin.Begin);
                stream.Write(off);
                stream.Seek(0, SeekOrigin.End);

                BinaryMapping.WriteObject <Pmo.Header>(stream, nPmoList[p].header);

                for (int g = 0; g < nPmoList[p].textureInfo.Length; g++)
                {
                    BinaryMapping.WriteObject <Pmo.TextureInfo>(stream, nPmoList[p].textureInfo[g]);
                }

                Pmo.WriteMeshData(stream, nPmoList[p]);
            }

            uint pos = (uint)stream.Position;

            stream.Seek(0x1C, SeekOrigin.Begin);
            stream.Write(pos);
            stream.Seek(0, SeekOrigin.End);

            for (int tl = 0; tl < pmp.TextureList.Count; tl++)
            {
                BinaryMapping.WriteObject <PMPTextureInfo>(stream, pmp.TextureList[tl]);
            }

            for (int td = 0; td < pmp.TextureList.Count; td++)
            {
                uint       sPos = (uint)stream.Position;
                List <Tm2> l    = new List <Tm2>();
                l.Add(pmp.TextureDataList[td]);
                Tm2.Write(stream, l);

                stream.Seek(pos + (td * 0x20), SeekOrigin.Begin);
                stream.Write(sPos);
                stream.Seek(0, SeekOrigin.End);
            }
        }
Beispiel #4
0
 public static void WriteTextureData(Stream stream, Pmo pmo)
 {
     // Write textures.
     for (int t = 0; t < pmo.texturesData.Count; t++)
     {
         pmo.TextureOffsets.Add((uint)stream.Position);
         List <Tm2> tm2list = new List <Tm2>();
         tm2list.Add(pmo.texturesData[t]);
         Tm2.Write(stream, tm2list);
     }
 }
Beispiel #5
0
        public void ReadImagePropertiesTest(
            string fileName,
            int width,
            int height,
            PixelFormat pixelFormat) => File.OpenRead($"Imaging/res/{fileName}.tm2").Using(stream =>
        {
            var image = Tm2.Read(stream).Single();

            Assert.Equal(width, image.Size.Width);
            Assert.Equal(height, image.Size.Height);
            Assert.Equal(pixelFormat, image.PixelFormat);
        });
Beispiel #6
0
        public static MeshGroup FromFbx(string filePath)
        {
            const float Scale        = 1.0f;
            var         assimp       = new Assimp.AssimpContext();
            var         scene        = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
            var         baseFilePath = Path.GetDirectoryName(filePath);

            TexList     = new List <string>();
            TextureData = new List <Tm2>();

            foreach (Assimp.Material mat in scene.Materials)
            {
                TexList.Add(Path.GetFileName(mat.TextureDiffuse.FilePath));
                Stream str = File.OpenRead(TexList[TexList.Count - 1]);

                PngImage png     = new PngImage(str);
                Tm2      tmImage = Tm2.Create(png);
                TextureData.Add(tmImage);
            }

            int childCount = scene.RootNode.ChildCount;

            return(new MeshGroup()
            {
                MeshDescriptors = scene.Meshes
                                  .Select(x =>
                {
                    var vertices = new PositionColoredTextured[x.Vertices.Count];
                    for (var i = 0; i < vertices.Length; i++)
                    {
                        vertices[i].X = x.Vertices[i].X * Scale;
                        vertices[i].Y = x.Vertices[i].Y * Scale;
                        vertices[i].Z = x.Vertices[i].Z * Scale;
                        vertices[i].Tu = x.TextureCoordinateChannels[0][i].X;
                        vertices[i].Tv = 1.0f - x.TextureCoordinateChannels[0][i].Y;
                        vertices[i].R = 1.0f;
                        vertices[i].G = 1.0f;
                        vertices[i].B = 1.0f;
                        vertices[i].A = 1.0f;
                    }

                    return new MeshDescriptor
                    {
                        Vertices = vertices,
                        Indices = x.GetIndices(),
                        IsOpaque = true,
                        TextureIndex = x.MaterialIndex
                    };
                }).ToList()
            });
        }
Beispiel #7
0
        public static Pmo Read(Stream stream)
        {
            Pmo pmo = new Pmo();

            pmo.PMO_StartPosition = (uint)stream.Position;

            ReadHeader(stream, pmo);
            ReadTextureSection(stream, pmo);

            // Read all data
            if (pmo.header.MeshOffset0 != 0)
            {
                ReadMeshData(stream, pmo, 0);
            }
            if (pmo.header.MeshOffset1 != 0)
            {
                ReadMeshData(stream, pmo, 1);
            }

            // Read textures.
            for (int i = 0; i < pmo.textureInfo.Length; i++)
            {
                if (pmo.textureInfo[i].TextureOffset != 0)
                {
                    stream.Seek(pmo.textureInfo[i].TextureOffset + 0x10, SeekOrigin.Begin);
                    uint tm2size = stream.ReadUInt32() + 0x10;
                    stream.Seek(pmo.textureInfo[i].TextureOffset, SeekOrigin.Begin);
                    Tm2 tm2 = Tm2.Read(stream, true).First();

                    pmo.texturesData.Add(tm2);
                }
            }

            // Read Skeleton.
            if (pmo.header.SkeletonOffset != 0)
            {
                stream.Seek(pmo.PMO_StartPosition + pmo.header.SkeletonOffset, SeekOrigin.Begin);
                pmo.skeletonHeader = Mapping.ReadObject <SkeletonHeader>(stream);
                pmo.boneList       = new BoneData[pmo.skeletonHeader.BoneCount];
                for (int j = 0; j < pmo.skeletonHeader.BoneCount; j++)
                {
                    pmo.boneList[j] = Mapping.ReadObject <BoneData>(stream);
                }
            }

            return(pmo);
        }
Beispiel #8
0
        public static Pmp Read(Stream stream)
        {
            Pmp pmp = new Pmp();

            pmp.header = BinaryMapping.ReadObject <Header>(stream);

            // Read Object List.
            for (int i = 0; i < pmp.header.ObjectCount; i++)
            {
                pmp.objectInfo.Add(Mapping.ReadObject <ObjectInfo>(stream));
                pmp.hasDifferentMatrix.Add(BitsUtil.Int.GetBit(pmp.objectInfo[i].ObjectFlags, 0));
            }

            // Read PMO list.
            for (int p = 0; p < pmp.header.ObjectCount; p++)
            {
                ObjectInfo currentPmoInfo = pmp.objectInfo[p];
                if (currentPmoInfo.PMO_Offset != 0)
                {
                    stream.Seek(currentPmoInfo.PMO_Offset, SeekOrigin.Begin);
                    pmp.PmoList.Add(Pmo.Read(stream));
                }
                else
                {
                    pmp.PmoList.Add(null);
                }
            }

            stream.Seek(pmp.header.TextureListOffset, SeekOrigin.Begin);

            for (int t = 0; t < pmp.header.TextureCount; t++)
            {
                pmp.TextureList.Add(BinaryMapping.ReadObject <PMPTextureInfo>(stream));
            }

            // Read textures.
            for (int k = 0; k < pmp.TextureList.Count; k++)
            {
                stream.Seek(pmp.TextureList[k].Offset + 0x10, SeekOrigin.Begin);
                uint tm2size = stream.ReadUInt32() + 0x10;
                stream.Seek(pmp.TextureList[k].Offset, SeekOrigin.Begin);

                pmp.TextureDataList.Add(Tm2.Read(stream, true).First());
            }

            return(pmp);
        }
        static ImageFormatService()
        {
            imageFormat = new IImageFormat[]
            {
                GetImageFormat("PNG", "png", true, Png.IsValid, Png.Read, (stream, image) => Png.Write(stream, image)),
                GetImageFormat("BMP", "bmp", true, Bmp.IsValid, Bmp.Read, (stream, image) => Bmp.Write(stream, image)),
                GetImageFormat("TIFF", "tiff", true, Tiff.IsValid, Tiff.Read, (stream, image) => Tiff.Write(stream, image)),

                GetImageFormat("FAC", "fac", true, Imgd.IsFac, s => Imgd.ReadAsFac(s), (stream, images) =>
                               Imgd.WriteAsFac(stream, images.Select(x => x.AsImgd()))),

                GetImageFormat("IMGD", "imd", true, Imgd.IsValid, Imgd.Read, (stream, image) => image.AsImgd().Write(stream)),

                GetImageFormat("IMGZ", "imz", true, Imgz.IsValid, s => Imgz.Read(s), (stream, images) =>
                               Imgz.Write(stream, images.Select(x => x.AsImgd()))),

                GetImageFormat("KH2 Font", "bar", true, IsKh2Font, ReadKh2Font, WriteKh2Font),

                GetImageFormat("Font ARC", "arc", false, FontsArc.IsValid, s =>
                {
                    var fonts = FontsArc.Read(s);
                    return(new[]
                    {
                        fonts.FontCmd.Image1,
                        fonts.FontCmd.Image2,
                        fonts.FontHelp.Image1,
                        fonts.FontHelp.Image2,
                        fonts.FontMenu.Image1,
                        fonts.FontMenu.Image2,
                        fonts.FontMes.Image1,
                        fonts.FontMes.Image2,
                        fonts.FontNumeral.Image1,
                        fonts.FontNumeral.Image2,
                        fonts.FontIcon,
                    });
                }, (stream, images) =>
                               throw new NotImplementedException()),

                GetImageFormat("TIM2", "tm2", false, Tm2.IsValid, s => Tm2.Read(s), (stream, images) =>
                               throw new NotImplementedException()),

                GetImageFormat("KH2TIM", "tex", false, _ => true,
                               s => ModelTexture.Read(s).Images.Cast <IImageRead>(),
                               (stream, images) => throw new NotImplementedException()),
            };
Beispiel #10
0
        static ImageFormatService()
        {
            imageFormat = new IImageFormat[]
            {
                GetImageFormat("PNG", "png", true, Png.IsValid, Png.Read, (stream, image) => Png.Write(stream, image)),
                GetImageFormat("BMP", "bmp", true, Bmp.IsValid, Bmp.Read, (stream, image) => Bmp.Write(stream, image)),
                GetImageFormat("TIFF", "tiff", true, Tiff.IsValid, Tiff.Read, (stream, image) => Tiff.Write(stream, image)),
                GetImageFormat("IMGD", "imd", true, Imgd.IsValid, Imgd.Read, (stream, image) => image.AsImgd().Write(stream)),

                GetImageFormat("IMGZ", "imz", true, Imgz.IsValid, s => Imgz.Read(s), (stream, images) =>
                               Imgz.Write(stream, images.Select(x => x.AsImgd()))),

                GetImageFormat("TIM2", "tm2", false, Tm2.IsValid, s => Tm2.Read(s), (stream, images) =>
                               throw new NotImplementedException()),

                GetImageFormat("KH2TIM", "tex", true, _ => true,
                               s => ModelTexture.Read(s).Images.Cast <IImageRead>(),
                               (stream, images) => throw new NotImplementedException()),
            };
Beispiel #11
0
        public static void Write(Stream stream, Pmp pmp)
        {
            stream.Position = 0;
            BinaryMapping.WriteObject <Header>(stream, pmp.header);

            for (int i = 0; i < pmp.objectInfo.Count; i++)
            {
                BinaryMapping.WriteObject <ObjectInfo>(stream, pmp.objectInfo[i]);
            }

            List <Pmo> nPmoList = pmp.PmoList;

            nPmoList.Sort((l, r) => l.PMO_StartPosition.CompareTo(r.PMO_StartPosition));

            for (int p = 0; p < nPmoList.Count; p++)
            {
                BinaryMapping.WriteObject <Pmo.Header>(stream, nPmoList[p].header);

                for (int g = 0; g < nPmoList[p].textureInfo.Length; g++)
                {
                    BinaryMapping.WriteObject <Pmo.TextureInfo>(stream, nPmoList[p].textureInfo[g]);
                }

                Pmo.WriteMeshData(stream, nPmoList[p]);
            }

            for (int tl = 0; tl < pmp.TextureList.Count; tl++)
            {
                BinaryMapping.WriteObject <PMPTextureInfo>(stream, pmp.TextureList[tl]);
            }

            for (int td = 0; td < pmp.TextureList.Count; td++)
            {
                List <Tm2> l = new List <Tm2>();
                l.Add(pmp.TextureDataList[td]);
                Tm2.Write(stream, l);
            }
        }
Beispiel #12
0
        //[InlineData(".tests/kh2_data/map/jp")]
        public void ValidateAllKH2MapRadarImages(string mapFilesDir)
        {
            Directory.GetFiles(mapFilesDir, "*.map").ToList().ForEach(
                file =>
            {
                File.OpenRead(file).Using(
                    stream =>
                {
                    Bar.Read(stream)
                    // rada may be multiple occurrence like al06.map
                    .Where(
                        entry => true &&
                        entry.Name == "rada" &&
                        entry.Type == Bar.EntryType.Tim2
                        )
                    .ToList()
                    .ForEach(
                        entry =>
                    {
                        Assert.True(Tm2.IsValid(entry.Stream), "Should be TM2");

                        var imageSet = Tm2.Read(entry.Stream);

                        imageSet.ToList().ForEach(
                            texture =>
                        {
                            // All radar images are 4-bpp
                            Assert.NotEmpty(texture.GetData());
                            Assert.Equal(4 * 16, texture.GetClut().Length);
                        }
                            );
                    }
                        );
                }
                    );
            }
                );
        }
Beispiel #13
0
 public Tim2KingdomTexture(byte[] texture, GraphicsDevice graphics)
 {
     Texture2D = Tm2.Read(new MemoryStream(texture)).First().CreateTexture(graphics);
 }
Beispiel #14
0
        private static Pmo MeshGroup2PMO(MeshGroup meshGroup)
        {
            Pmo pmo = new Pmo();

            List <MeshDescriptor> Descriptors = meshGroup.MeshDescriptors;

            // Max 65K vertices.
            uint descriptorVertexCount = 0;
            uint indicesVertexCount    = 0;

            foreach (MeshDescriptor d in Descriptors)
            {
                descriptorVertexCount += (uint)d.Vertices.Length;
                indicesVertexCount    += (uint)d.Indices.Length;
            }

            // Mesh data.
            for (int i = 0; i < Descriptors.Count; i++)
            {
                MeshDescriptor desc        = Descriptors[i];
                int[]          vertIndices = desc.Indices;
                Pmo.MeshChunks chunk       = new Pmo.MeshChunks();

                // Obtain info for PMO Vertex Flag.
                bool UsesUniformColor = UsesUniformDiffuseFlag(desc);
                Pmo.CoordinateFormat TextureCoordinateFormat = GetTextureCoordinateFormat(desc);
                Pmo.CoordinateFormat VertexFormat            = GetVertexFormat(desc);

                chunk.SectionInfo             = new Pmo.MeshSection();
                chunk.SectionInfo.Attribute   = 0;
                chunk.SectionInfo.VertexCount = (ushort)desc.Vertices.Length;
                chunk.SectionInfo.TextureID   = (byte)desc.TextureIndex;
                chunk.SectionInfo.VertexFlags = 0x30000000; // 0011 000 0 0 00 000 0 000 0 00 00 11 00 000 01

                // Set extra flags.
                if (UsesUniformColor)
                {
                    var UniformColor = (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].A * 256f));
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].B * 256f)) << 8;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].G * 256f)) << 16;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].R * 256f)) << 24;
                    chunk.SectionInfo.VertexFlags       = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
                    chunk.SectionInfo_opt2              = new Pmo.MeshSectionOptional2();
                    chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
                }
                else
                {
                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 2, 3, (uint)0x7);
                }
                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, (uint)TextureCoordinateFormat);
                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, (uint)VertexFormat);

                chunk.SectionInfo.VertexSize += 0;                                                                                                                     // Weights.
                chunk.SectionInfo.VertexSize += (TextureCoordinateFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)8  : (byte)((int)TextureCoordinateFormat * 2); // Texture Coordinates
                if (chunk.SectionInfo.VertexSize % 4 != 0)
                {
                    chunk.SectionInfo.VertexSize += 2;
                }
                chunk.SectionInfo.VertexSize += UsesUniformColor ? (byte)0 : (byte)4;                                                            // VertexColor
                chunk.SectionInfo.VertexSize += (VertexFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)12 : (byte)((int)VertexFormat * 3); // Vertices


                for (int v = 0; v < desc.Indices.Length; v++)
                {
                    int index = vertIndices[v];

                    Vector4 Color = new Vector4();
                    Color.X = desc.Vertices[index].R * 2;
                    Color.Y = desc.Vertices[index].G * 2;
                    Color.Z = desc.Vertices[index].B * 2;
                    Color.W = desc.Vertices[index].A * 2;
                    chunk.colors.Add(Color);

                    Vector3 vec;
                    vec.X = desc.Vertices[index].X / 10000.0f;
                    vec.Y = desc.Vertices[index].Y / 10000.0f;
                    vec.Z = desc.Vertices[index].Z / 10000.0f;
                    chunk.vertices.Add(vec);

                    Vector2 Coords;
                    Coords.X = desc.Vertices[index].Tu;
                    Coords.Y = desc.Vertices[index].Tv;
                    chunk.textureCoordinates.Add(Coords);
                }

                pmo.Meshes.Add(chunk);
            }

            // Header.
            pmo.header                = new Pmo.Header();
            pmo.header.MagicCode      = 0x4F4D50;
            pmo.header.TextureCount   = (ushort)TextureData.Count; // TODO.
            pmo.header.Unk0A          = 0x80;
            pmo.header.MeshOffset0    = 0xA0 + ((uint)pmo.header.TextureCount * 0x20);
            pmo.header.VertexCount    = (ushort)indicesVertexCount;
            pmo.header.TriangleCount  = (ushort)indicesVertexCount;
            pmo.header.TriangleCount /= 3;
            pmo.header.ModelScale     = 1.0f;
            pmo.header.BoundingBox    = new float[32];

            // Texture block.
            if (TextureData.Count > 0)
            {
                pmo.textureInfo = new Pmo.TextureInfo[TextureData.Count];

                for (int t = 0; t < TextureData.Count; t++)
                {
                    Tm2 tm = TextureData[t];
                    pmo.textureInfo[t]             = new Pmo.TextureInfo();
                    pmo.textureInfo[t].TextureName = TexList[t];
                    pmo.textureInfo[t].Unknown     = new UInt32[4];
                    pmo.texturesData.Add(TextureData[t]);
                }
            }

            return(pmo);
        }
Beispiel #15
0
        private static Pmp MeshGroupList2PMP(List <MeshGroup> meshGroup)
        {
            Pmp pmp = new Pmp();

            pmp.header.MagicCode    = 0x504D50;
            pmp.header.TextureCount = (ushort)TexList.Count;
            pmp.header.ObjectCount  = (ushort)meshGroup.Count;
            pmp.header.ModelCount   = (ushort)meshGroup.Count;
            pmp.header.Padding      = new int[2];
            pmp.PmoList             = new List <Pmo>();
            pmp.objectInfo          = new List <Pmp.ObjectInfo>();
            pmp.TextureList         = new List <Pmp.PMPTextureInfo>();
            pmp.TextureDataList     = new List <Tm2>();

            Pmo pmo = new Pmo();

            foreach (MeshGroup group in meshGroup)
            {
                List <MeshDescriptor> Descriptors    = group.MeshDescriptors;
                List <int>            textureIndices = new List <int>();

                // Max 65K vertices.
                ushort descriptorVertexCount = 0;
                foreach (MeshDescriptor d in Descriptors)
                {
                    descriptorVertexCount += (ushort)d.Vertices.Length;
                    textureIndices.Add(d.TextureIndex);
                }

                // Mesh data.
                for (int i = 0; i < Descriptors.Count; i++)
                {
                    MeshDescriptor desc  = Descriptors[i];
                    Pmo.MeshChunks chunk = new Pmo.MeshChunks();

                    // Obtain info for PMO Vertex Flag.
                    bool UsesUniformColor = UsesUniformDiffuseFlag(desc);
                    Pmo.CoordinateFormat TextureCoordinateFormat = GetTextureCoordinateFormat(desc);
                    Pmo.CoordinateFormat VertexFormat            = GetVertexFormat(desc);

                    chunk.SectionInfo             = new Pmo.MeshSection();
                    chunk.SectionInfo.Attribute   = 0;
                    chunk.SectionInfo.VertexCount = (ushort)desc.Vertices.Length;
                    chunk.SectionInfo.TextureID   = (byte)desc.TextureIndex;
                    chunk.SectionInfo.VertexFlags = 0x30000000; // 0011 000 0 0 00 000 0 000 0 00 00 11 00 000 01

                    // Set extra flags.
                    if (UsesUniformColor)
                    {
                        var UniformColor = (uint)(desc.Vertices[0].A / 255f);
                        UniformColor += (uint)(desc.Vertices[0].B / 255f) << 8;
                        UniformColor += (uint)(desc.Vertices[0].G / 255f) << 16;
                        UniformColor += (uint)(desc.Vertices[0].R / 255f) << 24;
                        chunk.SectionInfo.VertexFlags       = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
                        chunk.SectionInfo_opt2              = new Pmo.MeshSectionOptional2();
                        chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
                    }
                    else
                    {
                        chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 2, 3, (uint)0x7);
                    }
                    //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, (uint)TextureCoordinateFormat);
                    //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, (uint)VertexFormat);

                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, 2);
                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, 2);

                    chunk.SectionInfo.VertexSize += 0;                                                                                                                    // Weights.
                    TextureCoordinateFormat       = Pmo.CoordinateFormat.NORMALIZED_16_BITS;
                    chunk.SectionInfo.VertexSize += (TextureCoordinateFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)8 : (byte)((int)TextureCoordinateFormat * 2); // Texture Coordinates
                    if (chunk.SectionInfo.VertexSize % 4 != 0)
                    {
                        chunk.SectionInfo.VertexSize += 2;
                    }
                    chunk.SectionInfo.VertexSize += UsesUniformColor ? (byte)0 : (byte)4;                                                            // VertexColor
                    VertexFormat = Pmo.CoordinateFormat.NORMALIZED_16_BITS;
                    chunk.SectionInfo.VertexSize += (VertexFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)12 : (byte)((int)VertexFormat * 3); // Vertices
                    if (chunk.SectionInfo.VertexSize % 4 != 0)
                    {
                        chunk.SectionInfo.VertexSize += 2;
                    }


                    for (int v = 0; v < desc.Vertices.Length; v++)
                    {
                        Vector4 Color = new Vector4();
                        Color.X = desc.Vertices[v].R * 256;
                        Color.Y = desc.Vertices[v].G * 256;
                        Color.Z = desc.Vertices[v].B * 256;
                        Color.W = 128;
                        chunk.colors.Add(Color);

                        Vector3 vec;
                        vec.X = desc.Vertices[v].X / 10000.0f;
                        vec.Y = desc.Vertices[v].Y / 10000.0f;
                        vec.Z = desc.Vertices[v].Z / 10000.0f;
                        chunk.vertices.Add(vec);

                        Vector2 Coords;
                        Coords.X = desc.Vertices[v].Tu;
                        Coords.Y = desc.Vertices[v].Tv;
                        chunk.textureCoordinates.Add(Coords);
                    }

                    pmo.Meshes.Add(chunk);
                }

                // Header.
                pmo.header                = new Pmo.Header();
                pmo.header.MagicCode      = 0x4F4D50;
                pmo.header.Number         = 1;
                pmo.header.Group          = 1;
                pmo.header.Version        = 3;
                pmo.header.TextureCount   = (byte)textureIndices.Count; // TODO.
                pmo.header.Flag           = 0x800;
                pmo.header.MeshOffset0    = 0xA0 + ((uint)pmo.header.TextureCount * 0x20);
                pmo.header.VertexCount    = descriptorVertexCount;
                pmo.header.TriangleCount  = pmo.header.VertexCount;
                pmo.header.TriangleCount /= 3;
                pmo.header.ModelScale     = 1.0f;
                pmo.header.BoundingBox    = new float[32];

                // Texture block.
                if (textureIndices.Count > 0)
                {
                    pmo.textureInfo = new Pmo.TextureInfo[textureIndices.Count];

                    for (int t = 0; t < textureIndices.Count; t++)
                    {
                        Tm2 tm = TextureData[textureIndices[t]];
                        pmo.textureInfo[t]             = new Pmo.TextureInfo();
                        pmo.textureInfo[t].TextureName = TexList[textureIndices[t]];
                        pmo.textureInfo[t].Unknown     = new UInt32[4];
                        pmo.texturesData.Add(tm);

                        Pmp.PMPTextureInfo pmpInfo = new Pmp.PMPTextureInfo();
                        pmpInfo.TextureName = pmo.textureInfo[t].TextureName;
                        pmpInfo.Unknown     = new uint[4];
                        pmp.TextureList.Add(pmpInfo);
                    }
                }

                Pmp.ObjectInfo info = new Pmp.ObjectInfo();
                info.PMO_Offset = 0x20 + (0x30 * (uint)meshGroup.Count) + 0;

                pmp.PmoList.Add(pmo);
                pmp.objectInfo.Add(info);
            }

            pmp.TextureDataList = TextureData;

            return(pmp);
        }
Beispiel #16
0
        private static Pmo MeshGroup2PMO(MeshGroup meshGroup)
        {
            Pmo pmo = new Pmo();

            List <MeshDescriptor> Descriptors = meshGroup.MeshDescriptors;

            // Max 65K vertices.
            uint descriptorVertexCount = 0;
            uint indicesVertexCount    = 0;

            foreach (MeshDescriptor d in Descriptors)
            {
                descriptorVertexCount += (uint)d.Vertices.Length;
                indicesVertexCount    += (uint)d.Indices.Length;
            }

            // Mesh data.
            for (int i = 0; i < Descriptors.Count; i++)
            {
                MeshDescriptor desc        = Descriptors[i];
                int[]          vertIndices = desc.Indices;
                Pmo.MeshChunks chunk       = new Pmo.MeshChunks();

                // Obtain info for PMO Vertex Flag.
                bool UsesUniformColor = UsesUniformDiffuseFlag(desc);
                Pmo.CoordinateFormat TextureCoordinateFormat = GetTextureCoordinateFormat(desc);
                Pmo.CoordinateFormat VertexFormat            = GetVertexFormat(desc);

                chunk.SectionInfo             = new Pmo.MeshSection();
                chunk.SectionInfo.Attribute   = 0;
                chunk.SectionInfo.VertexCount = (ushort)desc.Vertices.Length;
                chunk.SectionInfo.TextureID   = (byte)desc.TextureIndex;
                chunk.SectionInfo.VertexFlags = 0x30000000; // 0011 000 0 0 00 000 0 000 0 00 00 11 00 000 01

                // Set extra flags.
                if (UsesUniformColor)
                {
                    var UniformColor = (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].A * 256f));
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].B * 256f)) << 8;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].G * 256f)) << 16;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].R * 256f)) << 24;
                    chunk.SectionInfo.VertexFlags       = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
                    chunk.SectionInfo_opt2              = new Pmo.MeshSectionOptional2();
                    chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
                }
                else
                {
                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 2, 3, (uint)0x7);
                }
                //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, (uint)TextureCoordinateFormat);
                //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, (uint)VertexFormat);

                uint texFormat = 3;
                uint posFormat = 3;

                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, texFormat);
                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, posFormat);

                chunk.SectionInfo.VertexSize += 0;                                                                                                                     // Weights.
                TextureCoordinateFormat       = (Pmo.CoordinateFormat)texFormat;
                chunk.SectionInfo.VertexSize += (TextureCoordinateFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)8  : (byte)((int)TextureCoordinateFormat * 2); // Texture Coordinates
                if (chunk.SectionInfo.VertexSize % 4 != 0)
                {
                    chunk.SectionInfo.VertexSize += 2;
                }

                chunk.SectionInfo.VertexSize += UsesUniformColor ? (byte)0 : (byte)4; // VertexColor

                VertexFormat = (Pmo.CoordinateFormat)posFormat;
                chunk.SectionInfo.VertexSize += (VertexFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)12 : (byte)((int)VertexFormat * 3); // Vertices
                if (chunk.SectionInfo.VertexSize % 4 != 0)
                {
                    chunk.SectionInfo.VertexSize += 2;
                }

                for (int v = 0; v < desc.Indices.Length; v++)
                {
                    int index = vertIndices[v];

                    Vector4 Color = new Vector4();
                    Color.X = desc.Vertices[index].R * 256;
                    Color.Y = desc.Vertices[index].G * 256;
                    Color.Z = desc.Vertices[index].B * 256;
                    Color.W = 128;
                    chunk.colors.Add(Color);

                    Vector3 vec;
                    vec.X = desc.Vertices[index].X / 10000.0f;
                    vec.Y = desc.Vertices[index].Y / 10000.0f;
                    vec.Z = desc.Vertices[index].Z / 10000.0f;
                    chunk.vertices.Add(vec);

                    Vector2 Coords;
                    Coords.X = desc.Vertices[index].Tu;
                    Coords.Y = desc.Vertices[index].Tv;
                    chunk.textureCoordinates.Add(Coords);
                }

                pmo.Meshes.Add(chunk);
            }

            // Header.
            pmo.header                = new Pmo.Header();
            pmo.header.MagicCode      = 0x4F4D50;
            pmo.header.Number         = 1;
            pmo.header.Group          = 1;
            pmo.header.Version        = 3;
            pmo.header.TextureCount   = (byte)TextureData.Count; // TODO.
            pmo.header.Flag           = 0x800;
            pmo.header.MeshOffset0    = 0xA0 + ((uint)pmo.header.TextureCount * 0x20);
            pmo.header.VertexCount    = (ushort)indicesVertexCount;
            pmo.header.TriangleCount  = (ushort)indicesVertexCount;
            pmo.header.TriangleCount /= 3;
            pmo.header.ModelScale     = 1.0f;
            pmo.header.BoundingBox    = new float[32];

            // Texture block.
            if (TextureData.Count > 0)
            {
                pmo.textureInfo = new Pmo.TextureInfo[TextureData.Count];

                for (int t = 0; t < TextureData.Count; t++)
                {
                    Tm2 tm = TextureData[t];
                    pmo.textureInfo[t]             = new Pmo.TextureInfo();
                    pmo.textureInfo[t].TextureName = TexList[t];
                    pmo.textureInfo[t].Unknown     = new UInt32[4];
                    pmo.texturesData.Add(TextureData[t]);
                }
            }

            //pmo.header.SkeletonOffset = pmo.header.MeshOffset0 + 0;
            pmo.skeletonHeader = new Pmo.SkeletonHeader();
            pmo.boneList       = new Pmo.BoneData[0];

            /*pmo.skeletonHeader.MagicValue = 0x4E4F42;
             * pmo.skeletonHeader.BoneCount = (ushort)BoneData.Count;
             * pmo.skeletonHeader.SkinnedBoneCount = (ushort)BoneData.Count;
             * pmo.skeletonHeader.nStdBone = 2;
             *
             * pmo.boneList = new Pmo.BoneData[BoneData.Count];
             *
             * for(int b = 0; b < pmo.boneList.Length; b++)
             * {
             *  Pmo.BoneData bn = new Pmo.BoneData();
             *  bn.BoneIndex = (ushort)b;
             *
             *  Assimp.Node curNode = new Assimp.Node();
             *  ushort p = 0;
             *  foreach(var nd in NodeData)
             *  {
             *      p++;
             *      if(nd.Name == BoneData[b].Name)
             *      {
             *          curNode = nd;
             *          p--;
             *          break;
             *      }
             *  }
             *
             *  bn.ParentBoneIndex = p;
             *  bn.JointName = BoneData[b].Name;
             *
             *  Matrix4x4 mtx = new Matrix4x4();
             *  mtx.M11 = BoneData[b].OffsetMatrix.A1;
             *  mtx.M12 = BoneData[b].OffsetMatrix.A2;
             *  mtx.M13 = BoneData[b].OffsetMatrix.A3;
             *  mtx.M14 = BoneData[b].OffsetMatrix.A4;
             *  mtx.M21 = BoneData[b].OffsetMatrix.B1;
             *  mtx.M22 = BoneData[b].OffsetMatrix.B2;
             *  mtx.M23 = BoneData[b].OffsetMatrix.B3;
             *  mtx.M24 = BoneData[b].OffsetMatrix.B4;
             *  mtx.M31 = BoneData[b].OffsetMatrix.C1;
             *  mtx.M32 = BoneData[b].OffsetMatrix.C2;
             *  mtx.M33 = BoneData[b].OffsetMatrix.C3;
             *  mtx.M34 = BoneData[b].OffsetMatrix.C4;
             *  mtx.M41 = BoneData[b].OffsetMatrix.D1;
             *  mtx.M42 = BoneData[b].OffsetMatrix.D2;
             *  mtx.M43 = BoneData[b].OffsetMatrix.D3;
             *  mtx.M44 = BoneData[b].OffsetMatrix.D4;
             *
             *  bn.Transform = mtx;
             *  bn.InverseTransform = mtx;
             *  pmo.boneList[b] = bn;
             * }*/

            return(pmo);
        }
Beispiel #17
0
 public Tim2KingdomTexture(Tm2 tm2, GraphicsDevice graphics)
 {
     Texture2D = tm2.CreateTexture(graphics);
 }
Beispiel #18
0
        public static List <MeshGroup> FromFbx(string filePath)
        {
            List <MeshGroup> group = new List <MeshGroup>();

            const float Scale        = 1.0f;
            var         assimp       = new Assimp.AssimpContext();
            var         scene        = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
            var         baseFilePath = Path.GetDirectoryName(filePath);

            TexList     = new List <string>();
            TextureData = new List <Tm2>();

            foreach (Assimp.Material mat in scene.Materials)
            {
                TexList.Add(Path.GetFileName(mat.TextureDiffuse.FilePath));
                Stream str = File.OpenRead(TexList[TexList.Count - 1]);

                PngImage png     = new PngImage(str);
                Tm2      tmImage = Tm2.Create(png);
                TextureData.Add(tmImage);
            }

            for (int i = 0; i < scene.RootNode.ChildCount; i++)
            {
                Node      child            = scene.RootNode.Children[i];
                MeshGroup currentMeshGroup = new MeshGroup();
                currentMeshGroup.MeshDescriptors = new List <MeshDescriptor>();

                // Get meshes by ID.
                foreach (int j in child.MeshIndices)
                {
                    MeshDescriptor meshDescriptor = new MeshDescriptor();
                    Mesh           x = scene.Meshes[j];

                    var vertices = new PositionColoredTextured[x.Vertices.Count];
                    for (var k = 0; k < vertices.Length; k++)
                    {
                        vertices[k].X  = x.Vertices[k].X * Scale;
                        vertices[k].Y  = x.Vertices[k].Y * Scale;
                        vertices[k].Z  = x.Vertices[k].Z * Scale;
                        vertices[k].Tu = x.TextureCoordinateChannels[0][k].X;
                        vertices[k].Tv = 1.0f - x.TextureCoordinateChannels[0][k].Y;
                        vertices[k].R  = x.VertexColorChannels[0][i].R;
                        vertices[k].G  = x.VertexColorChannels[0][i].G;
                        vertices[k].B  = x.VertexColorChannels[0][i].B;
                        vertices[k].A  = x.VertexColorChannels[0][i].A;
                    }

                    meshDescriptor.Vertices     = vertices;
                    meshDescriptor.Indices      = x.GetIndices();
                    meshDescriptor.IsOpaque     = false;
                    meshDescriptor.TextureIndex = x.MaterialIndex;


                    currentMeshGroup.MeshDescriptors.Add(meshDescriptor);
                }

                group.Add(currentMeshGroup);
            }

            return(group);
        }
Beispiel #19
0
        public static MeshGroup FromFbx(string filePath)
        {
            const float Scale        = 1.0f;
            var         assimp       = new Assimp.AssimpContext();
            var         scene        = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
            var         BoneScene    = assimp.ImportFile(filePath);
            var         baseFilePath = Path.GetDirectoryName(filePath);

            TexList     = new List <string>();
            TextureData = new List <Tm2>();
            BoneData    = new List <Assimp.Bone>();
            NodeData    = new List <Assimp.Node>();

            foreach (Assimp.Material mat in scene.Materials)
            {
                Stream str  = null;
                var    name = Path.GetFileName(mat.TextureDiffuse.FilePath);
                if (name != "" || name != null)
                {
                    str = File.OpenRead(name);
                }

                if (str != null)
                {
                    TexList.Add(Path.GetFileName(mat.TextureDiffuse.FilePath));
                    PngImage png     = new PngImage(str);
                    Tm2      tmImage = Tm2.Create(png);
                    TextureData.Add(tmImage);
                }
            }

            Assimp.Bone rBone = new Assimp.Bone();
            foreach (var m in BoneScene.Meshes)
            {
                foreach (var bn in m.Bones)
                {
                    if (!BoneData.Contains(bn))
                    {
                        BoneData.Add(bn);
                    }
                }
            }

            NodeData.AddRange(BoneScene.RootNode.Children.ToList());

            return(new MeshGroup()
            {
                MeshDescriptors = scene.Meshes
                                  .Select(x =>
                {
                    var vertices = new PositionColoredTextured[x.Vertices.Count];
                    for (var i = 0; i < vertices.Length; i++)
                    {
                        vertices[i].X = x.Vertices[i].X * Scale;
                        vertices[i].Y = x.Vertices[i].Y * Scale;
                        vertices[i].Z = x.Vertices[i].Z * Scale;
                        vertices[i].Tu = x.TextureCoordinateChannels[0][i].X;
                        vertices[i].Tv = 1.0f - x.TextureCoordinateChannels[0][i].Y;
                        vertices[i].R = x.VertexColorChannels[0][i].R;
                        vertices[i].G = x.VertexColorChannels[0][i].G;
                        vertices[i].B = x.VertexColorChannels[0][i].B;
                        vertices[i].A = x.VertexColorChannels[0][i].A;
                    }

                    return new MeshDescriptor
                    {
                        Vertices = vertices,
                        Indices = x.GetIndices(),
                        IsOpaque = true,
                        TextureIndex = x.MaterialIndex
                    };
                }).ToList()
            });
        }