Exemplo n.º 1
0
        /// <summary>
        /// Returns a compressed byte[] of PixelData argument
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public byte[] Compress(byte[] Data)
        {
            // allocate a buffer with uncompressed length to write compressed stream to
            byte[] tempBuffer = new byte[UncompressedLength];
            int    compressedLength;

            // ZLIB
            if (version > BgfFile.VERSION9)
            {
                // init streams
                MemoryStream  destStream = new MemoryStream(tempBuffer, true);
                ZOutputStream destZ      = new ZOutputStream(destStream, zlibConst.Z_BEST_COMPRESSION);

                // compress
                destZ.Write(Data, 0, Data.Length);
                destZ.Flush();
                destZ.finish();

                // update compressed length
                compressedLength = (int)destZ.TotalOut;

                // cleanup
                destStream.Dispose();
                destZ.Dispose();
            }
            // CRUSH
            else
            {
#if WINCLR && X86
                // compress to tempBuffer
                compressedLength = Crush32.Compress(Data, 0, tempBuffer, 0, (int)UncompressedLength);
#else
                throw new Exception(ERRORCRUSHPLATFORM);
#endif
            }

            // copy all bytes we actually used from tempBuffer to new PixelData
            byte[] newPixelData = new byte[compressedLength];
            Array.Copy(tempBuffer, 0, newPixelData, 0, compressedLength);

            return(newPixelData);
        }
Exemplo n.º 2
0
        internal static MemoryStream Compress(byte[] buffer)
        {
            MemoryStream memoryStream1 = new MemoryStream();

            using (MemoryStream memoryStream2 = new MemoryStream(buffer))
            {
                using (ZOutputStream zoutputStream = new ZOutputStream((Stream)memoryStream1, -1))
                {
                    memoryStream2.Seek(0L, SeekOrigin.Begin);
                    byte[] buffer1 = new byte[2000];
                    int    count;
                    while ((count = memoryStream2.Read(buffer1, 0, 2000)) > 0)
                    {
                        zoutputStream.Write(buffer1, 0, count);
                    }
                    zoutputStream.Flush();
                }
            }
            return(memoryStream1);
        }
