diff --git a/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs b/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs index eac165db..ab9c0285 100644 --- a/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs +++ b/OpenMetaverse/Assets/AssetTypes/AssetMesh.cs @@ -25,7 +25,11 @@ */ using System; +using System.IO; +using System.IO.Compression; using OpenMetaverse; +using OpenMetaverse.StructuredData; +using zlib; namespace OpenMetaverse.Assets { @@ -37,6 +41,11 @@ namespace OpenMetaverse.Assets /// Override the base classes AssetType public override AssetType AssetType { get { return AssetType.Mesh; } } + /// + /// Decoded mesh data + /// + public OSDMap MeshData; + /// Initializes a new instance of an AssetMesh object public AssetMesh() { } @@ -49,14 +58,63 @@ namespace OpenMetaverse.Assets } /// - /// TODO: Encodes a scripts contents into a LSO Bytecode file + /// TODO: Encodes Collada file into LLMesh format /// public override void Encode() { } /// - /// TODO: Decode LSO Bytecode into a string + /// Decodes mesh asset /// /// true - public override bool Decode() { return true; } + public override bool Decode() + { + try + { + MeshData = new OSDMap(); + + using (MemoryStream data = new MemoryStream(AssetData)) + { + OSDMap header = (OSDMap)OSDParser.DeserializeLLSDBinary(data); + long start = data.Position; + + foreach(string partName in header.Keys) + { + if (header[partName].Type != OSDType.Map) + continue; + OSDMap partInfo = (OSDMap)header[partName]; + if (partInfo["offset"] < 0 || partInfo["size"] == 0) + continue; + + byte[] part = new byte[partInfo["size"]]; + Buffer.BlockCopy(AssetData, partInfo["offset"] + (int)start, part, 0, part.Length); + + using (MemoryStream input = new MemoryStream(part)) + { + using (MemoryStream output = new MemoryStream()) + { + using (ZOutputStream zout = new ZOutputStream(output)) + { + byte[] buffer = new byte[2048]; + int len; + while ((len = input.Read(buffer, 0, buffer.Length)) > 0) + { + zout.Write(buffer, 0, len); + } + zout.Flush(); + output.Seek(0, SeekOrigin.Begin); + MeshData[partName] = OSDParser.DeserializeLLSDBinary(output); + } + } + } + } + } + return true; + } + catch (Exception ex) + { + Logger.Log("Failed to decode mesh asset", Helpers.LogLevel.Error, ex); + return false; + } + } } } diff --git a/bin/zlib.net.dll b/bin/zlib.net.dll new file mode 100644 index 00000000..c156f8e7 Binary files /dev/null and b/bin/zlib.net.dll differ diff --git a/prebuild.xml b/prebuild.xml index 2555ef7d..2cb70da8 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -122,6 +122,7 @@ +