diff --git a/libsdf/code/2D/Sdf2D.cs b/libsdf/code/2D/Sdf2D.cs index 44d3e4b..d5aa3f5 100644 --- a/libsdf/code/2D/Sdf2D.cs +++ b/libsdf/code/2D/Sdf2D.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; namespace Sandbox.Sdf; @@ -129,19 +130,19 @@ public float this[Vector2 pos] } } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { writer.Write( Min ); writer.Write( Max ); writer.Write( CornerRadius ); } - public static RectSdf ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static RectSdf ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new RectSdf( - reader.Read(), - reader.Read(), - reader.Read() ); + reader.ReadVector2(), + reader.ReadVector2(), + reader.ReadSingle() ); } } @@ -158,17 +159,17 @@ public record struct CircleSdf( Vector2 Center, float Radius ) : ISdf2D /// public float this[Vector2 pos] => (pos - Center).Length - Radius; - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { writer.Write( Center ); writer.Write( Radius ); } - public static CircleSdf ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static CircleSdf ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new CircleSdf( - reader.Read(), - reader.Read() ); + reader.ReadVector2(), + reader.ReadSingle() ); } } @@ -221,19 +222,19 @@ public float this[Vector2 pos] } } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { writer.Write( PointA ); writer.Write( PointB ); writer.Write( Radius ); } - public static LineSdf ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static LineSdf ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new LineSdf( - reader.Read(), - reader.Read(), - reader.Read() ); + reader.ReadVector2(), + reader.ReadVector2(), + reader.ReadSingle() ); } } @@ -364,23 +365,23 @@ public float this[Vector2 pos] } } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { writer.Write( _texture.ResourcePath ); writer.Write( _gradientWidthPixels ); - writer.Write( _channel ); + writer.Write( (byte) _channel ); writer.Write( _worldSize ); writer.Write( _worldOffset ); } - public static TextureSdf ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static TextureSdf ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new TextureSdf( Texture.Load( FileSystem.Mounted, reader.ReadString() ), - reader.Read(), - reader.Read(), - reader.Read(), - reader.Read() ); + reader.ReadInt32(), + (ColorChannel) reader.ReadByte(), + reader.ReadVector2(), + reader.ReadVector2() ); } } @@ -416,7 +417,7 @@ public TransformedSdf2D( T sdf, Transform2D transform ) /// public float this[Vector2 pos] => Sdf[Transform.InverseTransformPoint( pos )] * Transform.InverseScale; - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { Sdf.Write( writer, sdfTypes ); writer.Write( Transform.Position ); @@ -424,14 +425,14 @@ public void WriteRaw( NetWrite writer, Dictionary sdfTypes writer.Write( Transform.Scale ); } - public static TransformedSdf2D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static TransformedSdf2D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new TransformedSdf2D( - (T)ISdf2D.Read( ref reader, sdfTypes ), + (T)ISdf2D.Read( reader, sdfTypes ), new Transform2D( - reader.Read(), - reader.Read(), - reader.Read() ) ); + reader.ReadVector2(), + reader.ReadVector2(), + reader.ReadSingle() ) ); } } @@ -447,17 +448,17 @@ public record struct TranslatedSdf2D( T Sdf, Vector2 Offset ) : ISdf2D /// public float this[Vector2 pos] => Sdf[pos - Offset]; - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { Sdf.Write( writer, sdfTypes ); writer.Write( Offset ); } - public static TranslatedSdf2D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static TranslatedSdf2D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new TranslatedSdf2D( - (T) ISdf2D.Read( ref reader, sdfTypes ), - reader.Read() ); + (T) ISdf2D.Read( reader, sdfTypes ), + reader.ReadVector2() ); } } @@ -473,16 +474,16 @@ public record struct ExpandedSdf2D( T Sdf, float Margin ) : ISdf2D /// public float this[Vector2 pos] => Sdf[pos] - Margin; - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { Sdf.Write( writer, sdfTypes ); writer.Write( Margin ); } - public static ExpandedSdf2D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static ExpandedSdf2D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new ExpandedSdf2D( - (T) ISdf2D.Read( ref reader, sdfTypes ), - reader.Read() ); + (T) ISdf2D.Read( reader, sdfTypes ), + reader.ReadSingle() ); } } diff --git a/libsdf/code/2D/Transform2D.cs b/libsdf/code/2D/Transform2D.cs index ea5af44..fe4a419 100644 --- a/libsdf/code/2D/Transform2D.cs +++ b/libsdf/code/2D/Transform2D.cs @@ -19,6 +19,22 @@ public static implicit operator Rotation2D( float degrees ) return new Rotation2D( degrees ); } + /// + /// Converts a rotation to its vector representation. + /// + public static implicit operator Vector2( Rotation2D rotation ) + { + return new Vector2( rotation.Cos, rotation.Sin ); + } + + /// + /// Converts a rotation from its vector representation. + /// + public static implicit operator Rotation2D( Vector2 vector ) + { + return new Rotation2D( vector.x, vector.y ); + } + /// /// Represents a rotation of 0 degrees. /// diff --git a/libsdf/code/3D/Noise/Cellular.cs b/libsdf/code/3D/Noise/Cellular.cs index 77ea8ee..27327e1 100644 --- a/libsdf/code/3D/Noise/Cellular.cs +++ b/libsdf/code/3D/Noise/Cellular.cs @@ -1,6 +1,7 @@ using System; using System.Buffers; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; @@ -139,16 +140,16 @@ async Task ISdf3D.SampleRangeAsync( Transform transform, float[] output, (int X, } } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { writer.Write( Seed ); writer.Write( CellSize ); writer.Write( DistanceOffset ); } - public static CellularNoiseSdf3D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static CellularNoiseSdf3D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { - return new CellularNoiseSdf3D( reader.Read(), reader.Read(), reader.Read() ); + return new CellularNoiseSdf3D( reader.ReadInt32(), reader.ReadVector3(), reader.ReadSingle() ); } } } diff --git a/libsdf/code/3D/Sdf3D.cs b/libsdf/code/3D/Sdf3D.cs index 7f92c6a..417c44d 100644 --- a/libsdf/code/3D/Sdf3D.cs +++ b/libsdf/code/3D/Sdf3D.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Buffers; using System.Collections.Generic; +using System.IO; using System.Threading.Tasks; using Sandbox.Sdf.Noise; using Sandbox.UI; @@ -172,19 +173,19 @@ public float this[Vector3 pos] } } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { writer.Write( Min ); writer.Write( Max ); writer.Write( CornerRadius ); } - public static BoxSdf3D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static BoxSdf3D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new BoxSdf3D( - reader.Read(), - reader.Read(), - reader.Read() ); + reader.ReadVector3(), + reader.ReadVector3(), + reader.ReadSingle() ); } } @@ -201,17 +202,17 @@ public record struct SphereSdf3D( Vector3 Center, float Radius ) : ISdf3D /// public float this[Vector3 pos] => (pos - Center).Length - Radius; - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { writer.Write( Center ); writer.Write( Radius ); } - public static SphereSdf3D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static SphereSdf3D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new SphereSdf3D( - reader.Read(), - reader.Read() ); + reader.ReadVector3(), + reader.ReadSingle() ); } } @@ -265,19 +266,19 @@ public float this[Vector3 pos] } } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { writer.Write( PointA ); writer.Write( PointB ); writer.Write( Radius ); } - public static CapsuleSdf3D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static CapsuleSdf3D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { return new CapsuleSdf3D( - reader.Read(), - reader.Read(), - reader.Read() ); + reader.ReadVector3(), + reader.ReadVector3(), + reader.ReadSingle() ); } } @@ -304,7 +305,7 @@ Task ISdf3D.SampleRangeAsync( Transform transform, float[] output, (int X, int Y return Sdf.SampleRangeAsync( Transform.ToLocal( transform ), output, outputSize ); } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { Sdf.Write( writer, sdfTypes ); writer.Write( Transform.Position ); @@ -312,13 +313,13 @@ public void WriteRaw( NetWrite writer, Dictionary sdfTypes writer.Write( Transform.Scale ); } - public static TransformedSdf3D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static TransformedSdf3D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { - return new TransformedSdf3D( (T) ISdf3D.Read( ref reader, sdfTypes ), + return new TransformedSdf3D( (T) ISdf3D.Read( reader, sdfTypes ), new Transform( - reader.Read(), - reader.Read(), - reader.Read() ) ); + reader.ReadVector3(), + reader.ReadRotation(), + reader.ReadSingle() ) ); } } @@ -339,15 +340,15 @@ Task ISdf3D.SampleRangeAsync( Transform transform, float[] output, (int X, int Y return Sdf.SampleRangeAsync( new Transform( Offset ).ToLocal( transform ), output, outputSize ); } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { Sdf.Write( writer, sdfTypes ); writer.Write( Offset ); } - public static TranslatedSdf3D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static TranslatedSdf3D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { - return new TranslatedSdf3D( (T) ISdf3D.Read( ref reader, sdfTypes ), reader.Read() ); + return new TranslatedSdf3D( (T) ISdf3D.Read( reader, sdfTypes ), reader.ReadVector3() ); } } @@ -375,15 +376,15 @@ async Task ISdf3D.SampleRangeAsync( Transform transform, float[] output, (int X, } } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { Sdf.Write( writer, sdfTypes ); writer.Write( Margin ); } - public static ExpandedSdf3D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static ExpandedSdf3D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { - return new ExpandedSdf3D( (T) ISdf3D.Read( ref reader, sdfTypes ), reader.Read() ); + return new ExpandedSdf3D( (T) ISdf3D.Read( reader, sdfTypes ), reader.ReadSingle() ); } } @@ -425,15 +426,15 @@ await GameTask.WhenAll( } } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { Sdf1.Write( writer, sdfTypes ); Sdf2.Write( writer, sdfTypes ); } - public static IntersectedSdf3D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static IntersectedSdf3D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { - return new IntersectedSdf3D( (T1) ISdf3D.Read( ref reader, sdfTypes ), (T2) ISdf3D.Read( ref reader, sdfTypes ) ); + return new IntersectedSdf3D( (T1) ISdf3D.Read( reader, sdfTypes ), (T2) ISdf3D.Read( reader, sdfTypes ) ); } } @@ -475,16 +476,16 @@ await GameTask.WhenAll( } } - public void WriteRaw( NetWrite writer, Dictionary sdfTypes ) + public void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ) { Sdf.Write( writer, sdfTypes ); BiasSdf.Write( writer, sdfTypes ); writer.Write( BiasScale ); } - public static BiasedSdf3D ReadRaw( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static BiasedSdf3D ReadRaw( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { - return new BiasedSdf3D( (T) ISdf3D.Read( ref reader, sdfTypes ), (TBias) ISdf3D.Read( ref reader, sdfTypes ), reader.Read() ); + return new BiasedSdf3D( (T) ISdf3D.Read( reader, sdfTypes ), (TBias) ISdf3D.Read( reader, sdfTypes ), reader.ReadSingle() ); } } } diff --git a/libsdf/code/Helpers.cs b/libsdf/code/Helpers.cs index 09707db..c47093c 100644 --- a/libsdf/code/Helpers.cs +++ b/libsdf/code/Helpers.cs @@ -46,4 +46,12 @@ public static float GetEpsilon( Vector2 a, Vector2 b, float frac = 0.0001f ) { return Math.Max( GetEpsilon( a, frac ), GetEpsilon( b, frac ) ); } + + public static int NextPowerOf2( int value ) + { + var po2 = 1; + while ( po2 < value ) po2 <<= 1; + + return po2; + } } diff --git a/libsdf/code/SdfWorld.cs b/libsdf/code/SdfWorld.cs index 64c3b04..5cdeded 100644 --- a/libsdf/code/SdfWorld.cs +++ b/libsdf/code/SdfWorld.cs @@ -17,8 +17,8 @@ public sealed class RegisterSdfTypesAttribute : Attribute } -public delegate T SdfReader( ref NetRead read, IReadOnlyDictionary> sdfTypes ) where T : ISdf; -public delegate T SdfReader( ref NetRead read, IReadOnlyDictionary> sdfTypes ) where TBase : ISdf where T : TBase; +public delegate T SdfReader( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) where T : ISdf; +public delegate T SdfReader( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) where TBase : ISdf where T : TBase; public interface ISdf where T : ISdf @@ -44,16 +44,16 @@ internal static void EnsureTypesRegistered() RegisteredTypes.Sort( ( a, b ) => string.CompareOrdinal( a.Type.FullName, b.Type.FullName ) ); } - void WriteRaw( NetWrite writer, Dictionary sdfTypes ); + void WriteRaw( BinaryWriter writer, Dictionary sdfTypes ); public static void RegisterType( SdfReader readRaw ) where TSdf : T { RegisteredTypes.Add( (GlobalGameNamespace.TypeLibrary.GetType( typeof(TSdf) ), - ( ref NetRead read, IReadOnlyDictionary> sdfTypes ) => readRaw( ref read, sdfTypes )) ); + ( reader, sdfTypes ) => readRaw( reader, sdfTypes )) ); } - public void Write( NetWrite writer, Dictionary sdfTypes ) + public void Write( BinaryWriter writer, Dictionary sdfTypes ) { EnsureTypesRegistered(); @@ -75,12 +75,12 @@ public void Write( NetWrite writer, Dictionary sdfTypes ) WriteRaw( writer, sdfTypes ); } - public static T Read( ref NetRead reader, IReadOnlyDictionary> sdfTypes ) + public static T Read( BinaryReader reader, IReadOnlyDictionary> sdfTypes ) { - var typeIndex = reader.Read(); + var typeIndex = reader.ReadInt32(); var sdfReader = sdfTypes[typeIndex]; - return sdfReader( ref reader, sdfTypes ); + return sdfReader( reader, sdfTypes ); } } @@ -291,8 +291,10 @@ public void Read( Stream stream ) // ReSharper disable StaticMemberInGenericType #pragma warning disable SB3000 - private static Dictionary NetWrite_TypeIndices { get; } = new (); - private static Dictionary> NetRead_TypeReaders { get; } = new(); + private static readonly Dictionary NetWrite_TypeIndices = new (); + private static readonly Dictionary> NetRead_TypeReaders = new(); + private static readonly BinaryWriter NetWrite_BinaryWriter = new ( new MemoryStream() ); + private static readonly BinaryReader NetRead_BinaryReader = new( new MemoryStream() ); // ReSharper enable StaticMemberInGenericType #pragma warning restore SB3000 @@ -305,20 +307,31 @@ public int Write( NetWrite msg, int prevModifications ) msg.Write( count ); msg.Write( ModificationCount ); - WriteRange( msg, prevModifications, count, NetWrite_TypeIndices ); + NetWrite_BinaryWriter.BaseStream.Seek( 0, SeekOrigin.Begin ); + NetWrite_BinaryWriter.BaseStream.SetLength( 0 ); + + WriteRange( NetWrite_BinaryWriter, prevModifications, count, NetWrite_TypeIndices ); + + NetWrite_BinaryWriter.Flush(); + + var buffer = ((MemoryStream)NetWrite_BinaryWriter.BaseStream).GetBuffer(); + var size = (int)NetWrite_BinaryWriter.BaseStream.Length; + + msg.Write( size ); + msg.Write( buffer, 0, size ); return count; } - private void WriteRange( NetWrite msg, int from, int count, Dictionary sdfTypes ) + private void WriteRange( BinaryWriter writer, int from, int count, Dictionary sdfTypes ) { for ( var i = 0; i < count; ++i ) { var modification = Modifications[from + i]; - msg.Write( modification.Operator ); - msg.Write( modification.Resource ); - modification.Sdf.Write( msg, sdfTypes ); + writer.Write( (byte) modification.Operator ); + writer.Write( modification.Resource.ResourceId ); + modification.Sdf.Write( writer, sdfTypes ); } } @@ -360,18 +373,33 @@ public bool Read( ref NetRead msg ) NetRead_TypeReaders[index++] = reader; } - ReadRange( ref msg, msgCount, NetRead_TypeReaders ); + var size = msg.Read(); + var stream = (MemoryStream)NetRead_BinaryReader.BaseStream; + + if ( stream.Capacity < size ) + { + stream.Capacity = Helpers.NextPowerOf2( size ); + } + + stream.Seek( 0, SeekOrigin.Begin ); + stream.SetLength( size ); + + msg.Read( stream.GetBuffer(), 0, size ); + + ReadRange( NetRead_BinaryReader, msgCount, NetRead_TypeReaders ); return true; } - private void ReadRange( ref NetRead msg, int count, IReadOnlyDictionary> sdfTypes ) + private void ReadRange( BinaryReader reader, int count, IReadOnlyDictionary> sdfTypes ) { for ( var i = 0; i < count; ++i ) { - var op = msg.Read(); - var res = msg.ReadClass(); - var sdf = ISdf.Read( ref msg, sdfTypes ); + var op = (Operator) reader.ReadByte(); + var resId = reader.ReadInt32(); + var res = GlobalGameNamespace.ResourceLibrary.Get( resId ); + + var sdf = ISdf.Read( reader, sdfTypes ); var modification = new Modification( sdf, res, op );