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)); });
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); }));
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); } }
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); } }
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); });
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() }); }
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); }
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()), };
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()), };
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); } }
//[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); } ); } ); } ); } ); }
public Tim2KingdomTexture(byte[] texture, GraphicsDevice graphics) { Texture2D = Tm2.Read(new MemoryStream(texture)).First().CreateTexture(graphics); }
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); }
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); }
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); }
public Tim2KingdomTexture(Tm2 tm2, GraphicsDevice graphics) { Texture2D = tm2.CreateTexture(graphics); }
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); }
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() }); }