Merge from branch giga

This commit is contained in:
Nitload
2025-08-31 10:42:51 +08:00
parent 1fc687f7d0
commit 1a0ccdd8cb
1619 changed files with 2812 additions and 733136 deletions
+26 -40
View File
@@ -1,33 +1,33 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="root.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// -----------------------------------------------------------------------
// file="root.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Internal;
using System;
@@ -38,19 +38,5 @@ using System.Threading.Tasks;
namespace StgSharp
{
public static unsafe partial class World
{
private static byte leastUnusedArea;
private static List<Area> root = new List<Area>();
private static SSD defaultIdProvider = new SSD();
public static byte NewArea()
{
byte ret = leastUnusedArea;
leastUnusedArea++;
return ret;
}
}//------------------ end of class ---------------------
public static unsafe partial class World { }//------------------ end of class ---------------------
}
+44 -40
View File
@@ -1,33 +1,33 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="GlobalSetting.cs"
// Project: World
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// -----------------------------------------------------------------------
// file="GlobalSetting.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
@@ -44,7 +44,7 @@ namespace StgSharp
internal const int ssdSegmentLength = 16;
private static byte[] _currentHash;
private static byte[] _currentHash = [];
private static bool _inited;
private static int _mainThreadID = -1;
@@ -53,12 +53,14 @@ namespace StgSharp
{
get
{
if( _currentHash == null ) {
if (_currentHash == null)
{
string route = Assembly.GetExecutingAssembly().Location;
string time = DateTime.UtcNow.ToString();
using( SHA256 sh = SHA256.Create() ) {
byte[] bytes = Encoding.UTF8.GetBytes( route );
_currentHash = sh.ComputeHash( bytes );
using (SHA256 sh = SHA256.Create())
{
byte[] bytes = Encoding.UTF8.GetBytes(route);
_currentHash = sh.ComputeHash(bytes);
}
}
return _currentHash;
@@ -67,24 +69,26 @@ namespace StgSharp
public static int MainThreadID
{
get => ( _mainThreadID == -1 ) ?
throw new InvalidOperationException(
"StgSharp environment is not inited. " + "Main thread id is not available" ) : _mainThreadID;
get => (_mainThreadID == -1) ?
throw new InvalidOperationException(
"StgSharp environment is not inited. Main thread id is not available") :
_mainThreadID;
internal set => _mainThreadID = value;
}
/// <summary>
/// CustomizeInit an instance of OpenGL program, This method should be called before any
/// other World api.
/// CustomizeInit an instance of OpenGL program, This method should be called before any
/// other World api.
/// </summary>
public static void InitGL( int majorVersion, int minorVersion )
public static void InitGL(int majorVersion, int minorVersion)
{
if( API == default ) {
if (API == default) {
API = GraphicAPI.GL;
}
if( API != GraphicAPI.GL ) {
if (API != GraphicAPI.GL) {
return;
}
InternalIO.InternalInitGL( majorVersion, minorVersion );
InternalIO.InternalInitGL(majorVersion, minorVersion);
}
public static class GlobalSetting
@@ -97,7 +101,7 @@ namespace StgSharp
get => vsyncActivated;
set
{
InternalIO.glfwSwapInterval( value ? 1 : 0 );
InternalIO.glfwSwapInterval(value ? 1 : 0);
vsyncActivated = value;
}
}
+31 -34
View File
@@ -1,33 +1,33 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Monitors.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// -----------------------------------------------------------------------
// file="Monitors.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Graphics;
using System;
@@ -42,28 +42,25 @@ namespace StgSharp
public static partial class World
{
private static unsafe IntPtr[] monitorsArray;
private static unsafe IntPtr[] monitorsArray = [];
public static unsafe IntPtr[] MonitorsHandleArray
{
get
{
if( monitorsArray == null )
if (monitorsArray == null)
{
int count = 0;
IntPtr* arrayhandle = InternalIO.glfwGetMonitors( &count );
IntPtr* arrayhandle = InternalIO.glfwGetMonitors(&count);
monitorsArray = new IntPtr[count];
Marshal.Copy( ( IntPtr )arrayhandle, monitorsArray, 0, count );
Marshal.FreeHGlobal( ( IntPtr )arrayhandle );
Marshal.Copy((IntPtr)arrayhandle, monitorsArray, 0, count);
Marshal.FreeHGlobal((IntPtr)arrayhandle);
}
return monitorsArray;
}
}
public static IntPtr DefaultMonitor
{
get { return MonitorsHandleArray[ 0 ]; }
}
public static IntPtr DefaultMonitor => MonitorsHandleArray[0];
}
}
+15 -1
View File
@@ -57,6 +57,16 @@ namespace StgSharp
private static uint markCount = 0;
internal static GraphicAPI API = default;
public static int DefaultSIMDAlignment => InternalIO.IntrinsicLevel switch
{
IntrinsicLevel.SSE => 16,
IntrinsicLevel.AVX2 => 32,
IntrinsicLevel.AVX512 => 64,
IntrinsicLevel.NEON => 16,
IntrinsicLevel.Non => 8,
_ => 8,
};
public static unsafe void Init()
{
mainTimeProvider = new StgSharpTime();
@@ -68,7 +78,7 @@ namespace StgSharp
InternalIO.InternalAppendLog("\n\n\n");
InternalIO.InternalWriteLog(
$"Program {Assembly.GetEntryAssembly()!.FullName} on {Environment.MachineName} Started.", LogType.Info);
_mainThreadID = Environment.CurrentManagedThreadId;
MainThreadID = Environment.CurrentManagedThreadId;
Dialogue.LoadDialogue();
@@ -84,21 +94,25 @@ namespace StgSharp
InternalIO.InternalWriteLog(ex.Message, LogType.Error);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void LogInfo(string log)
{
InternalIO.InternalWriteLog(log, LogType.Info);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void LogWarning(string log)
{
InternalIO.InternalWriteLog(log, LogType.Warning);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void LogWarning(Exception notVerySeriesException)
{
InternalIO.InternalWriteLog(notVerySeriesException.Message, LogType.Warning);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Mark(bool needConsole)
{
markCount++;
@@ -1,33 +1,33 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Cordinate.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// -----------------------------------------------------------------------
// file="Cordinate.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Mathematics;
using System;
@@ -40,10 +40,10 @@ using System.Threading.Tasks;
namespace StgSharp.Geometries
{
[StructLayout( LayoutKind.Sequential )]
[StructLayout(LayoutKind.Sequential)]
public struct PartialPlainCoordinate
{
/*
internal Matrix32 axis;
/// <summary>
@@ -55,9 +55,7 @@ namespace StgSharp.Geometries
{
this.origin = origin;
axis = new Matrix32();
#if NET5_0_OR_GREATER
Unsafe.SkipInit( out axis.mat );
#endif
axis.colum0 = horiziontial;
axis.colum1 = vertical;
}
@@ -77,6 +75,7 @@ namespace StgSharp.Geometries
{
return origin + axis.VerticalVecMultiply( raletiveLocation );
}
*/
}
}
@@ -1,33 +1,33 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Uniform.cs"
// Project: StepVisualizer
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// -----------------------------------------------------------------------
// file="Uniform.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Graphics;
using StgSharp.Mathematics;
@@ -47,24 +47,21 @@ namespace StgSharp.Graphics.OpenGL
internal GlHandle id;
public GlHandle Handle
{
get => id;
}
public GlHandle Handle => id;
}
public sealed class Uniform<T> : Uniform where T:unmanaged
public sealed class Uniform<T> : Uniform where T: unmanaged
{
internal Uniform() { }
internal unsafe Uniform( GlHandle id )
internal unsafe Uniform(GlHandle id)
{
this.id = id;
}
internal static Uniform<T> FromHandle( GlHandle handle )
internal static Uniform<T> FromHandle(GlHandle handle)
{
return new Uniform<T>
{
@@ -74,17 +71,17 @@ namespace StgSharp.Graphics.OpenGL
}
public sealed class Uniform<T, U> : Uniform where T:unmanaged where U: struct
public sealed class Uniform<T, U> : Uniform where T: unmanaged where U: struct
{
internal Uniform() { }
internal unsafe Uniform( GlHandle id )
internal unsafe Uniform(GlHandle id)
{
this.id = id;
}
internal static Uniform<T, U> FromHandle( GlHandle handle )
internal static Uniform<T, U> FromHandle(GlHandle handle)
{
return new Uniform<T, U>
{
@@ -94,17 +91,17 @@ namespace StgSharp.Graphics.OpenGL
}
public sealed class Uniform<T, U, V> : Uniform where T:unmanaged where U: struct where V: struct
public sealed class Uniform<T, U, V> : Uniform where T: unmanaged where U: struct where V: struct
{
internal Uniform() { }
internal unsafe Uniform( GlHandle id )
internal unsafe Uniform(GlHandle id)
{
this.id = id;
}
internal static Uniform<T, U, V> FromHandle( GlHandle handle )
internal static Uniform<T, U, V> FromHandle(GlHandle handle)
{
return new Uniform<T, U, V>
{
@@ -114,19 +111,17 @@ namespace StgSharp.Graphics.OpenGL
}
public sealed class Uniform<T, U, V, W> : Uniform where T:unmanaged where U: struct
where V: struct
where W: struct
public sealed class Uniform<T, U, V, W> : Uniform where T: unmanaged where U: struct where V: struct where W: struct
{
internal Uniform() { }
internal unsafe Uniform( GlHandle id )
internal unsafe Uniform(GlHandle id)
{
this.id = id;
}
internal static Uniform<T, U, V, W> FromHandle( GlHandle handle )
internal static Uniform<T, U, V, W> FromHandle(GlHandle handle)
{
return new Uniform<T, U, V, W>
{
@@ -139,66 +134,60 @@ namespace StgSharp.Graphics.OpenGL
public unsafe partial class OpenGLFunction
{
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void SetUniformValue( [NotNull] Uniform<Matrix44> uniform, Matrix44 mat )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetUniformValue([NotNull] Uniform<Matrix44> uniform, Matrix44 mat)
{
Matrix44 temp = mat;
Context.glUniformMatrix4fv( uniform.id.SignedValue, 1, false, ( float* )&temp );
Context.glUniformMatrix4fv(uniform.id.SignedValue, 1, false, (float*)&temp);
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void SetUniformValue(
[NotNull]Uniform<float, float, float, float> uniform,
Vec4 vec )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetUniformValue([NotNull]Uniform<float, float, float, float> uniform, Vec4 vec)
{
Vec4 temp = vec;
Context.glUniform1fv( uniform.id.SignedValue, 4, &temp.reg );
Context.glUniform1fv(uniform.id.SignedValue, 4, &temp.reg);
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void SetUniformValue( [NotNull]Uniform<Vec4> uniform, Vec4 vec )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetUniformValue([NotNull]Uniform<Vec4> uniform, Vec4 vec)
{
Vec4 temp = vec;
Context.glUniform1fv( uniform.id.SignedValue, 4, &temp.reg );
Context.glUniform1fv(uniform.id.SignedValue, 4, &temp.reg);
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void SetUniformValue( [NotNull]Uniform<float> uniform, float v0 )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetUniformValue([NotNull]Uniform<float> uniform, float v0)
{
Context.glUniform1f( uniform.id.SignedValue, v0 );
Context.glUniform1f(uniform.id.SignedValue, v0);
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void SetUniformValue( [NotNull]Uniform<int> uniform, int i0 )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetUniformValue([NotNull]Uniform<int> uniform, int i0)
{
Context.glUniform1i( uniform.id.SignedValue, i0 );
Context.glUniform1i(uniform.id.SignedValue, i0);
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void SetUniformValue( [NotNull] Uniform<float, float> uniform, float v0, float v1 )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetUniformValue([NotNull] Uniform<float, float> uniform, float v0, float v1)
{
Context.glUniform2f( uniform.id.SignedValue, v0, v1 );
Context.glUniform2f(uniform.id.SignedValue, v0, v1);
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void SetUniformValue(
[NotNull] Uniform<float, float, float> uniform,
float v0,
float v1,
float v2 )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetUniformValue([NotNull] Uniform<float, float, float> uniform, float v0, float v1, float v2)
{
Context.glUniform3f( uniform.id.SignedValue, v0, v1, v2 );
Context.glUniform3f(uniform.id.SignedValue, v0, v1, v2);
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetUniformValue(
[NotNull] Uniform<float, float, float, float> uniform,
float v0,
float v1,
float v2,
float v3 )
float v3)
{
Context.glUniform4f( uniform.id.SignedValue, v0, v1, v2, v3 );
Context.glUniform4f(uniform.id.SignedValue, v0, v1, v2, v3);
}
}
+7
View File
@@ -50,9 +50,16 @@ namespace StgSharp.HighPerformance
internal M128(Vector4 v)
{
Unsafe.SkipInit(out this);
Vec = v.AsVector128();
}
internal M128(Vector128<float> v)
{
Unsafe.SkipInit(out this);
Vec = v;
}
public ref T AsRef<T>() where T: unmanaged, INumber<T>
{
return ref Unsafe.As<byte, T>(ref Buffer[0]);
@@ -33,6 +33,8 @@ using StgSharp.HighPerformance;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
@@ -43,7 +45,9 @@ namespace StgSharp.HighPerformance
public unsafe struct MatrixKernel
{
[FieldOffset(0)] internal fixed float Buffer[16];
[FieldOffset(0)] internal fixed byte Buffer[64];
[FieldOffset(0)] internal fixed double FP64Buffer[8];
[FieldOffset(0)] internal fixed float FP32Buffer[16];
[FieldOffset(0)] public M128 XMM0;
[FieldOffset(16)] public M128 XMM1;
[FieldOffset(32)] public M128 XMM2;
@@ -52,5 +56,37 @@ namespace StgSharp.HighPerformance
[FieldOffset(32)] public M256 YMM1;
[FieldOffset(64)] public M512 ZMM0;
public MatrixKernel()
{
Unsafe.SkipInit(out this);
}
public MatrixKernel(bool clear)
{
if (!clear) {
Unsafe.SkipInit(out this);
}
}
public static MatrixKernel Fp32Unit
{
get
{
MatrixKernel kernel = new(true);
kernel.FP32Buffer[0] = 1f;
kernel.FP32Buffer[3] = 1f;
kernel.FP32Buffer[8] = 1f;
kernel.FP32Buffer[15] = 1f;
return kernel;
}
}
public ref T UnsafeIndex<T>(int column, int row) where T: unmanaged, INumber<T>
{
ref M128 col = ref Unsafe.As<byte, M128>(ref Buffer[0]);
col = ref Unsafe.Add(ref col, column);
return ref col.Member<T>(row);
}
}
}
@@ -87,8 +87,10 @@ namespace StgSharp.HighPerformance.Memory
public void Push(T item)
{
Header* header = (Header*)_buffer;
if (header->Top >= header->Capacity) {
if (header->Top >= header->Capacity)
{
Expand();
header = (Header*)_buffer;
}
T* dataStart = (T*)(_buffer + sizeof(Header));
@@ -125,8 +127,8 @@ namespace StgSharp.HighPerformance.Memory
T* dataStart = (T*)(_buffer + sizeof(Header));
fixed (T* sourcePtr = span) {
Buffer.MemoryCopy(sourcePtr, dataStart,
header->Capacity * (nuint)sizeof(T),
Buffer.MemoryCopy(sourcePtr, dataStart,
header->Capacity * (nuint)sizeof(T),
(nuint)span.Length * (nuint)sizeof(T));
}
@@ -1,251 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="ConcurrentStackBuffer.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Threading;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.HighPerformance.Memory
{
public static class ConcurrentStackBufferBuilder
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ConcurrentStackBuffer<T> BuildStack<T>(ReadOnlySpan<T> span)
where T: unmanaged
{
return new ConcurrentStackBuffer<T>(span);
}
}
[CollectionBuilder(
builderType: typeof(ConcurrentStackBufferBuilder),
methodName: nameof(ConcurrentStackBufferBuilder.BuildStack))]
public unsafe class ConcurrentStackBuffer<T> : IDisposable where T: unmanaged
{
private byte* _buffer;
private readonly BufferExpansionLock _lock = new();
private ulong _count;
internal ConcurrentStackBuffer(ReadOnlySpan<T> span)
{
AllocateBuffer(span.Length);
Span<T> targe = new(_buffer + sizeof(Header), span.Length);
span.CopyTo(targe);
}
public ConcurrentStackBuffer(int capacity)
{
if (capacity <= 0) {
throw new ArgumentOutOfRangeException(nameof(capacity));
}
AllocateBuffer(capacity);
}
public ulong Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Volatile.Read(ref _count);
}
public void Clear()
{
Header* header = (Header*)_buffer;
_lock.EnterExpansionProcess();
try
{
header->Top = 0;
}
finally
{
_lock.ExitExpansionProcess();
}
}
public void Dispose()
{
_lock.Dispose();
Marshal.FreeHGlobal((nint)_buffer);
}
public T Pop()
{
Header* header = (Header*)_buffer;
while (true)
{
nuint oldTop = Volatile.Read(ref header->Top);
if (oldTop <= 0) {
throw new InvalidOperationException("Stack underflow");
}
if (Interlocked.CompareExchange(ref header->Top, oldTop - 1, oldTop) == oldTop)
{
_lock.EnterBufferRead();
try
{
T* dataStart = (T*)(_buffer + sizeof(Header));
_ = Interlocked.Decrement(ref _count);
return dataStart[oldTop - 1];
}
finally
{
_lock.ExitBufferRead();
}
}
Thread.Sleep(0); // Yield to avoid busy waiting
}
}
public void Push(T item)
{
while (true)
{
_lock.EnterMetaDataRead();
try
{
Header* header = (Header*)_buffer;
nuint oldTop = Volatile.Read(ref header->Top);
nuint cap = Volatile.Read(ref header->Capacity);
if (oldTop >= cap)
{
_lock.ExitMetaDataRead();
_lock.EnterExpansionProcess();
try
{
header = (Header*)_buffer;
if (header->Top >= header->Capacity)
{
nuint newCap = header->Capacity * 2;
nuint newSize = (nuint)sizeof(Header) + (newCap * (nuint)sizeof(T));
_lock.EnterBufferCopy();
try
{
_buffer = (byte*)NativeMemory.Realloc(_buffer, newSize);
((Header*)_buffer)->Capacity = newCap;
}
finally
{
_lock.ExitBufferCopy();
}
}
}
finally
{
_lock.ExitExpansionProcess();
}
continue;
}
if (Interlocked.CompareExchange(ref header->Top, oldTop + 1, oldTop) == oldTop)
{
_lock.EnterBufferRead();
try
{
T* dataStart = (T*)(_buffer + sizeof(Header));
dataStart[oldTop] = item;
return;
}
finally
{
_lock.ExitBufferRead();
}
}
}
finally
{
if (_lock.IsThreadReadingMetaData) {
_lock.ExitMetaDataRead();
}
}
Thread.Sleep(0); // Yield to avoid busy waiting
}
}
public bool TryPop(out T value)
{
Header* header = (Header*)_buffer;
while (true)
{
nuint oldTop = Volatile.Read(ref header->Top);
if (oldTop <= 0)
{
value = default;
return false;
}
if (Interlocked.CompareExchange(ref header->Top, oldTop - 1, oldTop) == oldTop)
{
_lock.EnterBufferRead();
try
{
T* dataStart = (T*)(_buffer + sizeof(Header));
value = dataStart[oldTop - 1];
}
finally
{
_lock.ExitBufferRead();
}
return true;
}
Thread.Sleep(0); // Yield to avoid busy waiting
}
}
private void AllocateBuffer(int capacity)
{
nuint size = (nuint)sizeof(Header) + ((nuint)capacity * (nuint)sizeof(T));
_buffer = (byte*)NativeMemory.Alloc(size);
Header* header = (Header*)_buffer;
header->Top = 0;
header->Capacity = (nuint)capacity;
}
private struct Header
{
public nuint Capacity; // max capacity of the stack (number of elements)
public nuint Top; // next available index in the stack
}
}
}
@@ -28,17 +28,12 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Entities;
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Allocator = StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocator;
@@ -48,7 +43,6 @@ namespace StgSharp.HighPerformance.Memory
{
internal readonly byte* BufferPointer;
internal readonly Allocator.Entry* EntryHandle;
public readonly uint AllocSize;
@@ -48,8 +48,6 @@ namespace StgSharp.HighPerformance.Memory
public unsafe partial class HybridLayerSegregatedFitAllocator
{
private BufferExpansionLock _spareLock = new();
public hlsfHandle Alloc(uint size)
{
ArgumentOutOfRangeException.ThrowIfGreaterThan<nuint>(size, (nuint)levelSizeArray[^1] * 2);
@@ -57,15 +55,7 @@ namespace StgSharp.HighPerformance.Memory
int segmentIndex = DetermineSegmentIndex(size, level);
int i = level, s = segmentIndex;
if (TryPopLevelForAllocation(i, s, out Entry* handle))
{
SetEntryState(handle, EntryState.Allocated);
return new hlsfHandle(handle, size);
}
fallback:
i = level;
s = segmentIndex;
Entry* handle;
while (!TryPopLevelForAllocation(i, s, out handle))
{
if (++s >= 3)
@@ -75,30 +65,19 @@ namespace StgSharp.HighPerformance.Memory
}
if (i >= levelSizeArray.Length)
{
if (!TryAllocateNew16MBBlock(out handle)) {
throw new OverflowException("Out of memory: Unable to allocate new 16MB block or find suitable bucket for allocation.");
if (TryAllocateNew16MBBlock(out handle))
{
break;
}
Thread.Sleep(0);
goto fallback;
throw new OverflowException("Out of memory: Unable to allocate new 16MB block or find suitable bucket for allocation.");
}
}
try
{
if (handle != null)
{
AcquireEntryNextLock(handle);
SliceMemory(handle, (segmentIndex + 1) * levelSizeArray[level]);
SetEntryState(handle, EntryState.Allocated);
}
return new hlsfHandle(handle, size);
}
finally
{
ReleaseEntryNextLock(handle);
if (handle != null) {
SliceMemory(handle, (segmentIndex + 1) * levelSizeArray[level]);
}
handle->State = EntryState.Allocated;
return new hlsfHandle(handle, size);
}
private void SliceMemory(Entry* e, int offset)
@@ -109,116 +88,110 @@ namespace StgSharp.HighPerformance.Memory
ulong originOffset = e->Position - (ulong)m_Buffer;
ulong finalOffset = originOffset + (ulong)offset;
ulong end = e->Position + e->Size;
int remainSize = (int)(e->Size - offset);
AcquireEntryNextLock(e);
AcquireEntryPrevLock(next);
int minLevel = int.Max((BitOperations.TrailingZeroCount(finalOffset) - 6) / 2, 0);
int i = minLevel >= levelSizeArray.Length ? levelSizeArray.Length - 1 : minLevel;
try
for (; i < levelSizeArray.Length; i++)
{
if ((originOffset & 63) != 0) {
throw new InvalidOperationException("Entry position offset is not aligned to 64 bytes.");
}
int minLevel = Math.Max((BitOperations.TrailingZeroCount(originOffset) - 6) / 2, 0);
int i = minLevel >= levelSizeArray.Length ? levelSizeArray.Length - 1 : minLevel;
for (; i < levelSizeArray.Length; i++)
int levelSize = levelSizeArray[i];
ulong board = (finalOffset + (ulong)levelSize - 1) & ~((ulong)levelSize - 1);
int blockCount = (int)((ulong.Min(board, end) - board) / (ulong)levelSize);
if (blockCount == 0)
{
int levelSize = levelSizeArray[i];
int blockCount = remainSize / levelSize % 4;
if (blockCount == 0)
{
break;
}
int s = blockCount * levelSize;
// create and init new entry
Entry* newEntry = (Entry*)_entries.Allocate();
newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset);
newEntry->Size = (uint)s;
newEntry->LockBuffer = 0;
BucketNode* bucket = (BucketNode*)newEntry->Position;
bucket->EntryRef = newEntry;
bucket->LockBuffer = 0;
newEntry->State = EntryState.ThreadOccupied;
// link new entry
newEntry->PreviousNear = (ulong)current;
newEntry->NextNear = n;
current->NextNear = (ulong)newEntry;
next->PreviousNear = (ulong)newEntry;
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
// set new entry
Entry* old = current;
current = newEntry;
// update lock and data
finalOffset += (ulong)s;
remainSize -= s;
ReleaseEntryNextLock(old);
AcquireEntryNextLock(current);
break;
}
if (remainSize <= 0)
{
ReleaseEntryNextLock(current);
ReleaseEntryPrevLock(next);
return;
}
for (; i >= 0; i--)
{
int levelSize = levelSizeArray[i];
int blockCount = remainSize / levelSize % 4;
if (blockCount == 0)
{
continue;
}
int s = blockCount * levelSize;
int s = blockCount * levelSize;
// create and init new entry
Entry* newEntry = (Entry*)_entries.Allocate();
newEntry->LockBuffer = 0;
newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset);
newEntry->Size = (uint)s;
BucketNode* bucket = (BucketNode*)newEntry->Position;
bucket->EntryRef = newEntry;
bucket->LockBuffer = 0;
newEntry->State = EntryState.ThreadOccupied;
// create and init new entry
Entry* newEntry = (Entry*)_entries.Allocate();
newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset);
newEntry->Size = (uint)s;
BucketNode* bucket = (BucketNode*)newEntry->Position;
bucket->EntryRef = newEntry;
// link new entry
newEntry->PreviousNear = (ulong)current;
current->NextNear = (ulong)newEntry;
newEntry->NextNear = n;
next->PreviousNear = (ulong)newEntry;
// link new entry
newEntry->PreviousNear = (ulong)current;
newEntry->NextNear = n;
current->NextNear = (ulong)newEntry;
next->PreviousNear = (ulong)newEntry;
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
// set new entry
Entry* old = current;
current = newEntry;
// set new entry
Entry* old = current;
current = newEntry;
// update lock and data
finalOffset += (ulong)s;
remainSize -= s;
ReleaseEntryNextLock(old);
AcquireEntryNextLock(current);
if (remainSize <= 0)
{
break;
}
}
// update lock and data
finalOffset += (ulong)s;
remainSize -= s;
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
// set new entry
current = newEntry;
// update data
finalOffset += (ulong)s;
remainSize -= s;
}
catch (Exception)
{
throw;
if (remainSize <= 0) {
return;
}
finally
for (i -= 1; i >= 0; i--)
{
// Release locks in reverse order
ReleaseEntryNextLock(current);
ReleaseEntryPrevLock(next);
int levelSize = levelSizeArray[i];
ulong board = (finalOffset + (ulong)levelSize - 1) & ~((ulong)levelSize - 1);
int blockCount = (int)((ulong.Min(board, end) - finalOffset) / (ulong)levelSize);
if (blockCount == 0)
{
continue;
}
int s = blockCount * levelSize;
// create and init new entry
Entry* newEntry = (Entry*)_entries.Allocate();
newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset);
newEntry->Size = (uint)s;
BucketNode* bucket = (BucketNode*)newEntry->Position;
bucket->EntryRef = newEntry;
// link new entry
newEntry->PreviousNear = (ulong)current;
newEntry->NextNear = n;
current->NextNear = (ulong)newEntry;
if (next != null) {
next->PreviousNear = (ulong)newEntry;
}
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
// set new entry
Entry* old = current;
current = newEntry;
// update lock and data
finalOffset += (ulong)s;
remainSize -= s;
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
// set new entry
current = newEntry;
// update data
finalOffset += (ulong)s;
remainSize -= s;
}
}
@@ -233,22 +206,14 @@ namespace StgSharp.HighPerformance.Memory
/// </returns>
private bool TryAllocateNew16MBBlock(out Entry* handle)
{
nuint pos = Volatile.Read(ref _spareMemory->Position);
nuint pos = _spareMemory->Position;
nuint blockSize = (nuint)levelSizeArray[^1] * 2; // Use last level size (16MB)
nuint newPos = pos + blockSize;
ulong p;
Entry* previous;
do
{
p = Volatile.Read(ref _spareMemory->PreviousNear);
previous = (Entry*)p;
if (previous != null) {
AcquireEntryNextLock(previous);
}
AcquireEntryPrevLock(_spareMemory);
break;
} while (true);
p = _spareMemory->PreviousNear;
previous = (Entry*)p;
if (_spareMemory->Size <= 0)
{
handle = null;
@@ -263,42 +228,26 @@ namespace StgSharp.HighPerformance.Memory
}
// Try to allocate new Entry from slab allocator
try
{
handle = (Entry*)_entries.Allocate();
handle->Position = pos;
handle->Size = (uint)blockSize;
SetEntryState(handle, EntryState.ThreadOccupied);
handle->Level = GetLevelFromSize((uint)blockSize);
handle = (Entry*)_entries.Allocate();
handle->Position = pos;
handle->Size = (uint)blockSize;
handle->Level = GetLevelFromSize((uint)blockSize);
handle->PrevLock = 0;
handle->NextLock = 0;
// Update spare memory position
_spareMemory->Position = newPos; // Replace Volatile.Write with direct access
BucketNode* b = (BucketNode*)handle->Position;
b->EntryRef = handle;
PushLevel(handle->Level, DetermineSegmentIndex((uint)blockSize, handle->Level), b);
// Update spare memory position
_spareMemory->Position = newPos;
BucketNode* b = (BucketNode*)handle->Position;
b->EntryRef = handle;
PushLevel(handle->Level, DetermineSegmentIndex((uint)blockSize, handle->Level), b);
// update position linked list
handle->NextNear = (ulong)_spareMemory;
handle->PreviousNear = p;
_spareMemory->PreviousNear = (ulong)handle; // Replace Volatile.Write with direct access
if (previous != null) {
previous->NextNear = (ulong)handle;
}
// update position linked list
handle->NextNear = (ulong)_spareMemory;
handle->PreviousNear = p;
_spareMemory->PreviousNear = (ulong)handle;
if (previous != null) {
previous->NextNear = (ulong)handle;
}
return true;
}
catch
{
handle = null;
return false;
}
finally
{
ReleaseEntryNextLock(previous);
ReleaseEntryPrevLock(_spareMemory);
}
return true;
}
/// <summary>
@@ -39,12 +39,6 @@ namespace StgSharp.HighPerformance.Memory
public unsafe partial class HybridLayerSegregatedFitAllocator
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AcquireBucketNodeSpinLock(BucketNode* node)
{
AcquireBucketNodeBothLocks(node);
}
/// <summary>
/// Initialize bucket system (called in constructor)
/// </summary>
@@ -53,6 +47,16 @@ namespace StgSharp.HighPerformance.Memory
_bucketHeads = new ulong[levelSizeArray.Length * 3];
}
#region BucketNode Operations
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsNullOrEmpty(BucketNode* node)
{
return node == null || node->Magic != BucketNode.MAGIC_NUMBER;
}
#endregion
private void PushLevel(int levelIndex, int sizeIndex, BucketNode* node)
{
if (node == null || node->EntryRef == null) {
@@ -60,286 +64,110 @@ namespace StgSharp.HighPerformance.Memory
}
int index = (3 * levelIndex) + sizeIndex;
if (Interlocked.CompareExchange(ref _bucketHeads[index], (nuint)node, EmptyHandle) == EmptyHandle)
if (_bucketHeads[index] == EmptyHandle)
{
_bucketHeads[index] = (nuint)node;
node->IsInBucket = true;
node->Magic = BucketNode.MAGIC_NUMBER;
return;
} else
{
while (true)
{
AcquireBucketNodeNextLock(node);
ulong head = Volatile.Read(ref _bucketHeads[index]);
node->NextLevel = head;
BucketNode* headNode = (BucketNode*)head;
try
{
if (Interlocked.CompareExchange(ref _bucketHeads[index], (nuint)node, head) == head)
{
if (headNode != null && !TryAcquireBucketNodePrevLock(headNode))
{
// reset state and retry
_ = Interlocked.CompareExchange(ref _bucketHeads[index], head, (nuint)node);
Thread.Sleep(0);
continue;
}
try
{
node->IsInBucket = true;
node->Magic = BucketNode.MAGIC_NUMBER;
if (headNode != null) {
headNode->PreviousLevel = (ulong)node;
}
return;
}
finally
{
if (headNode != null) {
ReleaseBucketNodePrevLock(headNode);
}
}
} else
{
Thread.Sleep(0);
continue;
}
}
finally
{
ReleaseBucketNodeNextLock(node);
}
ulong head = _bucketHeads[index];
node->NextLevel = head;
BucketNode* headNode = (BucketNode*)head;
node->IsInBucket = true;
node->Magic = BucketNode.MAGIC_NUMBER;
if (headNode != null) {
headNode->PreviousLevel = (ulong)node;
}
}
}
/// <summary>
/// 根据锁类型释放BucketNode锁
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseBucketNodeLockByType(BucketNode* node, byte lockType)
{
switch (lockType)
{
case 0:
ReleaseBucketNodePrevLock(node);
return; // PrevLock
case 1:
ReleaseBucketNodeBothLocks(node);
return; // BothLocks
case 2:
ReleaseBucketNodeNextLock(node);
return; // NextLock
default:
return;
}
}
/// <summary>
/// 按地址顺序释放BucketNode锁
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseOrderedBucketLocks(BucketNode* previous, BucketNode* node, BucketNode* next)
{
if (previous != null) {
ReleaseBucketNodeNextLock(previous);
}
if (node != null) {
ReleaseBucketNodeBothLocks(node);
}
if (next != null) {
ReleaseBucketNodePrevLock(next);
return;
}
}
private void RemoveFromBucket(int levelIndex, int sizeIndex, BucketNode* node)
{
int index = (3 * levelIndex) + sizeIndex;
while (true)
if ((BucketNode*)_bucketHeads[index] == node)
{
if ((BucketNode*)Volatile.Read(ref _bucketHeads[index]) == node)
{
if (TryPopLevel(levelIndex, sizeIndex, out _)) {
return;
}
Thread.Sleep(0);
continue;
}
ulong p = Volatile.Read(ref node->PreviousLevel);
ulong n = Volatile.Read(ref node->NextLevel);
BucketNode* previous = (BucketNode*)p;
BucketNode* next = (BucketNode*)n;
if (!TryAcquireOrderedBucketLocks(previous, node, next))
{
Thread.Sleep(0);
continue;
}
try
{
if (Volatile.Read(ref node->PreviousLevel) != p || Volatile.Read(ref node->NextLevel) != n)
{
Thread.Sleep(0);
continue;
}
if (previous != null) {
previous->NextLevel = n;
}
if (next != null) {
next->PreviousLevel = p;
}
node->NextLevel = EmptyHandle;
node->PreviousLevel = EmptyHandle;
node->IsInBucket = false;
if (TryPopLevel(levelIndex, sizeIndex, out _)) {
return;
}
finally
{
ReleaseOrderedBucketLocks(previous, node, next);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryAcquireBucketNodeSpinLock(BucketNode* node)
{
return TryAcquireBucketNodeBothLocks(node);
}
ulong p = node->PreviousLevel;
ulong n = node->NextLevel;
BucketNode* previous = (BucketNode*)p;
BucketNode* next = (BucketNode*)n;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryAcquireOrderedBucketLocks(BucketNode* previous, BucketNode* node, BucketNode* next)
{
if (previous != null && node != null && next != null)
{
// previous -> node -> next
return TryAcquireBucketNodeNextLock(previous) &&
TryAcquireBucketNodeBothLocks(node) &&
TryAcquireBucketNodePrevLock(next);
} else if (previous != null && node != null) {
return TryAcquireBucketNodeNextLock(previous) && TryAcquireBucketNodeBothLocks(node);
if (previous != null) {
previous->NextLevel = n;
}
return true;
if (next != null) {
next->PreviousLevel = p;
}
node->NextLevel = EmptyHandle;
node->PreviousLevel = EmptyHandle;
node->IsInBucket = false;
return;
}
private bool TryPopLevel(int levelIndex, int sizeIndex, out BucketNode* node)
{
int index = (3 * levelIndex) + sizeIndex;
while (true)
ulong h = _bucketHeads[index];
BucketNode* head = (BucketNode*)h;
if (head == null)
{
ulong h = Volatile.Read(ref _bucketHeads[index]);
BucketNode* head = (BucketNode*)h;
if (head == null)
{
node = null;
return false;
}
if (!TryAcquireBucketNodeNextLock(head))
{
Thread.Sleep(0);
continue;
}
ulong n = Volatile.Read(ref head->NextLevel);
BucketNode* next = (BucketNode*)n;
if (next == null)
{
if (Interlocked.CompareExchange(ref _bucketHeads[index], EmptyHandle, h) == h)
{
node = head;
return true;
}
node = null;
return false;
}
try
{
if (!TryAcquireBucketNodePrevLock(next))
{
Thread.Sleep(0);
continue;
}
try
{
if (Interlocked.CompareExchange(ref _bucketHeads[index], head->NextLevel, h) == h)
{
node = head;
node->IsInBucket = false;
node->NextLevel = EmptyHandle;
if (next != null) {
next->PreviousLevel = EmptyHandle;
}
return true;
} else
{
Thread.Sleep(0);
continue;
}
}
finally
{
if (next != null) {
ReleaseBucketNodePrevLock(next);
}
}
}
finally
{
ReleaseBucketNodeNextLock(head);
}
node = null;
return false;
}
ulong n = head->NextLevel;
BucketNode* next = (BucketNode*)n;
if (next == null)
{
_bucketHeads[index] = EmptyHandle;
node = head;
return true;
}
_bucketHeads[index] = head->NextLevel;
node = head;
node->IsInBucket = false;
node->NextLevel = EmptyHandle;
if (next != null) {
next->PreviousLevel = EmptyHandle;
}
return true;
}
private bool TryRemoveFromBucket(int levelIndex, int sizeIndex, BucketNode* node)
{
int index = (3 * levelIndex) + sizeIndex;
if ((BucketNode*)Volatile.Read(ref _bucketHeads[index]) == node)
{
if (TryPopLevel(levelIndex, sizeIndex, out _)) {
return true;
}
return false;
if ((BucketNode*) _bucketHeads[index] == node) {
return TryPopLevel(levelIndex, sizeIndex, out _);
}
ulong p = Volatile.Read(ref node->PreviousLevel);
ulong n = Volatile.Read(ref node->NextLevel);
ulong p = node->PreviousLevel;
ulong n = node->NextLevel;
BucketNode* previous = (BucketNode*)p;
BucketNode* next = (BucketNode*)n;
if (!TryAcquireOrderedBucketLocks(previous, node, next)) {
return false;
if (previous != null) {
previous->NextLevel = n;
}
if (next != null) {
next->PreviousLevel = p;
}
try
{
if (Volatile.Read(ref node->PreviousLevel) != p || Volatile.Read(ref node->NextLevel) != n) {
return false;
}
if (previous != null) {
previous->NextLevel = n;
}
if (next != null) {
next->PreviousLevel = p;
}
node->NextLevel = EmptyHandle;
node->PreviousLevel = EmptyHandle;
node->IsInBucket = false;
return true;
}
finally
{
ReleaseOrderedBucketLocks(previous, node, next);
}
node->NextLevel = EmptyHandle;
node->PreviousLevel = EmptyHandle;
node->IsInBucket = false;
return true;
}
/// <summary>
@@ -364,139 +192,5 @@ namespace StgSharp.HighPerformance.Memory
}
#region BucketNode Operations
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsNullOrEmpty(BucketNode* node)
{
return node == null || node->Magic != BucketNode.MAGIC_NUMBER;
}
// BucketNode 前驱锁操作(控制PreviousLevel字段)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryAcquireBucketNodePrevLock(BucketNode* node)
{
if (node == null) {
return true;
}
int thread = Environment.CurrentManagedThreadId;
return Interlocked.CompareExchange(ref node->PrevLock, thread, 0) == 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AcquireBucketNodePrevLock(BucketNode* node)
{
if (node == null) {
return;
}
int thread = Environment.CurrentManagedThreadId;
if (Volatile.Read(ref node->PrevLock) != thread)
{
while (Interlocked.CompareExchange(ref node->PrevLock, thread, 0) != 0) {
Thread.Sleep(0);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseBucketNodePrevLock(BucketNode* node)
{
if (node == null) {
return;
}
int thread = Environment.CurrentManagedThreadId;
if (Volatile.Read(ref node->PrevLock) == thread) {
Volatile.Write(ref node->PrevLock, 0);
}
}
// BucketNode 后继锁操作(控制NextLevel字段)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryAcquireBucketNodeNextLock(BucketNode* node)
{
if (node == null) {
return true;
}
int thread = Environment.CurrentManagedThreadId;
return Interlocked.CompareExchange(ref node->NextLock, thread, 0) == 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AcquireBucketNodeNextLock(BucketNode* node)
{
if (node == null) {
return;
}
int thread = Environment.CurrentManagedThreadId;
if (Volatile.Read(ref node->NextLock) != thread)
{
while (Interlocked.CompareExchange(ref node->NextLock, thread, 0) != 0) {
Thread.Sleep(0);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseBucketNodeNextLock(BucketNode* node)
{
if (node == null) {
return;
}
int thread = Environment.CurrentManagedThreadId;
if (Volatile.Read(ref node->NextLock) == thread) {
Volatile.Write(ref node->NextLock, 0);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryAcquireBucketNodeBothLocks(BucketNode* node)
{
if (node == null) {
return true;
}
if (TryAcquireBucketNodePrevLock(node))
{
if (TryAcquireBucketNodeNextLock(node))
{
return true;
} else
{
ReleaseBucketNodePrevLock(node); // 回滚
return false;
}
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseBucketNodeBothLocks(BucketNode* node)
{
if (node == null) {
return;
}
ReleaseBucketNodePrevLock(node);
ReleaseBucketNodeNextLock(node);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AcquireBucketNodeBothLocks(BucketNode* node)
{
if (node == null) {
return;
}
AcquireBucketNodePrevLock(node);
AcquireBucketNodeNextLock(node);
}
#endregion
}
}
@@ -54,36 +54,26 @@ namespace StgSharp.HighPerformance.Memory
if (e == null) {
return;
}
AcquireEntrySpinLock(e);
try
{
if (GetEntryState(e) != EntryState.Allocated) {
return;
}
SetEntryState(e, EntryState.ThreadOccupied);
// Step 4: Try merge with adjacent free blocks and remove them from buckets
MergeAndRemoveFromBuckets(e);
// Step 5: Calculate final level and segment for the merged block
uint finalSize = e->Size;
int finalLevel = GetLevelFromSize(finalSize);
int finalSegment = DetermineSegmentIndex(finalSize, finalLevel);
// Step 6: Set the merged entry state to Empty (ready to be reused)
SetEntryState(e, EntryState.Empty);
// Step 7: Push the merged entry back to appropriate bucket
PushLevel(finalLevel, finalSegment, (BucketNode*)e->Position);
// Note: If mergedEntry is different from original e, the original e
// and any merged entries have already been freed to _entries by MergeAndRemoveFromBuckets
}
finally
{
// Step 8: Always release the spin lock
ReleaseEntrySpinLock(e);
if (e->State != EntryState.Allocated) {
return;
}
// Set to ThreadOccupied to prevent other operations
e->State = EntryState.Empty;
// Try merge with adjacent free blocks and remove them from buckets
MergeAndRemoveFromBuckets(e);
// Calculate final level and segment for the merged block
uint finalSize = e->Size;
int finalLevel = GetLevelFromSize(finalSize);
int finalSegment = DetermineSegmentIndex(finalSize, finalLevel);
// Set the merged entry state to Empty (ready to be reused)
e->State = EntryState.Empty;
// Push the merged entry back to appropriate bucket
PushLevel(finalLevel, finalSegment, (BucketNode*)e->Position);
}
}
@@ -41,24 +41,18 @@ namespace StgSharp.HighPerformance.Memory
public unsafe partial class HybridLayerSegregatedFitAllocator
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AcquireEntrySpinLock(Entry* entry)
private bool AssertBackwardBoundary(ulong currentOffset, Entry* target, int level)
{
AcquireEntryBothLocks(entry);
int nextLevelSize = levelSizeArray[level] * 4;
ulong targetHead = target->Position - (ulong)m_Buffer;
return (currentOffset / (ulong)nextLevelSize) == (targetHead / (ulong)nextLevelSize);
}
private bool AssertBackwardBoundary(ulong current, Entry* target, int level)
private bool AssertForwardBoundary(ulong currentOffset, Entry* target, int level)
{
int size = (level * 2) + 6;
ulong align = current >> size;
return align == target->Position >> size && align == (current + target->Size) >> size;
}
private bool AssertForwardBoundary(ulong current, Entry* target, int level)
{
int size = (level * 2) + 6;
ulong align = current >> size;
return align == target->Position >> size && align == (current - target->Size) >> size;
int nextLevelSize = levelSizeArray[level] * 4;
ulong targetTail = target->Position - (ulong)m_Buffer + target->Size - 1;
return (currentOffset / (ulong)nextLevelSize) == (targetTail / (ulong)nextLevelSize);
}
/// <summary>
@@ -94,113 +88,78 @@ namespace StgSharp.HighPerformance.Memory
Entry* result = entry;
uint size = entry->Size;
int originLevel = GetLevelFromSize(size);
int originLevel = entry->Level;
int segment = DetermineSegmentIndex(size, originLevel);
if (!TryAcquireEntrySpinLock(entry)) {
return;
}
if (!TryRemoveFromBucket(originLevel, segment, (BucketNode*)entry->Position)) { }
try
RemoveFromBucket(originLevel, segment, (BucketNode*)entry->Position);
do
{
_ = TrySetEntryState(entry, EntryState.Empty, EntryState.Merging);
// current Level merge
while (originLevel <= entry->Level)
originLevel = entry->Level;
while (true)
{
ulong offset = entry->Position - (ulong)m_Buffer;
// backward merging - simplified to single attempt
ulong p = entry->PreviousNear;
Entry* prev = (Entry*)p;
// backward merging
while (true)
{
ulong p = entry->PreviousNear;
Entry* prev = (Entry*)p;
if (prev == null || // null ref
prev == _spareMemory || // point at end of list
GetEntryState(prev) != EntryState.Empty || // not empty
!IsAdjacentTo(entry, prev) || // not nearby
entry->Level != prev->Level || // not same level
!AssertBackwardBoundary(offset, prev, entry->Level) || // not aligned if merge
!TryAcquireEntrySpinLock(prev)) // occupied by threads
{
break;
}
ulong pp = prev->NextNear;
Entry* prevPrev = (Entry*)pp;
if (!TryAcquireEntryNextLock(prevPrev))
{
break;
}
try
{
if (!TryRemoveFromBucket(originLevel, DetermineSegmentIndex(prev->Size, originLevel), (BucketNode*)prev->Position))
{
break;
}
entry->Position = prev->Position; // Update position to the previous entry
entry->Size += prev->Size; // Merge sizes
prevPrev->NextNear = (ulong)entry;
RecycleEntry(prev);
}
finally
{
ReleaseEntryNextLock(prevPrev);
ReleaseEntrySpinLock(prev);
}
}
// forward merging
while (true)
{
ulong n = entry->NextNear;
Entry* next = (Entry*)n;
if (next == null || // null ref
next == _spareMemory || // point at end of list
GetEntryState(next) != EntryState.Empty || // not empty
!IsAdjacentTo(entry, next) || // not nearby
entry->Level != next->Level || // not same level
!AssertBackwardBoundary(offset, next, entry->Level) || // not aligned if merge
!TryAcquireEntrySpinLock(next)) // occupied by threads
{
break;
}
ulong nn = next->NextNear;
Entry* nextNext = (Entry*)nn;
if (!TryAcquireEntryPrevLock(nextNext))
{
break;
}
try
{
if (!TryRemoveFromBucket(originLevel, DetermineSegmentIndex(next->Size, originLevel), (BucketNode*)next->Position))
{
break;
}
entry->Size += next->Size;
entry->NextNear = next->NextNear;
RecycleEntry(next);
}
finally
{
ReleaseEntrySpinLock(next);
}
}
// 计算当前块相对于分配空间基址的偏移量
ulong currentOffset = entry->Position - (ulong)m_Buffer;
entry->Level = GetLevelFromSize(entry->Size);
if (originLevel == entry->Level)
if (prev == null ||
prev == _spareMemory ||
!AssertBackwardBoundary(currentOffset, prev, originLevel) ||
!IsAdjacentTo(entry, prev) ||
entry->Level != prev->Level ||
!TryRemoveFromBucket(originLevel, DetermineSegmentIndex(prev->Size, originLevel), (BucketNode*)prev->Position))
{
break;
}
originLevel = entry->Level;
// Update linked list
Entry* prevPrev = (Entry*)prev->PreviousNear;
if (prevPrev != null) {
prevPrev->NextNear = (ulong)entry;
}
entry->PreviousNear = (ulong)prevPrev;
// Merge
entry->Position = prev->Position;
entry->Size += prev->Size;
RecycleEntry(prev);
}
_ = TrySetEntryState(entry, EntryState.Merging, EntryState.Empty);
return;
}
finally
{
ReleaseEntrySpinLock(entry);
}
while (true)
{
// forward merging - simplified to single attempt
ulong n = entry->NextNear;
Entry* next = (Entry*)n;
ulong currentOffset = entry->Position - (ulong)m_Buffer;
if (next == null ||
next == _spareMemory ||
!AssertForwardBoundary(currentOffset, next, entry->Level) ||
!IsAdjacentTo(entry, next) ||
entry->Level != next->Level ||
!TryRemoveFromBucket(originLevel, DetermineSegmentIndex(next->Size, originLevel), (BucketNode*)next->Position))
{
break;
}
// Update linked list
Entry* nextNext = (Entry*)next->NextNear;
if (nextNext != null) {
nextNext->PreviousNear = (ulong)entry;
}
entry->NextNear = (ulong)nextNext;
// Merge
entry->Size += next->Size;
RecycleEntry(next);
}
entry->Level = GetLevelFromSize(entry->Size);
} while (originLevel < entry->Level);
}
private void RecycleEntry(Entry* entry)
@@ -208,14 +167,10 @@ namespace StgSharp.HighPerformance.Memory
if (entry is null) {
return;
}
AcquireEntrySpinLock(entry);
_entries.Free((nuint)entry);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseEntrySpinLock(Entry* entry)
{
ReleaseEntryBothLocks(entry);
entry->PreviousNear = EmptyHandle;
entry->NextNear = EmptyHandle;
_entries.Free((nuint)entry);
}
/// <summary>
@@ -223,64 +178,45 @@ namespace StgSharp.HighPerformance.Memory
/// </summary>
private void RemoveFromPositionChain(Entry* entry)
{
AcquireEntrySpinLock(entry);
try
{
Entry* prev = (Entry*)entry->PreviousNear;
Entry* next = (Entry*)entry->NextNear;
Entry* prev = (Entry*)entry->PreviousNear;
Entry* next = (Entry*)entry->NextNear;
if (prev != null) {
prev->NextNear = entry->NextNear;
}
if (next != null) {
next->PreviousNear = entry->PreviousNear;
}
// Clear node pointers
entry->NextNear = EmptyHandle;
entry->PreviousNear = EmptyHandle;
_entries.Free((nuint)entry);
if (prev != null) {
prev->NextNear = entry->NextNear;
}
finally
{
ReleaseEntrySpinLock(entry);
if (next != null) {
next->PreviousNear = entry->PreviousNear;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryAcquireEntrySpinLock(Entry* entry)
{
return TryAcquireEntryBothLocks(entry);
// Clear node pointers
entry->NextNear = EmptyHandle;
entry->PreviousNear = EmptyHandle;
_entries.Free((nuint)entry);
}
/// <summary>
/// Entry structure - streamlined version (only position and state information) Stored in
/// external SLAB
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = 44)]
[StructLayout(LayoutKind.Explicit, Size = 36)]
internal struct Entry
{
[FieldOffset(28)] internal int Level; // Level of the block in the allocator
[FieldOffset(32)] internal int NextLock;
[FieldOffset(36)] internal int PrevLock;
[FieldOffset(40)] internal int State; // Node state (using int for atomic operations)
[FieldOffset(24)] internal uint Size; // Block size information
[FieldOffset(32)] internal ulong LockBuffer;
[FieldOffset(8)] internal ulong NextNear; // Position linked list: next pointer
[FieldOffset(16)] internal ulong PreviousNear; // Position linked list: previous pointer
[FieldOffset(32)] public EntryState State;
[FieldOffset(0)] public nuint Position; // Memory block position
}
// 更新后的EntryState常量类 - 使用int类型
private static class EntryState
internal enum EntryState : uint
{
public const int Allocated = 1; // Already allocated to user
public const int Empty = 0; // Free, can be allocated
public const int Merging = 3; // Currently being merged
public const int ThreadOccupied = 2; // Occupied by thread (being operated on)
Empty,
Allocated
}
@@ -298,176 +234,6 @@ namespace StgSharp.HighPerformance.Memory
return entry == null;
}
// Entry 状态操作
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TrySetEntryState(Entry* entry, int expectedState, int newState)
{
return Interlocked.CompareExchange(ref entry->State, newState, expectedState) == expectedState;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int GetEntryState(Entry* entry)
{
return entry != null ? Volatile.Read(ref entry->State) : 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void SetEntryState(Entry* entry, int newState)
{
if (entry != null) {
Volatile.Write(ref entry->State, newState);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsEntryEmpty(Entry* entry)
{
return GetEntryState(entry) == EntryState.Empty;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsEntryAllocated(Entry* entry)
{
return GetEntryState(entry) == EntryState.Allocated;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsEntryThreadOccupied(Entry* entry)
{
return GetEntryState(entry) == EntryState.ThreadOccupied;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsEntryMerging(Entry* entry)
{
return GetEntryState(entry) == EntryState.Merging;
}
// Entry 前驱锁操作(控制PreviousNear字段)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryAcquireEntryPrevLock(Entry* entry)
{
if (entry == null) {
return true;
}
int thread = Environment.CurrentManagedThreadId;
return Interlocked.CompareExchange(ref entry->PrevLock, thread, 0) == 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AcquireEntryPrevLock(Entry* entry)
{
if (entry == null) {
return;
}
int thread = Environment.CurrentManagedThreadId;
if (Volatile.Read(ref entry->PrevLock) != thread)
{
while (Interlocked.CompareExchange(ref entry->PrevLock, thread, 0) != 0) {
Thread.Sleep(0);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseEntryPrevLock(Entry* entry)
{
if (entry == null) {
return;
}
int thread = Environment.CurrentManagedThreadId;
if (Volatile.Read(ref entry->PrevLock) == thread) {
Volatile.Write(ref entry->PrevLock, 0);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryAcquireEntryNextLock(Entry* entry)
{
if (entry == null) {
return true;
}
int thread = Environment.CurrentManagedThreadId;
return Interlocked.CompareExchange(ref entry->NextLock, thread, 0) == 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AcquireEntryNextLock(Entry* entry)
{
if (entry == null) {
return;
}
int thread = Environment.CurrentManagedThreadId;
if (Volatile.Read(ref entry->NextLock) != thread)
{
while (Interlocked.CompareExchange(ref entry->NextLock, thread, 0) != 0) {
Thread.Sleep(0);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseEntryNextLock(Entry* entry)
{
if (entry == null) {
return;
}
int thread = Environment.CurrentManagedThreadId;
if (Volatile.Read(ref entry->NextLock) == thread) {
Volatile.Write(ref entry->NextLock, 0);
}
}
// Entry 双锁组合操作
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryAcquireEntryBothLocks(Entry* entry)
{
if (entry == null) {
return true;
}
if (TryAcquireEntryPrevLock(entry))
{
if (TryAcquireEntryNextLock(entry))
{
return true;
} else
{
ReleaseEntryPrevLock(entry); // 回滚
return false;
}
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseEntryBothLocks(Entry* entry)
{
if (entry == null) {
return;
}
ReleaseEntryPrevLock(entry);
ReleaseEntryNextLock(entry);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AcquireEntryBothLocks(Entry* entry)
{
if (entry == null) {
return;
}
AcquireEntryPrevLock(entry);
AcquireEntryNextLock(entry);
}
#endregion
}
}
@@ -54,7 +54,7 @@ namespace StgSharp.HighPerformance.Memory
if (byteSize < 64) {
throw new InvalidOperationException();
}
_entries = SlabAllocator<Entry>.Create(64, BufferLayout.Chunked);
_entries = SlabAllocator<Entry>.Create(64, SlabBufferLayout.Chunked, false);
_size = byteSize;
m_Buffer = (byte*)NativeMemory.AlignedAlloc(byteSize, 16);
_align = 16;
@@ -62,12 +62,10 @@ namespace StgSharp.HighPerformance.Memory
InitializeBucketSystem();
_spareMemory = (Entry*)_entries.Allocate();
SetEntryState(_spareMemory, EntryState.ThreadOccupied);
_spareMemory->State = EntryState.Empty;
_spareMemory->PreviousNear = EmptyHandle;
_spareMemory->NextNear = EmptyHandle;
_spareMemory->Position = (nuint)m_Buffer;
_spareMemory->PrevLock = 0;
_spareMemory->NextLock = 0;
_spareMemory->Size = (uint)byteSize;
}
@@ -77,7 +75,7 @@ namespace StgSharp.HighPerformance.Memory
throw new ArgumentException(
"Alignment must be a power of two and at least 8 bytes.");
}
_entries = SlabAllocator<Entry>.Create(64, BufferLayout.Chunked);
_entries = SlabAllocator<Entry>.Create(64, SlabBufferLayout.Chunked);
m_Buffer = (byte*)NativeMemory.AlignedAlloc(byteSize, (nuint)align);
_align = align;
_size = byteSize;
@@ -85,12 +83,10 @@ namespace StgSharp.HighPerformance.Memory
InitializeBucketSystem();
_spareMemory = (Entry*)_entries.Allocate();
SetEntryState(_spareMemory, EntryState.ThreadOccupied);
_spareMemory->State = EntryState.Empty;
_spareMemory->PreviousNear = EmptyHandle;
_spareMemory->NextNear = EmptyHandle;
_spareMemory->Position = (nuint)m_Buffer;
_spareMemory->PrevLock = 0;
_spareMemory->NextLock = 0;
_spareMemory->Size = (uint)byteSize;
}
@@ -1,40 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="ISlabAllocatable.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.HighPerformance.Memory
{
public interface ISlabAllocatable { }
}
@@ -32,21 +32,17 @@ using StgSharp.Threading;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.HighPerformance.Memory
{
internal sealed unsafe class ChunkedSlabAllocator<T> : SlabAllocator<T> where T: unmanaged
{
private readonly BufferExpansionLock _lock = new();
private ConcurrentStackBuffer<nuint> _buffers;
private ConcurrentStackBuffer<nuint> _recycle;
private BufferStack<nuint> _buffers;
private BufferStack<nuint> _recycle;
private readonly int _elementSize = Unsafe.SizeOf<T>();
private nuint _currentBuffer;
@@ -67,7 +63,7 @@ namespace StgSharp.HighPerformance.Memory
span[i] = _currentBuffer + (nuint)(i * _elementSize);
}
_buffers = new(4);
_recycle = new(span);
_recycle = BufferStackBuilder.Create(span);
_currentCapacity = count;
_currentIndex = (nuint)initCount;
}
@@ -77,42 +73,20 @@ namespace StgSharp.HighPerformance.Memory
if (_recycle.TryPop(out nuint handle)) {
return handle;
}
while (true)
nuint bufferHandle = _currentBuffer;
nuint curIndex = _currentIndex;
if (curIndex >= _currentCapacity)
{
nuint bufferHandle = Volatile.Read(ref _currentBuffer);
nuint curIndex = Volatile.Read(ref _currentIndex);
_lock.EnterMetaDataRead();
try
{
if (curIndex >= _currentCapacity)
{
_lock.ExitMetaDataRead();
_lock.EnterExpansionProcess();
try
{
nuint cap = Volatile.Read(ref _currentCapacity);
nuint newBuffer = (nuint)NativeMemory.Alloc(cap * (nuint)_elementSize);
_buffers.Push(bufferHandle);
_ = Interlocked.Exchange(ref _currentBuffer, newBuffer);
_ = Interlocked.Exchange(ref _currentIndex, 0);
}
finally
{
_lock.ExitExpansionProcess();
}
}
curIndex = Volatile.Read(ref _currentIndex);
_ = Interlocked.Add(
ref Unsafe.As<nuint, ulong>(ref _currentIndex), (ulong)_elementSize);
return _currentBuffer + ((nuint)_elementSize * curIndex);
}
finally
{
if (_lock.IsThreadReadingMetaData) {
_lock.ExitMetaDataRead();
}
}
nuint cap = _currentCapacity;
nuint newBuffer = (nuint)NativeMemory.Alloc(cap * (nuint)_elementSize);
_buffers.Push(bufferHandle);
_currentBuffer = newBuffer;
_currentIndex = 0;
}
curIndex = _currentIndex;
_ = Interlocked.Add(
ref Unsafe.As<nuint, ulong>(ref _currentIndex), (ulong)_elementSize);
return _currentBuffer + ((nuint)_elementSize * curIndex);
}
public override void Dispose()
@@ -121,7 +95,6 @@ namespace StgSharp.HighPerformance.Memory
while (_buffers.TryPop(out nuint buffer)) {
NativeMemory.Free((void*)buffer);
}
_lock.Dispose();
_buffers.Dispose();
_recycle.Dispose();
}
@@ -1,161 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="SlabAllocator.Sequencial.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Threading;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
namespace StgSharp.HighPerformance.Memory
{
public sealed unsafe class SequentialSlabAllocator<T> : SlabAllocator<T> where T: unmanaged
{
private T* _buffer;
private readonly BufferExpansionLock _lock = new();
private readonly ConcurrentStackBuffer<nuint> _stack;
private readonly int _elementSize;
private nuint _highestAllocated;
private ulong _capacity;
public SequentialSlabAllocator(nuint initialCapacity)
{
_elementSize = Unsafe.SizeOf<T>();
_capacity = initialCapacity;
_highestAllocated = 0;
_buffer = (T*)NativeMemory.Alloc((nuint)_capacity * (nuint)_elementSize);
int initCount = _capacity switch
{
<= 4 => 4,
> 64 => 64,
_ => (int)_capacity / 4
};
Span<nuint> span = stackalloc nuint[initCount];
for (int i = 0; i < initCount; i++) {
span[i] = (nuint)i;
}
_stack = new(span);
_highestAllocated += (nuint)initCount;
}
internal T* BasePointer
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _buffer;
}
public override nuint Allocate()
{
if (_stack.TryPop(out nuint index)) {
return index;
}
while (true)
{
index = Volatile.Read(ref _highestAllocated);
_lock.EnterMetaDataRead();
try
{
if (index >= _capacity)
{
_lock.ExitMetaDataRead();
_lock.EnterExpansionProcess();
try
{
_capacity = Volatile.Read(ref _capacity) * 2;
nuint newSize = (nuint)_capacity * (nuint)_elementSize;
_lock.EnterBufferCopy();
try
{
_buffer = (T*)NativeMemory.Realloc(_buffer, newSize);
}
finally
{
_lock.ExitBufferCopy();
}
}
finally
{
_lock.ExitExpansionProcess();
}
}
_ = Interlocked.Increment(ref Unsafe.As<nuint, ulong>(ref _highestAllocated));
return index;
}
finally
{
if (_lock.IsThreadReadingMetaData) {
_lock.ExitMetaDataRead();
}
}
}
}
public override void Dispose()
{
_stack.Dispose();
NativeMemory.Free(_buffer);
_lock.Dispose();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void EnterBufferReading()
{
_lock.EnterBufferRead();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void ExitBufferReading()
{
_lock.ExitBufferRead();
}
public override void Free(nuint index)
{
_stack.Push(index);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override SlabAllocationHandle<T> ReadAllocation()
{
EnterBufferReading();
return new SlabAllocationHandle<T>(this, true);
}
~SequentialSlabAllocator()
{
Dispose();
}
}
}
@@ -28,17 +28,7 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.HighPerformance.Memory;
using StgSharp.Threading;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.HighPerformance.Memory
{
@@ -47,12 +37,62 @@ namespace StgSharp.HighPerformance.Memory
public abstract nuint Allocate();
public static SlabAllocator<T> Create(nuint count, BufferLayout layout)
/// <summary>
/// Creates a new SLAB allocator instance with the specified configuration.
/// </summary>
/// <param name="count">
/// Initial number of objects that can be allocated.
/// </param>
/// <param name="layout">
/// Memory layout strategy for the SLAB allocator.
/// </param>
/// <param name="concurrentSupport">
/// Whether to enable concurrent access support.
/// </param>
/// <returns>
/// A new SLAB allocator instance.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown when an invalid layout is specified.
/// </exception>
/// <exception cref="NotSupportedException">
/// Thrown when requesting unsupported configurations.
/// </exception>
/// <remarks>
/// <para><strong> Important Threading Considerations: </strong></para> <para> While SLAB
/// allocators themselves may be designed for single-threaded use, allocated objects are
/// frequently shared across multiple threads in real-world applications. Due to the
/// special implementation of expandable concurrent sequential SLAB allocators, they rely
/// on internal expansion locks to ensure that memory buffer expansions (which involve
/// copying the entire buffer to a new location) do not occur while other threads are
/// reading from allocated regions.</para> <para><strong> Sequential Layout Limitations:
/// </strong><br /> Sequential layout SLAB allocators cannot provide a single-threaded
/// version because:<list type="bullet"><item><description> They use contiguous memory
/// layout that requires buffer expansion when capacity is exceeded
/// </description></item><item><description> Buffer expansion involves copying all
/// existing data to a new memory location </description></item><item><description>
/// Without proper synchronization, concurrent access to allocated objects during
/// expansion would cause memory corruption </description></item><item><description> The
/// expansion lock mechanism is essential even if allocation itself is single-threaded
/// </description></item></list></para> <para><strong> Chunked Layout: </strong><br />
/// Chunked layout allocators can optionally provide single-threaded versions since they
/// don't require buffer expansion and copying. Each chunk is allocated independently,
/// avoiding the memory relocation issues present in sequential layouts.</para>
/// </remarks>
public static SlabAllocator<T> Create(nuint count, SlabBufferLayout layout, bool concurrentSupport = true)
{
if (concurrentSupport) {
return layout switch
{
SlabBufferLayout.Sequential => new ConcurrentSequentialSlabAllocator<T>(count),
SlabBufferLayout.Chunked => new ConcurrentChunkedSlabAllocator<T>(count),
_ => throw new ArgumentOutOfRangeException(nameof(layout), layout, null)
};
}
return layout switch
{
BufferLayout.Sequential => new SequentialSlabAllocator<T>(count),
BufferLayout.Chunked => new ChunkedSlabAllocator<T>(count),
SlabBufferLayout.Sequential => throw new NotSupportedException("Non-concurrent version of sequential layout SLAB is not supported due to expansion lock requirements for memory safety during buffer expansion."),
SlabBufferLayout.Chunked => new ChunkedSlabAllocator<T>(count),
_ => throw new ArgumentOutOfRangeException(nameof(layout), layout, null)
};
}
@@ -69,12 +109,11 @@ namespace StgSharp.HighPerformance.Memory
}
public enum BufferLayout
public enum SlabBufferLayout
{
Sequential,
Chunked,
HybridLayerSegregatedFit
Chunked
}
}
@@ -1,100 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="UnmanagedMemoryHandle.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.HighPerformance.Memory
{
public unsafe struct UnmanagedMemoryHandle
{
public readonly byte* BufferHandle, AllocatorHandle;
public readonly nuint Size;
public UnmanagedMemoryHandle(byte* pointer, byte* handle, nuint s)
{
BufferHandle = pointer;
AllocatorHandle = handle;
Size = s;
}
public readonly ref byte this[nuint index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref Unsafe.AddByteOffset(ref Unsafe.AsRef<byte>(BufferHandle), index);
}
public readonly Enumerator GetEnumerator()
{
return new Enumerator(this);
}
public ref struct Enumerator : IEnumerator<byte>
{
private nuint _index = nuint.MaxValue;
private UnmanagedMemoryHandle _handle;
internal Enumerator(UnmanagedMemoryHandle span)
{
_handle = span;
}
public ref byte RefCurrent => ref _handle[_index];
public readonly void Dispose() { }
public bool MoveNext()
{
_index++;
return _index < _handle.Size;
}
public void Reset()
{
_index = 0;
}
object IEnumerator.Current => RefCurrent;
byte IEnumerator<byte>.Current => RefCurrent;
}
}
}
@@ -1,52 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="UnmanagedMemoryPool.BucketTLSF.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.HighPerformance.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.HighPerformance.Memory
{
public unsafe partial class UnmanagedMemoryPool
{
private struct Entry : ISlabAllocatable
{
public Entry* NextNear, PreviousNear;
}
}
}
@@ -1,51 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="UnmanagedMemoryPool.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Collections.Concurrent;
using System.Drawing;
using System.Net.Security;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Transactions;
namespace StgSharp.HighPerformance.Memory
{
public unsafe partial class UnmanagedMemoryPool
{
private byte* m_Buffer;
private SlabAllocator<Entry> _nodes = new(64);
public
}
}
@@ -1,62 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="UnmanagedMemoryHandle.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.HighPerformance
{
public ref struct UnmanagedMemoryHandle
{
public nuint Postion;
public Span<byte> Buffer;
public UnmanagedMemoryHandle() { }
public ref byte this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref Buffer[index];
}
public Span<byte>.Enumerator GetEnumerator()
{
return Buffer.GetEnumerator();
}
}
}
@@ -1,144 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="UnmanagedMemoryPool.IndexNode.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.HighPerformance
{
public unsafe partial class UnmanagedMemoryPool
{
private const int
LevelOf4096 = 4,
LevelOf1024 = 3,
LevelOf256 = 2,
LevelOf64 = 1;
internal readonly ref struct NextIndexNode
{
private readonly Span<M64> _layout;
public readonly nuint this[int level]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Position - _layout[level].Member<uint>(0);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => _layout[level].Member<uint>(0) = (uint)(Position - value);
}
private readonly ref nuint Position
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref _layout[0].Member<nuint>(0);
}
}
internal readonly ref struct PreviousIndexNode
{
private readonly Span<M64> _layout;
public readonly nuint this[int level]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Position - _layout[level].Member<uint>(1);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => _layout[level].Member<uint>(1) = (uint)(Position - value);
}
private readonly ref nuint Position
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref _layout[0].Member<nuint>(0);
}
}
[StructLayout(LayoutKind.Explicit)]
internal readonly ref struct IndexNode
{
private static readonly uint[] _sizeArr = [16, 64, 256, 1024, 4096];
[FieldOffset(0)] private readonly NextIndexNode nxt;
[FieldOffset(0)] private readonly PreviousIndexNode pre;
[FieldOffset(0)] private readonly Span<M64> _layout;
public IndexNode(ref byte span)
{
_layout = MemoryMarshal.CreateSpan(ref Unsafe.As<byte, M64>(ref span), 8);
}
public readonly ref nuint Position => ref _layout[0].Member<nuint>(0);
public readonly ref uint Size => ref _layout[5].Member<uint>(0);
public readonly ref int Level => ref _layout[5].Member<int>(1);
public readonly ref nuint Segment => ref _layout[6].Member<nuint>(0);
public readonly uint BlockSize => LevelToSize(Level);
public static uint LevelToSize(int level)
{
return level switch
{
< 0 or > 4 => throw new ArgumentOutOfRangeException(
nameof(level), "Level must be from 1 to 4."),
_ => _sizeArr[level]
};
}
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public readonly ref readonly NextIndexNode Next
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref nxt;
}
public readonly ref readonly PreviousIndexNode Previous
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref pre;
}
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
}
}
}
@@ -1,187 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="UnmanagedMemoryPool.IndexOperation.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System.Runtime.CompilerServices;
namespace StgSharp.HighPerformance
{
public unsafe partial class UnmanagedMemoryPool
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConnectToNodeAtLevel(
IndexNode previous,
IndexNode current,
int level,
bool isHead)
{
if (isHead)
{
_entrance[level] = current.Position;
current.Previous[level] = 0;
} else
{
previous.Next[level] = current.Previous[level] = (uint)(current.Position - previous.Position);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private IndexNode GetNode(nuint pos)
{
ref byte span = ref *(_buffer + pos);
IndexNode node = new(ref span)
{
Position = pos
};
return node;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool IsNodeBeginning(nuint pos, int level)
{
return _entrance[level] == pos;
}
private bool Rebase(IndexNode n, uint offset)
{
nuint pos = n.Position;
uint size = n.Size;
if (size <= offset + 64)
{
for (int i = 0; i <= n.Level; i++) {
RemoveLevelHead(n, i);
}
return false;
}
uint
newOffset = ((offset / 64) + 1) * 64,
remain = n.Size - newOffset,
c64 = remain % 4,
c256 = remain / 4,
c1024 = c256 / 4,
c4096 = c1024 / 4;
c256 %= 4;
c1024 %= 4;
IndexNode
/*
* level is not important here, higher level will get 0 Size,
* and ignored in coming logic
*/
p64 = GetNode(n.Position - n.Previous[1]),
p256 = GetNode(n.Position - n.Previous[2]),
p1024 = GetNode(n.Position - n.Previous[3]),
p4096 = GetNode(n.Position - n.Previous[4]),
n64 = GetNode(n.Position + n.Previous[1]),
n256 = GetNode(n.Position + n.Previous[2]),
n1024 = GetNode(n.Position + n.Previous[3]),
n4096 = GetNode(n.Position + n.Previous[4]);
IndexNode nTemp;
if (c64 != 0)
{
// set param to separated 64 bytes block and set next and previous offset to it.
size = c64 * 64;
pos += size;
nTemp = GetNode(pos);
nTemp.Position = pos;
nTemp.Size = size;
ConnectToNodeAtLevel(p64, nTemp, 1, n.Position == _entrance[1]);
p64 = nTemp;
}
if (c256 != 0)
{
size = c256 * 256;
pos += size;
nTemp = GetNode(pos);
nTemp.Position = pos;
nTemp.Size = size;
nTemp.Previous[2] = n.Previous[2] + size;
ConnectToNodeAtLevel(p64, nTemp, 1, p64.Position == _entrance[1]);
ConnectToNodeAtLevel(p256, nTemp, 2, n.Position == _entrance[2]);
p64 = p256 = nTemp;
}
if (c1024 != 0)
{
size = c1024 * 1024;
pos += size;
nTemp = GetNode(pos);
nTemp.Position = pos;
nTemp.Size = size;
nTemp.Previous[2] = n.Previous[2] + size;
// connect to previous node
ConnectToNodeAtLevel(p64, nTemp, 1, p64.Position == _entrance[1]);
ConnectToNodeAtLevel(p256, nTemp, 2, p256.Position == _entrance[2]);
ConnectToNodeAtLevel(p1024, nTemp, 3, n.Position == _entrance[3]);
p64 = p256 = p1024 = nTemp;
}
if (c4096 != 0)
{
size = c1024 * 1024;
pos += size;
nTemp = GetNode(pos);
nTemp.Position = pos;
nTemp.Size = size;
nTemp.Previous[2] = n.Previous[2] + size;
// connect to previous node
ConnectToNodeAtLevel(p64, nTemp, 1, p64.Position == _entrance[1]);
ConnectToNodeAtLevel(p256, nTemp, 2, p256.Position == _entrance[2]);
ConnectToNodeAtLevel(p1024, nTemp, 3, p1024.Position == _entrance[3]);
ConnectToNodeAtLevel(p4096, nTemp, 4, n.Position == _entrance[4]);
p64 = p256 = p1024 = p4096 = nTemp;
}
ConnectToNodeAtLevel(p64, n64, 1, false);
ConnectToNodeAtLevel(
p256, n256, 2, _entrance[2] == n.Position && n256.Position == n.Position);
ConnectToNodeAtLevel(
p1024, n1024, 3, _entrance[3] == n.Position && n1024.Position == n.Position);
ConnectToNodeAtLevel(
p4096, n4096, 4, _entrance[4] == n.Position && n4096.Position == n.Position);
return true;
}
private void RemoveLevelHead(IndexNode n, int level)
{
IndexNode nxt, pre;
if (n.Previous[level] == 0)
{
// head of usable LEVEL;
nxt = GetNode(n.Position + n.Next[level]);
_entrance[level] = nxt.Position;
}
pre = GetNode(n.Previous[level]);
nxt = GetNode(n.Next[level]);
nxt.Previous[level] = nxt.Previous[level] + n.Previous[level];
pre.Next[level] = pre.Next[level] + n.Next[level];
}
}
}
@@ -1,158 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="UnmanagedMemoryPool.MegaManage.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace StgSharp.HighPerformance
{
public unsafe partial class UnmanagedMemoryPool
{
private readonly LinkedList<MegaBlockHead> _megaAlloc = new();
private readonly LinkedList<MegaBlockHead> _megaEmpty = new();
private MegaBlockHead _megaFirst;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void InsertMegaNear(MegaBlockHead previous, MegaBlockHead current)
{
MegaBlockHead pp = current.PreviousNear;
pp.NextNear = previous;
previous.PreviousNear = pp;
previous.NextNear = current;
current.PreviousNear = previous;
}
private static void InsertMegaSorted(LinkedList<MegaBlockHead> list, MegaBlockHead newItem)
{
LinkedListNode<MegaBlockHead>? node = list.First;
while (node != null && node.Value.Position < newItem.Position) {
node = node.Next;
}
_ = node != null ? list.AddBefore(node, newItem) : list.AddLast(newItem);
}
private bool TryGetMegaBlock(nuint size, out nuint position, int align = 1)
{
LinkedListNode<MegaBlockHead> node = _megaEmpty.First!;
while (node is not null)
{
MegaBlockHead block = node.Value;
if (block.Size >= size + (nuint)align)
{
position = block.Position;
nuint s = position + (nuint)(align - 1);
MegaBlockHead b;
if (block.Rebase(s))
{
b = new()
{
Position = position,
Size = position + (nuint)(align - 1),
Usage = MegaBlockUsage.MegaAlloc,
};
InsertMegaSorted(_megaAlloc, b);
InsertMegaNear(b, block);
} else
{
b = new()
{
Position = position,
Size = block.Size,
Usage = MegaBlockUsage.MegaAlloc,
};
InsertMegaSorted(_megaAlloc, b);
_megaEmpty.Remove(node);
InsertMegaNear(b, block.NextNear);
}
position = s & (nuint)~(align - 1);
return true;
}
node = node.Next!;
}
position = 0;
return false;
}
private unsafe class MegaBlockHead
{
private readonly ulong[] Heads = new ulong[4];
public MegaBlockHead NextNear { get; set; }
public MegaBlockHead PreviousNear { get; set; }
public MegaBlockUsage Usage { get; set; }
public nuint Position { get; set; }
public nuint Size { get; set; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref nuint DagHead(int level)
{
return ref Unsafe.As<ulong, nuint>(ref Heads[level]);
}
public bool Rebase(nuint size)
{
nuint s = this.Size - size;
if (s > 1024 * 1024 * 128)//space larger than 128MB is considered a new mega block
{
Position += size;
this.Size -= size;
Usage = MegaBlockUsage.EmptyDag;
return true;
}
MegaBlockHead pre = PreviousNear, nxt = NextNear;
pre.NextNear = nxt;
nxt.PreviousNear = pre;
return false;
}
}
private enum MegaBlockUsage
{
EmptyDag = 0,
UsedDag = 1,
MegaAlloc = 2
}
private MegaBlockHead
}
}
@@ -1,171 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="UnmanagedMemoryPool.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Collections.Concurrent;
using System.Net.Security;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Transactions;
namespace StgSharp.HighPerformance
{
public unsafe partial class UnmanagedMemoryPool
{
private readonly byte* _buffer;
// 4k,1k,256b,64b,16b
private nuint[] _entrance = new nuint[5];
private bool _disposedValue;
private readonly nuint _initialCapacity;
internal UnmanagedMemoryPool(nuint initialCapacity, int memoryAlign)
{
_initialCapacity = initialCapacity;
_buffer = (byte*)NativeMemory.AlignedAlloc(initialCapacity, (nuint)memoryAlign);
}
public UnmanagedMemoryHandle Allocate(uint size = 0)
{
if (size == 0) {
return new UnmanagedMemoryHandle
{
Postion = 0,
Buffer = new Span<byte>(_buffer, 0)
};
}
if (size > 0x8000_0000) {
throw new ArgumentOutOfRangeException(
"Size of buffer cannot be greater than 2147483648");
}
int level = GetLevelFromSize(size);
IndexNode allocator = GetNode(_entrance[level]);
nuint previous = allocator.Previous[level];
if (allocator.Size < size)
{
previous = allocator.Position;
allocator = GetNode(allocator.Next[level]);
}
bool isOverflow = false;
checked
{
try
{
isOverflow = (uint)(allocator.Position - previous + size) > 0xC0000000;
}
catch (OverflowException)
{
isOverflow = true;
}
}
if (isOverflow)
{
// offset is too large
}
UnmanagedMemoryHandle handle = new()
{
Postion = allocator.Position,
Buffer = new Span<byte>(_buffer + allocator.Position, (int)size),
};
Rebase(allocator, size);
return handle;
}
public static UnmanagedMemoryPool Create(nuint initialCapacity, int memoryAlign = 16)
{
UnmanagedMemoryPool pool = new(initialCapacity, memoryAlign);
IndexNode node = pool.GetNode(0);
for (int i = 4; i > 0; i--)
{
node.Previous[i] = 0;
node.Next[i] = IndexNode.LevelToSize(i);
}
node.Size = (uint)initialCapacity;
pool._megaFirst = new MegaBlockHead
{
Position = 0,
Size = initialCapacity,
Usage = MegaBlockUsage.EmptyDag
};
_ = pool._megaEmpty.AddLast(pool._megaFirst);
return pool;
}
public void Dispose()
{
Dispose(disposing:true);
GC.SuppressFinalize(this);
}
public void Free(UnmanagedMemoryHandle handle)
{
if (_buffer + handle.Postion != Unsafe.AsPointer(ref handle.Buffer[0])) {
throw new InvalidOperationException("Handle does not belong to pool");
}
nuint location = handle.Postion;
IndexNode root = GetNode(_entrance[4]);
while (root.Position > location) { }
}
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing) { }
NativeMemory.AlignedFree(_buffer);
_entrance = null!;
_disposedValue = true;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetLevelFromSize(uint size)
{
int level = 0;
uint temp = size / 8;
while (temp > 3)
{
level++;
temp >>= 2;
}
return level;
}
~UnmanagedMemoryPool()
{
Dispose(disposing:false);
}
}
}
@@ -1,75 +1,58 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IntrinsicContext.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// -----------------------------------------------------------------------
// file="IntrinsicContext.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp;
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.HighPerformance;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Internal.Intrinsic
{
[StructLayout( LayoutKind.Sequential )]
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct IntrinsicContext
{
public delegate* unmanaged[Cdecl]<ColumnSet2*, ColumnSet2*, ColumnSet2*, void> add_mat_2;
public delegate* unmanaged[Cdecl]<ColumnSet3*, ColumnSet3*, ColumnSet3*, void> add_mat_3;
public delegate* unmanaged[Cdecl]<ColumnSet4*, ColumnSet4*, ColumnSet4*, void> add_mat_4;
public delegate* unmanaged[Cdecl]<char*, int, int> city_hash_simplify;
public delegate* unmanaged[Cdecl]<ColumnSet3*, ColumnSet3*, float> det_mat_3;
public delegate* unmanaged[Cdecl]<ColumnSet4*, ColumnSet4*, float> det_mat_4;
public delegate* unmanaged[Cdecl]<ColumnSet3*, Vector4*, Vector4*, void> dot_31;
public delegate* unmanaged[Cdecl]<ColumnSet3*, Vector4*, Vector4*, void> dot_32;
public delegate* unmanaged[Cdecl]<ColumnSet4*, Vector4*, Vector4*, void> dot_41;
public delegate* unmanaged[Cdecl]<ColumnSet4*, Vector4*, Vector4*, void> dot_42;
public delegate* unmanaged[Cdecl]<ColumnSet4*, Vector4*, Vector4*, void> dot_43;
public delegate* unmanaged[Cdecl]<int,ulong> factorial_simd;
public delegate* unmanaged[Cdecl]<int, ulong> factorial_simd;
public delegate* unmanaged[Cdecl]<char*, int, int, int> index_pair;
public delegate* unmanaged[Cdecl]<Vector4*, Vector4*, void> normalize_v3;
public delegate* unmanaged[Cdecl]<ColumnSet2*, ColumnSet2*, ColumnSet2*, void> sub_mat_2;
public delegate* unmanaged[Cdecl]<ColumnSet3*, ColumnSet3*, ColumnSet3*, void> sub_mat_3;
public delegate* unmanaged[Cdecl]<ColumnSet4*, ColumnSet4*, ColumnSet4*, void> sub_mat_4;
public delegate* unmanaged[Cdecl]<ColumnSet2*, ColumnSet3*, void> transpose23;
public delegate* unmanaged[Cdecl]<ColumnSet2*, ColumnSet4*, void> transpose24;
public delegate* unmanaged[Cdecl]<ColumnSet3*, ColumnSet2*, void> transpose32;
public delegate* unmanaged[Cdecl]<ColumnSet3*, ColumnSet3*, void> transpose33;
public delegate* unmanaged[Cdecl]<ColumnSet3*, ColumnSet4*, void> transpose34;
public delegate* unmanaged[Cdecl]<ColumnSet4*, ColumnSet2*, void> transpose42;
public delegate* unmanaged[Cdecl]<ColumnSet4*, ColumnSet3*, void> transpose43;
public delegate* unmanaged[Cdecl]<ColumnSet4*, ColumnSet4*, void> transpose44;
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> kernel_add;
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> kernel_fma;
public delegate* unmanaged[Cdecl]<MatrixKernel*, float, MatrixKernel*, void> kernel_scalar_mul;
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> kernel_sub;
public delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, void> kernel_transpose;
public delegate* unmanaged[Cdecl]<Vector4*, Vector4*, void> normalize_3;
public IntrinsicContext()
{
Unsafe.SkipInit(out this);
}
}
}
@@ -1,33 +1,33 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="intrinsicContextProvider.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// -----------------------------------------------------------------------
// file="intrinsicContextProvider.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the ¡°Software¡±), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the ¡°Software¡±), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED ¡°AS IS¡±,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// THE SOFTWARE IS PROVIDED ¡°AS IS¡±,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
@@ -40,10 +40,13 @@ namespace StgSharp.Internal
internal static unsafe partial class InternalIO
{
private static readonly IntrinsicContext _intrinsicContext = new IntrinsicContext();
private static readonly IntrinsicContext _intrinsicContext = new();
public static IntrinsicLevel IntrinsicLevel { get; set; }
internal static IntrinsicContext Intrinsic
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _intrinsicContext;
}
@@ -51,25 +54,37 @@ namespace StgSharp.Internal
{
int statCode;
fixed( IntrinsicContext* cptr = &_intrinsicContext ) {
statCode = LoadIntrinsicFunction( cptr );
fixed (IntrinsicContext* cPtr = &_intrinsicContext) {
statCode = LoadIntrinsicFunction(cPtr);
}
switch( statCode )
switch (statCode)
{
case 0:
//Dialogue.PostError(new PlatformNotSupportedException("No SIMD instructions supported on current hardware platform"));
Environment.Exit( -1 );
// Dialogue.PostError(new PlatformNotSupportedException("No SIMD instructions supported on current hardware platform"));
Environment.Exit(-1);
break;
default:
IntrinsicLevel = (IntrinsicLevel)statCode;
break;
}
}
[LibraryImport( NativeLibName, EntryPoint = "load_intrinsic_function" )]
[UnmanagedCallConv( CallConvs = [typeof( CallConvCdecl )] )]
private static partial int LoadIntrinsicFunction( IntrinsicContext* context );
[LibraryImport(NativeLibName, EntryPoint = "load_intrinsic_function")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
private static partial int LoadIntrinsicFunction(IntrinsicContext* context);
}
internal enum IntrinsicLevel : sbyte
{
Non = 0,
SSE = 1,
AVX2 = 2,
AVX512 = 3,
NEON = -1
}
}
@@ -1,175 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Blueprint.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
namespace StgSharp.Blueprint
{
/// <summary>
/// A sets of complex logic designed for running in multi threads environment. Warning: do not
/// run a <see cref="BlueprintScheduler" /> instance in multi threads more than once.
/// </summary>
public partial class BlueprintScheduler : IConvertableToBlueprintNode
{
private BeginningNode beginNode;
private Dictionary<string, BlueprintNode> allNode;
private EndingNode endNode;
private Func<bool> terminate;
private List<BlueprintNode> globalNodeList;
private List<BlueprintNode> nativeNodeList;
private SemaphoreSlim runningStat;
internal int currentGlobalNodeIndex;
internal int currentNativeNodeIndex;
public BlueprintScheduler()
{
allNode = new Dictionary<string, BlueprintNode>();
globalNodeList = new List<BlueprintNode>();
nativeNodeList = new List<BlueprintNode>();
runningStat = new SemaphoreSlim( 1, 1 );
beginNode = new BeginningNode( this );
endNode = new EndingNode( this );
}
public BlueprintNode BeginLayer => beginNode;
public BlueprintNode EndLayer => endNode;
public BlueprintNodeOperation Operation
{
get => ExecuteMain;
}
public bool IsRunning
{
get => runningStat.CurrentCount == 0;
}
public IEnumerable<string> InputInterfacesName
{
get { return beginNode.OutputInterfaces.Keys; }
}
public IEnumerable<string> OutputInterfacesName
{
get { return beginNode.OutputInterfaces.Keys; }
}
/**/
internal SemaphoreSlim RunningStat
{
get => runningStat;
}
/**/
public void AddNode( BlueprintNode node, bool isNative )
{
_ = node ?? throw new ArgumentNullException( nameof( node ) );
node.IsNative = isNative;
allNode.Add( node.Name, node );
}
public void ExecuteMain(
in Dictionary<string, BlueprintPipeline> input,
in Dictionary<string, BlueprintPipeline> output )
{
BlueprintRunner.Run( this );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public (string name, BlueprintPipelineArgs arg)[] GetOutput()
{
return endNode.OutputData;
}
public void Init()
{
foreach( KeyValuePair<string, BlueprintNode> item in allNode ) {
if( item.Value.IsNative ) {
nativeNodeList.Add( item.Value );
} else {
globalNodeList.Add( item.Value );
}
}
nativeNodeList.Sort();
globalNodeList.Sort();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void SetInput(
params (string name, BlueprintPipelineArgs arg)[] parameters )
{
beginNode.InputData = parameters;
}
public void Terminate()
{
Interlocked.Exchange( ref currentGlobalNodeIndex, int.MaxValue );
Interlocked.Exchange( ref currentNativeNodeIndex, int.MaxValue );
}
internal bool RequestNexGlobalNode( out BlueprintNode node )
{
if( currentGlobalNodeIndex < globalNodeList.Count ) {
node = globalNodeList[ currentGlobalNodeIndex ];
Interlocked.Increment( ref currentGlobalNodeIndex );
return true;
}
node = default!;
return false;
}
internal bool RequestNextNativeNode( out BlueprintNode node )
{
if( currentNativeNodeIndex < nativeNodeList.Count ) {
node = nativeNodeList[ currentNativeNodeIndex ];
Interlocked.Increment( ref currentNativeNodeIndex );
return true;
}
node = default!;
return false;
}
~BlueprintScheduler()
{
runningStat.Dispose();
}
}
}
@@ -1,303 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="BlueprintNode.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Entities;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.Blueprint
{
/// <summary>
///
/// </summary>
/// <risk>
/// Reset pipeline has risk, this operation is a direct operation to port in current node, the
/// port on the other node cannot get the change.
/// </risk>
#pragma warning disable CA1036
public class BlueprintNode : IComparable<BlueprintNode>
#pragma warning restore CA1036
{
private static BlueprintNode _emptyNode = new BlueprintNode(
string.Empty, null!, false );
private static Dictionary<string, BlueprintPipeline> _emptyLayer = new();
private protected bool _levelAvailable, _nativeRequested;
private protected Dictionary<string, BlueprintPipeline> _inputInterfaces;
private protected Dictionary<string, BlueprintPipeline> _outputInterfaces;
private protected int _level;
private IConvertableToBlueprintNode _mainOperation;
private string _name;
internal BlueprintNode(
string name,
IConvertableToBlueprintNode node,
bool isNative )
{
_levelAvailable = false;
_name = name;
_nativeRequested = isNative;
_mainOperation = node;
_inputInterfaces = new Dictionary<string, BlueprintPipeline>();
_outputInterfaces = new Dictionary<string, BlueprintPipeline>();
foreach( string portName in node.InputInterfacesName ) {
_inputInterfaces.Add( portName, null! );
}
foreach( string portName in node.OutputInterfacesName ) {
_outputInterfaces.Add( portName, null! );
}
}
#pragma warning disable CS8618
internal BlueprintNode(
BlueprintNodeOperation operation,
string name,
bool isNative,
string[] inputPorts,
string[] outputPorts )
#pragma warning restore CS8618
{
if( ( inputPorts == null ) || ( inputPorts.Length == 0 ) ) {
throw new ArgumentNullException( nameof( inputPorts ) );
}
if( ( outputPorts == null ) || ( outputPorts.Length == 0 ) ) {
throw new ArgumentNullException( nameof( outputPorts ) );
}
_levelAvailable = false;
_name = name;
_nativeRequested = isNative;
operation = operation ?? DefaultOperation;
_mainOperation = new DefaultConvertableToBlueprintNode(
operation,
inputPorts,
outputPorts);
_inputInterfaces = new Dictionary<string, BlueprintPipeline>();
_outputInterfaces = new Dictionary<string, BlueprintPipeline>();
foreach( string portName in inputPorts ) {
_inputInterfaces.Add(
portName,
SealedBlueprintPiipeline.SealOutput( this, name ) );
}
foreach( string portName in outputPorts ) {
_outputInterfaces.Add( portName, null! );
}
}
protected static void DefaultOperation(
in Dictionary<string, BlueprintPipeline> input,
in Dictionary<string, BlueprintPipeline> output)
{
BlueprintPipeline.SkipAll(output);
}
public static BlueprintNode Empty
{
get => _emptyNode;
}
public bool IsNative
{
get => _nativeRequested;
internal set => _nativeRequested = value;
}
public static Dictionary<string, BlueprintPipeline> EmptyPortLayer
{
get => _emptyLayer;
}
public int Level
{
get
{
if( _levelAvailable ) {
return _level;
}
_level = 0;
foreach( KeyValuePair<string, BlueprintPipeline> item in _inputInterfaces ) {
if( item.Value == null ) {
continue;
}
if( _level < item.Value.Level ) {
_level = item.Value.Level;
}
}
_level += 1;
_levelAvailable = true;
return _level;
}
}
public string Name => _name;
internal Dictionary<string, BlueprintPipeline> InputInterfaces => _inputInterfaces;
internal Dictionary<string, BlueprintPipeline> OutputInterfaces => _outputInterfaces;
internal IConvertableToBlueprintNode Value
{
get => _mainOperation;
}
public void Append(
[NotNull] BlueprintNode next,
string thisOutputPortName,
string afterInputPortName )
{
this._levelAvailable = false;
BlueprintPipeline pipeline = new BlueprintPipeline( this, next );
if( next is EndingNode enode ) {
enode.SetCertainInputPort( afterInputPortName, pipeline );
} else {
next.SetCertainInputPort( afterInputPortName, pipeline );
}
SetCertainOutputPort( thisOutputPortName, pipeline );
}
public int CompareTo( BlueprintNode other )
{
if( null == other ) {
throw new ArgumentNullException( nameof( other ) );
}
return this.Level.CompareTo( other.Level );
}
public void Prepend(
[NotNull] BlueprintNode former,
string formerOutputPortName,
string thisInputPortName )
{
this._levelAvailable = false;
BlueprintPipeline pipeline = new BlueprintPipeline( former, this );
if( former is BeginningNode bnode ) {
bnode.SetCertainOutputPort( formerOutputPortName, pipeline );
} else {
former.SetCertainOutputPort( formerOutputPortName, pipeline );
}
SetCertainInputPort( thisInputPortName, pipeline );
}
public virtual void Run()
{
try {
//Console.WriteLine(_name);
BlueprintPipeline.WaitAll( _inputInterfaces );
if( _mainOperation != null ) {
_mainOperation.Operation(
in _inputInterfaces, in _outputInterfaces );
}
}
catch( Exception ) {
throw;
}
}
#region port operation
public BlueprintPipeline GetInputPort( string name )
{
BlueprintPipeline ret;
if( !_inputInterfaces.TryGetValue( name, out ret ) ) {
throw new ArgumentOutOfRangeException(
$"Cannot find the interface named {name} in node {Name}." );
}
return ret;
}
public BlueprintPipeline GetOutputPort( string name )
{
BlueprintPipeline ret;
if( !_outputInterfaces.TryGetValue( name, out ret ) ) {
throw new ArgumentOutOfRangeException(
$"Cannot find the interface named {name} in node {Name}." );
}
return ret;
}
public void SetCertainInputPort(
string name,
BlueprintPipeline pipeline )
{
if( !_inputInterfaces.ContainsKey( name ) ) {
throw new ArgumentException(
$"Cannot find the interface named {name} in node {Name}." );
}
_inputInterfaces[ name ] = pipeline;
}
public void SetCertainOutputPort(
string name,
BlueprintPipeline pipeline )
{
if( !_outputInterfaces.ContainsKey( name ) ) {
throw new ArgumentOutOfRangeException(
$"Cannot find the interface named {name} in node {Name}." );
}
_outputInterfaces[ name ] = pipeline;
}
#endregion
}//--------------------------------- end of class -----------------------------------
public class BlueprintNodeRunException : Exception
{
protected BlueprintNodeRunException(
SerializationInfo info,
StreamingContext context )
: base( info, context ) { }
public BlueprintNodeRunException() { }
public BlueprintNodeRunException( Exception ex )
: base( string.Empty, ex ) { }
public BlueprintNodeRunException( string message ) : base( message ) { }
public BlueprintNodeRunException(
string message,
Exception innerException )
: base( message, innerException ) { }
}
}
@@ -1,58 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="BlueprintNodeCraeater.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
namespace StgSharp.Blueprint
{
public partial class BlueprintScheduler
{
public BlueprintNode CreateBlueprintNode(
string name,
BlueprintNodeOperation operation,
string[] inputPort,
string[] outputPort,
bool isNative )
{
BlueprintNode node = new BlueprintNode(
operation, name, isNative, inputPort, outputPort );
if( isNative ) {
nativeNodeList.Add( node );
} else {
globalNodeList.Add( node );
}
return node;
}
}
}
@@ -1,229 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="BlueprintRunner.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Threading;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.Blueprint
{
public static class BlueprintRunner
{
private static NodeRunner[] allAvailableTask = CreateBlueprintRunnerArray(
);
private static CancellationTokenSource cts = new CancellationTokenSource(
);
private static ConcurrentStack<BlueprintScheduler> blueprintInWaiting
= new ConcurrentStack<BlueprintScheduler>();
private static int _callingThread;
private static SemaphoreSlim bpLock = new SemaphoreSlim( 0, 1 );
/// <summary>
/// Only the fallowing occasions of calling are valid: 1. no bp is running or the only bp is
/// quitting. 2. calling from the main thread and the current running bp.
/// </summary>
internal static bool IsValidCalling
{
get
{
if( ( NodeRunner.CurrentBlueprint == null ) || //no bp running at all
( ( blueprintInWaiting.IsEmpty ) && ( NodeRunner.CurrentBlueprint.IsRunning ==
false ) ) )
// a bp is quiting
{
//in case no bp is running
return true;
}
int? id = Task.CurrentId;
if( id is null ) {
// in case calling from main thread and current running bp
return _callingThread == Environment.CurrentManagedThreadId;
}
foreach( NodeRunner item in allAvailableTask ) {
if( item.Id == id ) {
//if calling from any bp running task
return true;
}
}
return false;
}
}
public static void Run( BlueprintScheduler blueprint )
{
//Console.WriteLine();
if( blueprint == null ) {
return;
}
if( blueprint.IsRunning ) {
throw new InvalidOperationException(
"Attempt to run a blueprint instance twice." );
}
if( IsValidCalling ) {
//Console.WriteLine("valid and run");
if( InterruptAndRunNewBp( blueprint ) ) {
while( InterruptAndRunNewBp( NodeRunner.CurrentBlueprint ) ) { }
;
}
} else {
bpLock.Wait();
if( InterruptAndRunNewBp( blueprint ) ) {
while( InterruptAndRunNewBp( NodeRunner.CurrentBlueprint ) ) { }
}
bpLock.Release();
}
Interlocked.Exchange( ref _callingThread, -1 );
}
public static void SetMaxTaskCount( int size )
{
if( size < 1 ) {
size = 1;
}
if( allAvailableTask.Length >= size ) {
for( int i = size; i < allAvailableTask.Length; i++ ) {
if( allAvailableTask[ i ] != null ) {
allAvailableTask[ i ].Cancel();
}
}
}
Array.Resize( ref allAvailableTask, size );
}
public static void Terminate()
{
cts.Cancel();
NodeRunner.CurrentBlueprint.Terminate();
foreach( NodeRunner task in allAvailableTask ) {
task.Cts.Cancel();
}
foreach( BlueprintScheduler bp in blueprintInWaiting ) {
bp.Terminate();
}
blueprintInWaiting.Clear();
}
internal static bool InterruptAndRunNewBp( BlueprintScheduler newBp )
{
Debug.Assert( newBp != null );
if( ( newBp != NodeRunner.CurrentBlueprint ) && ( NodeRunner.CurrentBlueprint !=
null ) ) {
//if a running bp exists
blueprintInWaiting.Push( NodeRunner.CurrentBlueprint );
}
//load new bp to current bp
Interlocked.Exchange( ref NodeRunner.CurrentBlueprint!, newBp );
Interlocked.Exchange(
ref _callingThread, Environment.CurrentManagedThreadId );
//run beginning node to init it first.
if( !NodeRunner.CurrentBlueprint.IsRunning ) {
( NodeRunner.CurrentBlueprint.BeginLayer as BeginningNode )!.Run(
);
}
//refresh all tasks
for( int i = 0; i < allAvailableTask.Length; i++ ) {
NodeRunner item = allAvailableTask[ i ];
if( ( item is null ) || item.IsCompleted ) {
allAvailableTask[ i ] = NodeRunner.Run();
}
}
BlueprintNode node;
while( !cts.Token.IsCancellationRequested && NodeRunner.CurrentBlueprint
.RequestNextNativeNode( out node ) ) {
node.Run();
if( !NodeRunner.CurrentBlueprint.IsRunning ) {
break;
}
}
( NodeRunner.CurrentBlueprint.EndLayer as EndingNode )!.Run();
return blueprintInWaiting.TryPeek( out NodeRunner.CurrentBlueprint );
}
private static NodeRunner[] CreateBlueprintRunnerArray()
{
int count = Environment.ProcessorCount;
return new NodeRunner[ count < 2 ? count : count - 2];
}
}
internal class NodeRunner : CancellableTask
{
private static BlueprintScheduler _current;
internal NodeRunner()
: base()
{
_startup = InternalRun;
}
internal static ref BlueprintScheduler CurrentBlueprint
{
get => ref _current;
}
internal static NodeRunner Run()
{
NodeRunner ret = new NodeRunner { _startup = InternalRun };
ret._internalTask = Task.Run( ret.InternalAction );
return ret;
}
private static void InternalRun( CancellationToken token )
{
//Console.WriteLine("Task Begin");
BlueprintNode item;
while( ( CurrentBlueprint != null ) && CurrentBlueprint.IsRunning && !token.IsCancellationRequested && CurrentBlueprint.RequestNexGlobalNode(
out item ) ) {
//Console.WriteLine($"Get node of {item.Name}, going to run.");
item.Run();
}
//Console.WriteLine("Task Completed");
}
}//------------------------------------- End of Class ------------------------------------------
}
@@ -1,91 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="CrossFrameBlueprintNode.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Blueprint;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.Blueprint
{
public class CrossFrameOperation : IConvertableToBlueprintNode
{
private static string[] _inputName = ["TaskIn"];
private static string[] _outputName = ["TaskOut"];
private Action _mainExecution;
private int currentCount;
private readonly int cycleCount;
public CrossFrameOperation( Action startup, int cycleCount )
{
MainExecution = startup;
this.cycleCount = ( cycleCount > 1 ) ?
cycleCount : throw new ArgumentException(
$"{$"The {typeof(CrossFrameOperation).Name} crosses only one cycle, "}{$"please use a {typeof(BlueprintNode).Name} instead."}" );
this.cycleCount = cycleCount;
currentCount = cycleCount;
}
public Action MainExecution
{
get => _mainExecution;
private protected set => _mainExecution = value;
}
public BlueprintNodeOperation Operation
{
get => ExecuteMain;
}
public IEnumerable<string> InputInterfacesName => _inputName;
public IEnumerable<string> OutputInterfacesName => _outputName;
public void ExecuteMain(
in Dictionary<string, BlueprintPipeline> input,
in Dictionary<string, BlueprintPipeline> output )
{
if( currentCount < cycleCount ) {
Interlocked.Increment( ref currentCount );
} else {
Interlocked.Exchange( ref currentCount, 0 );
Task.Run( MainExecution );
}
//Console.WriteLine(currentCount);
BlueprintPipeline.SkipAll( output );
}
}
}
@@ -1,86 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IConvertableToBlueprintNode.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace StgSharp.Blueprint
{
public delegate void BlueprintNodeOperation(
in Dictionary<string, BlueprintPipeline> input,
in Dictionary<string, BlueprintPipeline> output );
public interface IConvertableToBlueprintNode
{
BlueprintNodeOperation Operation
{
get;
}
public IEnumerable<string> InputInterfacesName
{
get;
}
public IEnumerable<string> OutputInterfacesName
{
get;
}
}
internal class DefaultConvertableToBlueprintNode : IConvertableToBlueprintNode
{
private string[] _input;
private string[] _output;
private BlueprintNodeOperation _execution;
public DefaultConvertableToBlueprintNode(
BlueprintNodeOperation execution,
string[] input,
string[] output )
{
_input = input;
_output = output;
_execution = execution;
}
public BlueprintNodeOperation Operation => _execution;
public IEnumerable<string> InputInterfacesName => _input;
public IEnumerable<string> OutputInterfacesName => _output;
}
}
-164
View File
@@ -1,164 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="PipeLine.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Security.Authentication.ExtendedProtection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.Blueprint
{
public class BlueprintPipeline
{
private protected BlueprintNode after;
private protected BlueprintNode former;
private protected BlueprintPipelineArgs args;
private protected SemaphoreSlim formerCompleteSemaphore;
public BlueprintPipeline( BlueprintNode former, BlueprintNode after )
{
this.former = former;
this.after = after;
formerCompleteSemaphore = new SemaphoreSlim(
initialCount: 0, maxCount: 1 );
}
public BlueprintNode After => after;
public BlueprintNode Former => former;
public BlueprintPipelineArgs Args
{
get => args;
set => args = value;
}
public int Level => former.Level;
public static void SkipAll(
Dictionary<string, BlueprintPipeline> ports )
{
if( ports == null ) {
return;
}
foreach( KeyValuePair<string, BlueprintPipeline> item in ports ) {
if( item.Value != null ) {
item.Value.CompleteAndSkip();
}
}
}
public static void WaitAll(
Dictionary<string, BlueprintPipeline> ports )
{
if( ports == null ) {
return;
}
foreach( KeyValuePair<string, BlueprintPipeline> item in ports ) {
if( item.Value != null ) {
item.Value.WaitForStart();
}
}
}
public virtual void WaitForStart()
{
//Console.WriteLine($"Waiting \t{former.ContextName}\t->\t{after.ContextName}");
formerCompleteSemaphore.Wait();
}
~BlueprintPipeline()
{
formerCompleteSemaphore.Dispose();
}
#region pipline op
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void CompleteAndSkip()
{
//Console.WriteLine($"Complete\t{former.Name}\t->\t{after.Name}");
formerCompleteSemaphore.Release();
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public void CompleteAndWriteData( BlueprintPipelineArgs args )
{
this.args = args;
CompleteAndSkip();
}
#endregion
}
public abstract class BlueprintPipelineArgs
{
public object? Value
{
get;
set;
}
public object? ValueDefault
{
get;
}
}
public sealed class SealedBlueprintPiipeline:BlueprintPipeline
{
internal SealedBlueprintPiipeline(BlueprintNode former, BlueprintNode after):
base(former, after)
{
}
public static SealedBlueprintPiipeline SealOutput(BlueprintNode node, string portName)
{
return new SealedBlueprintPiipeline(node, BlueprintNode.Empty);
}
public static SealedBlueprintPiipeline SealInput(BlueprintNode node, string portName)
{
return new SealedBlueprintPiipeline(BlueprintNode.Empty, node);
}
public sealed override void WaitForStart()
{
}
}
}
@@ -1,111 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="RouteSwitch.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace StgSharp.Blueprint
{
public class RouteSwitch : BlueprintNode
{
private protected Dictionary<string, (BlueprintPipeline pipeline, Func<bool> openingRule)> outputDictionary;
public RouteSwitch( string name, bool isNative, string inputPorts )
: base(DefaultOperation, name, isNative, [inputPorts], [string.Empty] )
{
outputDictionary = new Dictionary<string, (BlueprintPipeline pipeline, Func<bool> openingRule)>(
);
}
public new int Level
{
get
{
if( _levelAvailable ) {
return _level;
}
_level = 0;
KeyValuePair<string, BlueprintPipeline> item = _inputInterfaces.First(
);
if( item.Value == null ) {
throw new InvalidOperationException();
}
if( _level <= item.Value.Level ) {
_level = item.Value.Level;
}
return _level;
}
}
public new void AddBefore(
BlueprintNode after,
string thisOutputPortName,
string afterInputPortName )
{
this.AppendNode( after, afterInputPortName, () => true );
}
public void AppendNode(
BlueprintNode node,
string portName,
Func<bool> openningRule )
{
if( node == null ) {
throw new ArgumentNullException( nameof( node ) );
}
string indexName = $"{node.Name}.{portName}";
BlueprintPipeline p = new BlueprintPipeline( this, node );
node.InputInterfaces[ portName ] = p;
outputDictionary.Add( indexName, (p, openningRule) );
}
public new void Run()
{
try {
BlueprintPipeline input = InputInterfaces.First().Value;
input.WaitForStart();
foreach( KeyValuePair<string, (BlueprintPipeline pipeline, Func<bool> openingRule)> item in outputDictionary ) {
if( item.Value.openingRule() ) {
item.Value.pipeline.CompleteAndWriteData( input.Args );
}
}
}
catch( Exception ) {
throw;
}
}
}
}
-125
View File
@@ -1,125 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="SideNode.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.Blueprint
{
internal sealed class BeginningNode : BlueprintNode
{
private BlueprintScheduler _bp;
public BeginningNode( BlueprintScheduler bp )
: base(
DefaultOperation, name: "BeginningNode", true, ["default"],
["default"] )
{
_bp = bp;
}
internal (string name, BlueprintPipelineArgs arg)[] InputData
{
set
{
if( value == null ) {
return;
}
foreach( (string name, BlueprintPipelineArgs arg) parameter in value ) {
OutputInterfaces[ parameter.name ].Args = parameter.arg;
}
}
}
public override void Run()
{
_bp.RunningStat.Wait();
BlueprintPipeline.SkipAll( _outputInterfaces );
}
public new void SetCertainOutputPort(
string name,
BlueprintPipeline pipeline )
{
if( _outputInterfaces.ContainsKey( name ) ) {
_outputInterfaces[ name ] = pipeline;
}
_outputInterfaces.Add( name, pipeline );
}
}
internal sealed class EndingNode : BlueprintNode
{
private BlueprintScheduler _bp;
public EndingNode( BlueprintScheduler bp )
: base(
DefaultOperation, name: "EndingNode", true, ["default"],
["default"] )
{
_bp = bp;
}
internal (string name, BlueprintPipelineArgs arg)[] OutputData
{
get { return InputInterfaces.Select(
key => (key.Key, key.Value.Args) )
.ToArray(); }
}
public override void Run()
{
BlueprintPipeline.WaitAll( _inputInterfaces );
Interlocked.Exchange( ref _bp.currentGlobalNodeIndex, 0 );
Interlocked.Exchange( ref _bp.currentNativeNodeIndex, 0 );
_bp.RunningStat.Release();
}
public new void SetCertainInputPort(
string name,
BlueprintPipeline pipeline )
{
if( _inputInterfaces.ContainsKey( name ) ) {
_inputInterfaces[ name ] = pipeline;
}
_inputInterfaces.Add( name, pipeline );
}
}
}
-131
View File
@@ -1,131 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Counter.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
namespace StgSharp
{
public class Counter<T>
where T: struct, IConvertible, IFormattable, IComparable
#if NET8_OR_GREATER
,INumber
#endif
{
internal dynamic _value;
internal readonly T _defualtIncreament;
internal readonly T _defualtDecreament;
internal readonly T _defaultValue;
public Counter( T defualtValue, T defualtIncreament, T defualtDecreament )
{
Type tType = typeof( T );
if (
tType != typeof(byte) &&
tType != typeof(short) &&
tType != typeof(int) &&
tType != typeof(long) &&
tType != typeof(sbyte) &&
tType != typeof(ushort) &&
tType != typeof(uint) &&
tType != typeof(ulong) &&
tType != typeof(float) &&
tType != typeof(double))
{
throw new ArgumentException(
"Input is not number value type");
}
_value = defualtValue;
_defaultValue = defualtValue;
_defualtIncreament = defualtIncreament;
_defualtDecreament = defualtDecreament;
}
public T DecreamentSoan => _defualtDecreament;
public T IncreamentSpan => _defualtIncreament;
public T CurrentSpan => _value - _defaultValue;
public T Value
{
get => _value;
set => _value = value;
}
public void Add( T value )
{
_value += value;
}
public void QuickAdd()
{
_value += _defualtIncreament;
}
public void QuickSub()
{
_value -= _defualtDecreament;
}
public void Reset()
{
_value = _defaultValue;
}
public void Sub( T value )
{
_value -= value;
}
public override string ToString()
{
return Value.ToString();
}
public static Counter<T> operator --( Counter<T> counter )
{
counter.QuickSub();
return counter;
}
public static Counter<T> operator ++( Counter<T> counter )
{
counter.QuickAdd();
return counter;
}
public static implicit operator T( Counter<T> counter )
{
return counter.Value;
}
}
}
@@ -1,81 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="PlainGeometryCollisionSensor.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Geometries;
using System;
namespace StgSharp
{
public class CollisionEventArgs:EventArgs
{
public CollisionEventArgs(IGeometry target, IGeometry boarder)
{
Target = target;
Boarder = boarder;
}
public IGeometry Target { get; set; }
public IGeometry Boarder { get; set; }
}
public class PlainGeometryCollisionSensor<TBoarder,TTarget>
where TBoarder : IGeometry
where TTarget : IGeometry
{
internal PlainGeometry _boarder;
internal PlainGeometry _target;
internal EventHandler<CollisionEventArgs> _rule;
public event EventHandler<CollisionEventArgs> Rule
{
add { _rule += value; }
remove
{
if (value == null)
{
return;
}
#pragma warning disable CS8601
_rule -= value;
#pragma warning restore CS8601
}
}
public PlainGeometry boarder => _boarder;
public PlainGeometry target
{
get => _target;
set => _target = value;
}
}
}
-72
View File
@@ -1,72 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="StateMachine.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp
{
public interface IStateMachine<T> where T: Enum
{
public T LastStableState
{
get;
}
public bool TryEnterState();
public bool TryExitState();
public bool TrySwitchState();
}
public interface IStateMachineWithSwitchSpan<TState, TSpan> : IStateMachine<TState>
where TState: Enum
{
public bool IsInStabelState
{
get;
}
public TState NextStableState
{
get;
}
public bool TrySwitchState();
}
}
@@ -1,164 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="TimeFunction.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
namespace StgSharp.Timing
{
public class TimeFunction
{
private float _beginning, _ending;
private Func<float, float> _timeRelatedCalculation;
private TimeSpanProvider _timeProvider;
internal TimeFunction() { }
public TimeFunction(
TimeSpanProvider timeSpanProvider,
Func<float, float> timeRelatedCalculation,
float range )
{
_timeProvider = timeSpanProvider;
_timeRelatedCalculation = timeRelatedCalculation;
if( timeSpanProvider == null ) {
return;
}
_beginning = _timeProvider.CurrentSecond;
_ending = _timeProvider.CurrentSecond + range;
}
public virtual bool IsComplete
{
get => _timeProvider.CurrentSecond > _ending;
}
public Func<float, float> TimeRelatedCalculation
{
get { return _timeRelatedCalculation; }
set { _timeRelatedCalculation = value; }
}
public static TimeFunction One
{
get => new TimeFunctionOne();
}
public TimeSpanProvider TimeSpanProvider
{
get { return _timeProvider; }
set { _timeProvider = value; }
}
public virtual float Calculate()
{
if( _timeProvider.CurrentSecond < _ending ) {
return 0;
}
return _timeRelatedCalculation(
_timeProvider.CurrentSecond - _beginning );
}
public static TimeFunction Proportional(
TimeSpanProvider time,
float begin,
float range )
{
return new TimeFunction( time, ( float t ) => t + begin, range );
}
public virtual TimeFunction Renew(
(Func<float, float> func, float range) funcPair )
{
return new TimeFunction(
_timeProvider, funcPair.func, funcPair.range );
}
public virtual TimeFunction Renew(
Func<float, float> func,
float range )
{
return new TimeFunction( _timeProvider, func, range );
}
public void Reset()
{
float range = _ending - _beginning;
_beginning = _timeProvider.CurrentSecond;
_ending = _beginning + range;
}
public virtual TimeFunction Reverse()
{
float range = _ending - _beginning;
return new TimeFunction(
_timeProvider, p => _timeRelatedCalculation( range - p ),
range );
}
}
public sealed class TimeFunctionOne : TimeFunction
{
internal TimeFunctionOne() : base() { }
public override bool IsComplete
{
get => true;
}
public override float Calculate()
{
return 1;
}
public override TimeFunction Renew(
(Func<float, float> func, float range) funcPair )
{
throw new NotSupportedException();
}
public override TimeFunction Renew(
Func<float, float> func,
float range )
{
throw new NotSupportedException();
}
#pragma warning disable CA1822
public new void Reset()
#pragma warning restore CA1822
{ }
}
}
@@ -1,152 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="TimeProvider.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Timing;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
namespace StgSharp
{
public static partial class StgSharp
{
internal static StgSharpTime mainTimeProvider = new StgSharpTime();
internal static TimeSourceProviderBase MainTimeProvider => mainTimeProvider;
}
public sealed class StgSharpTime : TimeSourceProviderBase
{
private static List<TimeSpanProvider> subscriberList = new List<TimeSpanProvider>(
);
private static long accuracy;
private static Stopwatch mainProvider = new Stopwatch();
private static Thread timeProvideThread;
internal StgSharpTime() { }
public static TimeSourceProviderBase OnlyInstance => StgSharp.MainTimeProvider;
public override sealed void StartProvidingTime()
{
if( mainProvider.IsRunning ) {
return;
}
mainProvider.Start();
//speed test
long totalMS, internalFrequncy = Stopwatch.Frequency;
for( int i = 0; i < 100; i++ ) {
totalMS = mainProvider.ElapsedTicks / ( internalFrequncy / ( 1000L * 1000L ) );
for( int t = 0; t < 10; t++ ) {
if( totalMS < 1000 ) {
subscriberList.Add(
new TimeSpanProvider(
100L, TimeSpanProvider.DefaultProvider ) );
}
}
}
mainProvider.Stop();
subscriberList.Clear();
totalMS = mainProvider.ElapsedTicks / ( internalFrequncy / ( 1000L * 1000L ) ) / 100L;
accuracy = ( totalMS * 2 ) / 3;
mainProvider.Reset();
timeProvideThread = new Thread( new ThreadStart( ProvideTime ) );
timeProvideThread.Start();
}
public override void StopProvidingTime()
{
lock( mainProvider ) {
mainProvider.Stop();
}
}
public void Terminate()
{
lock( mainProvider ) {
mainProvider.Stop();
}
}
protected override sealed void AddSubscriberUnsynced(
TimeSpanProvider subscriber )
{
subscriberList.Add( subscriber );
}
protected override sealed void RemoveSubscriberUnsynced(
TimeSpanProvider subscriber )
{
subscriberList.Remove( subscriber );
}
private void ProvideTime()
{
long totalMS, internalFrequncy = Stopwatch.Frequency;
lock( mainProvider ) {
mainProvider.Restart();
}
while( mainProvider.IsRunning ) {
totalMS = mainProvider.ElapsedTicks / ( internalFrequncy / ( 1000L * 1000L ) );
if( subscriberList.Count == 0 ) {
continue;
}
CheckSubscriberSemaphore.Wait();
List<TimeSpanProvider> toRemoveList = new List<TimeSpanProvider>(
);
foreach( TimeSpanProvider subscriber in subscriberList ) {
if( !subscriber.CheckTime( totalMS ) ) {
toRemoveList.Add( subscriber );
InternalIO.InternalWriteLog(
$"Time subscriber {subscriber} is to be removed.",
LogType.Info );
}
;
}
if( toRemoveList.Count != 0 ) {
foreach( TimeSpanProvider subscriber in toRemoveList ) {
subscriberList.Remove( subscriber );
}
}
CheckSubscriberSemaphore.Release();
}
}
}
}
@@ -1,89 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="TimeSourceProvider.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp;
using System;
using System.Linq;
using System.Threading;
namespace StgSharp.Timing
{
public abstract class TimeSourceProviderBase
{
private SemaphoreSlim _addSubscriberSemaphore = new SemaphoreSlim(
1, 1 );
protected SemaphoreSlim CheckSubscriberSemaphore
{
get => _addSubscriberSemaphore;
}
public void AddSubscriber( TimeSpanProvider subscriber )
{
try {
_addSubscriberSemaphore.Wait();
AddSubscriberUnsynced( subscriber );
}
catch( Exception ) {
throw;
}
finally {
_addSubscriberSemaphore.Release();
}
}
public void RemoveSubscriber( TimeSpanProvider subscriber )
{
_addSubscriberSemaphore.Wait();
try {
RemoveSubscriberUnsynced( subscriber );
}
catch( Exception ) {
throw;
}
finally {
_addSubscriberSemaphore.Release();
}
}
public abstract void StartProvidingTime();
public abstract void StopProvidingTime();
protected abstract void AddSubscriberUnsynced(
TimeSpanProvider subscriber );
protected abstract void RemoveSubscriberUnsynced(
TimeSpanProvider subscriber );
}
}
@@ -1,165 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="TimeSpanAwaitingToken.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.Timing
{
#nullable enable
public sealed class TimeSpanAwaitingToken : IDisposable
{
private static readonly ConcurrentStack<int> s_unusedID = new ConcurrentStack<int>(
[0] );
private static int s_maxID;
private static readonly object s_lock = new object();
private EventHandler? _refreshHandler,_missHandler;
private int _size, _id;
private object _participantObject = new object();
private SemaphoreSlim _awaitingSemaphore;
private TimeSpanProvider _provider;
internal TimeSpanAwaitingToken( TimeSpanProvider provider )
{
if( s_unusedID.Count == 1 ) {
lock( s_lock ) {
s_unusedID.TryPop( out int id );
TokenID = id;
s_unusedID.Push( s_maxID++ );
}
} else {
s_unusedID.TryPop( out int id );
TokenID = id;
}
_provider = provider;
_size = 1;
_awaitingSemaphore = new SemaphoreSlim( 0, 1 );
}
internal TimeSpanAwaitingToken( TimeSpanProvider provider, int count )
{
if( s_unusedID.Count == 1 ) {
lock( s_lock ) {
s_unusedID.TryPop( out int id );
TokenID = id;
s_unusedID.Push( s_maxID++ );
}
} else {
s_unusedID.TryPop( out int id );
TokenID = id;
}
_provider = provider;
_size = count;
_awaitingSemaphore = new SemaphoreSlim( 0, _size );
}
public event EventHandler MissTimeSpanRefreshed
{
add { _missHandler += value; }
remove { _missHandler -= value; }
}
public event EventHandler TimeSpanRefreshed
{
add { _refreshHandler += value; }
remove { _refreshHandler -= value; }
}
public int TokenID
{
get => _id;
private set => _id = value;
}
internal SemaphoreSlim AwaitingSemaphoreSlim
{
get => _awaitingSemaphore;
}
public void Dispose()
{
_provider.QuitSpanAwaiting( this );
s_unusedID.Push( TokenID );
_awaitingSemaphore.Dispose();
GC.SuppressFinalize( this );
}
public override int GetHashCode()
{
return _id;
}
public void Participant()
{
lock( _participantObject ) {
_size++;
SemaphoreSlim newSemaphore = new SemaphoreSlim(
_awaitingSemaphore.CurrentCount, _size );
Interlocked.Exchange( ref _awaitingSemaphore, newSemaphore )
.Dispose();
}
}
public void WaitNextSpan()
{
_awaitingSemaphore.Wait();
}
internal void MissRefresh()
{
_missHandler?.Invoke( this, EventArgs.Empty );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal void Refresh()
{
_refreshHandler?.Invoke( this, EventArgs.Empty );
}
~TimeSpanAwaitingToken()
{
Dispose();
}
}
#nullable restore
}
@@ -1,233 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="TimeSpanProvider.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
namespace StgSharp.Timing
{
/// <summary>
/// A microsecond-accuracy timer. It will refresh every a certain time span.
/// </summary>
public class TimeSpanProvider
{
private bool _subscribed;
private ConcurrentQueue<TimeSpanAwaitingToken> _tokenToAdd = new ConcurrentQueue<TimeSpanAwaitingToken>(
);
private ConcurrentQueue<TimeSpanAwaitingToken> _tokenToQuit;
private Counter<int> timeSpanCount = new Counter<int>( -1, 1, 1 );
private HashSet<TimeSpanAwaitingToken> _awaitingTokens;
private long _maxSpanCount;
private long _spanBegin;
private readonly long _spanLength;
private readonly TimeSourceProviderBase _timeSource;
/// <summary>
/// Create a new <see cref="TimeSpanProvider" /> and define the length of time span. Length
/// of a single time span is defined in microseconds.
/// </summary>
/// <param _name="spanMicroSeconds"></param>
/// <param _name="provider"></param>
public TimeSpanProvider(
long spanMicroSeconds,
TimeSourceProviderBase provider )
{
if( provider == null ) {
throw new ArgumentNullException( nameof( provider ) );
}
_timeSource = provider;
_spanLength = spanMicroSeconds;
_maxSpanCount = int.MaxValue;
provider.AddSubscriber( this );
_subscribed = true;
_awaitingTokens = new HashSet<TimeSpanAwaitingToken>();
_tokenToQuit = new ConcurrentQueue<TimeSpanAwaitingToken>();
}
/// <summary>
/// Create a new <see cref="TimeSpanProvider" /> and define the length of time span. Length
/// of a single time span is defined in seconds.
/// </summary>
/// <param _name="spanSeconds"></param>
/// <param _name="provider"></param>
public TimeSpanProvider(
double spanSeconds,
TimeSourceProviderBase provider )
{
if( provider == null ) {
throw new ArgumentNullException( nameof( provider ) );
}
_timeSource = provider;
_spanLength = ( long )( spanSeconds * 1000L * 1000L );
_spanBegin = -_spanLength;
_maxSpanCount = long.MaxValue;
provider.AddSubscriber( this );
_subscribed = true;
_awaitingTokens = new HashSet<TimeSpanAwaitingToken>();
_tokenToQuit = new ConcurrentQueue<TimeSpanAwaitingToken>();
}
/// <summary>
/// Create a new <see cref="TimeSpanProvider" /> and define the length of time span. Length
/// of a single time span is defined in microseconds.
/// </summary>
/// <param _name="spanLength"></param>
/// <param _name="maxSpan"></param>
/// <param _name="provider"></param>
public TimeSpanProvider(
long spanLength,
long maxSpan,
TimeSourceProviderBase provider )
{
if( provider == null ) {
throw new ArgumentNullException( nameof( provider ) );
}
if( maxSpan <= 0 ) {
throw new ArgumentException(
"Sapn count cannot be smaller than zero" );
}
_timeSource = provider;
_spanLength = spanLength;
_spanBegin = -_spanLength;
provider.AddSubscriber( this );
_subscribed = true;
_awaitingTokens = new HashSet<TimeSpanAwaitingToken>();
_tokenToQuit = new ConcurrentQueue<TimeSpanAwaitingToken>();
}
public double SpanLength
{
get => ( _spanLength * 1.0 ) / ( 1000L * 1000L );
}
public float CurrentSecond
{
get => timeSpanCount.Value * SpanLengthLowPrecession;
}
public float SpanLengthLowPrecession
{
get => ( _spanLength * 1.0f ) / ( 1000 * 1000 );
}
public int CurrentSpan
{
get => timeSpanCount.Value;
}
/// <summary>
/// Time source provider provided in <see cref="StgSharp" /> internal framework.
/// </summary>
public static TimeSourceProviderBase DefaultProvider => StgSharpTime.OnlyInstance;
public TimeSpanAwaitingToken ParticipantSpanAwaiting( int count )
{
TimeSpanAwaitingToken token = new TimeSpanAwaitingToken(
this, count );
_tokenToAdd.Enqueue( token );
return token;
}
public void QuitSpanAwaiting( TimeSpanAwaitingToken token )
{
_tokenToQuit.Enqueue( token );
}
public void StopSpanProviding()
{
Interlocked.Exchange( ref _maxSpanCount, 0 );
}
public void SubscribeToTimeSource(
TimeSourceProviderBase serviceHandler )
{
if( serviceHandler == null ) {
throw new ArgumentNullException( nameof( serviceHandler ) );
}
if( _subscribed ) {
return;
}
_subscribed = true;
serviceHandler.AddSubscriber( this );
}
public int ToInt32()
{
return timeSpanCount.Value;
}
internal bool CheckTime( long microseconds )
{
if( microseconds - _spanBegin < _spanLength ) {
return true;
}
while( !_tokenToAdd.IsEmpty ) {
_tokenToAdd.TryDequeue( out TimeSpanAwaitingToken tokenAdd );
_awaitingTokens.Add( tokenAdd );
}
while( !_tokenToQuit.IsEmpty ) {
_tokenToQuit.TryDequeue( out TimeSpanAwaitingToken tokenQuit );
_awaitingTokens.Remove( tokenQuit );
InternalIO.InternalWriteLog(
$"Awaiting token {tokenQuit!.TokenID} has been removed.",
LogType.Info );
}
_spanBegin = microseconds;
timeSpanCount++;
foreach( TimeSpanAwaitingToken item in _awaitingTokens ) {
if( item.AwaitingSemaphoreSlim.CurrentCount == 0 ) {
item.AwaitingSemaphoreSlim.Release();
item.Refresh();
} else {
item.MissRefresh();
}
}
return timeSpanCount < _maxSpanCount;
}
public static explicit operator int(
[NotNull]TimeSpanProvider provider )
{
return provider.ToInt32();
}
}
}
-313
View File
@@ -1,313 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Camera.cs"
// Project: StepVisualizer
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Graphics;
using StgSharp.Graphics.OpenGL;
using StgSharp.Graphics.ShaderEdit;
using StgSharp.Math;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace StgSharp.Graphics
{
public sealed class Camera : IglConvertable
{
private bool _isLookAtAvailable;
internal Matrix44 _lookAt;
internal Matrix44 _projection;
internal Matrix44 cameraAtt;
internal Matrix44 rotation;
internal Matrix44 rotationAtt;
internal Radius _pitch;
internal Radius _row;
internal Radius _yaw;
internal Uniform<Matrix44> convertedUniform;
internal Vec3 _target, up;
public Camera()
{
cameraAtt = Matrix44.Unit;
_target = Vec3.Zero;
up = Vec3.Zero;
_isLookAtAvailable = false;
_lookAt = Matrix44.Unit;
rotationAtt = Matrix44.Unit;
_projection = new Matrix44();
}
public Camera( Vec3 position, Vec3 target, Vec3 up )
: this()
{
rotationAtt = Matrix44.Unit;
cameraAtt = new Matrix44();
SetViewDirection( position, target, up );
_pitch = Radius.Zero;
_row = Radius.Zero;
_yaw = Radius.Zero;
}
public Matrix44 Projection => _projection;
public Matrix44 View
{
get
{
if( _isLookAtAvailable ) {
return _lookAt;
}
Matrix44 move = Matrix44.Unit;
move.colum3.vec -= cameraAtt.colum3.vec;
_lookAt = rotationAtt.Transpose * move;
_isLookAtAvailable = true;
return _lookAt;
}
}
public Matrix44 CameraMatrix()
{
return Projection * View;
}
public void DisplayGLtypeDefinition()
{
Console.WriteLine( "uniform matrix4x4 cameraName;" );
}
/// <summary>
/// Get all uniform related to this <see cref="Camera" />.
/// </summary>
/// <param _label="source">
/// Shader program requires this camera.
/// </param>
/// <param _label="uniformName">
/// ContextName of all related uniforms. If you fallow form from <see
/// cref="IglConvertable.DisplayGLtypeDefinition" />
/// </param>
/// <exception cref="ArgumentException">
///
/// </exception>
public unsafe void GainAllUniforms( ShaderProgram source, params string[] uniformName )
{
if( uniformName is null || uniformName.Length != 1 ) {
throw new ArgumentException(
"Camera needs exactly one uniform.", nameof( uniformName ) );
}
convertedUniform = source.GetUniform<Matrix44>( uniformName[ 0 ] );
}
public void MoveNear( float distance )
{
cameraAtt.colum3.Z -= distance;
_isLookAtAvailable = false;
}
public void MoveRight( float distance )
{
cameraAtt.colum3.X -= distance;
_isLookAtAvailable = false;
}
public void MoveUp( float distance )
{
cameraAtt.colum3.Y -= distance;
_isLookAtAvailable = false;
}
public unsafe void SetAllUniforms()
{
//Console.WriteLine(Projection * ViewBase);
OpenGL.OpenGLFunction.CurrentGL.SetUniformValue( convertedUniform, Projection * View );
}
public void SetViewDirection( Vec3 position, Vec3 target, Vec3 up )
{
Vec3 direction = position - target;
if( ( position.reg == cameraAtt.colum3.reg ) &&
( this.up == up ) &&
( cameraAtt.colum2.reg == direction.reg ) ) {
return;
}
if( direction.GetLength() == 0 )
{
//deadlock
throw new ArgumentException();
}
if( Vec3.IsParallel( direction, up ) ) {
throw new ArgumentException();
}
_target = direction;
this.up = up;
_isLookAtAvailable = false;
Linear.Orthogonalize( ref direction, ref up );
Vec3 right = Linear.Orthogonalize( Linear.Cross( up, direction ) );
cameraAtt.colum0.reg = right.reg;
cameraAtt.colum1.reg = up.reg;
cameraAtt.colum2.reg = direction.reg;
cameraAtt.colum3.reg = position.reg;
InternalPitch();
InternalRow();
InternalYaw();
}
public void SetViewRange(
Radius fovRadius,
Vec2 size,
Vec2 offset,
(float front, float back) dephRange )
{
float
distance = _target.GetLength(),
near = distance - dephRange.front,
far = distance + dephRange.back,
offsetX = offset.X,
offsetY = offset.Y,
width = Scaler.Abs( GeometryScaler.Tan( fovRadius / 2 ) * near * 2 ),
height = ( width * size.Y ) / size.X;
_projection.colum0.X = ( 2 * near ) / width;
_projection.colum1.Y = ( 2 * near ) / height;
_projection.colum2.X = ( 2 * offsetX ) / width;
_projection.colum2.Y = ( 2 * offsetY ) / height;
_projection.colum2.Z = ( far + near ) / ( near - far );
_projection.colum2.W = -1;
_projection.colum3.Z = ( 2 * near * far ) / ( near - far );
}
public void Test( params Vec4[] vec )
{
Console.WriteLine( View );
Console.WriteLine( Projection );
Console.WriteLine( Projection * View );
Console.WriteLine( View );
foreach( Vec4 item in vec ) {
Console.Write( $"{Projection * View * item};" );
}
}
ShaderStruct IglConvertable.GetConvertedGLtype()
{
throw new NotImplementedException();
}
~Camera() { }
#region rotation
public void Yaw( Radius r )
{
_yaw -= r;
//Console.WriteLine(_yaw._radius);
//Console.WriteLine(rotationAtt);
InternalYaw();
}
public void Pitch( Radius r )
{
_pitch -= r;
//Console.WriteLine(_pitch._radius);
//Console.WriteLine(rotationAtt);
InternalPitch();
}
public void Row( Radius r )
{
_row -= r;
//Console.WriteLine(_row._radius);
//Console.WriteLine(rotationAtt);
InternalRow();
}
internal void InternalPitch()
{
_isLookAtAvailable = false;
Matrix32 partialCoord = new Matrix32( cameraAtt.colum1.vec, cameraAtt.colum2.vec );
float angle = _pitch._radius;
Matrix22 rotation = new Matrix22(
Scaler.Cos( angle ), -Scaler.Sin( angle ), Scaler.Sin( angle ),
Scaler.Cos( angle ) );
partialCoord *= rotation;
rotationAtt.colum1.reg = partialCoord.colum0.reg;
rotationAtt.colum2.reg = partialCoord.colum1.reg;
rotationAtt.isTransposed = false;
}
internal void InternalRow()
{
_isLookAtAvailable = false;
Matrix32 partialCoord = new Matrix32( cameraAtt.colum0.vec, cameraAtt.colum1.vec );
float angle = _row._radius;
Matrix22 rotation = new Matrix22(
Scaler.Cos( angle ), -Scaler.Sin( angle ), Scaler.Sin( angle ),
Scaler.Cos( angle ) );
partialCoord *= rotation;
rotationAtt.colum0.reg = partialCoord.colum0.reg;
rotationAtt.colum1.reg = partialCoord.colum1.reg;
rotationAtt.isTransposed = false;
}
internal void InternalYaw()
{
_isLookAtAvailable = false;
Matrix32 partialCoord = new Matrix32( cameraAtt.colum0.vec, cameraAtt.colum2.vec );
float angle = _yaw._radius;
Matrix22 rotation = new Matrix22(
Scaler.Cos( angle ), -Scaler.Sin( angle ), Scaler.Sin( angle ),
Scaler.Cos( angle ) );
partialCoord *= rotation;
rotationAtt.colum0.reg = partialCoord.colum0.reg;
rotationAtt.colum2.reg = partialCoord.colum1.reg;
rotationAtt.isTransposed = false;
}
#endregion
}
}
@@ -1,67 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vec2HP.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.HighPerformance;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math.HighPrecision
{
[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct Vec2HP : IFixedVector<Vec2HP>
{
[FieldOffset(0)] private M256 buffer;
[FieldOffset(0)] private Vector256<float> clrBuffer;
[FieldOffset(0 * sizeof(double))] public double X;
[FieldOffset(1 * sizeof(double))] public double Y;
public Vec2HP(double x, double y)
{
this.X = x;
this.Y = y;
Unsafe.SkipInit(out buffer);
Unsafe.SkipInit(out clrBuffer);
}
public static Vec2HP Zero => new Vec2HP(0, 0);
public static Vec2HP One => new Vec2HP(1, 1);
}
}
@@ -1,86 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vec3HP.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.HighPerformance;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math.HighPrecision
{
[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct Vec3HP : IFixedVector<Vec3HP>
{
[FieldOffset(0)] internal M256 buffer;
[FieldOffset(0)] internal Vector256<float> clrBuffer;
[FieldOffset(0 * sizeof(double))] public double X;
[FieldOffset(1 * sizeof(double))] public double Y;
[FieldOffset(2 * sizeof(double))] public double Z;
public Vec3HP() : this(0, 0, 0) { }
public Vec3HP(Vector256<float> clrBuffer)
{
this.X = 0;
this.Y = 0;
this.Z = 0;
Unsafe.SkipInit(out buffer);
Unsafe.SkipInit(out this.clrBuffer);
this.clrBuffer = clrBuffer;
}
public Vec3HP(double x, double y, double z)
{
this.X = x;
this.Y = y;
this.Z = z;
Unsafe.SkipInit(out buffer);
Unsafe.SkipInit(out clrBuffer);
}
public static Vec3HP Zero => new Vec3HP(1, 1, 1);
public static Vec3HP One => throw new NotImplementedException();
public override string ToString()
{
return $"Double precision 3D Vector<{X},{Y},{Z}>";
}
}
}
@@ -1,70 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vec4HP.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.HighPerformance;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math.HighPrecision
{
[StructLayout(LayoutKind.Explicit, Pack =16)]
public struct Vec4HP : IFixedVector<Vec4HP>
{
[FieldOffset(0)] private M256 buffer;
[FieldOffset(0)] private Vector256<float> clrBuffer;
[FieldOffset(3 * sizeof(double))] public double W;
[FieldOffset(0 * sizeof(double))] public double X;
[FieldOffset(1 * sizeof(double))] public double Y;
[FieldOffset(2 * sizeof(double))] public double Z;
public Vec4HP(double x, double y, double z, double w)
{
this.X = x;
this.Y = y;
this.Z = z;
this.W = w;
Unsafe.SkipInit(out buffer);
Unsafe.SkipInit(out clrBuffer);
}
public static Vec4HP Zero => new Vec4HP(0, 0, 0, 0);
public static Vec4HP One => new Vec4HP(1, 1, 1, 1);
}
}
@@ -1,41 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Cordination.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
namespace StgSharp.Math
{
public enum CoordinatePlain
{
XY,
YZ,
XZ,
}
}
@@ -1,49 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IFixedVector.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
public interface IFixedVector<TSelf> where TSelf: struct, IFixedVector<TSelf>
{
public static abstract TSelf Zero { get; }
public static abstract TSelf One { get; }
}
}
-40
View File
@@ -1,40 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IMatrix.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Graphics;
using System;
using System.Collections.Generic;
using System.Text;
namespace StgSharp.Math
{
public interface IMatrix<TSelf> where TSelf: IMatrix<TSelf> { }
}
-48
View File
@@ -1,48 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IVector.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
public interface IVector<TSelf> where TSelf: struct, IVector<TSelf>
{
public static abstract TSelf Zero { get; }
public static abstract TSelf One { get; }
}
}
-180
View File
@@ -1,180 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix22.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(
LayoutKind.Explicit,
Size = ( 2 * 2 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix22 : IMatrix<Matrix22>
{
[FieldOffset( 2 * 2 * 4 * sizeof( float ) )]
internal bool isTransposed = false;
[FieldOffset( 0 )]
internal ColumnSet2 _mat;
[FieldOffset( 2 * 4 * sizeof( float ) )]
internal ColumnSet2 _transpose;
internal Matrix22( ColumnSet2 mat )
{
this._mat = mat;
}
internal Matrix22( Vector4 c0, Vector4 c1 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
_mat.colum0 = c0;
_mat.colum1 = c1;
}
public Matrix22()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix22( float a00, float a01, float a10, float a11 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
_mat.colum0 = new Vector4( a00, a10, 0, 0 );
_mat.colum1 = new Vector4( a01, a11, 0, 0 );
}
public Matrix22 Transpose
{
get
{
InternalTranspose();
return new Matrix22( this._transpose );
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public float Det()
{
return ( _mat.m00 * _mat.m11 ) - ( _mat.m10 * _mat.m01 );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal void InternalTranspose()
{
if( !isTransposed )
{
_transpose = _mat;
float cache = _transpose.m10;
_transpose.m10 = _transpose.m01;
_transpose.m01 = cache;
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix22 operator -( Matrix22 left, Matrix22 right )
{
Matrix22 ret = new Matrix22();
InternalIO.Intrinsic.sub_mat_2( &left._mat, &right._mat, &ret._mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix22 operator *( Matrix22 mat, float value )
{
return new Matrix22( mat._mat.colum0 * value, mat._mat.colum1 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix22 operator *( Matrix22 left, Matrix22 right )
{
left.InternalTranspose();
return new Matrix22(
Vector4.Dot( left._transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left._transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left._transpose.colum1, right._mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix23 operator *( Matrix22 left, Matrix23 right )
{
left.InternalTranspose();
return new Matrix23(
Vector4.Dot( left._transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right._mat.colum2 ),
Vector4.Dot( left._transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left._transpose.colum1, right._mat.colum1 ),
Vector4.Dot( left._transpose.colum1, right._mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix24 operator *( Matrix22 left, Matrix24 right )
{
left.InternalTranspose();
return new Matrix24(
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left._transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left._transpose.colum1, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix22 operator /( Matrix22 mat, float value )
{
return new Matrix22( mat._mat.colum0 / value, mat._mat.colum1 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix22 operator +( Matrix22 left, Matrix22 right )
{
Matrix22 ret = new Matrix22();
InternalIO.Intrinsic.add_mat_2( &left._mat, &right._mat, &ret._mat );
return ret;
}
}
}
-195
View File
@@ -1,195 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix23.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(
LayoutKind.Explicit,
Size = ( ( 3 + 2 ) * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix23 : IMatrix<Matrix23>
{
[FieldOffset( 5 * 4 * sizeof( float ) )] internal bool isTransposed = false;
[FieldOffset( 3 * 4 * sizeof( float ) )] internal ColumnSet2 _transpose;
[FieldOffset( 0 )] internal ColumnSet3 _mat;
internal Matrix23( Vector4 c0, Vector4 c1, Vector4 c2 )
{
_mat.colum0 = c0;
_mat.colum1 = c1;
_mat.colum2 = c2;
}
public Matrix23()
{
Unsafe.SkipInit( out _mat );
Unsafe.SkipInit( out _transpose );
}
public Matrix23( float a00, float a01, float a02, float a10, float a11, float a12 )
{
_mat.colum0 = new Vector4( a00, a10, 0, 0 );
_mat.colum1 = new Vector4( a01, a11, 0, 0 );
_mat.colum2 = new Vector4( a02, a12, 0, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 1 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this._transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 1 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this._transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet3* source = &this._mat )
{
fixed( ColumnSet2* target = &this._transpose ) {
InternalIO.Intrinsic.transpose32( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix23 operator -( Matrix23 left, Matrix23 right )
{
Matrix23 ret = new Matrix23();
InternalIO.Intrinsic.sub_mat_3( &left._mat, &right._mat, &ret._mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix23 operator *( Matrix23 mat, float value )
{
return new Matrix23(
mat._mat.colum0 * value, mat._mat.colum1 * value, mat._mat.colum2 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix22 operator *( Matrix23 left, Matrix32 right )
{
left.InternalTranspose();
return new Matrix22(
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix23 operator *( Matrix23 left, Matrix33 right )
{
left.InternalTranspose();
return new Matrix23(
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix24 operator *( Matrix23 left, Matrix34 right )
{
left.InternalTranspose();
return new Matrix24(
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix23 operator /( Matrix23 mat, float value )
{
return new Matrix23(
mat._mat.colum0 / value, mat._mat.colum1 / value, mat._mat.colum2 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix23 operator +( Matrix23 left, Matrix23 right )
{
Matrix23 ret = new Matrix23();
InternalIO.Intrinsic.add_mat_3( &left._mat, &right._mat, &ret._mat );
return ret;
}
}
}
-223
View File
@@ -1,223 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix24.cs"
// Project: World
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(
LayoutKind.Explicit,
Size = ( ( 4 + 2 ) * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix24 : IMatrix<Matrix24>
{
[FieldOffset( 6 * 4 * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 4 * 4 * sizeof( float ) )] internal ColumnSet2 transpose;
[FieldOffset( 0 )] internal ColumnSet4 mat;
[FieldOffset( 0 )] public Vec2 Colum0;
[FieldOffset( 16 )] public Vec2 Colum1;
[FieldOffset( 32 )] public Vec2 Colum2;
[FieldOffset( 48 )] public Vec2 Colum3;
internal Matrix24( Vector4 c0, Vector4 c1, Vector4 c2, Vector4 c3 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
mat.colum2 = c2;
mat.colum3 = c3;
}
public Matrix24()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix24(
float a00,
float a01,
float a02,
float a03,
float a10,
float a11,
float a12,
float a13 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, 0, 0 );
mat.colum1 = new Vector4( a01, a11, 0, 0 );
mat.colum2 = new Vector4( a02, a12, 0, 0 );
mat.colum3 = new Vector4( a03, a13, 0, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 1 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 ) {
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 1 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 ) {
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
public override string ToString()
{
InternalTranspose();
return $"{$"[{mat.m00},{mat.m01},{mat.m02},{mat.m03}],"}{$"[{mat.m10},{mat.m11},{mat.m12},{mat.m13}]"}";
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed ) {
fixed( ColumnSet4* source = &this.mat ) {
fixed( ColumnSet2* target = &this.transpose ) {
InternalIO.Intrinsic.transpose42( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix24 operator -(
Matrix24 left,
Matrix24 right )
{
Matrix24 ret = new Matrix24();
InternalIO.Intrinsic.sub_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix24 operator *( Matrix24 mat, float value )
{
return new Matrix24(
mat.mat.colum0 * value, mat.mat.colum1 * value,
mat.mat.colum2 * value, mat.mat.colum3 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix22 operator *( Matrix24 left, Matrix42 right )
{
left.InternalTranspose();
return new Matrix22(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix23 operator *( Matrix24 left, Matrix43 right )
{
left.InternalTranspose();
return new Matrix23(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix24 operator *( Matrix24 left, Matrix44 right )
{
left.InternalTranspose();
return new Matrix24(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix24 operator /( Matrix24 mat, float value )
{
return new Matrix24(
mat.mat.colum0 / value, mat.mat.colum1 / value,
mat.mat.colum2 / value, mat.mat.colum3 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix24 operator +(
Matrix24 left,
Matrix24 right )
{
Matrix24 ret = new Matrix24();
InternalIO.Intrinsic.add_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}
-215
View File
@@ -1,215 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix32.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(
LayoutKind.Explicit,
Size = ( 5 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix32 : IMatrix<Matrix32>
{
[FieldOffset( 5 * 4 * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 0 )] internal ColumnSet2 mat;
[FieldOffset( 2 * 4 * sizeof( float ) )] internal ColumnSet3 transpose;
[FieldOffset( 0 )] internal Vec3 colum0;
[FieldOffset( 4 * 4 )] internal Vec3 colum1;
internal Matrix32( Vector4 c0, Vector4 c1 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
}
public Matrix32()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public unsafe Matrix32( float a00, float a01, float a10, float a11, float a20, float a21 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, 0 );
mat.colum1 = new Vector4( a01, a11, a21, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 1 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 1 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
public Vec3 VerticalVecMultiply( Vec2 vec )
{
return ( colum0 * vec.X ) + ( colum1 * vec.Y );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet2* source = &this.mat )
{
fixed( ColumnSet3* target = &this.transpose ) {
InternalIO.Intrinsic.transpose23( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator -( Matrix32 left, Matrix32 right )
{
return new Matrix32(
left.mat.colum0 - right.mat.colum0, left.mat.colum1 - right.mat.colum1 );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator *( Matrix32 mat, float value )
{
return new Matrix32( mat.mat.colum0 * value, mat.mat.colum1 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator *( Matrix32 left, Matrix22 right )
{
left.InternalTranspose();
return new Matrix32(
Vector4.Dot( left.transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator *( Matrix32 left, Matrix23 right )
{
left.InternalTranspose();
return new Matrix33(
Vector4.Dot( left.transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator *( Matrix32 left, Matrix24 right )
{
left.InternalTranspose();
return new Matrix34(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator /( Matrix32 mat, float value )
{
return new Matrix32( mat.mat.colum0 / value, mat.mat.colum1 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix32 operator +( Matrix32 left, Matrix32 right )
{
Matrix32 ret = new Matrix32();
InternalIO.Intrinsic.add_mat_2( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}
-240
View File
@@ -1,240 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix33.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(
LayoutKind.Explicit,
Size = ( 6 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix33 : IMatrix<Matrix33>
{
[FieldOffset( 6 * 4 * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 0 )] internal ColumnSet3 mat;
[FieldOffset( 3 * 4 * sizeof( float ) )] internal ColumnSet3 transpose;
[FieldOffset( 0 * 4 * sizeof( float ) )] public Vec3 Colum0;
[FieldOffset( 1 * 4 * sizeof( float ) )] public Vec3 Colum1;
[FieldOffset( 2 * 4 * sizeof( float ) )] public Vec3 Colum2;
internal Matrix33( Vector4 c0, Vector4 c1, Vector4 c2 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
mat.colum2 = c2;
}
public Matrix33()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix33(
float a00,
float a01,
float a02,
float a10,
float a11,
float a12,
float a20,
float a21,
float a22 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, 0 );
mat.colum1 = new Vector4( a01, a11, a21, 0 );
mat.colum2 = new Vector4( a02, a12, a22, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
InternalIO.InternalWriteLog(
$"Attempt to write unused space in {GetType().Name} {nameof(mat)}",
LogType.Error );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe float Det()
{
fixed( ColumnSet3* mat = &this.mat ) {
return InternalIO.Intrinsic.det_mat_3( mat, ( ColumnSet3* )0 );
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet3* source = &this.mat, target = &this.transpose ) {
InternalIO.Intrinsic.transpose33( source, target );
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix33 operator -( Matrix33 left, Matrix33 right )
{
Matrix33 ret = new Matrix33();
InternalIO.Intrinsic.sub_mat_3( &left.mat, &right.mat, &ret.mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator *( Matrix33 mat, float value )
{
return new Matrix33(
mat.mat.colum0 * value, mat.mat.colum1 * value, mat.mat.colum2 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Vec3 operator *( Matrix33 left, Vec3 right )
{
left.InternalTranspose();
return new Vec3(
Vector4.Dot( left.transpose.colum0, right.reg.AsVector4() ),
Vector4.Dot( left.transpose.colum1, right.reg.AsVector4() ),
Vector4.Dot( left.transpose.colum2, right.reg.AsVector4() ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator *( Matrix33 left, Matrix32 right )
{
left.InternalTranspose();
return new Matrix32(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator *( Matrix33 left, Matrix33 right )
{
left.InternalTranspose();
return new Matrix33(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator *( Matrix33 left, Matrix34 right )
{
left.InternalTranspose();
return new Matrix34(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator /( Matrix33 mat, float value )
{
return new Matrix33(
mat.mat.colum0 / value, mat.mat.colum1 / value, mat.mat.colum2 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix33 operator +( Matrix33 left, Matrix33 right )
{
Matrix33 ret = new Matrix33();
InternalIO.Intrinsic.add_mat_3( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}
-240
View File
@@ -1,240 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix34.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Drawing;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(
LayoutKind.Explicit,
Size = ( 7 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix34 : IMatrix<Matrix34>
{
[FieldOffset( 7 * 4 * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 4 * 4 * sizeof( float ) )] internal ColumnSet3 transpose;
[FieldOffset( 0 )] internal ColumnSet4 mat;
[FieldOffset( 0 * 4 * sizeof( float ) )] public Vec3 Colum0;
[FieldOffset( 1 * 4 * sizeof( float ) )] public Vec3 Colum1;
[FieldOffset( 2 * 4 * sizeof( float ) )] public Vec3 Colum2;
[FieldOffset( 3 * 4 * sizeof( float ) )] public Vec3 Colum3;
internal Matrix34( ColumnSet4 mat )
{
Unsafe.SkipInit( out this );
isTransposed = false;
this.mat = mat;
}
internal Matrix34( Vector4 c0, Vector4 c1, Vector4 c2, Vector4 c3 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
mat.colum2 = c2;
mat.colum3 = c3;
}
public Matrix34()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix34(
float a00,
float a01,
float a02,
float a03,
float a10,
float a11,
float a12,
float a13,
float a20,
float a21,
float a22,
float a23 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, 0 );
mat.colum0 = new Vector4( a01, a11, a21, 0 );
mat.colum0 = new Vector4( a02, a12, a22, 0 );
mat.colum0 = new Vector4( a03, a13, a23, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet4* source = &this.mat )
{
fixed( ColumnSet3* target = &this.transpose ) {
InternalIO.Intrinsic.transpose43( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix34 operator -( Matrix34 left, Matrix34 right )
{
Matrix34 ret = new Matrix34();
InternalIO.Intrinsic.sub_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator *( Matrix34 mat, float value )
{
return new Matrix34(
mat.mat.colum0 * value, mat.mat.colum1 * value, mat.mat.colum2 * value,
mat.mat.colum3 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator *( Matrix34 left, Matrix42 right )
{
left.InternalTranspose();
return new Matrix32(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator *( Matrix34 left, Matrix43 right )
{
left.InternalTranspose();
return new Matrix33(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator *( Matrix34 left, Matrix44 right )
{
left.InternalTranspose();
return new Matrix34(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator /( Matrix34 mat, float value )
{
return new Matrix34(
mat.mat.colum0 / value, mat.mat.colum1 / value, mat.mat.colum2 / value,
mat.mat.colum3 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix34 operator +( Matrix34 left, Matrix34 right )
{
Matrix34 ret = new Matrix34();
InternalIO.Intrinsic.add_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}
-240
View File
@@ -1,240 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix42.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(
LayoutKind.Explicit,
Size = ( ( 16 + 8 ) * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix42 : IMatrix<Matrix42>
{
[FieldOffset( ( 16 + 8 ) * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 0 )] internal ColumnSet2 mat;
[FieldOffset( 8 * sizeof( float ) )] internal ColumnSet4 transpose;
internal Matrix42( ColumnSet2 mat )
{
Unsafe.SkipInit( out this );
isTransposed = false;
this.mat = mat;
}
internal Matrix42( Vector4 c0, Vector4 c1 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
}
public Matrix42()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix42(
float a00,
float a01,
float a10,
float a11,
float a20,
float a21,
float a30,
float a31 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, a30 );
mat.colum1 = new Vector4( a01, a11, a21, a31 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 3 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 1 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 3 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 1 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
public override int GetHashCode()
{
return HashCode.Combine( mat.colum0.GetHashCode(), mat.colum1.GetHashCode() );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet2* source = &this.mat )
{
fixed( ColumnSet4* target = &this.transpose ) {
InternalIO.Intrinsic.transpose24( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix42 operator -( Matrix42 left, Matrix42 right )
{
Matrix42 ret = new Matrix42();
InternalIO.Intrinsic.sub_mat_2( &left.mat, &right.mat, &ret.mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix42 operator *( Matrix42 mat, float value )
{
return new Matrix42( mat.mat.colum0 * value, mat.mat.colum1 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix42 operator *( Matrix42 left, Matrix22 right )
{
left.InternalTranspose();
return new Matrix42(
Vector4.Dot( left.transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix43 operator *( Matrix42 left, Matrix23 right )
{
left.InternalTranspose();
return new Matrix43(
Vector4.Dot( left.transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix44 operator *( Matrix42 left, Matrix24 right )
{
left.InternalTranspose();
return new Matrix44(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix42 operator /( Matrix42 mat, float value )
{
return new Matrix42( mat.mat.colum0 / value, mat.mat.colum1 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix42 operator +( Matrix42 left, Matrix42 right )
{
Matrix42 ret = new Matrix42();
InternalIO.Intrinsic.add_mat_2( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}
-267
View File
@@ -1,267 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix43.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
namespace StgSharp.Math
{
[StructLayout(
layoutKind: LayoutKind.Explicit,
Size = ( 7 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix43 : IEquatable<Matrix43>, IMatrix<Matrix43>
{
[FieldOffset( 7 * 4 * sizeof( float ) )]
internal bool isTransposed;
[FieldOffset( 0 )]
internal ColumnSet3 mat;
[FieldOffset( 3 * 4 * sizeof( float ) )]
internal ColumnSet4 transpose;
internal Matrix43( Vector4 c0, Vector4 c1, Vector4 c2 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
mat.colum2 = c2;
}
public Matrix43()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix43(
float a00,
float a01,
float a02,
float a10,
float a11,
float a12,
float a20,
float a21,
float a22,
float a30,
float a31,
float a32 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, a30 );
mat.colum1 = new Vector4( a01, a11, a21, a31 );
mat.colum2 = new Vector4( a02, a12, a22, a32 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 3 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 3 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
public override bool Equals( object? obj )
{
return ( obj is Matrix43 x ) && Equals( x );
}
public bool Equals( Matrix43 other )
{
return EqualityComparer<ColumnSet3>.Default.Equals( mat, other.mat );
}
public override int GetHashCode()
{
return HashCode.Combine(
mat.colum0.GetHashCode(), mat.colum1.GetHashCode(), mat.colum2.GetHashCode() );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet3* source = &this.mat )
{
fixed( ColumnSet4* target = &this.transpose ) {
InternalIO.Intrinsic.transpose34( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix43 operator -( Matrix43 left, Matrix43 right )
{
return new Matrix43(
left.mat.colum0 - right.mat.colum0, left.mat.colum1 - right.mat.colum1,
left.mat.colum2 - right.mat.colum2 );
}
public static bool operator !=( Matrix43 left, Matrix43 right )
{
return !( left == right );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix43 operator *( Matrix43 mat, float value )
{
return new Matrix43(
mat.mat.colum0 * value, mat.mat.colum1 * value, mat.mat.colum2 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix42 operator *( Matrix43 left, Matrix32 right )
{
left.InternalTranspose();
return new Matrix42(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix43 operator *( Matrix43 left, Matrix33 right )
{
left.InternalTranspose();
return new Matrix43(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix44 operator *( Matrix43 left, Matrix34 right )
{
left.InternalTranspose();
return new Matrix44(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix43 operator /( Matrix43 mat, float value )
{
return new Matrix43(
mat.mat.colum0 / value, mat.mat.colum1 / value, mat.mat.colum2 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix43 operator +( Matrix43 left, Matrix43 right )
{
Matrix43 ret = new Matrix43();
InternalIO.Intrinsic.add_mat_3( &left.mat, &right.mat, &ret.mat );
return ret;
}
public static bool operator ==( Matrix43 left, Matrix43 right )
{
return left.Equals( right );
}
}
}
-326
View File
@@ -1,326 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix44.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(
LayoutKind.Explicit,
Size = ( 2 * 16 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public unsafe struct Matrix44 : IEquatable<Matrix44>, IMatrix<Matrix44>
{
[FieldOffset( 2 * 64 * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 0 )] internal ColumnSet4 mat;
[FieldOffset( 16 * sizeof( float ) )] internal ColumnSet4 transpose;
[FieldOffset( 0 * sizeof( float ) )] internal Vec4 colum0;
[FieldOffset( 4 * sizeof( float ) )] internal Vec4 colum1;
[FieldOffset( 8 * sizeof( float ) )] internal Vec4 colum2;
[FieldOffset( 12 * sizeof( float ) )] internal Vec4 colum3;
internal Matrix44( ColumnSet4 mat )
{
Unsafe.SkipInit( out this );
isTransposed = false;
this.mat = mat;
}
internal Matrix44( Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = vec0;
mat.colum1 = vec1;
mat.colum2 = vec2;
mat.colum3 = vec3;
}
public Matrix44()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public unsafe Matrix44(
float a00,
float a01,
float a02,
float a03,
float a10,
float a11,
float a12,
float a13,
float a20,
float a21,
float a22,
float a23,
float a30,
float a31,
float a32,
float a33 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, a30 );
mat.colum1 = new Vector4( a01, a11, a21, a31 );
mat.colum2 = new Vector4( a02, a12, a22, a32 );
mat.colum3 = new Vector4( a03, a13, a23, a33 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
#if DEBUG
if( ( rowNum > 3 ) || ( rowNum < 0 ) )
{
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
#endif
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
#if DEBUG
if( ( rowNum > 3 ) || ( rowNum < 0 ) )
{
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
#endif
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
public Matrix44 Transpose
{
get
{
InternalTranspose();
return new Matrix44( this.transpose );
}
}
public static Matrix44 Unit => new Matrix44(
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
public static Matrix44 WNegativeUnit => new Matrix44(
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1 );
public static Matrix44 XNegativeUnit => new Matrix44(
-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
public static Matrix44 YNegativeUnit => new Matrix44(
1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
public static Matrix44 ZNegativeUnit => new Matrix44(
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1 );
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe float Det()
{
InternalTranspose();
fixed( ColumnSet4* _this = &mat, _trans = &transpose ) {
return InternalIO.Intrinsic.det_mat_4( _this, _trans );
}
}
public override bool Equals( object? obj )
{
return ( obj is Matrix44 x ) && Equals( x );
}
public bool Equals( Matrix44 other )
{
return mat.Equals( other.mat );
}
public override int GetHashCode()
{
return HashCode.Combine(
mat.colum0.GetHashCode(), mat.colum1.GetHashCode(), mat.colum2.GetHashCode(),
mat.colum3.GetHashCode() );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe Matrix42 Multiple( in Matrix42 right )
{
InternalTranspose();
Matrix42 ans = new Matrix42();
fixed( ColumnSet4* lptr = &transpose )
{
fixed( Vector4* rptr = &right.mat.colum0 ) {
InternalIO.Intrinsic.dot_42( lptr, rptr, &ans.mat.colum0 );
}
}
return ans;
}
public unsafe Matrix43 Multiple( in Matrix43 right )
{
InternalTranspose();
Matrix43 ans = new Matrix43();
fixed( Vector4* rptr = &right.mat.colum0 )
{
fixed( ColumnSet4* lptr = &transpose ) {
InternalIO.Intrinsic.dot_43( lptr, rptr, &ans.mat.colum0 );
}
}
return ans;
}
public override string ToString()
{
InternalTranspose();
return $"{transpose.colum0}{transpose.colum1}{transpose.colum2}{transpose.colum3}";
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet4* source = &mat, target = &transpose ) {
InternalIO.Intrinsic.transpose44( source, target );
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix44 operator -( Matrix44 left, Matrix44 right )
{
return new Matrix44(
right.mat.colum0 - left.mat.colum0, right.mat.colum1 - left.mat.colum1,
right.mat.colum2 - left.mat.colum2, right.mat.colum3 - left.mat.colum3 );
}
public static bool operator !=( Matrix44 left, Matrix44 right )
{
return !( left == right );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix44 operator *( Matrix44 mat, float value )
{
return new Matrix44(
mat.mat.colum0 * value, mat.mat.colum1 * value, mat.mat.colum2 * value,
mat.mat.colum3 * value );
}
[Obsolete(
"The operand may cause performance loss, use Matrix.Multiple() method instead.",
false )]
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix42 operator *( Matrix44 left, Matrix42 right )
{
return left.Multiple( right );
}
[Obsolete(
"The operand may cause performance loss, use Matrix.Multiple() method instead.",
false )]
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix43 operator *( Matrix44 left, Matrix43 right )
{
return left.Multiple( in right );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix44 operator *( Matrix44 left, Matrix44 right )
{
left.InternalTranspose();
return new Matrix44(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix44 operator +( Matrix44 left, Matrix44 right )
{
Matrix44 ret = new Matrix44();
InternalIO.Intrinsic.add_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
public static bool operator ==( Matrix44 left, Matrix44 right )
{
return left.Equals( right );
}
}
}
@@ -1,96 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="MatrixIndexLabel.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
public readonly struct MatrixIndexLabel
{
private readonly bool _isRange;
public readonly Range R;
internal MatrixIndexLabel(Index i)
{
_isRange = false;
R = new Range(i, Index.End);
}
internal MatrixIndexLabel(Range r)
{
_isRange = true;
R = r;
}
public (int offset,int legnth) GetOffsetAndLength(int CountOfCollection)
{
return _isRange ?
R.GetOffsetAndLength(CountOfCollection) : (R.Start.GetOffset(CountOfCollection), 1);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Length(int CountOfCollection)
{
return _isRange ? R.GetOffsetAndLength(CountOfCollection).Length : 1;
}
public int Offset(int CountOfCollection)
{
return _isRange ?
R.GetOffsetAndLength(CountOfCollection).Offset : R.Start
.GetOffset(CountOfCollection);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator MatrixIndexLabel(Index i)
{
return new MatrixIndexLabel(i);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator MatrixIndexLabel(Range r)
{
return new MatrixIndexLabel(r);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator MatrixIndexLabel(int i)
{
return new MatrixIndexLabel(i);
}
}
}
-164
View File
@@ -1,164 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vec2.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.HighPerformance;
using System.Net.Http.Headers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
/// <summary>
/// A two dimension vector defined by two elements. Vec2 in World are default used as colum
/// vector.
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)]
public struct Vec2 : IFixedVector<Vec2>
{
[FieldOffset(0)] internal unsafe fixed float num[2];
[FieldOffset(0)]
internal M128 reg;
[FieldOffset(0)]
internal Vector2 v;
[FieldOffset(0)]
public float X;
[FieldOffset(4)]
public float Y;
internal Vec2(Vector2 vec)
{
Unsafe.SkipInit(out reg);
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
v = vec;
}
internal Vec2(M128 vec)
{
Unsafe.SkipInit(out reg);
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
reg = vec;
reg.Member<ulong>(1) = 0;
}
public Vec2(float x, float y)
{
v = new Vector2(x, y);
}
public static Vec2 Unit => new Vec2(1, 1);
public static Vec2 Zero => new Vec2(0, 0);
public static Vec2 One
{
get => new Vec2(1, 1);
}
public Vec2 XY
{
readonly get => this;
set => this = value;
}
public Vec3 XYZ
{
readonly get => new(reg);
set
{
reg = value.reg;
reg.Member<ulong>(1) = 0;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float Cross(Vec2 right)
{
return (X * right.Y) - (Y * right.X);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float Dot(Vec2 vec)
{
return Vector2.Dot(v, vec.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec2 operator -(Vec2 left, Vec2 right)
{
return new Vec2(left.v - right.v);
}
public static bool operator !=(Vec2 left, Vec2 right)
{
return !(left == right);
}
public static Vec2 operator *(Vec2 vec, float value)
{
return new Vec2(vec.v * value);
}
public static Vec2 operator *(float value, Vec2 vec)
{
return new Vec2(vec.v * value);
}
public static Vec2 operator /(Vec2 vec, float value)
{
return new Vec2(vec.v / value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec2 operator +(Vec2 left, Vec2 right)
{
return new Vec2(left.v + right.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vec2 left, Vec2 right)
{
return left.v == right.v;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Vec2((float, float) tuple)
{
return new Vec2(tuple.Item1, tuple.Item2);
}
}
}
-228
View File
@@ -1,228 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vec3.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.HighPerformance;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)]
public struct Vec3 : IEquatable<Vec3>, IFixedVector<Vec3>
{
[FieldOffset(0)] internal unsafe fixed float num[3];
[FieldOffset(0)] internal M128 reg;
[FieldOffset(0)] internal Vector3 v;
[FieldOffset(0)] public float X;
[FieldOffset(4)] public float Y;
[FieldOffset(8)] public float Z;
internal Vec3(M128 vector)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out v);
reg = vector;
reg.Member<uint>(3) = 0;
}
internal Vec3(Vector3 vector)
{
v = vector;
}
public Vec3(Vec2 xy, float z)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out v);
reg = xy.reg;
Z = z;
}
public Vec3(float x, float y, float z)
{
Unsafe.SkipInit(out reg);
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
v = new Vector3(x, y, z);
}
public unsafe Vec2 XY
{
get => new Vec2(this.reg);
set
{
fixed (Vector3* vptr = &v) {
*(Vector2*)vptr = value.v;
}
}
}
public Vec3 XYZ
{
get => new(v);
set => this = value;
}
public static Vec3 Zero => new Vec3(0, 0, 0);
public static Vec3 One => new Vec3(1, 1, 1);
public static Vec3 UnitX => new Vec3(1, 0, 0);
public static Vec3 UnitY => new Vec3(0, 1, 0);
public static Vec3 UnitZ => new Vec3(0, 0, 1);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 Cross(Vec3 left, Vec3 right)
{
return Linear.Cross(left, right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float Dot(Vec3 right)
{
return Vector3.Dot(v, right.v);
}
public bool Equals(Vec3 other)
{
return this.reg == other.reg;
}
public override bool Equals(object obj)
{
if (obj is Vec3)
{
return this == (Vec3)obj;
} else
{
return false;
}
}
public override unsafe int GetHashCode()
{
fixed (float* add = &X) {
return HashCode.Combine(X, Y, Z, (ulong)add);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float GetMaxValue()
{
float ret = X;
ret = (ret > Y) ? ret : Y;
ret = (ret > Z) ? ret : Z;
return ret;
}
public static bool IsParallel(Vec3 left, Vec3 right)
{
return Cross(left, right) == Zero;
}
public override string ToString()
{
return $"[{X},{Y},{Z}]";
}
public string ToString(string sample)
{
return $"[{X.ToString(sample)},{Y.ToString(sample)},{Z.ToString(sample)}]";
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator -(Vec3 vec)
{
return new Vec3(-vec.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator -(Vec3 left, Vec3 right)
{
return new Vec3(left.v - right.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Vec3 left, Vec3 right)
{
return left.v != right.v;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator *(Vec3 vec, float value)
{
return new Vec3(vec.v * value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float operator *(Vec3 left, Vec3 right)
{
return Vector3.Dot(left.v, right.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator /(Vec3 vec, float value)
{
return new Vec3(vec.v / value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator +(Vec3 left, Vec3 right)
{
return new Vec3(left.v + right.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vec3 left, Vec3 right)
{
return left.v == right.v;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe implicit operator Vec3((float, float, float) tuple)
{
Vec3 vec = new Vec3(*(Vector3*)&tuple);
return vec;
}
}
}
-192
View File
@@ -1,192 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vec4.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.HighPerformance;
using StgSharp.Internal.Intrinsic;
using StgSharp.Math;
using System;
using System.Data.Common;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)]
public struct Vec4 : IEquatable<Vec4>, IFixedVector<Vec4>
{
[FieldOffset(0)] internal unsafe fixed float num[4];
[FieldOffset(0)] internal M128 reg;
[FieldOffset(0)] internal Vector4 vec;
[FieldOffset(12)] public float W;
[FieldOffset(0)] public float X;
[FieldOffset(4)] public float Y;
[FieldOffset(8)] public float Z;
internal Vec4(Vector4 v)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out W);
Unsafe.SkipInit(out reg);
vec = v;
}
internal Vec4(M128 v)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out W);
Unsafe.SkipInit(out vec);
reg = v;
}
public Vec4(Vec3 v3, float w)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out W);
reg = v3.reg;
W = w;
}
public Vec4(float x, float y, float z, float w)
{
vec = new Vector4(x, y, z, w);
}
public unsafe Vec2 XY
{
get => new Vec2(reg);
set
{
X = value.X;
Y = value.Y;
}
}
public unsafe Vec3 XYZ
{
get => new Vec3(reg);
set
{
float w = W;
reg = value.reg;
W = w;
}
}
public static Vec4 One
{
get => new Vec4(1, 1, 1, 1);
}
public static Vec4 Zero
{
get => new Vec4(0, 0, 0, 0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 Add(Vec4 left, Vec4 right)
{
return left + right;
}
public override bool Equals(object obj)
{
return (obj is Vec4 v) ? (v == this) : false;
}
public override int GetHashCode()
{
return vec.GetHashCode();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 Subtract(Vec4 left, Vec4 right)
{
return left - right;
}
public override string ToString()
{
return vec.ToString();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 operator -(Vec4 left, Vec4 right)
{
return new Vec4(left.vec - right.vec);
}
public static bool operator !=(Vec4 left, Vec4 right)
{
return !(left == right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 operator *(Matrix44 mat, Vec4 vec)
{
mat.InternalTranspose();
return new Vec4(
Vector4.Dot(mat.transpose.colum0, vec.vec),
Vector4.Dot(mat.transpose.colum1, vec.vec),
Vector4.Dot(mat.transpose.colum2, vec.vec),
Vector4.Dot(mat.transpose.colum3, vec.vec));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 operator +(Vec4 left, Vec4 right)
{
return new Vec4(left.vec + right.vec);
}
public static bool operator ==(Vec4 left, Vec4 right)
{
return left.vec == right.vec;
}
bool IEquatable<Vec4>.Equals(Vec4 other)
{
return vec == other.vec;
}
}
}
-97
View File
@@ -1,97 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="VecAny.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
[CollectionBuilder(typeof(VecAnyBuilder), nameof(VecAnyBuilder.Build))]
public class VecAny : IEnumerable<float>
{
private float[] _values;
internal VecAny(ReadOnlySpan<float> values)
{
_values = values.ToArray();
}
public VecAny(int size)
{
if (size <= 0) {
throw new ArgumentOutOfRangeException(
nameof(size), "Size must be greater than zero.");
}
_values = new float[size];
}
public VecAny? this[ReadOnlySpan<MatrixIndexLabel> span]
{
get
{
if (span.Length == 0) {
return null;
}
int size = 0;
foreach (MatrixIndexLabel label in span) {
size += label.Length(_values.Length);
}
return new VecAny(size);
}
}
public IEnumerator<float> GetEnumerator()
{
return ((IEnumerable<float>)_values).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _values.GetEnumerator();
}
}
public class VecAnyBuilder
{
public static VecAny Build(ReadOnlySpan<float> span)
{
return new VecAny(span);
}
}
}
@@ -1,50 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vector.Cross.cs"
// Project: World
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
namespace StgSharp.Math
{
public static unsafe partial class Linear
{
public static float Cross( Vec2 vec1, Vec2 vec2 )
{
return ( vec1.X * vec2.Y ) - ( vec1.Y * vec2.X );
}
public static Vec3 Cross( Vec3 vec1, Vec3 vec2 )
{
return new Vec3(
( vec1.Y * vec2.Z ) - ( vec1.Z * vec2.Y ),
( vec1.X * vec2.Z ) - ( vec1.Z * vec2.X ),
( vec1.X * vec2.Y ) - ( vec1.Y * vec2.X ) );
}
}
}
@@ -1,50 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vector.GetAngle.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
namespace StgSharp.Math
{
public static unsafe partial class Linear
{
public static float GetAngle( Vec2 vec1, Vec2 vec2 )
{
return Scaler.ACos(
1
//vec1.multiple(vec2)
/ ( vec1.GetLength() * vec2.GetLength() ) );
}
public static float GetAngle( Vec3 vec1, Vec3 vec2 )
{
return Scaler.ACos( ( vec1 * vec2 ) / ( vec1.GetLength() * vec2.GetLength() ) );
}
}
}
@@ -1,47 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vector.GetLength.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
namespace StgSharp.Math
{
public static unsafe partial class Linear
{
public static float GetLength( this Vec3 vec )
{
return Scaler.Sqrt( vec.Dot( vec ) );
}
public static float GetLength( this Vec2 vec )
{
return Scaler.Sqrt( vec.Dot( vec ) );
}
}
}
@@ -1,94 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vector.Normalize.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal;
using StgSharp.Math;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
public static partial class Linear
{
public static Vec4 Normalize( Vec4 vec )
{
return new Vec4
{
vec = Vector4.Normalize( vec.vec )
};
}
public static Vec3 Normalize( Vec3 vec )
{
return new Vec3
{
v = Vector3.Normalize( vec.v )
};
}
public static unsafe void Normalize( ref Vec4 source, ref Vec4 target )
{
Vector4 s = source.vec;
Vector4 t = target.vec;
s = Vector4.Normalize( s );
float dotProduct = Vector4.Dot( s, t );
Vector4 projection = Vector4.Multiply( s, t );
t -= projection;
source.vec = s;
target.vec = t;
}
public static unsafe void Normalize( ref Vec3 source, ref Vec3 target )
{
Vector3 s = source.v;
Vector3 t = target.v;
s = Vector3.Normalize( s );
Vector3 projection = ( Vector3.Dot( t, s ) / Vector3.Dot( s, s ) ) * s;
t -= projection;
t = Vector3.Normalize( t );
source.v = s;
target.v = t;
}
}
}
@@ -1,104 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Vector.Orthogonalize.cs"
// Project: World
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using StgSharp.Math;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
public static partial class Linear
{
public static Vec4 Orthogonalize( Vec4 vec )
{
return new Vec4
{
vec = Vector4.Normalize( vec.vec )
};
}
public static Vec3 Orthogonalize( Vec3 vec )
{
return new Vec3
{
v = Vector3.Normalize( vec.v )
};
}
public static unsafe void Orthogonalize( ref Vec4 source, ref Vec4 target )
{
Vector4 s = source.vec;
Vector4 t = target.vec;
s = Vector4.Normalize( s );
float dotProduct = Vector4.Dot( s, t );
Vector4 projection = Vector4.Multiply( s, t );
t -= projection;
source.vec = s;
target.vec = t;
}
/// <summary>
/// Orthogonalize two <see cref="Vec3" />s, let their length be 1 and perpendicular to
/// each other.
/// </summary>
/// <param _label="source">
///
/// </param>
/// <param _label="target">
///
/// </param>
public static unsafe void Orthogonalize( ref Vec3 source, ref Vec3 target )
{
Vector3 s = source.v;
Vector3 t = target.v;
s = Vector3.Normalize( s );
Vector3 projection = ( Vector3.Dot( t, s ) / Vector3.Dot( s, s ) ) * s;
t -= projection;
t = Vector3.Normalize( t );
source.v = s;
target.v = t;
}
}
}
-110
View File
@@ -1,110 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ACos.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Math
{
public static unsafe partial class Scaler
{
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe float ACos( float x )
{
return MathF.Acos( x );
/*
int sign = 1;
float y;
if (x < 0)
{
sign = -1;
y = -x;
}
else
{
y = x;
}
if (x > 1)
{
throw new ArgumentException();
}
float r, s, u, vec = 0.0f;
bool transform = (y >= 0.5f);
if (transform)
{
r = 0.5f * (1.0f - y);
s = Scaler.Sqrt(r);
y = s;
}
else
{
r = y * y;
}
u = r * (0.184161606965100694821398249421F +
(-0.0565298683201845211985026327361F +
(-0.0133819288943925804214011424456F -
0.00396137437848476485201154797087F * r) * r) * r) /
(1.10496961524520294485512696706F -
0.836411276854206731913362287293F * r);
/*
if (transform)
{
float c, s1, p, q;
uint us;
us = *(uint*)&s;
uint uss = us & 0xffff0000;
s1 = *(float*)&uss;
c = (r - s1 * s1) / (s + s1);
p = 2.0F * s * u - (piby2_tail - 2.0F * c);
q = hpiby2_head - 2.0F * s1;
vec = hpiby2_head - (p - q);
}
else
{
vec = y + y * u;
}
vec = sign * vec;
return piby2 - vec;
*/
}
}
}
-122
View File
@@ -1,122 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ASin.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
namespace StgSharp.Math
{
public static unsafe partial class Scaler
{
private const float
piby2_tail = 7.5497894159e-08f, /* 0x33a22168 */
hpiby2_head = 7.8539812565e-01f, /* 0x3f490fda */
piby2 = 1.5707963705e+00f; /* 0x3fc90fdb */
/// <summary>
/// Reurns the value of ArcSin(x)
/// </summary>
/// <param _label="x">
/// The sine value of the angle
/// </param>
/// <returns>
///
/// </returns>
/// <exception cref="ArgumentException">
///
/// </exception>
public static float ASin( float x )
{
return MathF.Asin( x );
/*
int sign = 1;
float y;
if (x < 0)
{
sign = -1;
y = -x;
}
else
{
y = x;
}
if (x > 1)
{
throw new ArgumentException();
}
float r, s, u, vec = 0.0f;
bool transform = (y >= 0.5f);
if (transform)
{
r = 0.5f * (1.0f - y);
s = Scaler.Sqrt(r);
y = s;
}
else
{
r = y * y;
}
u = r * (0.184161606965100694821398249421F +
(-0.0565298683201845211985026327361F +
(-0.0133819288943925804214011424456F -
0.00396137437848476485201154797087F * r) * r) * r) /
(1.10496961524520294485512696706F -
0.836411276854206731913362287293F * r);
/*
if (transform)
{
float c, s1, p, q;
uint us;
us = *(uint*)&s;
uint uss = us & 0xffff0000;
s1 = *(float*)&uss;
c = (r - s1 * s1) / (s + s1);
p = 2.0F * s * u - (piby2_tail - 2.0F * c);
q = hpiby2_head - 2.0F * s1;
vec = hpiby2_head - (p - q);
}
else
{
vec = y + y * u;
}/*
return sign * vec;
*/
}
}
}
-119
View File
@@ -1,119 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ATan.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Math
{
public static unsafe partial class Scaler
{
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe float ATan( float x )
{
return MathF.Atan( x );
/*
float sign = 1, angle = 0;
if (x < 0)
{
sign = -1;
x = -x;
}
uint xBit = *(uint*)&x;
int xExp = (int)(xBit >> 23) - 127;
if (xExp >= 26)
{
return 1;
}
if (xExp <= -15)
{
return x;
}
if (xExp >= 0)
{
x = (x - 1) / (x + 1);
angle = 0.7853981634f;
}
float vec = 0.7853981634f * x + x * (1 - x) * (0.2447f + 0.0663f * x);
vec += angle;
vec *= sign;
return vec;
}
public static unsafe float ATan(float x, float y)
{
float z = y / x;
float sign = 1, angle = 0, angle2 = 0;
if (x < 0)
{
angle = -3.1415926535f;
}
if (z < 0)
{
sign = -1;
z = -z;
}
uint zBit = *(uint*)&z;
int zExp = (int)(zBit >> 23) - 127;
if (zExp >= 26)
{
return 1;
}
if (zExp <= -15)
{
return z;
}
if (zExp >= 0)
{
z = (z - 1) / (z + 1);
angle2 = 0.7853981634f;
}
float vec = 0.7853981634f * z + z * (1 - z) * (0.2447f + 0.0663f * z);
vec *= 57.29577951f;
vec += angle2;
vec += angle;
vec *= sign;
return vec;
*/
}
}
}
-70
View File
@@ -1,70 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="BasicOps.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
namespace StgSharp.Math
{
public static unsafe partial class Scaler
{
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe float Abs( float x )
{
uint* a = ( uint* )&x;
*a &= 0b_0111_1111_1111_1111_1111_1111_1111_1111;
return *( float* )a;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe int Abs( int x )
{
uint* a = ( uint* )&x;
*a &= 0b_0111_1111_1111_1111_1111_1111_1111_1111;
return *( int* )a;
}
internal static string GetListSeparator( IFormatProvider formatProvider )
{
if( formatProvider is CultureInfo cultureInfo ) {
return cultureInfo.TextInfo.ListSeparator;
}
if( formatProvider?.GetFormat( typeof( TextInfo ) ) is TextInfo textInfo ) {
return textInfo.ListSeparator;
}
return CultureInfo.CurrentCulture.TextInfo.ListSeparator;
}
}
}
-67
View File
@@ -1,67 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Compare.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
public static partial class Scaler
{
public static float MaxOf( params float[] stream )
{
float ret = stream[ 0 ];
foreach( float num in stream )
{
if( ret < num ) {
ret = num;
}
}
return ret;
}
public static float MinOf( params float[] stream )
{
float ret = stream[ 0 ];
foreach( float num in stream )
{
if( ret > num ) {
ret = num;
}
}
return ret;
}
}
}
-60
View File
@@ -1,60 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Cos.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Math
{
public static partial class Scaler
{
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static float Cos( float x )
{
/*
float refer = x / 360.0f;
refer -= (int)refer;
refer *= 40;
int a = (int)refer; //大分度,查表
refer -= a; //小分度,拟合
float refer2 = refer * refer;
return ((-sinData[a]) * ((0.1570796327f * refer) - (6.459640975e-4f * refer * refer2)))
+ (cosData[a] * ((1 - (0.0123370055f * refer2)) + (2.536695709e-5f * refer2 * refer2)));
*/
return MathF.Cos( x );
}
}
}
-59
View File
@@ -1,59 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Ctor.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Runtime.InteropServices;
namespace StgSharp.Math
{
public unsafe delegate float ScalarCalcHandler( float* x );
public static unsafe partial class Scaler
{
private const uint MEM_COMMIT = 0x1000;
private const uint MEM_RELEASE = 0x8000;
private const uint MEM_RESERVE = 0x2000;
private const uint PAGE_EXECUTE_READWRITE = 0x40;
static Scaler() { }
[DllImport( "Kernel32.dll", EntryPoint = "VirtualAlloc" )]
private static extern IntPtr VirtualAlloc(
IntPtr address,
int size,
uint allocType,
uint protect );
[DllImport( "Kernel32.dll", EntryPoint = "VirtualFree" )]
private static extern bool VirtualFree( IntPtr address, int size, uint freeType );
}
}
-112
View File
@@ -1,112 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Exp.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Math
{
public static unsafe partial class Scaler
{
public const float E = 2.718281828f;
public const double EDouble = System.Math.E;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static float Exp( float x )
{
return MathF.Exp( x );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static double Exp( double x )
{
return System.Math.Exp( x );
}
/// <summary>
/// Get the value of E ^ x;
/// </summary>
/// <param _label="x">
///
/// </param>
/// <returns>
///
/// </returns>
public static unsafe float ExpSlow( float x )
{
if( x == 1 ) {
return E;
}
if( x == 0 ) {
return 1;
}
bool sign = false;
if( x < 0 )
{
sign = true;
x = -x;
}
float z = x, t;
if( x < 0.5f )
{
t = 1.0f + ( x * ( 1.0f + ( x * ( 0.5f + ( x * ( 0.1666666667f + ( x * ( 0.0416666666667f + ( x * 8.333333333e-3f ) ) ) ) ) ) ) ) );
} else
{
/*
* define z = n * 2 ^ m
* n is between 0 and 0.5
*/
uint zBit = *( uint* )&z;
uint zBitAbs = zBit & 0b_0111_1111_1111_1111_1111_1111_1111_1111;
uint uintm = zBitAbs >> 23;
int m = ( *( int* )&uintm ) - 126;
uint nBit = ( zBitAbs & 0b_0000_0000_0111_1111_1111_1111_1111_1111 ) + 0b_0011_1111_0000_0000_0000_0000_0000_0000;
float n = ( *( float* )&nBit ) - 1;
t = 2.718281828f + ( n * ( 2.718281828f + ( n * ( 1.359140914f + ( n * ( 0.4530469714f + ( n * ( 0.1132617429f + ( n * 0.02265234857f ) ) ) ) ) ) ) ) );
for( int i = 0; i < m; i++ ) {
t = t * t;
}
}
if( sign ) {
t = 1 / t;
}
return t;
}
}
}
-61
View File
@@ -1,61 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Factorial.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
public static partial class Scaler
{
private static readonly uint[] factorialResult = [1, 1, 2, 6, 24,120,720,5040,40320,362880,3628800,39916800,479001600];
public static unsafe ulong Factorial( int n )
{
ArgumentOutOfRangeException.ThrowIfLessThan( n, 0 );
if( n < 13 ) {
return factorialResult[ n ];
}
if( n < 30 ) {
return InternalIO.Intrinsic.factorial_simd( n );
}
double
dn = n,
stir = Sqrt( 2 * PiDouble * dn ) * Pow( dn / EDouble, dn ),
correction = Exp( 1 / ( 12 * dn ) );
return ( ulong )( stir * correction );
}
}
}
-34
View File
@@ -1,34 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Function.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
namespace StgSharp.Math
{
public class Function { }
}
-83
View File
@@ -1,83 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Log.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
namespace StgSharp.Math
{
public static partial class Scaler
{
private static readonly float[] logArray = {
0f, 0.00995033085316809f, 0.0198026272961797f, 0.0295588022415444f, 0.0392207131532813f, 0.048790164169432f, 0.0582689081239758f, 0.0676586484738149f, 0.0769610411361284f, 0.0861776962410524f, 0.0953101798043249f, 0.104360015324243f, 0.113328685307003f, 0.122217632724249f, 0.131028262406404f, 0.139761942375159f, 0.148420005118273f, 0.157003748809665f, 0.165514438477573f, 0.173953307123438f, 0.182321556793955f, 0.19062035960865f, 0.198850858745165f, 0.207014169384326f, 0.215111379616945f, 0.22314355131421f, 0.231111720963387f, 0.2390169004705f, 0.246860077931526f, 0.254642218373581f, 0.262364264467491f, 0.27002713721306f, 0.27763173659828f, 0.285178942233662f, 0.29266961396282f, 0.300104592450338f, 0.307484699747961f, 0.314810739840034f, 0.322083499169113f, 0.3293037471426f, 0.336472236621213f, 0.343589704390077f, 0.350656871613169f, 0.357674444271816f, 0.364643113587909f, 0.371563556432483f, 0.378436435720245f, 0.385262400790645f, 0.392042087776024f, 0.398776119957368f, 0.405465108108164f, 0.412109650826833f, 0.418710334858185f, 0.425267735404344f, 0.431782416425538f, 0.438254930931155f, 0.444685821261446f, 0.451075619360217f, 0.457424847038875f, 0.46373401623214f, 0.470003629245736f, 0.476234178996372f, 0.482426149244293f, 0.488580014818671f, 0.494696241836107f, 0.500775287912489f, 0.506817602368452f, 0.512823626428664f, 0.518793793415168f, 0.524728528934982f, 0.53062825106217f, 0.536493370514568f, 0.542324290825362f, 0.548121408509688f, 0.553885113226438f, 0.559615787935423f, 0.56531380905006f, 0.570979546585738f, 0.576613364303994f, 0.582215619852664f, 0.587786664902119f, 0.593326845277734f, 0.598836501088704f, 0.60431596685333f, 0.609765571620894f, 0.615185639090233f, 0.62057648772511f, 0.625938430866495f, 0.631271776841858f, 0.636576829071551f, 0.641853886172395f, 0.647103242058538f, 0.65232518603969f, 0.657520002916794f, 0.662687973075237f, 0.667829372575655f, 0.672944473242426f, 0.678033542749897f, 0.683096844706444f, 0.688134638736401f,
};
/// <summary>
///
/// </summary>
/// <param _label="x">
///
/// </param>
/// <returns>
/// Returns the value of ln(x).
/// </returns>
public static unsafe float Log( float x )
{
if( x < 0 ) {
throw new ArgumentOutOfRangeException();
}
uint input = *( uint* )&x;
int f = ( int )input;
f >>= 23;
f -= 127;
input <<= 9;
input >>= 9;
input += 0b_0011_1111_1000_0000_0000_0000_0000_0000;
float result = *( float* )&input;
uint order = ( ( uint )( result * 100 ) ) - 100;
float cache = ( result / ( 1f + ( 0.01f * order ) ) ) - 1;
result = ( cache * ( -0.25f ) ) + 0.3333333333333f;
result = ( result * cache ) - 0.5f;
result = ( result * cache ) + 1.0f;
result *= cache;
return
( f * 0.6931471806f ) + result + logArray[ order ];
}
public static float Log( float x, float y )
{
return Log( x ) / Log( y );
}
}
}
-124
View File
@@ -1,124 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Pow.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System.Runtime.CompilerServices;
namespace StgSharp.Math
{
public static unsafe partial class Scaler
{
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe float Pow( float x, float y )
{
return System.MathF.Pow( x, y );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe double Pow( double x, double y )
{
return System.Math.Pow( x, y );
}
/// <summary>
/// calculate the value of x^y
/// </summary>
/// <param _label="x">
///
/// </param>
/// <param _label="y">
///
/// </param>
/// <returns>
/// Returns the value of x^y
/// </returns>
public static unsafe float PowSlow( float x, float y )
{
/*
* x^y = E ^ ( log( x ) * y )
* Now define z = | log(x) * y | = m * n
* and m is an integer, and 0.5 < |n| < 1
* then E ^ z = ( E ^ n ) ^ m
*
*
* As a float number can be expressed in (1+e)*(2^f)
* n = (1+e)/2
* m = 2 ^ (f + 1)
*
*/
float z, t;
if( ( x == 1 ) || ( y == 0 ) ) {
return 1;
}
if( ( x == 1 ) && ( y == 0 ) ) {
return float.PositiveInfinity;
}
if( ( x == 0 ) && ( y != 0 ) ) {
return 0;
}
z = Scaler.Log( x ) * y;
bool sign = false;
if( z < 0 )
{
sign = true;
z = -z;
}
if( z < 0.5f )
{
t = 1.0f + ( z * ( 1.0f + ( z * ( 0.5f + ( z * ( 0.1666666667f + ( z * ( 0.0416666666667f + ( z * 8.333333333e-3f ) ) ) ) ) ) ) ) );
} else
{
uint zBit = *( uint* )&z;
uint zBitAbs = zBit & 0b_0111_1111_1111_1111_1111_1111_1111_1111;
uint uintm = zBitAbs >> 23;
int m = ( *( int* )&uintm ) - 126;
uint nBit = ( zBitAbs & 0b_0000_0000_0111_1111_1111_1111_1111_1111 ) + 0b_0011_1111_0000_0000_0000_0000_0000_0000;
float n = ( *( float* )&nBit ) - 1;
t = 2.718281828f + ( n * ( 2.718281828f + ( n * ( 1.359140914f + ( n * ( 0.4530469714f + ( n * ( 0.1132617429f + ( n * 0.02265234857f ) ) ) ) ) ) ) ) );
for( int i = 0; i < m; i++ ) {
t = t * t;
}
}
if( sign ) {
t = 1 / t;
}
return t;
}
}
}
-133
View File
@@ -1,133 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Random.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Math;
using System;
using System.Collections.Generic;
using System.Data;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
namespace StgSharp.Math
{
public static unsafe partial class Scaler
{
private static byte[] randomSeed;
internal static float currentSeed
#if DEBUG
= 0.5f;
#else
= Abs(System.DateTime.UtcNow.GetHashCode());
#endif
/// <summary>
/// returns a random float number between 0 and 1.
/// </summary>
/// <returns>
///
/// </returns>
public static unsafe float LowProceisionRandom()
{
float seed = currentSeed;
float sample = Scaler.Pow(Scaler.SeedSqrt(seed), 2);
float sample2 = (sample - seed) / seed;
sample2 = Scaler.Abs(sample2);
if (sample == 1) {
sample = sample2;
}
currentSeed = sample;
sample2 *= 1000000;
float result = sample2 - ((int)sample2);
if (result == 0)
{
currentSeed = sample2 + 0.1f;
result = Scaler.LowProceisionRandom();
}
return result;
}
/// <summary>
///
/// </summary>
/// <returns>
///
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Random<T>() where T: unmanaged, IConvertible, INumber<T>
{
if (randomSeed == null)
{
randomSeed = new byte[64];
string originSeed =
($"{((Assembly.GetEntryAssembly() == null) ? (Assembly.GetAssembly(typeof(World))!) :
Assembly.GetEntryAssembly())}") + ($"{DateTime.UtcNow.ToString("o")}");
using (SHA256 sha = SHA256.Create()) {
randomSeed = sha.ComputeHash(Encoding.UTF8.GetBytes(originSeed));
}
}
using (SHA256 sha = SHA256.Create()) {
randomSeed = sha.ComputeHash(randomSeed);
}
fixed (byte* bptr = randomSeed) {
return *(T*)bptr;
}
}
/// <summary>
/// Generates a random seed in int value.
/// </summary>
/// <returns>
///
/// </returns>
public static unsafe int RandomSeed()
{
float seedValue1 = LowProceisionRandom();
float seedValue2 = LowProceisionRandom();
uint seedValueBits = *(uint*)&seedValue1;
float seedValue = seedValueBits * seedValue2;
return *(int*)&seedValue;
}
}
}
-68
View File
@@ -1,68 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="SignOf.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
public static unsafe partial class Scaler
{
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe int SignOf( float x )
{
if( x == 0 ) {
return 0;
}
if( x > 0 ) {
return 1;
}
return -1;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe int SignOf( int x )
{
if( x == 0 ) {
return 0;
}
if( x > 0 ) {
return 1;
}
return -1;
}
}
}
-50
View File
@@ -1,50 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Sin.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Net.NetworkInformation;
using System.Runtime.CompilerServices;
namespace StgSharp.Math
{
public static partial class Scaler
{
public const float Pi = 3.1415926f;
public const double PiDouble = System.Math.PI;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe float Sin( float x )
{
return MathF.Sin( x );
}
}
}
-77
View File
@@ -1,77 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Sqrt.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Math
{
public static partial class Scaler
{
public static unsafe float SeedSqrt( float x )
{
ArgumentOutOfRangeException.ThrowIfNegative( x );
if( x <= 1e-12 ) {
return 0;
}
uint a = *( uint* )&x;
uint f = a;
f >>= 23;
f /= 2;
f += 64;
a -= 0b_0011_1111_0000_0000_0000_0000_0000_0000;
uint e = a << 8;
e >>= 8;
e *= 0b_1101_0001;
e >>= 24;
e += 0b_0000_0000_0001_0000_1010_1000_1110_0010;
f <<= 23;
e += f;
float result = *( float* )&e;
result = ( result + ( x / result ) ) / 2;
return ( result + ( x / result ) ) / 2;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static float Sqrt( float x )
{
return MathF.Sqrt( x );
/**/
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static double Sqrt( double x )
{
return System.Math.Sqrt( x );
}
}
}
-46
View File
@@ -1,46 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Tan.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Math
{
public static partial class Scaler
{
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static float Tan( float x )
{
return MathF.Tan( x );
}
}
}
@@ -31,6 +31,7 @@
using StgSharp.Graphics;
using StgSharp.Graphics.OpenGL;
using StgSharp.Graphics.ShaderEdit;
using StgSharp.HighPerformance;
using StgSharp.Mathematics;
using System;
@@ -155,9 +156,7 @@ namespace StgSharp.Graphics
public void SetViewDirection(Vec3 position, Vec3 target, Vec3 up)
{
Vec3 direction = position - target;
if ((position.reg == cameraAtt.colum3.reg) &&
(this.up == up) &&
(cameraAtt.colum2.reg == direction.reg)) {
if ((position.reg == cameraAtt.colum3.reg) && (this.up == up) && (cameraAtt.colum2.reg == direction.reg)) {
return;
}
if (direction.GetLength() == 0)
@@ -187,11 +186,7 @@ namespace StgSharp.Graphics
InternalYaw();
}
public void SetViewRange(
Radius fovRadius,
Vec2 size,
Vec2 offset,
(float front, float back) dephRange)
public void SetViewRange(Radius fovRadius, Vec2 size, Vec2 offset, (float front, float back) dephRange)
{
float
distance = _target.GetLength(),
@@ -260,6 +255,7 @@ namespace StgSharp.Graphics
internal void InternalPitch()
{
/*
_isLookAtAvailable = false;
Matrix32 partialCoord = new Matrix32(cameraAtt.colum1.vec, cameraAtt.colum2.vec);
@@ -272,10 +268,12 @@ namespace StgSharp.Graphics
rotationAtt.colum1.reg = partialCoord.colum0.reg;
rotationAtt.colum2.reg = partialCoord.colum1.reg;
rotationAtt.isTransposed = false;
/**/
}
internal void InternalRow()
{
/*
_isLookAtAvailable = false;
Matrix32 partialCoord = new Matrix32(cameraAtt.colum0.vec, cameraAtt.colum1.vec);
@@ -288,10 +286,12 @@ namespace StgSharp.Graphics
rotationAtt.colum0.reg = partialCoord.colum0.reg;
rotationAtt.colum1.reg = partialCoord.colum1.reg;
rotationAtt.isTransposed = false;
*/
}
internal void InternalYaw()
{
/*
_isLookAtAvailable = false;
Matrix32 partialCoord = new Matrix32(cameraAtt.colum0.vec, cameraAtt.colum2.vec);
@@ -303,6 +303,7 @@ namespace StgSharp.Graphics
rotationAtt.colum0.reg = partialCoord.colum0.reg;
rotationAtt.colum2.reg = partialCoord.colum1.reg;
rotationAtt.isTransposed = false;
*/
}
#endregion
+165 -21
View File
@@ -29,47 +29,191 @@
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.HighPerformance;
using StgSharp.HighPerformance.Memory;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using hlsfHandle = StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle;
using hlsfAllocator = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocator;
using hlsfHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle;
namespace StgSharp.Mathematics
{
public abstract unsafe partial class Matrix<T> where T: unmanaged, INumber<T>
{
public abstract ref float this[int column, int row]
private protected readonly int t_count = 16 / sizeof(T);
private protected readonly int t_size = sizeof(T);
private protected Matrix() { }
public abstract ref T this[int column, int row]
{
get;
}
public abstract MatrixKernel* GetMatrixKernel(int column, int row);
public abstract unsafe Matrix<T> this[ReadOnlySpan<MatrixIndex> column, ReadOnlySpan<MatrixIndex> row]
{
get;
set;
}
public static hlsfAllocator? DefaultAllocator
{
get
{
ArgumentNullException.ThrowIfNull(field, nameof(DefaultAllocator));
return null;
}
set;
} = null;
public int ColumnLength { get; init; }
public int RowLength { get; init; }
public static MatrixAllocation DefaultAllocation { get; set; } = MatrixAllocation.GC;
protected int KernelColumnLength { get; init; }
protected int KernelRowLength { get; init; }
public static Matrix<T> FromDefault(int columnLength, int rowLength)
{
return DefaultAllocation switch
{
MatrixAllocation.GC => FromGC(columnLength, rowLength),
MatrixAllocation.HLSF => FromHlsf(columnLength, rowLength, DefaultAllocator!),
_ => throw new NotSupportedException("This allocation is not supported."),
};
}
public static Matrix<T> FromGC(int columnLength, int rowLength)
{
return new GCMatrix<T>(columnLength, rowLength);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix<T> FromHlsf(int columnLength, int rowLength, hlsfAllocator allocator)
{
return new HlsfMatrix<T>(columnLength, rowLength, allocator);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public abstract MatrixSegmentEnumeration GetColumnEnumeration();
public abstract ref MatrixKernel GetMatrixKernel(int column, int row);
public abstract MatrixSegmentEnumeration GetRowEnumeration();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public abstract MatrixSegmentEnumeration GetSequentialEnumeration();
[Obsolete("This method does not contain boarder check, so be careful on size or use indexer instead.", false)]
public abstract T* UnsafeIndex(int column, int row);
public abstract ref T UnsafeIndex(int column, int row);
}
private unsafe class HlsfMatrix<T> : Matrix<T> where T : unmanaged, INumber<T>
{
public override ref float this[int column, int row] => throw new NotImplementedException();
public override unsafe MatrixKernel* GetMatrixKernel(int column, int row)
private protected void AssertIndex(int column, int row)
{
throw new NotImplementedException();
if (column < 0 || column >= ColumnLength) {
throw new ArgumentOutOfRangeException(nameof(column));
}
if (row < 0 || row >= RowLength) {
throw new ArgumentOutOfRangeException(nameof(row));
}
}
public override unsafe T* UnsafeIndex(int column, int row)
public readonly unsafe ref struct MatrixSegmentEnumeration(
MatrixKernel* source,
int stride,
int size,
int secondaryStride,
int secondarySize)
{
throw new NotImplementedException();
private readonly MatrixKernel* _source = source;
private readonly int _secondarySize = secondarySize;
private readonly int _secondaryStride = secondaryStride;
private readonly int _size = size;
private readonly int _stride = stride;
public Enumerator GetEnumerator()
{
return new Enumerator(in this);
}
public ref struct Enumerator(in MatrixSegmentEnumeration enumeration)
{
private MatrixKernel* _current = enumeration._source - enumeration._stride;
private readonly MatrixKernel* _end = enumeration._source + enumeration._size;
private readonly int _secondarySize = enumeration._secondarySize;
private readonly int _secondaryStride = enumeration._secondaryStride;
private readonly int _stride = enumeration._stride;
public readonly Segment Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new(_current, _secondarySize, _secondaryStride);
}
public bool MoveNext()
{
_current += _stride;
return _current < _end;
}
}
}
public readonly unsafe ref struct Segment(MatrixKernel* source, int size, int stride)
{
private readonly MatrixKernel* _source = source;
private readonly int _size = size;
private readonly int _stride = stride;
public ref MatrixKernel this[int index]
{
get
{
if (index < 0 || index >= _size) {
throw new ArgumentOutOfRangeException(nameof(index));
}
return ref _source[index * _stride];
}
}
public Enumerator GetEnumerator()
{
return new Enumerator(_source, _size, _stride);
}
public ref struct Enumerator(MatrixKernel* source, int count, int stride)
{
private readonly MatrixKernel* _end = source + (count * stride);
private readonly int _stride = stride;
public MatrixKernel* Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private set;
} = source - stride;
public bool MoveNext()
{
Current += _stride;
return Current < _end;
}
}
}
}
}
@@ -1,177 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Matrix22.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
[StructLayout(LayoutKind.Explicit, Size = (2 * 2 * 4 * sizeof(float)) + sizeof(bool), Pack = 16)]
public struct Matrix22 : IMatrix<Matrix22>
{
[FieldOffset(2 * 2 * 4 * sizeof(float))]
internal bool isTransposed = false;
[FieldOffset(0)]
internal ColumnSet2 _mat;
[FieldOffset(2 * 4 * sizeof(float))]
internal ColumnSet2 _transpose;
internal Matrix22(ColumnSet2 mat)
{
this._mat = mat;
}
internal Matrix22(Vector4 c0, Vector4 c1)
{
Unsafe.SkipInit(out this);
isTransposed = false;
_mat.colum0 = c0;
_mat.colum1 = c1;
}
public Matrix22()
{
Unsafe.SkipInit(out this);
isTransposed = false;
}
public Matrix22(float a00, float a01, float a10, float a11)
{
Unsafe.SkipInit(out this);
isTransposed = false;
_mat.colum0 = new Vector4(a00, a10, 0, 0);
_mat.colum1 = new Vector4(a01, a11, 0, 0);
}
public Matrix22 Transpose
{
get
{
InternalTranspose();
return new Matrix22(this._transpose);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float Det()
{
return (_mat.m00 * _mat.m11) - (_mat.m10 * _mat.m01);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void InternalTranspose()
{
if (!isTransposed)
{
_transpose = _mat;
float cache = _transpose.m10;
_transpose.m10 = _transpose.m01;
_transpose.m01 = cache;
isTransposed = true;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Matrix22 operator -(Matrix22 left, Matrix22 right)
{
Matrix22 ret = new Matrix22();
InternalIO.Intrinsic.sub_mat_2(&left._mat, &right._mat, &ret._mat);
return ret;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix22 operator *(Matrix22 mat, float value)
{
return new Matrix22(mat._mat.colum0 * value, mat._mat.colum1 * value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix22 operator *(Matrix22 left, Matrix22 right)
{
left.InternalTranspose();
return new Matrix22(
Vector4.Dot(left._transpose.colum0, right._mat.colum0),
Vector4.Dot(left._transpose.colum0, right._mat.colum1),
Vector4.Dot(left._transpose.colum1, right._mat.colum0),
Vector4.Dot(left._transpose.colum1, right._mat.colum1));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix23 operator *(Matrix22 left, Matrix23 right)
{
left.InternalTranspose();
return new Matrix23(
Vector4.Dot(left._transpose.colum0, right._mat.colum0),
Vector4.Dot(left._transpose.colum0, right._mat.colum1),
Vector4.Dot(left._transpose.colum0, right._mat.colum2),
Vector4.Dot(left._transpose.colum1, right._mat.colum0),
Vector4.Dot(left._transpose.colum1, right._mat.colum1),
Vector4.Dot(left._transpose.colum1, right._mat.colum2));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix24 operator *(Matrix22 left, Matrix24 right)
{
left.InternalTranspose();
return new Matrix24(
Vector4.Dot(left._transpose.colum0, right.mat.colum0),
Vector4.Dot(left._transpose.colum0, right.mat.colum1),
Vector4.Dot(left._transpose.colum0, right.mat.colum2),
Vector4.Dot(left._transpose.colum0, right.mat.colum3),
Vector4.Dot(left._transpose.colum1, right.mat.colum0),
Vector4.Dot(left._transpose.colum1, right.mat.colum1),
Vector4.Dot(left._transpose.colum1, right.mat.colum2),
Vector4.Dot(left._transpose.colum1, right.mat.colum3));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix22 operator /(Matrix22 mat, float value)
{
return new Matrix22(mat._mat.colum0 / value, mat._mat.colum1 / value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Matrix22 operator +(Matrix22 left, Matrix22 right)
{
Matrix22 ret = new Matrix22();
InternalIO.Intrinsic.add_mat_2(&left._mat, &right._mat, &ret._mat);
return ret;
}
}
}
@@ -1,195 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix23.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
[StructLayout(
LayoutKind.Explicit,
Size = ( ( 3 + 2 ) * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix23 : IMatrix<Matrix23>
{
[FieldOffset( 5 * 4 * sizeof( float ) )] internal bool isTransposed = false;
[FieldOffset( 3 * 4 * sizeof( float ) )] internal ColumnSet2 _transpose;
[FieldOffset( 0 )] internal ColumnSet3 _mat;
internal Matrix23( Vector4 c0, Vector4 c1, Vector4 c2 )
{
_mat.colum0 = c0;
_mat.colum1 = c1;
_mat.colum2 = c2;
}
public Matrix23()
{
Unsafe.SkipInit( out _mat );
Unsafe.SkipInit( out _transpose );
}
public Matrix23( float a00, float a01, float a02, float a10, float a11, float a12 )
{
_mat.colum0 = new Vector4( a00, a10, 0, 0 );
_mat.colum1 = new Vector4( a01, a11, 0, 0 );
_mat.colum2 = new Vector4( a02, a12, 0, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 1 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this._transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 1 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this._transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet3* source = &this._mat )
{
fixed( ColumnSet2* target = &this._transpose ) {
InternalIO.Intrinsic.transpose32( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix23 operator -( Matrix23 left, Matrix23 right )
{
Matrix23 ret = new Matrix23();
InternalIO.Intrinsic.sub_mat_3( &left._mat, &right._mat, &ret._mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix23 operator *( Matrix23 mat, float value )
{
return new Matrix23(
mat._mat.colum0 * value, mat._mat.colum1 * value, mat._mat.colum2 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix22 operator *( Matrix23 left, Matrix32 right )
{
left.InternalTranspose();
return new Matrix22(
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix23 operator *( Matrix23 left, Matrix33 right )
{
left.InternalTranspose();
return new Matrix23(
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix24 operator *( Matrix23 left, Matrix34 right )
{
left.InternalTranspose();
return new Matrix24(
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left._transpose.colum0, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix23 operator /( Matrix23 mat, float value )
{
return new Matrix23(
mat._mat.colum0 / value, mat._mat.colum1 / value, mat._mat.colum2 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix23 operator +( Matrix23 left, Matrix23 right )
{
Matrix23 ret = new Matrix23();
InternalIO.Intrinsic.add_mat_3( &left._mat, &right._mat, &ret._mat );
return ret;
}
}
}
@@ -1,223 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix24.cs"
// Project: World
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
[StructLayout(
LayoutKind.Explicit,
Size = ( ( 4 + 2 ) * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix24 : IMatrix<Matrix24>
{
[FieldOffset( 6 * 4 * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 4 * 4 * sizeof( float ) )] internal ColumnSet2 transpose;
[FieldOffset( 0 )] internal ColumnSet4 mat;
[FieldOffset( 0 )] public Vec2 Colum0;
[FieldOffset( 16 )] public Vec2 Colum1;
[FieldOffset( 32 )] public Vec2 Colum2;
[FieldOffset( 48 )] public Vec2 Colum3;
internal Matrix24( Vector4 c0, Vector4 c1, Vector4 c2, Vector4 c3 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
mat.colum2 = c2;
mat.colum3 = c3;
}
public Matrix24()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix24(
float a00,
float a01,
float a02,
float a03,
float a10,
float a11,
float a12,
float a13 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, 0, 0 );
mat.colum1 = new Vector4( a01, a11, 0, 0 );
mat.colum2 = new Vector4( a02, a12, 0, 0 );
mat.colum3 = new Vector4( a03, a13, 0, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 1 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 ) {
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 1 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 ) {
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
public override string ToString()
{
InternalTranspose();
return $"{$"[{mat.m00},{mat.m01},{mat.m02},{mat.m03}],"}{$"[{mat.m10},{mat.m11},{mat.m12},{mat.m13}]"}";
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed ) {
fixed( ColumnSet4* source = &this.mat ) {
fixed( ColumnSet2* target = &this.transpose ) {
InternalIO.Intrinsic.transpose42( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix24 operator -(
Matrix24 left,
Matrix24 right )
{
Matrix24 ret = new Matrix24();
InternalIO.Intrinsic.sub_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix24 operator *( Matrix24 mat, float value )
{
return new Matrix24(
mat.mat.colum0 * value, mat.mat.colum1 * value,
mat.mat.colum2 * value, mat.mat.colum3 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix22 operator *( Matrix24 left, Matrix42 right )
{
left.InternalTranspose();
return new Matrix22(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix23 operator *( Matrix24 left, Matrix43 right )
{
left.InternalTranspose();
return new Matrix23(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix24 operator *( Matrix24 left, Matrix44 right )
{
left.InternalTranspose();
return new Matrix24(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix24 operator /( Matrix24 mat, float value )
{
return new Matrix24(
mat.mat.colum0 / value, mat.mat.colum1 / value,
mat.mat.colum2 / value, mat.mat.colum3 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix24 operator +(
Matrix24 left,
Matrix24 right )
{
Matrix24 ret = new Matrix24();
InternalIO.Intrinsic.add_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}
@@ -1,215 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix32.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
[StructLayout(
LayoutKind.Explicit,
Size = ( 5 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix32 : IMatrix<Matrix32>
{
[FieldOffset( 5 * 4 * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 0 )] internal ColumnSet2 mat;
[FieldOffset( 2 * 4 * sizeof( float ) )] internal ColumnSet3 transpose;
[FieldOffset( 0 )] internal Vec3 colum0;
[FieldOffset( 4 * 4 )] internal Vec3 colum1;
internal Matrix32( Vector4 c0, Vector4 c1 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
}
public Matrix32()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public unsafe Matrix32( float a00, float a01, float a10, float a11, float a20, float a21 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, 0 );
mat.colum1 = new Vector4( a01, a11, a21, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 1 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 1 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
public Vec3 VerticalVecMultiply( Vec2 vec )
{
return ( colum0 * vec.X ) + ( colum1 * vec.Y );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet2* source = &this.mat )
{
fixed( ColumnSet3* target = &this.transpose ) {
InternalIO.Intrinsic.transpose23( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator -( Matrix32 left, Matrix32 right )
{
return new Matrix32(
left.mat.colum0 - right.mat.colum0, left.mat.colum1 - right.mat.colum1 );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator *( Matrix32 mat, float value )
{
return new Matrix32( mat.mat.colum0 * value, mat.mat.colum1 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator *( Matrix32 left, Matrix22 right )
{
left.InternalTranspose();
return new Matrix32(
Vector4.Dot( left.transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator *( Matrix32 left, Matrix23 right )
{
left.InternalTranspose();
return new Matrix33(
Vector4.Dot( left.transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator *( Matrix32 left, Matrix24 right )
{
left.InternalTranspose();
return new Matrix34(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator /( Matrix32 mat, float value )
{
return new Matrix32( mat.mat.colum0 / value, mat.mat.colum1 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix32 operator +( Matrix32 left, Matrix32 right )
{
Matrix32 ret = new Matrix32();
InternalIO.Intrinsic.add_mat_2( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}
@@ -1,240 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix33.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
[StructLayout(
LayoutKind.Explicit,
Size = ( 6 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix33 : IMatrix<Matrix33>
{
[FieldOffset( 6 * 4 * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 0 )] internal ColumnSet3 mat;
[FieldOffset( 3 * 4 * sizeof( float ) )] internal ColumnSet3 transpose;
[FieldOffset( 0 * 4 * sizeof( float ) )] public Vec3 Colum0;
[FieldOffset( 1 * 4 * sizeof( float ) )] public Vec3 Colum1;
[FieldOffset( 2 * 4 * sizeof( float ) )] public Vec3 Colum2;
internal Matrix33( Vector4 c0, Vector4 c1, Vector4 c2 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
mat.colum2 = c2;
}
public Matrix33()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix33(
float a00,
float a01,
float a02,
float a10,
float a11,
float a12,
float a20,
float a21,
float a22 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, 0 );
mat.colum1 = new Vector4( a01, a11, a21, 0 );
mat.colum2 = new Vector4( a02, a12, a22, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 2 ) || ( columNum < 0 ) ) {
InternalIO.InternalWriteLog(
$"Attempt to write unused space in {GetType().Name} {nameof(mat)}",
LogType.Error );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public unsafe float Det()
{
fixed( ColumnSet3* mat = &this.mat ) {
return InternalIO.Intrinsic.det_mat_3( mat, ( ColumnSet3* )0 );
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet3* source = &this.mat, target = &this.transpose ) {
InternalIO.Intrinsic.transpose33( source, target );
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix33 operator -( Matrix33 left, Matrix33 right )
{
Matrix33 ret = new Matrix33();
InternalIO.Intrinsic.sub_mat_3( &left.mat, &right.mat, &ret.mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator *( Matrix33 mat, float value )
{
return new Matrix33(
mat.mat.colum0 * value, mat.mat.colum1 * value, mat.mat.colum2 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Vec3 operator *( Matrix33 left, Vec3 right )
{
left.InternalTranspose();
return new Vec3(
Vector4.Dot( left.transpose.colum0, right.reg.AsVector4() ),
Vector4.Dot( left.transpose.colum1, right.reg.AsVector4() ),
Vector4.Dot( left.transpose.colum2, right.reg.AsVector4() ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator *( Matrix33 left, Matrix32 right )
{
left.InternalTranspose();
return new Matrix32(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator *( Matrix33 left, Matrix33 right )
{
left.InternalTranspose();
return new Matrix33(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator *( Matrix33 left, Matrix34 right )
{
left.InternalTranspose();
return new Matrix34(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator /( Matrix33 mat, float value )
{
return new Matrix33(
mat.mat.colum0 / value, mat.mat.colum1 / value, mat.mat.colum2 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix33 operator +( Matrix33 left, Matrix33 right )
{
Matrix33 ret = new Matrix33();
InternalIO.Intrinsic.add_mat_3( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}
@@ -1,240 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix34.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Drawing;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
[StructLayout(
LayoutKind.Explicit,
Size = ( 7 * 4 * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix34 : IMatrix<Matrix34>
{
[FieldOffset( 7 * 4 * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 4 * 4 * sizeof( float ) )] internal ColumnSet3 transpose;
[FieldOffset( 0 )] internal ColumnSet4 mat;
[FieldOffset( 0 * 4 * sizeof( float ) )] public Vec3 Colum0;
[FieldOffset( 1 * 4 * sizeof( float ) )] public Vec3 Colum1;
[FieldOffset( 2 * 4 * sizeof( float ) )] public Vec3 Colum2;
[FieldOffset( 3 * 4 * sizeof( float ) )] public Vec3 Colum3;
internal Matrix34( ColumnSet4 mat )
{
Unsafe.SkipInit( out this );
isTransposed = false;
this.mat = mat;
}
internal Matrix34( Vector4 c0, Vector4 c1, Vector4 c2, Vector4 c3 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
mat.colum2 = c2;
mat.colum3 = c3;
}
public Matrix34()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix34(
float a00,
float a01,
float a02,
float a03,
float a10,
float a11,
float a12,
float a13,
float a20,
float a21,
float a22,
float a23 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, 0 );
mat.colum0 = new Vector4( a01, a11, a21, 0 );
mat.colum0 = new Vector4( a02, a12, a22, 0 );
mat.colum0 = new Vector4( a03, a13, a23, 0 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 2 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 3 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet4* source = &this.mat )
{
fixed( ColumnSet3* target = &this.transpose ) {
InternalIO.Intrinsic.transpose43( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix34 operator -( Matrix34 left, Matrix34 right )
{
Matrix34 ret = new Matrix34();
InternalIO.Intrinsic.sub_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator *( Matrix34 mat, float value )
{
return new Matrix34(
mat.mat.colum0 * value, mat.mat.colum1 * value, mat.mat.colum2 * value,
mat.mat.colum3 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix32 operator *( Matrix34 left, Matrix42 right )
{
left.InternalTranspose();
return new Matrix32(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix33 operator *( Matrix34 left, Matrix43 right )
{
left.InternalTranspose();
return new Matrix33(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator *( Matrix34 left, Matrix44 right )
{
left.InternalTranspose();
return new Matrix34(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum3 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum3 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix34 operator /( Matrix34 mat, float value )
{
return new Matrix34(
mat.mat.colum0 / value, mat.mat.colum1 / value, mat.mat.colum2 / value,
mat.mat.colum3 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix34 operator +( Matrix34 left, Matrix34 right )
{
Matrix34 ret = new Matrix34();
InternalIO.Intrinsic.add_mat_4( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}
@@ -1,240 +0,0 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Matrix42.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using StgSharp.Internal.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
[StructLayout(
LayoutKind.Explicit,
Size = ( ( 16 + 8 ) * sizeof( float ) ) + sizeof( bool ),
Pack = 16 )]
public struct Matrix42 : IMatrix<Matrix42>
{
[FieldOffset( ( 16 + 8 ) * sizeof( float ) )] internal bool isTransposed;
[FieldOffset( 0 )] internal ColumnSet2 mat;
[FieldOffset( 8 * sizeof( float ) )] internal ColumnSet4 transpose;
internal Matrix42( ColumnSet2 mat )
{
Unsafe.SkipInit( out this );
isTransposed = false;
this.mat = mat;
}
internal Matrix42( Vector4 c0, Vector4 c1 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = c0;
mat.colum1 = c1;
}
public Matrix42()
{
Unsafe.SkipInit( out this );
isTransposed = false;
}
public Matrix42(
float a00,
float a01,
float a10,
float a11,
float a20,
float a21,
float a30,
float a31 )
{
Unsafe.SkipInit( out this );
isTransposed = false;
mat.colum0 = new Vector4( a00, a10, a20, a30 );
mat.colum1 = new Vector4( a01, a11, a21, a31 );
}
public unsafe float this[ int rowNum, int columNum ]
{
get
{
if( ( rowNum > 3 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 1 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
return *( float* )pbit;
}
}
set
{
if( ( rowNum > 3 ) || ( rowNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
if( ( columNum > 1 ) || ( columNum < 0 ) ) {
throw new ArgumentOutOfRangeException( nameof( columNum ) );
}
InternalTranspose();
fixed( float* p = &this.transpose.m00 )
{
ulong pbit = ( ( ulong )p ) + ( ( ( ulong )sizeof( Vector4 ) ) * ( ( ulong )rowNum ) ) + ( ( ( ulong )sizeof( float ) ) * ( ( ulong )columNum ) );
*( float* )pbit = value;
}
isTransposed = false;
}
}
public override int GetHashCode()
{
return HashCode.Combine( mat.colum0.GetHashCode(), mat.colum1.GetHashCode() );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
internal unsafe void InternalTranspose()
{
if( !isTransposed )
{
fixed( ColumnSet2* source = &this.mat )
{
fixed( ColumnSet4* target = &this.transpose ) {
InternalIO.Intrinsic.transpose24( source, target );
}
}
isTransposed = true;
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix42 operator -( Matrix42 left, Matrix42 right )
{
Matrix42 ret = new Matrix42();
InternalIO.Intrinsic.sub_mat_2( &left.mat, &right.mat, &ret.mat );
return ret;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix42 operator *( Matrix42 mat, float value )
{
return new Matrix42( mat.mat.colum0 * value, mat.mat.colum1 * value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix42 operator *( Matrix42 left, Matrix22 right )
{
left.InternalTranspose();
return new Matrix42(
Vector4.Dot( left.transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum1 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix43 operator *( Matrix42 left, Matrix23 right )
{
left.InternalTranspose();
return new Matrix43(
Vector4.Dot( left.transpose.colum0, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right._mat.colum2 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right._mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix44 operator *( Matrix42 left, Matrix24 right )
{
left.InternalTranspose();
return new Matrix44(
Vector4.Dot( left.transpose.colum0, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum0, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum1, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum2, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum0 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum1 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum2 ),
Vector4.Dot( left.transpose.colum3, right.mat.colum2 ) );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static Matrix42 operator /( Matrix42 mat, float value )
{
return new Matrix42( mat.mat.colum0 / value, mat.mat.colum1 / value );
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static unsafe Matrix42 operator +( Matrix42 left, Matrix42 right )
{
Matrix42 ret = new Matrix42();
InternalIO.Intrinsic.add_mat_2( &left.mat, &right.mat, &ret.mat );
return ret;
}
}
}

Some files were not shown because too many files have changed in this diff Show More