Exemplo n.º 3
0
    private static IDictionary <string, string> GetFromQch(string docsPath)
    {
        string dataSource = Path.Combine(docsPath, "qch", "qt.qch");

        if (!File.Exists(dataSource))
        {
            return(new Dictionary <string, string>());
        }
        SqliteConnectionStringBuilder sqliteConnectionStringBuilder = new SqliteConnectionStringBuilder();

        sqliteConnectionStringBuilder.DataSource = dataSource;
        using (SqliteConnection sqliteConnection = new SqliteConnection(sqliteConnectionStringBuilder.ConnectionString))
        {
            sqliteConnection.Open();
            using (SqliteCommand sqliteCommand = new SqliteCommand(
                       "SELECT Name, Data FROM FileNameTable INNER JOIN FileDataTable ON FileNameTable.FileId = FileDataTable.Id " +
                       "WHERE Name LIKE '%.html' " +
                       "ORDER BY Name", sqliteConnection))
            {
                using (SqliteDataReader sqliteDataReader = sqliteCommand.ExecuteReader())
                {
                    Dictionary <string, string> documentation = new Dictionary <string, string>();
                    while (sqliteDataReader.Read())
                    {
                        byte[] blob   = new byte[ushort.MaxValue];
                        int    length = (int)sqliteDataReader.GetBytes(1, 0, blob, 0, blob.Length);
                        using (MemoryStream output = new MemoryStream(length - 4))
                        {
                            using (ZOutputStream zOutputStream = new ZOutputStream(output))
                            {
                                zOutputStream.Write(blob, 4, length - 4);
                                zOutputStream.Flush();
                                documentation.Add(sqliteDataReader.GetString(0), Encoding.UTF8.GetString(output.ToArray()).Replace(@"\", @"\\"));
                            }
                        }
                    }
                    return(documentation);
                }
            }
        }
    }
Exemplo n.º 4
0
        /// <summary>
        /// 压缩
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        static public void CompressByteZipNet(byte[] inBytes, uint startPos, uint inLen, ref byte[] outBytes, ref uint outLen)
        {
            MemoryStream  ms        = new MemoryStream();
            ZOutputStream zipStream = new ZOutputStream(ms, 9);

            try
            {
                zipStream.Write(inBytes, (int)startPos, (int)inLen);

                zipStream.Flush();
                zipStream.Close();      // 一定要先 Close ZipOutputStream ,然后再获取 ToArray ,如果不关闭, ToArray 将不能返回正确的值

                outBytes = ms.ToArray();
                outLen   = (uint)outBytes.Length;
                ms.Close();
            }
            catch
            {
                Ctx.m_instance.m_logSys.error("CompressByteZipNet error");
            }
        }
Exemplo n.º 5
0
            public Stream OpenStream()
            {
                var output = new MemoryStream();

                if (entry.Length != 0)
                {
                    reader.BaseStream.Position = (long)entry.Offset;
                    uint num = entry.zIndex;
                    do
                    {
                        if (zLengths[num] == 0)
                        {
                            byte[] array = reader.ReadBytes((int)blockSize);
                            output.Write(array, 0, (int)blockSize);
                        }
                        else
                        {
                            ushort num2 = reader.ReadUInt16();
                            reader.BaseStream.Position -= 2;
                            byte[] array = reader.ReadBytes((int)zLengths[num]);
                            if (num2 == 30938)
                            {
                                ZOutputStream zOutputStream = new ZOutputStream(output);
                                zOutputStream.Write(array, 0, array.Length);
                                zOutputStream.Flush();
                            }
                            else
                            {
                                output.Write(array, 0, array.Length);
                            }
                        }
                        num += 1;
                    }while (output.Length < (long)entry.Length);
                }
                output.Flush();
                output.Seek(0, SeekOrigin.Begin);

                return(output);
            }
Exemplo n.º 6
0
        private string deflate()
        {
            int totalSize = 0;

            foreach (DSMCCDownloadDataBlock block in blocks)
            {
                totalSize += block.DataSize;
            }

            byte[] moduleData = new byte[totalSize];
            int    dataIndex  = 0;

            foreach (DSMCCDownloadDataBlock block in blocks)
            {
                for (int inputIndex = 0; inputIndex < block.DataSize; inputIndex++)
                {
                    moduleData[dataIndex] = block.Data[inputIndex];
                    dataIndex++;
                }
            }

            try
            {
                MemoryStream  output  = new MemoryStream();
                ZOutputStream zstream = new ZOutputStream(output);

                data = new byte[originalSize];
                zstream.Write(moduleData, 0, moduleData.Length);
                zstream.Flush();
                output.Seek(0, SeekOrigin.Begin);
                int readCount = output.Read(data, 0, data.Length);

                return(null);
            }
            catch (Exception e)
            {
                return(e.Message);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// 对日服数据包的内容进行解压以及转码
        /// <para>源数据→zlib解压→base64转码→json数据</para>
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private static string DecryptData(byte[] source)
        {
            MemoryStream  resultStream = new MemoryStream();
            ZOutputStream outStream    = new ZOutputStream(resultStream);

            outStream.Write(source, 0, source.Length);
            outStream.Flush();
            outStream.finish();
            byte[] buffer = new byte[resultStream.Length];
            resultStream.Position = 0;
            resultStream.Read(buffer, 0, buffer.Length);
            resultStream.Close();
            outStream.Close();
            string data = Encoding.UTF8.GetString(buffer);

            try
            {
                data = Encoding.UTF8.GetString(Convert.FromBase64String(data));
            }
            catch { }
            return(data);
        }
Exemplo n.º 8
0
        public static byte[] Decompress(string inFile)
        {
            using (var outStream = new MemoryStream())
            {
                using (var zOutputStream = new ZOutputStream(outStream))
                {
                    using (var inFileStream = new FileStream(inFile, FileMode.Open))
                    {
                        var buffer = new byte[2000];
                        int len;
                        while ((len = inFileStream.Read(buffer, 0, 2000)) > 0)
                        {
                            zOutputStream.Write(buffer, 0, len);
                        }

                        zOutputStream.Flush();

                        return(outStream.ToArray());
                    }
                }
            }
        }
Exemplo n.º 9
0
 public override void Flush()
 {
     try
     {
         _ZOutStream.Flush();
         //解压 此处不解压。
         //using (SevenZip.SevenZipExtractor sz = new SevenZipExtractor(_Stream))
         //{
         //    for (int i = 0; i < sz.ArchiveFileData.Count; i++)
         //    {
         //        sz.ExtractFiles(this._BackupPath, sz.ArchiveFileData[i].Index);
         //    }
         //}
     }
     catch (IOException e)
     {
         throw new ApplicationException("Cat to file: Writing local file failed!", e);
     }
     finally
     {
         Dispose();
     }
 }
Exemplo n.º 10
0
        public RiftPacket Read(DateTime pTransmitted)
        {
            long packetLength;
            int  sizeOfPacketLength;

            switch (mProtocolState)
            {
            case EProtocolState.Normal:
            {
                if (ReadEncodedLong(mUnprocessedBuffer, 0, mUnprocessedLength, out packetLength, out sizeOfPacketLength) &&
                    (sizeOfPacketLength + packetLength) <= mUnprocessedLength)
                {
                    Buffer.BlockCopy(mUnprocessedBuffer, 0, mProcessedBuffer, mProcessedLength, sizeOfPacketLength + (int)packetLength);
                    mUnprocessedLength -= (sizeOfPacketLength + (int)packetLength);
                    mProcessedLength   += (sizeOfPacketLength + (int)packetLength);
                    if (mUnprocessedLength > 0)
                    {
                        Buffer.BlockCopy(mUnprocessedBuffer, sizeOfPacketLength + (int)packetLength, mUnprocessedBuffer, 0, mUnprocessedLength);
                    }
                }
                break;
            }

            case EProtocolState.Compressed:
            {
                for (int index = 0; index < mUnprocessedLength; ++index)
                {
                    if (index >= 3 &&
                        mUnprocessedBuffer[index] == 0xFF &&
                        mUnprocessedBuffer[index - 1] == 0xFF &&
                        mUnprocessedBuffer[index - 2] == 0x00 &&
                        mUnprocessedBuffer[index - 3] == 0x00)
                    {
                        mInflaterStream.SetLength(0);
                        mInflater.Write(mUnprocessedBuffer, 0, index + 1);
                        mInflater.Flush();
                        mInflaterStream.Position = 0;
                        mProcessedLength        += mInflaterStream.Read(mProcessedBuffer, mProcessedLength, mProcessedBuffer.Length - mProcessedLength);
                        mUnprocessedLength      -= (index + 1);
                        if (mUnprocessedLength > 0)
                        {
                            Buffer.BlockCopy(mUnprocessedBuffer, index + 1, mUnprocessedBuffer, 0, mUnprocessedLength);
                        }
                        break;
                    }
                }
                break;
            }

            case EProtocolState.EncryptedAndCompressed:
            {
                for (int index = 0; index < mUnprocessedLength; ++index)
                {
                    if (mDecryptLength >= mDecryptBuffer.Length || index >= mUnprocessedBuffer.Length)
                    {
                        System.Diagnostics.Debug.Write("Bad");
                    }
                    mDecryptBuffer[mDecryptLength] = DecryptByte(mUnprocessedBuffer[index]);
                    ++mDecryptLength;
                    if (mDecryptLength >= 4 &&
                        mDecryptBuffer[mDecryptLength - 1] == 0xFF &&
                        mDecryptBuffer[mDecryptLength - 2] == 0xFF &&
                        mDecryptBuffer[mDecryptLength - 3] == 0x00 &&
                        mDecryptBuffer[mDecryptLength - 4] == 0x00)
                    {
                        mInflaterStream.SetLength(0);
                        mInflater.Write(mDecryptBuffer, 0, mDecryptLength);
                        mInflater.Flush();
                        mInflaterStream.Position = 0;
                        mProcessedLength        += mInflaterStream.Read(mProcessedBuffer, mProcessedLength, mProcessedBuffer.Length - mProcessedLength);
                        mDecryptLength           = 0;
                    }
                }
                mUnprocessedLength = 0;
                break;
            }

            default: break;
            }

            if (!ReadEncodedLong(mProcessedBuffer, 0, mProcessedLength, out packetLength, out sizeOfPacketLength))
            {
                return(null);
            }
            if (mProcessedLength < (sizeOfPacketLength + packetLength))
            {
                return(null);
            }
            byte[] packetBuffer = new byte[packetLength];
            Buffer.BlockCopy(mProcessedBuffer, sizeOfPacketLength, packetBuffer, 0, (int)packetLength);
            mProcessedLength -= (sizeOfPacketLength + (int)packetLength);
            if (mProcessedLength > 0)
            {
                Buffer.BlockCopy(mProcessedBuffer, sizeOfPacketLength + (int)packetLength, mProcessedBuffer, 0, mProcessedLength);
            }
            //PacketDescriptions.PacketDescription description = PacketDescriptions.Instance.Descriptions.Find(d => d.Outbound == mOutbound && d.Opcode == opcode);
            RiftPacketReader reader = new RiftPacketReader(pTransmitted, mOutbound, packetBuffer, 0, packetBuffer.Length);
            RiftPacket       packet;
            int sizeOfPacket;

            if (!reader.ReadPacket(out packet, out sizeOfPacket))
            {
                return(null);
            }
            packet.Raw = packetBuffer;
            return(packet);
        }
Exemplo n.º 11
0
        /// <summary>
        /// decompresses a gzipped OSD object
        /// </summary>
        /// <param name="meshBytes"></param>
        /// <returns></returns>
        static OSD DecompressOsd (byte [] meshBytes)
        {
            OSD decodedOsd = null;

            using (MemoryStream outMs = new MemoryStream ()) {
                using (ZOutputStream zOut = new ZOutputStream (outMs)) {
                    using (Stream inMs = new MemoryStream (meshBytes)) {
                        byte [] readBuffer = new byte [meshBytes.Length];
                        int readLen;

                        while ((readLen = inMs.Read (readBuffer, 0, readBuffer.Length)) > 0) {
                            zOut.Write (readBuffer, 0, readLen);
                        }
                        zOut.Flush ();
                        zOut.finish ();

                        byte [] decompressedBuf = outMs.GetBuffer (); //  ToArray();

                        decodedOsd = OSDParser.DeserializeLLSDBinary (decompressedBuf);
                    }
                }
            }

            return decodedOsd;
        }
Exemplo n.º 12
0
        /// <summary>
        /// Generate the co-ords and faces necessary to construct a mesh from the mesh data the accompanies a prim.
        /// </summary>
        /// <param name="primName"></param>
        /// <param name="primShape"></param>
        /// <param name="size"></param>
        /// <param name="coords">Coords are added to this list by the method.</param>
        /// <param name="faces">Faces are added to this list by the method.</param>
        /// <returns>true if coords and faces were successfully generated, false if not</returns>
        private bool GenerateCoordsAndFacesFromPrimMeshData(
            string primName, PrimitiveBaseShape primShape, Vector3 size, out List <Coord> coords, out List <Face> faces)
        {
            m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);

            coords = new List <Coord>();
            faces  = new List <Face>();
            OSD meshOsd = null;

            if (primShape.SculptData.Length <= 0)
            {
                m_log.Error("[MESH]: asset data is zero length");
                return(false);
            }

            long start = 0;

            using (MemoryStream data = new MemoryStream(primShape.SculptData))
            {
                try
                {
                    OSD osd = OSDParser.DeserializeLLSDBinary(data);
                    if (osd is OSDMap)
                    {
                        meshOsd = (OSDMap)osd;
                    }
                    else
                    {
                        m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
                        return(false);
                    }
                }
                catch (Exception e)
                {
                    m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
                }

                start = data.Position;
            }

            if (meshOsd is OSDMap)
            {
                OSDMap physicsParms = null;
                OSDMap map          = (OSDMap)meshOsd;
                if (map.ContainsKey("physics_shape"))
                {
                    physicsParms = (OSDMap)map["physics_shape"]; // old asset format
                }
                else if (map.ContainsKey("physics_mesh"))
                {
                    physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
                }
                if (physicsParms == null)
                {
                    m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset");
                    return(false);
                }

                int physOffset = physicsParms["offset"].AsInteger() + (int)start;
                int physSize   = physicsParms["size"].AsInteger();

                if (physOffset < 0 || physSize == 0)
                {
                    return(false); // no mesh data in asset
                }
                OSD    decodedMeshOsd = new OSD();
                byte[] meshBytes      = new byte[physSize];
                System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
//                        byte[] decompressed = new byte[physSize * 5];
                try
                {
                    using (MemoryStream inMs = new MemoryStream(meshBytes))
                    {
                        using (MemoryStream outMs = new MemoryStream())
                        {
                            using (ZOutputStream zOut = new ZOutputStream(outMs))
                            {
                                byte[] readBuffer = new byte[2048];
                                int    readLen    = 0;
                                while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
                                {
                                    zOut.Write(readBuffer, 0, readLen);
                                }
                                zOut.Flush();
                                outMs.Seek(0, SeekOrigin.Begin);

                                byte[] decompressedBuf = outMs.GetBuffer();

                                decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
                    return(false);
                }

                OSDArray decodedMeshOsdArray = null;

                // physics_shape is an array of OSDMaps, one for each submesh
                if (decodedMeshOsd is OSDArray)
                {
//                            Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));

                    decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
                    foreach (OSD subMeshOsd in decodedMeshOsdArray)
                    {
                        if (subMeshOsd is OSDMap)
                        {
                            AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
                        }
                    }
                }
            }

            return(true);
        }
Exemplo n.º 13
0
        public void Read(Stream stream)
        {
            BinaryReader input  = new BinaryReader(stream, Encoding.UTF8);
            MemoryStream buffer = null;

            // Part 1
            _header = new Header();
            _header.ReadExternal(input);

            if (_header.IsCompressed)
            {
                int    len;
                byte[] bb = new byte[1024];

                buffer = new MemoryStream();

                /* TODO can we do something about this zlib crap? */

                ZOutputStream zo = new ZOutputStream(buffer);

#if DEBUG
                Console.WriteLine("[i] Decompressing ...");
#endif
                while ((len = input.Read(bb, 0, 1024)) > 0)
                {
                    // Careful ... This is getting stuck in an endless loop if Z_BEST_COMPRESSION was used when
                    // compressing the output.
                    zo.Write(bb, 0, len);
                }

#if DEBUG
                Console.WriteLine("[+] Decompressed");
#endif

                zo.Flush();

                input.Close();

                buffer.Seek(0, SeekOrigin.Begin);

                input = new BinaryReader(buffer, Encoding.UTF8);
            }

            // Part 2
            _frameSize = new RECT();
            _frameSize.ReadExternal(input);

            // 8.8 fixed value ??
            // TODO verify
            byte lo = input.ReadByte();
            byte hi = input.ReadByte();
            _frameRate = hi + (lo * 0.01f);

            _frameCount = input.ReadUInt16();

            _tags = new ArrayList();

            while (true)
            {
                Tag tag = new Tag(this);

                tag.ReadExternal(input);

                _tags.Add(tag);

                if (0x00 == tag.Header.Type)
                {
                    break;
                }
            }

            input.Close();

            if (null != buffer)
            {
                buffer.Close();
                buffer.Dispose();
            }
        }
Exemplo n.º 14
0
        public void Write(Stream stream)
        {
            BinaryWriter output = new BinaryWriter(stream, Encoding.UTF8);
            MemoryStream buffer = new MemoryStream();
            BinaryWriter bufferOut;

            Console.WriteLine("BAD! SETTING COMPRESSION TO FALSE ALWAYS FOR OUTPUT CURRENTLY!");
            _header.IsCompressed = false;

            // Part 1: Write header basics)
            output.Write(_header.Signature);
            output.Write(_header.Version);

            bufferOut = new BinaryWriter(buffer, Encoding.UTF8);

            // Part 2: Write tags into buffer
            _frameSize.WriteExternal(bufferOut);

            // 8.8 fixed ??
            // TODO verify
            float d = _frameRate - ((byte)(_frameRate));

            d *= 100;

            bufferOut.Write((byte)d);
            bufferOut.Write((byte)_frameRate);

            bufferOut.Write(_frameCount);

            foreach (Tag tag in _tags)
            {
                tag.WriteExternal(bufferOut);
            }

            // Part 3: Update header size
            output.Write((uint)((uint)buffer.Length + 8U));


            // Part 4: Write buffer (compressed) to the main stream
            buffer.Seek(0, SeekOrigin.Begin);

            byte[] bb = new byte[1024];
            int    len;

            if (_header.IsCompressed)
            {
                /* TODO can we do something about this zlib crap? */

                // Careful! zlib.net can not read when itself compresses using Z_BEST_COMPRESSION
                // So since zlib.Inflate was getting stuck in and endless lopp I decided to use
                // Z_DEFAULT_COMPRESSION which has been working fine for me now ...

                ZOutputStream zOut = new ZOutputStream(stream, zlibConst.Z_DEFAULT_COMPRESSION);

                while ((len = buffer.Read(bb, 0, 1024)) > 0)
                {
                    zOut.Write(bb, 0, len);
                }

                zOut.Flush();
                zOut.finish();
            }
            else
            {
                while ((len = buffer.Read(bb, 0, 1024)) > 0)
                {
                    output.Write(bb, 0, len);
                }
            }

            // Part 4: Finalize
            bufferOut.Close();
            buffer.Dispose();

            output.Close();
        }
Exemplo n.º 15
0
        // parses convex hulls component
        private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls)
        {
            nvertices = 0;
            nhulls    = 1;

            OSD decodedMeshOsd = new OSD();

            byte[] meshBytes = new byte[size];
            System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
            try
            {
                using (MemoryStream inMs = new MemoryStream(meshBytes))
                {
                    using (MemoryStream outMs = new MemoryStream())
                    {
                        using (ZOutputStream zOut = new ZOutputStream(outMs))
                        {
                            byte[] readBuffer = new byte[4096];
                            int    readLen    = 0;
                            while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
                            {
                                zOut.Write(readBuffer, 0, readLen);
                            }
                            zOut.Flush();
                            outMs.Seek(0, SeekOrigin.Begin);

                            byte[] decompressedBuf = outMs.GetBuffer();
                            decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
                        }
                    }
                }
            }
            catch
            {
                return(false);
            }

            OSDMap cmap = (OSDMap)decodedMeshOsd;

            if (cmap == null)
            {
                return(false);
            }

            byte[] dummy;

            // must have one of this
            if (cmap.ContainsKey("BoundingVerts"))
            {
                dummy     = cmap["BoundingVerts"].AsBinary();
                nvertices = dummy.Length / bytesPerCoord;
            }
            else
            {
                return(false);
            }

/* upload is done with convex shape type
 *          if (cmap.ContainsKey("HullList"))
 *          {
 *              dummy = cmap["HullList"].AsBinary();
 *              nhulls += dummy.Length;
 *          }
 *
 *
 *          if (cmap.ContainsKey("Positions"))
 *          {
 *              dummy = cmap["Positions"].AsBinary();
 *              nvertices = dummy.Length / bytesPerCoord;
 *          }
 */

            return(true);
        }
Exemplo n.º 16
0
        // parses a LOD or physics mesh component
        private bool submesh(byte[] data, int offset, int size, out int ntriangles)
        {
            ntriangles = 0;

            OSD decodedMeshOsd = new OSD();

            byte[] meshBytes = new byte[size];
            System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
            try
            {
                using (MemoryStream inMs = new MemoryStream(meshBytes))
                {
                    using (MemoryStream outMs = new MemoryStream())
                    {
                        using (ZOutputStream zOut = new ZOutputStream(outMs))
                        {
                            byte[] readBuffer = new byte[4096];
                            int    readLen    = 0;
                            while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
                            {
                                zOut.Write(readBuffer, 0, readLen);
                            }
                            zOut.Flush();
                            outMs.Seek(0, SeekOrigin.Begin);

                            byte[] decompressedBuf = outMs.GetBuffer();
                            decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
                        }
                    }
                }
            }
            catch
            {
                return(false);
            }

            OSDArray decodedMeshOsdArray = null;

            byte[] dummy;

            decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
            foreach (OSD subMeshOsd in decodedMeshOsdArray)
            {
                if (subMeshOsd is OSDMap)
                {
                    OSDMap subtmpmap = (OSDMap)subMeshOsd;
                    if (subtmpmap.ContainsKey("NoGeometry") && ((OSDBoolean)subtmpmap["NoGeometry"]))
                    {
                        continue;
                    }

                    if (!subtmpmap.ContainsKey("Position"))
                    {
                        return(false);
                    }

                    if (subtmpmap.ContainsKey("TriangleList"))
                    {
                        dummy       = subtmpmap["TriangleList"].AsBinary();
                        ntriangles += dummy.Length / bytesPerCoord;
                    }
                    else
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 17
0
        private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod,
                                              ulong key)
        {
            PrimMesh   primMesh;
            SculptMesh sculptMesh;

            List <Coord> coords = new List <Coord>();
            List <Face>  faces  = new List <Face>();

            Image  idata = null;
            string decodedSculptFileName = "";

            if (primShape.SculptEntry)
            {
                if (((SculptType)primShape.SculptType & SculptType.Mesh) == SculptType.Mesh)
                {
                    if (!UseMeshesPhysicsMesh)
                    {
                        return(null);
                    }

                    MainConsole.Instance.Debug("[MESH]: experimental mesh proxy generation");

                    OSD meshOsd = null;

                    if (primShape.SculptData == null || primShape.SculptData.Length <= 0)
                    {
                        //MainConsole.Instance.Error("[MESH]: asset data is zero length");
                        return(null);
                    }

                    long start = 0;
                    using (MemoryStream data = new MemoryStream(primShape.SculptData))
                    {
                        try
                        {
                            meshOsd = OSDParser.DeserializeLLSDBinary(data);
                        }
                        catch (Exception e)
                        {
                            MainConsole.Instance.Error("[MESH]: Exception deserializing mesh asset header:" + e);
                        }
                        start = data.Position;
                    }

                    if (meshOsd is OSDMap)
                    {
                        OSDMap map          = (OSDMap)meshOsd;
                        OSDMap physicsParms = new OSDMap();

                        if (map.ContainsKey("physics_cached"))
                        {
                            OSD  cachedMeshMap = map["physics_cached"]; // cached data from Aurora
                            Mesh cachedMesh    = new Mesh(key);
                            cachedMesh.Deserialize(cachedMeshMap);
                            cachedMesh.WasCached = true;
                            return(cachedMesh); //Return here, we found all of the info right here
                        }
                        if (map.ContainsKey("physics_shape"))
                        {
                            physicsParms = (OSDMap)map["physics_shape"];  // old asset format
                        }
                        if (physicsParms.Count == 0 && map.ContainsKey("physics_mesh"))
                        {
                            physicsParms = (OSDMap)map["physics_mesh"];  // new asset format
                        }
                        if (physicsParms.Count == 0 && map.ContainsKey("physics_convex"))
                        {
                            // convex hull format, which we can't read, so instead
                            // read the highest lod that exists, and use it instead
                            physicsParms = (OSDMap)map["high_lod"];
                        }

                        int physOffset = physicsParms["offset"].AsInteger() + (int)start;
                        int physSize   = physicsParms["size"].AsInteger();

                        if (physOffset < 0 || physSize == 0)
                        {
                            return(null); // no mesh data in asset
                        }
                        OSD    decodedMeshOsd = new OSD();
                        byte[] meshBytes      = new byte[physSize];
                        Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
                        try
                        {
                            using (MemoryStream inMs = new MemoryStream(meshBytes))
                            {
                                using (MemoryStream outMs = new MemoryStream())
                                {
                                    using (ZOutputStream zOut = new ZOutputStream(outMs))
                                    {
                                        byte[] readBuffer = new byte[2048];
                                        int    readLen    = 0;
                                        while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
                                        {
                                            zOut.Write(readBuffer, 0, readLen);
                                        }
                                        zOut.Flush();
                                        outMs.Seek(0, SeekOrigin.Begin);

                                        byte[] decompressedBuf = outMs.GetBuffer();

                                        decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            MainConsole.Instance.Error("[MESH]: exception decoding physical mesh: " + e);
                            return(null);
                        }

                        OSDArray decodedMeshOsdArray = null;

                        // physics_shape is an array of OSDMaps, one for each submesh
                        if (decodedMeshOsd is OSDArray)
                        {
                            decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
                            foreach (OSD subMeshOsd in decodedMeshOsdArray)
                            {
                                if (subMeshOsd is OSDMap)
                                {
                                    OSDMap subMeshMap = (OSDMap)subMeshOsd;

                                    // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level
                                    // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no
                                    // geometry for this submesh.
                                    if (subMeshMap.ContainsKey("NoGeometry") && (subMeshMap["NoGeometry"]))
                                    {
                                        continue;
                                    }

                                    Vector3 posMax = new Vector3(0.5f, 0.5f, 0.5f);
                                    Vector3 posMin = new Vector3(-0.5f, -0.5f, -0.5f);
                                    if (subMeshMap.ContainsKey("PositionDomain"))
                                    //Optional, so leave the max and min values otherwise
                                    {
                                        posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3();
                                        posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"].AsVector3();
                                    }
                                    ushort faceIndexOffset = (ushort)coords.Count;

                                    byte[] posBytes = subMeshMap["Position"].AsBinary();
                                    for (int i = 0; i < posBytes.Length; i += 6)
                                    {
                                        ushort uX = Utils.BytesToUInt16(posBytes, i);
                                        ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
                                        ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);

                                        Coord c = new Coord(
                                            Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X,
                                            Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y,
                                            Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z);

                                        coords.Add(c);
                                    }

                                    byte[] triangleBytes = subMeshMap["TriangleList"].AsBinary();
                                    for (int i = 0; i < triangleBytes.Length; i += 6)
                                    {
                                        ushort v1 = (ushort)(Utils.BytesToUInt16(triangleBytes, i) + faceIndexOffset);
                                        ushort v2 =
                                            (ushort)(Utils.BytesToUInt16(triangleBytes, i + 2) + faceIndexOffset);
                                        ushort v3 =
                                            (ushort)(Utils.BytesToUInt16(triangleBytes, i + 4) + faceIndexOffset);
                                        Face f = new Face(v1, v2, v3);
                                        faces.Add(f);
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
                    {
                        decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath,
                                                                       "smap_" + primShape.SculptTexture.ToString());
                        try
                        {
                            if (File.Exists(decodedSculptFileName))
                            {
                                idata = Image.FromFile(decodedSculptFileName);
                            }
                        }
                        catch (Exception e)
                        {
                            MainConsole.Instance.Error("[SCULPT]: unable to load cached sculpt map " +
                                                       decodedSculptFileName + " " + e);
                        }
                        //if (idata != null)
                        //    MainConsole.Instance.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
                    }

                    if (idata == null)
                    {
                        if (primShape.SculptData == null || primShape.SculptData.Length == 0)
                        {
                            return(null);
                        }

                        try
                        {
                            idata = m_j2kDecoder.DecodeToImage(primShape.SculptData);

                            if (idata != null && cacheSculptMaps &&
                                (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) == 0)))
                            {
                                try
                                {
                                    idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp);
                                }
                                catch (Exception e)
                                {
                                    MainConsole.Instance.Error("[SCULPT]: unable to cache sculpt map " +
                                                               decodedSculptFileName + " " +
                                                               e);
                                }
                            }
                        }
                        catch (DllNotFoundException)
                        {
                            MainConsole.Instance.Error(
                                "[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed.  Often times this is because of an old version of GLIBC.  You must have version 2.4 or above!");
                            return(null);
                        }
                        catch (IndexOutOfRangeException)
                        {
                            MainConsole.Instance.Error(
                                "[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
                            return(null);
                        }
                        catch (Exception ex)
                        {
                            MainConsole.Instance.Error(
                                "[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " +
                                ex);
                            return(null);
                        }
                    }

                    SculptMesh.SculptType sculptType;
                    switch ((SculptType)primShape.SculptType)
                    {
                    case SculptType.Cylinder:
                        sculptType = SculptMesh.SculptType.cylinder;
                        break;

                    case SculptType.Plane:
                        sculptType = SculptMesh.SculptType.plane;
                        break;

                    case SculptType.Torus:
                        sculptType = SculptMesh.SculptType.torus;
                        break;

                    case SculptType.Sphere:
                        sculptType = SculptMesh.SculptType.sphere;
                        break;

                    default:
                        sculptType = SculptMesh.SculptType.plane;
                        break;
                    }

                    bool mirror = ((primShape.SculptType & 128) != 0);
                    bool invert = ((primShape.SculptType & 64) != 0);

                    if (idata == null)
                    {
                        return(null);
                    }

                    sculptMesh = new SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert);

                    idata.Dispose();
                    idata = null;

                    sculptMesh.DumpRaw(baseDir, primName, "primMesh");

                    sculptMesh.Scale(size.X, size.Y, size.Z);

                    coords = sculptMesh.coords;
                    faces  = sculptMesh.faces;
                }
            }
            else
            {
                float pathShearX = primShape.PathShearX < 128
                                       ? primShape.PathShearX * 0.01f
                                       : (primShape.PathShearX - 256) * 0.01f;
                float pathShearY = primShape.PathShearY < 128
                                       ? primShape.PathShearY * 0.01f
                                       : (primShape.PathShearY - 256) * 0.01f;
                float pathBegin  = primShape.PathBegin * 2.0e-5f;
                float pathEnd    = 1.0f - primShape.PathEnd * 2.0e-5f;
                float pathScaleX = (primShape.PathScaleX - 100) * 0.01f;
                float pathScaleY = (primShape.PathScaleY - 100) * 0.01f;

                float profileBegin  = primShape.ProfileBegin * 2.0e-5f;
                float profileEnd    = 1.0f - primShape.ProfileEnd * 2.0e-5f;
                float profileHollow = primShape.ProfileHollow * 2.0e-5f;
                if (profileHollow > 0.95f)
                {
                    if (profileHollow > 0.99f)
                    {
                        profileHollow = 0.99f;
                    }
                    float sizeX = primShape.Scale.X - (primShape.Scale.X * profileHollow);
                    if (sizeX < 0.1f)                        //If its > 0.1, its fine to mesh at the small hollow
                    {
                        profileHollow = 0.95f + (sizeX / 2); //Scale the rest by how large the size of the prim is
                    }
                }

                int sides = 4;
                switch ((primShape.ProfileCurve & 0x07))
                {
                case (byte)ProfileShape.EquilateralTriangle:
                    sides = 3;
                    break;

                case (byte)ProfileShape.Circle:
                    sides = 24;
                    break;

                case (byte)ProfileShape.HalfCircle:
                    sides        = 24;
                    profileBegin = 0.5f * profileBegin + 0.5f;
                    profileEnd   = 0.5f * profileEnd + 0.5f;
                    break;
                }

                int hollowSides = sides;
                switch (primShape.HollowShape)
                {
                case HollowShape.Circle:
                    hollowSides = 24;
                    break;

                case HollowShape.Square:
                    hollowSides = 4;
                    break;

                case HollowShape.Triangle:
                    hollowSides = 3;
                    break;
                }

                primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);

                if (primMesh.errorMessage != null)
                {
                    if (primMesh.errorMessage.Length > 0)
                    {
                        MainConsole.Instance.Error("[ERROR] " + primMesh.errorMessage);
                    }
                }

                primMesh.topShearX    = pathShearX;
                primMesh.topShearY    = pathShearY;
                primMesh.pathCutBegin = pathBegin;
                primMesh.pathCutEnd   = pathEnd;

                if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte)Extrusion.Flexible)
                {
                    primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
                    primMesh.twistEnd   = primShape.PathTwist * 18 / 10;
                    primMesh.taperX     = pathScaleX;
                    primMesh.taperY     = pathScaleY;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f)
                        {
                            profileBegin = 0.0f;
                        }
                        if (profileEnd > 1.0f)
                        {
                            profileEnd = 1.0f;
                        }
                    }
#if SPAM
                    MainConsole.Instance.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.Extrude(primShape.PathCurve == (byte)Extrusion.Straight
                                             ? PathType.Linear
                                             : PathType.Flexible);
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex, primName, primMesh);
                        return(null);
                    }
                }
                else
                {
                    primMesh.holeSizeX   = (200 - primShape.PathScaleX) * 0.01f;
                    primMesh.holeSizeY   = (200 - primShape.PathScaleY) * 0.01f;
                    primMesh.radius      = 0.01f * primShape.PathRadiusOffset;
                    primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
                    primMesh.skew        = 0.01f * primShape.PathSkew;
                    primMesh.twistBegin  = primShape.PathTwistBegin * 36 / 10;
                    primMesh.twistEnd    = primShape.PathTwist * 36 / 10;
                    primMesh.taperX      = primShape.PathTaperX * 0.01f;
                    primMesh.taperY      = primShape.PathTaperY * 0.01f;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f)
                        {
                            profileBegin = 0.0f;
                        }
                        if (profileEnd > 1.0f)
                        {
                            profileEnd = 1.0f;
                        }
                    }
#if SPAM
                    MainConsole.Instance.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.Extrude(PathType.Circular);
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex, primName, primMesh);
                        return(null);
                    }
                }

                primMesh.DumpRaw(baseDir, primName, "primMesh");

                primMesh.Scale(size.X, size.Y, size.Z);

                coords   = primMesh.coords;
                faces    = primMesh.faces;
                primMesh = null;
            }

            Mesh mesh = new Mesh(key);
            //mesh.m_triangles = faces;
            //mesh.m_vertices = coords;
            // Add the corresponding triangles to the mesh
            mesh.Set(coords, faces);
            coords.Clear();
            faces.Clear();
            coords = null;
            faces  = null;
            return(mesh);
        }
