public void WritesBackCorrectly() => File.OpenRead(FileName).Using(stream => Helpers.AssertStream(stream, x => { var outStream = new MemoryStream(); Pmp.Write(outStream, Pmp.Read(stream)); return(outStream); }));
private static void Convert(string fileIn, string fileOut) { List <MeshGroup> p = FromFbx(fileIn); Pmp pmp = MeshGroupList2PMP(p); using Stream stream = File.Create(fileOut); Pmp.Write(stream, pmp); stream.Close(); }
private void LoadBBSMap(string MapPath) { Pmp pmp = Pmp.Read(File.OpenRead(MapPath)); List <MeshGroup> group = new List <MeshGroup>(); int PmoIndex = 0; for (int i = 0; i < pmp.objectInfo.Count; i++) { Pmp.ObjectInfo currentInfo = pmp.objectInfo[i]; if (currentInfo.PMO_Offset != 0) { PmpEntity pmpEnt = new PmpEntity(PmoIndex, new System.Numerics.Vector3(currentInfo.PositionX, currentInfo.PositionY, currentInfo.PositionZ), new System.Numerics.Vector3(currentInfo.RotationX, currentInfo.RotationY, currentInfo.RotationZ), new System.Numerics.Vector3(currentInfo.ScaleX, currentInfo.ScaleY, currentInfo.ScaleZ)); pmpEnt.DifferentMatrix = pmp.hasDifferentMatrix[PmoIndex]; PmoParser pParser = new PmoParser(pmp.PmoList[PmoIndex], 100.0f); List <Tim2KingdomTexture> BbsTextures = new List <Tim2KingdomTexture>(); MeshGroup g = new MeshGroup(); g.MeshDescriptors = pParser.MeshDescriptors; g.Textures = new IKingdomTexture[pmp.PmoList[PmoIndex].header.TextureCount]; for (int j = 0; j < pmp.PmoList[PmoIndex].header.TextureCount; j++) { BbsTextures.Add(new Tim2KingdomTexture(pmp.PmoList[PmoIndex].texturesData[j], _graphics.GraphicsDevice)); g.Textures[j] = BbsTextures[j]; } _pmpEntities.Add(pmpEnt); _pmpModels.Add(g); PmoIndex++; } } }
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); }
public void ReadCorrectHeader() => File.OpenRead(FileName).Using(stream => { var TestPmo = Pmp.Read(stream); Assert.Equal(0x504D50, (int)TestPmo.header.MagicCode); Assert.Equal(1, TestPmo.header.ObjectCount); });