/// <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); }
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); }
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); } } } }
/// <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"); } }
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); }
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); } }
/// <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); }
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()); } } } }
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(); } }
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); }
/// <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; }
/// <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); }
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(); } }
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(); }
// 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); }
// 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); }
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); }
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(); }
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(); } }
/// <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; } }
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); }