Exemplo n.º 18
0
        private static void Main(string[] args)
        {
            Console.WriteLine("Bitsquid Toolchain - bsunp (bitsquid_unp) by daemon1");
            Console.WriteLine("Modified by xyx0826");
            Console.WriteLine("Usage: bsunp.exe [package-name]");
            if (args.Length == 0) // If no parameters are given
            {
                Console.WriteLine("ERROR: package file not specified.");
                Console.ReadKey();
                return;
            }

            // Read package file
            FileStream   packageFile  = new FileStream(args[0], FileMode.Open);
            BinaryReader binaryReader = new BinaryReader(packageFile);
            MemoryStream memoryStream = new MemoryStream();
            String       path         = Path.GetDirectoryName(
                System.Reflection.Assembly.GetExecutingAssembly().Location);

            // Check if stream file exists with package file
            FileStream streamFile = null;

            if (File.Exists(args[0] + ".stream"))
            {
                streamFile = new FileStream(args[0] + ".stream", FileMode.Open);
            }
            else
            {
                Console.WriteLine("INFO: stream file not found.");
            }
            packageFile.Seek(12L, SeekOrigin.Begin);
            byte[] buffer = new byte[66000];
            while (packageFile.Position < packageFile.Length)
            {
                int num = binaryReader.ReadInt32();
                packageFile.Read(buffer, 0, num);
                if (num == 65536)
                {
                    memoryStream.Write(buffer, 0, num);
                }
                else
                {
                    ZOutputStream zOutputStream = new ZOutputStream(memoryStream);
                    zOutputStream.Write(buffer, 0, num);
                    zOutputStream.Flush();
                }
            }
            binaryReader = new BinaryReader(memoryStream);
            memoryStream.Seek(4L, SeekOrigin.Begin);

            Directory.CreateDirectory(path + "\\bsunp_extracted");

            // Write data.bin
            byte[] buffer2 = new byte[288];
            binaryReader.Read(buffer2, 0, 288);
            FileStream dataFile = new FileStream(path + "\\bsunp_extracted\\data.bin", FileMode.Create);

            dataFile.Write(buffer2, 0, 288);
            dataFile.Close();
            memoryStream.Seek(0L, SeekOrigin.Begin);

            if (!File.Exists(path + "\\hashdict.txt"))
            {
                Console.WriteLine("ERROR: hashdict.txt not found.");
                Console.ReadKey();
                return;
            }

            // Read hash dictionary
            StreamReader streamReader = new StreamReader(path + "\\hashdict.txt");
            int          hashCount    = Convert.ToInt32(streamReader.ReadLine());

            ulong[]  hashes = new ulong[hashCount];
            string[] types  = new string[hashCount];
            for (int i = 0; i < hashCount; i++)
            {
                string hashEntry = streamReader.ReadLine();
                int    tabPos    = hashEntry.IndexOf('\t', 0);
                hashes[i] = Convert.ToUInt64(hashEntry.Substring(0, tabPos), 16);
                types[i]  = hashEntry.Substring(tabPos + 1);
            }
            int num4 = binaryReader.ReadInt32();

            memoryStream.Seek(256L, SeekOrigin.Current);

            // Identify file hashes
            for (int j = 0; j < num4; j++)
            {
                ulong currentHash = binaryReader.ReadUInt64();
                binaryReader.ReadUInt64();
                bool known = false;
                for (int i = 0; i < hashCount; i++)
                {
                    if (currentHash == hashes[i])
                    {
                        Console.WriteLine("INFO: extracting file " + types[i]);
                        known = true;
                        break;
                    }
                }
                if (!known)
                {
                    Console.WriteLine("INFO: file hash unknown " + currentHash);
                }
            }
            for (int j = 0; j < num4; j++)
            {
                ulong  num6       = binaryReader.ReadUInt64();
                ulong  num7       = binaryReader.ReadUInt64();
                string outputType = num6.ToString("X16");
                for (int i = 0; i < hashCount; i++)
                {
                    if (num6 == hashes[i])
                    {
                        outputType = types[i];
                        break;
                    }
                }
                string outputHash = num7.ToString("X16");
                int    num8       = binaryReader.ReadInt32();
                binaryReader.ReadInt32();
                int[] array3 = new int[num8];
                int[] array4 = new int[num8];
                int[] array5 = new int[num8];
                for (int i = 0; i < num8; i++)
                {
                    array4[i] = binaryReader.ReadInt32();
                    array3[i] = binaryReader.ReadInt32();
                    array5[i] = binaryReader.ReadInt32();
                }
                // Write output file
                for (int i = 0; i < num8; i++)
                {
                    string outputFileName;
                    if (i == 0)
                    {
                        outputFileName = outputType.Substring(0, 3) + "_" + outputHash + "." + outputType;
                    }
                    else
                    {
                        outputFileName = string.Concat(new string[]
                        {
                            outputType.Substring(0, 3),
                            "_",
                            outputHash,
                            "_",
                            array4[i].ToString("X"),
                            ".",
                            outputType
                        });
                    }
                    byte[] array6 = new byte[array3[i]];
                    memoryStream.Read(array6, 0, array3[i]);
                    File.WriteAllBytes(path + "\\bsunp_extracted\\" + outputFileName, array6);

                    if (streamFile != null && array5[i] > 0)
                    {
                        byte[] array7 = new byte[array5[i]];
                        streamFile.Read(array7, 0, array5[i]);
                        File.WriteAllBytes(path + "\\bsunp_extracted\\" + outputFileName + ".stream", array7);
                    }
                }
            }
            Console.WriteLine("Extraction complete.");
            Console.ReadKey();
        }
