public DeformerList(FbxNode objectsNode) { using var buf = new UnsafeRawArray <int>(objectsNode.Children.Count, false); var count = objectsNode.FindChildIndexAll(FbxConstStrings.Deformer(), buf.AsSpan()); _dic = new BufferPooledDictionary <long, FbxNode>(count); foreach (var index in buf.AsSpan(0, count)) { var deformer = objectsNode.Children[index]; var id = deformer.Properties[0].AsInt64(); _dic.Add(id, deformer); } }
public static void SafeSkip(this Stream stream, int byteLength) { if (byteLength < 0) { ThrowHelper.ThrowArgOutOfRange(nameof(byteLength)); } if (stream.CanSeek) { var pos = stream.Position + byteLength; if (pos > stream.Length) { stream.Position = stream.Length; ThrowEOS(); } stream.Position = pos; } else { if (byteLength > 128) { using var buf = new UnsafeRawArray <byte>(byteLength, false); SafeRead(stream, buf.AsSpan()); } else { Span <byte> buf = stackalloc byte[byteLength]; SafeRead(stream, buf); } } }
static UnsafeRawArray <T> Decode <T>(Reader reader, int arrayLength, int compressedSize) where T : unmanaged { const int deflateMetaDataSize = 2; reader.Int16(out var _); // deflateMetaData (not be used) // read compressed data using var buf = new UnsafeRawArray <byte>(compressedSize - deflateMetaDataSize); reader.Read(buf.AsSpan()); // decompress data var ptr = (byte *)buf.Ptr; using var ms = (_ms is null) ? (_ms = new MemoryStreamUM(ptr, buf.Length)) : _ms.RefreshInstance(ptr, buf.Length); using var ds = new DeflateStream(ms, CompressionMode.Decompress); var decoded = new UnsafeRawArray <T>(arrayLength); try { ds.Read(MemoryMarshal.Cast <T, byte>(decoded.AsSpan())); } catch { decoded.Dispose(); throw; } return(decoded); }
private unsafe static void ParseProperty(Reader reader, ref FbxProperty property) { reader.Byte(out var propertyType); switch (propertyType) { case INT16_PROPERTY: { reader.Int16(out var value); property.SetInt16(value); break; } case BOOL_PROPERTY: { reader.Byte(out var value); // two types format exist. (Oh my gosh !! Fuuuuuuuu*k !!) // blender -> true/false = 0x01/0x00 // Autodesk production -> true/false = 'Y'/'T' = 0x59/0x54 property.SetBool(value != 0x00 && value != 0x54); break; } case INT32_PROPERTY: { reader.Int32(out var value); property.SetInt32(value); break; } case FLOAT_PROPERTY: { reader.Float(out var value); property.SetFloat(value); break; } case DOUBLE_PROPERTY: { reader.Double(out var value); property.SetDouble(value); break; } case INT64_PROPERTY: { reader.Int64(out var value); property.SetInt64(value); break; } case STRING_PROPERTY: { reader.Int32(out var len); RawStringMem str = default; try { str = new RawStringMem(len); reader.Read(str.AsSpan()); SanitizeString(str.AsSpan()); property.SetString((byte *)str.Ptr, str.ByteLength); } catch { str.Dispose(); throw; } break; } case BOOL_ARRAY_PROPERTY: { reader.Int32(out var len); reader.UInt32(out var encoded); reader.UInt32(out var compressedSize); UnsafeRawArray <bool> array = default; // Don't dispose try { if (encoded != 0) { array = Decode <bool>(reader, len, (int)compressedSize); } else { array = new UnsafeRawArray <bool>((int)compressedSize); reader.Read(MemoryMarshal.Cast <bool, byte>(array.AsSpan())); } property.SetBoolArray((bool *)array.Ptr, array.Length); } catch { array.Dispose(); throw; } break; } case INT32_ARRAY_PROPERTY: { reader.Int32(out var len); reader.UInt32(out var encoded); reader.UInt32(out var compressedSize); UnsafeRawArray <int> array = default; // Don't dispose try { if (encoded != 0) { array = Decode <int>(reader, len, (int)compressedSize); } else { array = new UnsafeRawArray <int>((int)compressedSize / sizeof(int)); reader.Read(MemoryMarshal.Cast <int, byte>(array.AsSpan())); } property.SetInt32Array((int *)array.Ptr, array.Length); } catch { array.Dispose(); throw; } break; } case FLOAT_ARRAY_PROPERTY: { reader.Int32(out var len); reader.UInt32(out var encoded); reader.UInt32(out var compressedSize); UnsafeRawArray <float> array = default; // Don't dispose try { if (encoded != 0) { array = Decode <float>(reader, len, (int)compressedSize); } else { array = new UnsafeRawArray <float>((int)compressedSize / sizeof(float)); reader.Read(MemoryMarshal.Cast <float, byte>(array.AsSpan())); } property.SetFloatArray((float *)array.Ptr, array.Length); } catch { array.Dispose(); throw; } break; } case DOUBLE_ARRAY_PROPERTY: { reader.Int32(out var len); reader.UInt32(out var encoded); reader.UInt32(out var compressedSize); UnsafeRawArray <double> array = default; try { if (encoded != 0) { array = Decode <double>(reader, len, (int)compressedSize); } else { array = new UnsafeRawArray <double>((int)compressedSize / sizeof(double)); reader.Read(MemoryMarshal.Cast <double, byte>(array.AsSpan())); } property.SetDoubleArray((double *)array.Ptr, array.Length); } catch { array.Dispose(); throw; } break; } case INT64_ARRAY_PROPERTY: { reader.Int32(out var len); reader.UInt32(out var encoded); reader.UInt32(out var compressedSize); UnsafeRawArray <long> array = default; try { if (encoded != 0) { array = Decode <long>(reader, len, (int)compressedSize); } else { array = new UnsafeRawArray <long>((int)compressedSize / sizeof(long)); reader.Read(MemoryMarshal.Cast <long, byte>(array.AsSpan())); } property.SetInt64Array((long *)array.Ptr, array.Length); } catch { array.Dispose(); throw; } break; } case RAW_BINARY_PROPERTY: { reader.Int32(out var len); var buf = new UnsafeRawArray <byte>(len); try { reader.Read(buf.AsSpan()); property.SetByteArray((byte *)buf.Ptr, buf.Length); } catch { buf.Dispose(); throw; } break; } default: { Debug.WriteLine($"[Skip Unknow Type Property] Position : {reader.BaseStream.Position}, type : {propertyType}"); break; } }