private static void WriteSectionLibraryVisualScenes(XmlTextWriter xw, GeomFile geomFile) { xw.WriteStartElement("library_visual_scenes"); { xw.WriteStartElement("visual_scene"); xw.WriteAttributeString("id", "default"); { foreach (GeomMesh mesh in geomFile.Meshes) { GeomUnknownMaterialData unkBlock = geomFile.UnknownMaterialData[mesh.MaterialDataIndex]; GeomUnknownMaterialDataEntry textureBlock = unkBlock.DataEntries1.FirstOrDefault(x => x.DataUsage == DataUsage.TextureID); string mat = "defmat"; if (textureBlock != null) { mat = geomFile.TextureNames[textureBlock.RawData[0]]; } else { continue; } string nodeId = string.Format("node-{0:X8}", mesh.GetHashCode()); xw.WriteStartElement("node"); xw.WriteAttributeString("id", nodeId); xw.WriteAttributeString("name", nodeId); { xw.WriteStartElement("translate"); xw.WriteString("0.0 0.0 0.0"); xw.WriteEndElement(); xw.WriteStartElement("rotate"); xw.WriteString("0.0 0.0 1.0 0.0"); xw.WriteEndElement(); xw.WriteStartElement("rotate"); xw.WriteString("0.0 1.0 0.0 0.0"); xw.WriteEndElement(); xw.WriteStartElement("rotate"); xw.WriteString("1.0 0.0 0.0 0.0"); xw.WriteEndElement(); xw.WriteStartElement("scale"); xw.WriteString("1.0 1.0 1.0"); xw.WriteEndElement(); xw.WriteStartElement("instance_geometry"); xw.WriteAttributeString("url", string.Format("#geom-{0:X8}", mesh.GetHashCode())); { xw.WriteStartElement("bind_material"); { xw.WriteStartElement("technique_common"); { xw.WriteStartElement("instance_material"); xw.WriteAttributeString("symbol", string.Format("material-{0}-symbol", mat)); xw.WriteAttributeString("target", string.Format("#material-{0}", mat)); xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } } xw.WriteEndElement(); } xw.WriteEndElement(); }
public List <Mesh> GetMeshes() { List <Mesh> meshes = new List <Mesh>(); foreach (GeomMesh geomMesh in Meshes) { Mesh mesh = new Mesh(); switch (geomMesh.PrimitiveType) { case PrimitiveType.TriangleStrip: mesh.SetPrimitiveType(OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip); break; case PrimitiveType.Triangles: mesh.SetPrimitiveType(OpenTK.Graphics.OpenGL.PrimitiveType.Triangles); break; default: throw new NotImplementedException("Unknown primitive type"); } mesh.SetVertexData <CommonVertex>(geomMesh.Vertices); mesh.SetIndices <ushort>(geomMesh.VertexIndices); Material material = new Material(); // Material, or something... GeomUnknownMaterialData matData = UnknownMaterialData[geomMesh.MaterialDataIndex]; // Get texture ID GeomUnknownMaterialDataEntry textureData = matData.DataEntries1.FirstOrDefault(x => x.DataUsage == DataUsage.TextureID); if (textureData != null) { FileInfo textureFileInfo = new DirectoryInfo(Program.ImageDir).GetFiles(TextureNames[textureData.RawData[0]] + " *.*").FirstOrDefault(); if (textureFileInfo != null) { material.Texture = new Texture(new System.Drawing.Bitmap(textureFileInfo.FullName)); } } // Testing 1, 2, 3... GeomUnknownMaterialDataEntry tmpFloatData = matData.DataEntries1.FirstOrDefault(x => x.DataUsage == DataUsage.Unknown0x33); if (tmpFloatData != null) { // Probably wrong, some maps have 2.0 in the assumed RGB channels...? // ...lets not apply this right for now //material.Ambient = new Color4(BitConverter.ToSingle(tmpFloatData.RawData, 0), BitConverter.ToSingle(tmpFloatData.RawData, 4), BitConverter.ToSingle(tmpFloatData.RawData, 8), BitConverter.ToSingle(tmpFloatData.RawData, 12)); } // Dummy texture if none was found if (material.Texture == null) { System.Drawing.Bitmap tmpBitmap = new System.Drawing.Bitmap(32, 32); using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(tmpBitmap)) { g.Clear(System.Drawing.Color.White); } material.Texture = new Texture(tmpBitmap); } mesh.SetMaterial(material); meshes.Add(mesh); } if (false) { // More testing... foreach (GeomUnknownData1 unkData1 in UnknownData1) { Mesh mesh = new Mesh(); CommonVertex[] verts = new CommonVertex[4]; verts[0] = new CommonVertex() { Position = unkData1.Unknown0x00, Color = Color4.White }; verts[1] = new CommonVertex() { Position = unkData1.Unknown0x0C, Color = Color4.Red }; verts[2] = new CommonVertex() { Position = unkData1.Unknown0x18, Color = Color4.Green }; verts[3] = new CommonVertex() { Position = unkData1.Unknown0x24, Color = Color4.Blue }; mesh.SetPrimitiveType(OpenTK.Graphics.OpenGL.PrimitiveType.Points); mesh.SetVertexData <CommonVertex>(verts); System.Drawing.Bitmap tmpBitmap = new System.Drawing.Bitmap(32, 32); using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(tmpBitmap)) { g.Clear(System.Drawing.Color.White); } mesh.SetMaterial(new Material(new Texture(tmpBitmap))); meshes.Add(mesh); } } return(meshes); }
private static void WriteSectionLibraryGeometry(XmlTextWriter xw, GeomFile geomFile) { xw.WriteStartElement("library_geometries"); { foreach (GeomMesh mesh in geomFile.Meshes) { GeomUnknownMaterialData unkBlock = geomFile.UnknownMaterialData[mesh.MaterialDataIndex]; GeomUnknownMaterialDataEntry textureBlock = unkBlock.DataEntries1.FirstOrDefault(x => x.DataUsage == DataUsage.TextureID); string mat = "defmat"; if (textureBlock != null) { mat = geomFile.TextureNames[textureBlock.RawData[0]]; } else { continue; } string meshId = string.Format("geom-{0:X8}", mesh.GetHashCode()); xw.WriteStartElement("geometry"); xw.WriteAttributeString("id", meshId); xw.WriteAttributeString("name", meshId); { xw.WriteStartElement("mesh"); { /* Vertices */ xw.WriteStartElement("source"); xw.WriteAttributeString("id", string.Format("{0}-pos", meshId)); { Vector3[] vtxData = mesh.Vertices.Select(x => x.Position).ToArray(); xw.WriteStartElement("float_array"); xw.WriteAttributeString("id", string.Format("{0}-pos-array", meshId)); xw.WriteAttributeString("count", string.Format("{0}", vtxData.Length * 3)); { for (int i = 0; i < vtxData.Length; i++) { xw.WriteString(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00} {1:0.00} {2:0.00} ", vtxData[i].X, vtxData[i].Y, vtxData[i].Z)); } } xw.WriteEndElement(); xw.WriteStartElement("technique_common"); { xw.WriteStartElement("accessor"); xw.WriteAttributeString("source", string.Format("#{0}-pos-array", meshId)); xw.WriteAttributeString("count", string.Format("{0}", vtxData.Length)); xw.WriteAttributeString("stride", "3"); { xw.WriteStartElement("param"); xw.WriteAttributeString("name", "X"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); xw.WriteStartElement("param"); xw.WriteAttributeString("name", "Y"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); xw.WriteStartElement("param"); xw.WriteAttributeString("name", "Z"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); /* Texcoords */ xw.WriteStartElement("source"); xw.WriteAttributeString("id", string.Format("{0}-texcoord", meshId)); { Vector2[] texCoordData = mesh.Vertices.Select(x => x.TexCoord).ToArray(); xw.WriteStartElement("float_array"); xw.WriteAttributeString("id", string.Format("{0}-texcoord-array", meshId)); xw.WriteAttributeString("count", string.Format("{0}", texCoordData.Length * 2)); { for (int i = 0; i < texCoordData.Length; i++) { xw.WriteString(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00} {1:0.00} ", texCoordData[i].X, -texCoordData[i].Y)); } } xw.WriteEndElement(); xw.WriteStartElement("technique_common"); { xw.WriteStartElement("accessor"); xw.WriteAttributeString("source", string.Format("#{0}-texcoord-array", meshId)); xw.WriteAttributeString("count", string.Format("{0}", texCoordData.Length)); xw.WriteAttributeString("stride", "2"); { xw.WriteStartElement("param"); xw.WriteAttributeString("name", "S"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); xw.WriteStartElement("param"); xw.WriteAttributeString("name", "T"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); /* Colors */ xw.WriteStartElement("source"); xw.WriteAttributeString("id", string.Format("{0}-colors", meshId)); { Color4[] colorData = mesh.Vertices.Select(x => x.Color).ToArray(); xw.WriteStartElement("float_array"); xw.WriteAttributeString("id", string.Format("{0}-colors-array", meshId)); xw.WriteAttributeString("count", string.Format("{0}", colorData.Length * 4)); { for (int i = 0; i < colorData.Length; i++) { xw.WriteString(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00} {1:0.00} {2:0.00} {3:0.00} ", colorData[i].R, colorData[i].G, colorData[i].B, colorData[i].A)); } } xw.WriteEndElement(); xw.WriteStartElement("technique_common"); { xw.WriteStartElement("accessor"); xw.WriteAttributeString("source", string.Format("#{0}-colors-array", meshId)); xw.WriteAttributeString("count", string.Format("{0}", colorData.Length)); xw.WriteAttributeString("stride", "4"); { xw.WriteStartElement("param"); xw.WriteAttributeString("name", "R"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); xw.WriteStartElement("param"); xw.WriteAttributeString("name", "G"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); xw.WriteStartElement("param"); xw.WriteAttributeString("name", "B"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); xw.WriteStartElement("param"); xw.WriteAttributeString("name", "A"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); /* Normals */ xw.WriteStartElement("source"); xw.WriteAttributeString("id", string.Format("{0}-norm", meshId)); { Vector3[] normData = mesh.Vertices.Select(x => x.Normal).ToArray(); xw.WriteStartElement("float_array"); xw.WriteAttributeString("id", string.Format("{0}-norm-array", meshId)); xw.WriteAttributeString("count", string.Format("{0}", normData.Length * 3)); { for (int i = 0; i < normData.Length; i++) { xw.WriteString(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00} {1:0.00} {2:0.00} ", normData[i].X, normData[i].Y, normData[i].Z)); } } xw.WriteEndElement(); xw.WriteStartElement("technique_common"); { xw.WriteStartElement("accessor"); xw.WriteAttributeString("source", string.Format("#{0}-norm-array", meshId)); xw.WriteAttributeString("count", string.Format("{0}", normData.Length)); xw.WriteAttributeString("stride", "3"); { xw.WriteStartElement("param"); xw.WriteAttributeString("name", "X"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); xw.WriteStartElement("param"); xw.WriteAttributeString("name", "Y"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); xw.WriteStartElement("param"); xw.WriteAttributeString("name", "Z"); xw.WriteAttributeString("type", "float"); xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); xw.WriteStartElement("vertices"); xw.WriteAttributeString("id", string.Format("{0}-vtx", meshId)); { xw.WriteStartElement("input"); xw.WriteAttributeString("semantic", "POSITION"); xw.WriteAttributeString("source", string.Format("#{0}-pos", meshId)); xw.WriteEndElement(); } xw.WriteEndElement(); string primitiveType = string.Empty; switch (mesh.PrimitiveType) { case PrimitiveType.Triangles: primitiveType = "triangles"; break; case PrimitiveType.TriangleStrip: primitiveType = "tristrips"; break; default: throw new Exception("Unknown primitive type"); } xw.WriteStartElement(primitiveType); xw.WriteAttributeString("count", string.Format("{0}", mesh.NumIndices)); xw.WriteAttributeString("material", string.Format("material-{0}-symbol", mat)); { xw.WriteStartElement("input"); xw.WriteAttributeString("semantic", "VERTEX"); xw.WriteAttributeString("source", string.Format("#{0}-vtx", meshId)); xw.WriteAttributeString("offset", "0"); xw.WriteEndElement(); xw.WriteStartElement("input"); xw.WriteAttributeString("semantic", "TEXCOORD"); xw.WriteAttributeString("source", string.Format("#{0}-texcoord", meshId)); xw.WriteAttributeString("offset", "0"); xw.WriteEndElement(); xw.WriteStartElement("input"); xw.WriteAttributeString("semantic", "COLOR"); xw.WriteAttributeString("source", string.Format("#{0}-colors", meshId)); xw.WriteAttributeString("offset", "0"); xw.WriteEndElement(); xw.WriteStartElement("input"); xw.WriteAttributeString("semantic", "NORMAL"); xw.WriteAttributeString("source", string.Format("#{0}-norm", meshId)); xw.WriteAttributeString("offset", "0"); xw.WriteEndElement(); // TODO: if non-ushort indices exist, convert them here! xw.WriteStartElement("p"); { if (mesh.PrimitiveType == PrimitiveType.TriangleStrip) { for (int i = 2; i < mesh.VertexIndices.Length; i++) { if ((i % 2) != 0) { xw.WriteString(string.Format("{0} {1} {2} ", mesh.VertexIndices[i], mesh.VertexIndices[i - 1], mesh.VertexIndices[i - 2])); } else { xw.WriteString(string.Format("{0} {1} {2} ", mesh.VertexIndices[i - 2], mesh.VertexIndices[i - 1], mesh.VertexIndices[i])); } } } else { for (int i = 0; i < mesh.VertexIndices.Length; i++) { xw.WriteString(string.Format("{0} ", mesh.VertexIndices[i])); } } } xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } } xw.WriteEndElement(); }
public GeomFile(Stream stream) { EndianBinaryReader reader = new EndianBinaryReader(stream, Endian.LittleEndian); Unknown0x00 = reader.ReadUInt32(); NumMeshes = reader.ReadUInt16(); NumUnknownMaterialData = reader.ReadUInt16(); Unknown0x08 = reader.ReadUInt32(); NumUnknownData1 = reader.ReadUInt32(); SizeOfTextureNames = reader.ReadUInt32(); Unknown0x14 = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Unknown0x20 = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Unknown0x2C = reader.ReadUInt32(); MeshesOffset = reader.ReadUInt32(); Unknown0x34 = reader.ReadUInt32(); UnknownMaterialDataOffset = reader.ReadUInt32(); Unknown0x3C = reader.ReadUInt32(); Unknown0x40 = reader.ReadUInt32(); Unknown0x44 = reader.ReadUInt32(); Unknown0x48 = reader.ReadUInt32(); Unknown0x4C = reader.ReadUInt32(); UnknownData1Offset = reader.ReadUInt32(); Unknown0x54 = reader.ReadUInt32(); Unknown0x58 = reader.ReadUInt32(); Unknown0x5C = reader.ReadUInt32(); TextureNamesOffset = reader.ReadUInt32(); Unknown0x64 = reader.ReadUInt32(); UnknownData2Offset = reader.ReadUInt32(); Unknown0x6C = reader.ReadUInt32(); Meshes = new GeomMesh[NumMeshes]; if (NumMeshes != 0) { stream.Seek(MeshesOffset, SeekOrigin.Begin); for (int i = 0; i < Meshes.Length; i++) { Meshes[i] = new GeomMesh(stream); } } UnknownMaterialData = new GeomUnknownMaterialData[NumUnknownMaterialData]; if (NumUnknownMaterialData != 0) { stream.Seek(UnknownMaterialDataOffset, SeekOrigin.Begin); for (int i = 0; i < UnknownMaterialData.Length; i++) { UnknownMaterialData[i] = new GeomUnknownMaterialData(stream); } } UnknownData1 = new GeomUnknownData1[NumUnknownData1]; if (NumUnknownData1 != 0) { stream.Seek(UnknownData1Offset, SeekOrigin.Begin); for (int i = 0; i < UnknownData1.Length; i++) { UnknownData1[i] = new GeomUnknownData1(stream); } } int numTextureNames = (int)(SizeOfTextureNames > 0 ? SizeOfTextureNames / 0x20 : 0); TextureNames = new string[numTextureNames]; if (SizeOfTextureNames != 0) { stream.Seek(TextureNamesOffset, SeekOrigin.Begin); for (int i = 0; i < TextureNames.Length; i++) { TextureNames[i] = Encoding.ASCII.GetString(reader.ReadBytes(0x20)).TrimEnd('\0'); } } }