Exemplo n.º 19
0
 public void Deserialize(OSDMap map)
 {
     try
     {
         using (MemoryStream input = new MemoryStream(map["Zipped"].AsBinary()))
         {
             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);
                     MaterialData = OSDParser.DeserializeLLSDBinary(output);
                 }
             }
         }
     }
     catch (Exception ex)
     {
         Logger.Log("Failed to decode RenderMaterials message:", Helpers.LogLevel.Warning, ex);
         MaterialData = new OSDMap();
     }
 }
Exemplo n.º 20
0
        /// <summary>
        /// Decodes mesh asset. See <see cref="OpenMetaverse.Rendering.FacetedMesh.TryDecodeFromAsset"/>
        /// to furter decode it for rendering</summary>
        /// <returns>true</returns>
        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)
                        {
                            MeshData[partName] = header[partName];
                            continue;
                        }

                        OSDMap partInfo = (OSDMap)header[partName];
                        if (partInfo["offset"] < 0 || partInfo["size"] == 0)
                        {
                            MeshData[partName] = partInfo;
                            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;
            }
        }
Exemplo n.º 21
0
        private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
        {
            PrimMesh primMesh;

            PrimMesher.SculptMesh sculptMesh;

            List <Coord> coords = new List <Coord>();
            List <Face>  faces  = new List <Face>();

            Image  idata = null;
            string decodedSculptFileName = "";

            if (primShape.SculptEntry)
            {
                if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh)
                {
                    if (!useMeshiesPhysicsMesh)
                    {
                        return(null);
                    }

                    m_log.Debug("[MESH]: experimental mesh proxy generation");

                    OSD meshOsd;

                    if (primShape.SculptData.Length <= 0)
                    {
                        m_log.Error("[MESH]: asset data is zero length");
                        return(null);
                    }

                    long start = 0;
                    using (MemoryStream data = new MemoryStream(primShape.SculptData))
                    {
                        meshOsd = (OSDMap)OSDParser.DeserializeLLSDBinary(data);
                        start   = data.Position;
                    }

                    if (meshOsd is OSDMap)
                    {
                        OSDMap map          = (OSDMap)meshOsd;
                        OSDMap physicsParms = (OSDMap)map["physics_shape"];
                        int    physOffset   = physicsParms["offset"].AsInteger() + (int)start;
                        int    physSize     = physicsParms["size"].AsInteger();

                        if (physOffset < 0 || physSize == 0)
                        {
                            return(null); // no mesh data in asset
                        }
                        OSD    decodedMeshOsd = new OSD();
                        byte[] meshBytes      = new byte[physSize];
                        System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
                        byte[] decompressed = new byte[physSize * 5];
                        try
                        {
                            using (MemoryStream inMs = new MemoryStream(meshBytes))
                            {
                                using (MemoryStream outMs = new MemoryStream())
                                {
                                    using (ZOutputStream zOut = new ZOutputStream(outMs))
                                    {
                                        byte[] readBuffer = new byte[2048];
                                        int    readLen    = 0;
                                        while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
                                        {
                                            zOut.Write(readBuffer, 0, readLen);
                                        }
                                        zOut.Flush();
                                        outMs.Seek(0, SeekOrigin.Begin);

                                        byte[] decompressedBuf = outMs.GetBuffer();

                                        decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
                            return(null);
                        }

                        OSDArray decodedMeshOsdArray = null;

                        // physics_shape is an array of OSDMaps, one for each submesh
                        if (decodedMeshOsd is OSDArray)
                        {
                            decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
                            foreach (OSD subMeshOsd in decodedMeshOsdArray)
                            {
                                if (subMeshOsd is OSDMap)
                                {
                                    OSDMap subMeshMap = (OSDMap)subMeshOsd;

                                    OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3();
                                    OpenMetaverse.Vector3 posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"].AsVector3();
                                    ushort faceIndexOffset       = (ushort)coords.Count;

                                    byte[] posBytes = subMeshMap["Position"].AsBinary();
                                    for (int i = 0; i < posBytes.Length; i += 6)
                                    {
                                        ushort uX = Utils.BytesToUInt16(posBytes, i);
                                        ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
                                        ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);

                                        Coord c = new Coord(
                                            Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X,
                                            Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y,
                                            Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z);

                                        coords.Add(c);
                                    }

                                    byte[] triangleBytes = subMeshMap["TriangleList"].AsBinary();
                                    for (int i = 0; i < triangleBytes.Length; i += 6)
                                    {
                                        ushort v1 = (ushort)(Utils.BytesToUInt16(triangleBytes, i) + faceIndexOffset);
                                        ushort v2 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 2) + faceIndexOffset);
                                        ushort v3 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 4) + faceIndexOffset);
                                        Face   f  = new Face(v1, v2, v3);
                                        faces.Add(f);
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
                    {
                        decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString());
                        try
                        {
                            if (File.Exists(decodedSculptFileName))
                            {
                                idata = Image.FromFile(decodedSculptFileName);
                            }
                        }
                        catch (Exception e)
                        {
                            m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message);
                        }
                        //if (idata != null)
                        //    m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
                    }

                    if (idata == null)
                    {
                        if (primShape.SculptData == null || primShape.SculptData.Length == 0)
                        {
                            return(null);
                        }

                        try
                        {
                            OpenMetaverse.Imaging.ManagedImage unusedData;
                            OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
                            unusedData = null;

                            //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);

                            if (cacheSculptMaps && idata != null)
                            {
                                try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
                                catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
                            }
                        }
                        catch (DllNotFoundException)
                        {
                            m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed.  Often times this is because of an old version of GLIBC.  You must have version 2.4 or above!");
                            return(null);
                        }
                        catch (IndexOutOfRangeException)
                        {
                            m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
                            return(null);
                        }
                        catch (Exception ex)
                        {
                            m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
                            return(null);
                        }
                    }

                    PrimMesher.SculptMesh.SculptType sculptType;
                    switch ((OpenMetaverse.SculptType)primShape.SculptType)
                    {
                    case OpenMetaverse.SculptType.Cylinder:
                        sculptType = PrimMesher.SculptMesh.SculptType.cylinder;
                        break;

                    case OpenMetaverse.SculptType.Plane:
                        sculptType = PrimMesher.SculptMesh.SculptType.plane;
                        break;

                    case OpenMetaverse.SculptType.Torus:
                        sculptType = PrimMesher.SculptMesh.SculptType.torus;
                        break;

                    case OpenMetaverse.SculptType.Sphere:
                        sculptType = PrimMesher.SculptMesh.SculptType.sphere;
                        break;

                    default:
                        sculptType = PrimMesher.SculptMesh.SculptType.plane;
                        break;
                    }

                    bool mirror = ((primShape.SculptType & 128) != 0);
                    bool invert = ((primShape.SculptType & 64) != 0);

                    sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert);

                    idata.Dispose();

                    sculptMesh.DumpRaw(baseDir, primName, "primMesh");

                    sculptMesh.Scale(size.X, size.Y, size.Z);

                    coords = sculptMesh.coords;
                    faces  = sculptMesh.faces;
                }
            }
            else
            {
                float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
                float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
                float pathBegin  = (float)primShape.PathBegin * 2.0e-5f;
                float pathEnd    = 1.0f - (float)primShape.PathEnd * 2.0e-5f;
                float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f;
                float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f;

                float profileBegin  = (float)primShape.ProfileBegin * 2.0e-5f;
                float profileEnd    = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
                float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
                if (profileHollow > 0.95f)
                {
                    profileHollow = 0.95f;
                }

                int sides = 4;
                if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
                {
                    sides = 3;
                }
                else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
                {
                    sides = 24;
                }
                else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
                { // half circle, prim is a sphere
                    sides = 24;

                    profileBegin = 0.5f * profileBegin + 0.5f;
                    profileEnd   = 0.5f * profileEnd + 0.5f;
                }

                int hollowSides = sides;
                if (primShape.HollowShape == HollowShape.Circle)
                {
                    hollowSides = 24;
                }
                else if (primShape.HollowShape == HollowShape.Square)
                {
                    hollowSides = 4;
                }
                else if (primShape.HollowShape == HollowShape.Triangle)
                {
                    hollowSides = 3;
                }

                primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);

                if (primMesh.errorMessage != null)
                {
                    if (primMesh.errorMessage.Length > 0)
                    {
                        m_log.Error("[ERROR] " + primMesh.errorMessage);
                    }
                }

                primMesh.topShearX    = pathShearX;
                primMesh.topShearY    = pathShearY;
                primMesh.pathCutBegin = pathBegin;
                primMesh.pathCutEnd   = pathEnd;

                if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte)Extrusion.Flexible)
                {
                    primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
                    primMesh.twistEnd   = primShape.PathTwist * 18 / 10;
                    primMesh.taperX     = pathScaleX;
                    primMesh.taperY     = pathScaleY;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f)
                        {
                            profileBegin = 0.0f;
                        }
                        if (profileEnd > 1.0f)
                        {
                            profileEnd = 1.0f;
                        }
                    }
#if SPAM
                    m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.ExtrudeLinear();
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
                        return(null);
                    }
                }
                else
                {
                    primMesh.holeSizeX   = (200 - primShape.PathScaleX) * 0.01f;
                    primMesh.holeSizeY   = (200 - primShape.PathScaleY) * 0.01f;
                    primMesh.radius      = 0.01f * primShape.PathRadiusOffset;
                    primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
                    primMesh.skew        = 0.01f * primShape.PathSkew;
                    primMesh.twistBegin  = primShape.PathTwistBegin * 36 / 10;
                    primMesh.twistEnd    = primShape.PathTwist * 36 / 10;
                    primMesh.taperX      = primShape.PathTaperX * 0.01f;
                    primMesh.taperY      = primShape.PathTaperY * 0.01f;

                    if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
                    {
                        ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
                        if (profileBegin < 0.0f)
                        {
                            profileBegin = 0.0f;
                        }
                        if (profileEnd > 1.0f)
                        {
                            profileEnd = 1.0f;
                        }
                    }
#if SPAM
                    m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
#endif
                    try
                    {
                        primMesh.ExtrudeCircular();
                    }
                    catch (Exception ex)
                    {
                        ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
                        return(null);
                    }
                }

                primMesh.DumpRaw(baseDir, primName, "primMesh");

                primMesh.Scale(size.X, size.Y, size.Z);

                coords = primMesh.coords;
                faces  = primMesh.faces;
            }

            // Remove the reference to any JPEG2000 sculpt data so it can be GCed
            primShape.SculptData = Utils.EmptyBytes;

            int numCoords = coords.Count;
            int numFaces  = faces.Count;

            // Create the list of vertices
            List <Vertex> vertices = new List <Vertex>();
            for (int i = 0; i < numCoords; i++)
            {
                Coord c = coords[i];
                vertices.Add(new Vertex(c.X, c.Y, c.Z));
            }

            Mesh mesh = new Mesh();
            // Add the corresponding triangles to the mesh
            for (int i = 0; i < numFaces; i++)
            {
                Face f = faces[i];
                mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
            }
            return(mesh);
        }