Refactor and enhance math utilities and code generation
Refactored `StbImage` classes to be publicly accessible. Updated namespaces and introduced `NumericTypeAttribute` for metadata. Enhanced `VectorGenerator` with new utility methods (`any`, `all`, `length`, etc.) and improved code generation. Consolidated vector operations in `math` utilities. Refactored `Plane` and `svd` classes for better encapsulation and readability. Improved `DynamicArray` with `uint` indexer support and cleaner loops. Added SIMD-based benchmarking placeholders in `MathematicsBenchmark`. Removed redundant code and unused files, including `IUnsafeSet.cs`. Updated project file to include `CodeGen` as an analyzer. Introduced `SupportedVectorMath` and `SupportedMatrixMath` enums for better operation definitions. Improved code style, fixed minor bugs, and cleaned up unused code in `Program.cs`. Enhanced maintainability and readability across the codebase.
This commit is contained in:
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Image
|
namespace Misaki.HighPerformance.Image
|
||||||
{
|
{
|
||||||
unsafe partial class StbImage
|
public unsafe partial class StbImage
|
||||||
{
|
{
|
||||||
public static int stbi__bmp_test(stbi__context s)
|
public static int stbi__bmp_test(stbi__context s)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Image
|
namespace Misaki.HighPerformance.Image
|
||||||
{
|
{
|
||||||
unsafe partial class StbImage
|
public unsafe partial class StbImage
|
||||||
{
|
{
|
||||||
public const int STBI_default = 0;
|
public const int STBI_default = 0;
|
||||||
public const int STBI_grey = 1;
|
public const int STBI_grey = 1;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Image
|
namespace Misaki.HighPerformance.Image
|
||||||
{
|
{
|
||||||
unsafe partial class StbImage
|
public unsafe partial class StbImage
|
||||||
{
|
{
|
||||||
public static int stbi__gif_test(stbi__context s)
|
public static int stbi__gif_test(stbi__context s)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using Misaki.HighPerformance.Image.Runtime;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Image
|
namespace Misaki.HighPerformance.Image
|
||||||
{
|
{
|
||||||
unsafe partial class StbImage
|
public unsafe partial class StbImage
|
||||||
{
|
{
|
||||||
public static int stbi__hdr_test(stbi__context s)
|
public static int stbi__hdr_test(stbi__context s)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Image
|
namespace Misaki.HighPerformance.Image
|
||||||
{
|
{
|
||||||
unsafe partial class StbImage
|
public unsafe partial class StbImage
|
||||||
{
|
{
|
||||||
public delegate void delegate0(byte* arg0, int arg1, short* arg2);
|
public delegate void delegate0(byte* arg0, int arg1, short* arg2);
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Image
|
namespace Misaki.HighPerformance.Image
|
||||||
{
|
{
|
||||||
unsafe partial class StbImage
|
public unsafe partial class StbImage
|
||||||
{
|
{
|
||||||
public const int STBI__F_none = 0;
|
public const int STBI__F_none = 0;
|
||||||
public const int STBI__F_sub = 1;
|
public const int STBI__F_sub = 1;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using Misaki.HighPerformance.Image.Runtime;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Image
|
namespace Misaki.HighPerformance.Image
|
||||||
{
|
{
|
||||||
unsafe partial class StbImage
|
public unsafe partial class StbImage
|
||||||
{
|
{
|
||||||
public static int stbi__psd_test(stbi__context s)
|
public static int stbi__psd_test(stbi__context s)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using Misaki.HighPerformance.Image.Runtime;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Image
|
namespace Misaki.HighPerformance.Image
|
||||||
{
|
{
|
||||||
unsafe partial class StbImage
|
public unsafe partial class StbImage
|
||||||
{
|
{
|
||||||
public static int stbi__tga_test(stbi__context s)
|
public static int stbi__tga_test(stbi__context s)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Image
|
namespace Misaki.HighPerformance.Image
|
||||||
{
|
{
|
||||||
unsafe partial class StbImage
|
public unsafe partial class StbImage
|
||||||
{
|
{
|
||||||
public static byte[] stbi__zdefault_distance =
|
public static byte[] stbi__zdefault_distance =
|
||||||
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
|
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Drawing;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.LowLevel.Buffer;
|
namespace Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
namespace Misaki.HighPerformance.LowLevel.Collections.Contracts;
|
|
||||||
internal class IUnsafeSet<T>
|
|
||||||
where T : unmanaged, IEquatable<T>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -66,7 +66,7 @@ public unsafe interface IAllocator
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a reference to the allocation handle associated with this allocator.
|
/// Gets a reference to the allocation handle associated with this allocator.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ref AllocationHandle Handle
|
ref AllocationHandle Handle
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
|||||||
public KeyValuePair<TKey, TValue> GetCurrent<TValue>()
|
public KeyValuePair<TKey, TValue> GetCurrent<TValue>()
|
||||||
where TValue : unmanaged
|
where TValue : unmanaged
|
||||||
{
|
{
|
||||||
return new KeyValuePair<TKey, TValue>(buffer->_keys[index], UnsafeUtilities.ReadArrayElement<TValue>(buffer->_buffer, index));
|
return new KeyValuePair<TKey, TValue>(buffer->_keys[index], UnsafeUtilities.ReadArrayElementRef<TValue>(buffer->_buffer, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Microsoft.CodeAnalysis;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||||
@@ -11,6 +10,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{
|
{
|
||||||
private int _vectorBitsSize;
|
private int _vectorBitsSize;
|
||||||
private int _missingComponents;
|
private int _missingComponents;
|
||||||
|
private string _componentTypePrefix = null!;
|
||||||
|
|
||||||
private readonly List<(string signature, string assignment)> _constructorSignatures = new();
|
private readonly List<(string signature, string assignment)> _constructorSignatures = new();
|
||||||
|
|
||||||
@@ -34,6 +34,14 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
|
|
||||||
_vectorBitsSize = vectorBytesSize * 8;
|
_vectorBitsSize = vectorBytesSize * 8;
|
||||||
_missingComponents = (vectorBytesSize - typeSize) / componentSize;
|
_missingComponents = (vectorBytesSize - typeSize) / componentSize;
|
||||||
|
|
||||||
|
_componentTypePrefix = typeInfo.ComponentTypeSymbol.SpecialType switch
|
||||||
|
{
|
||||||
|
SpecialType.System_UInt16 or SpecialType.System_UInt32 or SpecialType.System_UInt64 => "u",
|
||||||
|
SpecialType.System_Single => "f",
|
||||||
|
SpecialType.System_Double => "d",
|
||||||
|
_ => string.Empty
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void GenerateBody()
|
protected override void GenerateBody()
|
||||||
@@ -426,8 +434,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator +({typeName} lhs, {typeName} rhs)
|
public static {typeName} operator +({typeName} lhs, {typeName} rhs)
|
||||||
{{
|
{{
|
||||||
var vector = lhs.AsVector{_vectorBitsSize}() + rhs.AsVector{_vectorBitsSize}();
|
return (lhs.AsVector{_vectorBitsSize}() + rhs.AsVector{_vectorBitsSize}()).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
@@ -462,8 +469,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator -({typeName} lhs, {typeName} rhs)
|
public static {typeName} operator -({typeName} lhs, {typeName} rhs)
|
||||||
{{
|
{{
|
||||||
var vector = lhs.AsVector{_vectorBitsSize}() - rhs.AsVector{_vectorBitsSize}();
|
return (lhs.AsVector{_vectorBitsSize}() - rhs.AsVector{_vectorBitsSize}()).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
@@ -498,15 +504,13 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator *({typeName} lhs, {typeName} rhs)
|
public static {typeName} operator *({typeName} lhs, {typeName} rhs)
|
||||||
{{
|
{{
|
||||||
var vector = lhs.AsVector{_vectorBitsSize}() * rhs.AsVector{_vectorBitsSize}();
|
return (lhs.AsVector{_vectorBitsSize}() * rhs.AsVector{_vectorBitsSize}()).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator *({typeName} lhs, {componentType} rhs)
|
public static {typeName} operator *({typeName} lhs, {componentType} rhs)
|
||||||
{{
|
{{
|
||||||
var vector = lhs.AsVector{_vectorBitsSize}() * rhs;
|
return (lhs.AsVector{_vectorBitsSize}() * rhs).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
@@ -535,15 +539,13 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator /({typeName} lhs, {typeName} rhs)
|
public static {typeName} operator /({typeName} lhs, {typeName} rhs)
|
||||||
{{
|
{{
|
||||||
var vector = lhs.AsVector{_vectorBitsSize}() / rhs.AsVector{_vectorBitsSize}();
|
return (lhs.AsVector{_vectorBitsSize}() / rhs.AsVector{_vectorBitsSize}()).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator /({typeName} lhs, {componentType} rhs)
|
public static {typeName} operator /({typeName} lhs, {componentType} rhs)
|
||||||
{{
|
{{
|
||||||
var vector = lhs.AsVector{_vectorBitsSize}() / rhs;
|
return (lhs.AsVector{_vectorBitsSize}() / rhs).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
@@ -613,22 +615,19 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator -({typeName} value)
|
public static {typeName} operator -({typeName} value)
|
||||||
{{
|
{{
|
||||||
var vector = -value.AsVector{_vectorBitsSize}();
|
return (-value.AsVector{_vectorBitsSize}()).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator ++({typeName} value)
|
public static {typeName} operator ++({typeName} value)
|
||||||
{{
|
{{
|
||||||
var vector = value.AsVector{_vectorBitsSize}() + global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Create<{componentType}>(1);
|
return (value.AsVector{_vectorBitsSize}() + global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.CreateScalar(1{_componentTypePrefix})).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator --({typeName} value)
|
public static {typeName} operator --({typeName} value)
|
||||||
{{
|
{{
|
||||||
var vector = value.AsVector{_vectorBitsSize}() - global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Create<{componentType}>(1);
|
return (value.AsVector{_vectorBitsSize}() - global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.CreateScalar(1{_componentTypePrefix})).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
// Comparison operators
|
// Comparison operators
|
||||||
@@ -666,36 +665,31 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator <<({typeName} x, int n)
|
public static {typeName} operator <<({typeName} x, int n)
|
||||||
{{
|
{{
|
||||||
var vector = x.AsVector{_vectorBitsSize}() << n;
|
return (x.AsVector{_vectorBitsSize}() << n).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator >>({typeName} x, int n)
|
public static {typeName} operator >>({typeName} x, int n)
|
||||||
{{
|
{{
|
||||||
var vector = x.AsVector{_vectorBitsSize}() >> n;
|
return (x.AsVector{_vectorBitsSize}() >> n).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator &({typeName} lhs, {typeName} rhs)
|
public static {typeName} operator &({typeName} lhs, {typeName} rhs)
|
||||||
{{
|
{{
|
||||||
var vector = global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.BitwiseAnd(lhs.AsVector{_vectorBitsSize}(), rhs.AsVector{_vectorBitsSize}());
|
return (global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.BitwiseAnd(lhs.AsVector{_vectorBitsSize}(), rhs.AsVector{_vectorBitsSize}())).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator |({typeName} lhs, {typeName} rhs)
|
public static {typeName} operator |({typeName} lhs, {typeName} rhs)
|
||||||
{{
|
{{
|
||||||
var vector = global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.BitwiseOr(lhs.AsVector{_vectorBitsSize}(), rhs.AsVector{_vectorBitsSize}());
|
return (global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.BitwiseOr(lhs.AsVector{_vectorBitsSize}(), rhs.AsVector{_vectorBitsSize}())).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} operator ^({typeName} lhs, {typeName} rhs)
|
public static {typeName} operator ^({typeName} lhs, {typeName} rhs)
|
||||||
{{
|
{{
|
||||||
var vector = global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Xor(lhs.AsVector{_vectorBitsSize}(), rhs.AsVector{_vectorBitsSize}());
|
return (global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Xor(lhs.AsVector{_vectorBitsSize}(), rhs.AsVector{_vectorBitsSize}())).{asResult};
|
||||||
return vector.{asResult};
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
@@ -775,15 +769,15 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
|
|
||||||
private void GenerateVectorExtension()
|
private void GenerateVectorExtension()
|
||||||
{
|
{
|
||||||
var typeName = typeInfo.TypeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
var typeName = typeInfo.TypeFullName;
|
||||||
var typeSimpleName = typeInfo.TypeSymbol.Name;
|
var typeSimpleName = typeInfo.TypeName;
|
||||||
var componentType = typeInfo.ComponentTypeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
var componentType = typeInfo.ComponentTypeFullName;
|
||||||
|
|
||||||
sourceBuilder.Append($@"
|
sourceBuilder.Append($@"
|
||||||
public static partial class VectorInterop
|
public static partial class VectorInterop
|
||||||
{{
|
{{
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}<{componentType}> AsVector{_vectorBitsSize}(ref this {typeName} value)
|
public unsafe static global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}<{componentType}> AsVector{_vectorBitsSize}(this {typeName} value)
|
||||||
{{");
|
{{");
|
||||||
|
|
||||||
if (typeInfo.Row == 4)
|
if (typeInfo.Row == 4)
|
||||||
@@ -794,13 +788,13 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sourceBuilder.Append($@"
|
sourceBuilder.Append($@"
|
||||||
return global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Create({string.Join(", ", Enumerable.Range(0, typeInfo.Row + _missingComponents).Select(i => i < typeInfo.Row ? $"value.{s_vectorComponents[i]}" : "1"))});");
|
return global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Create({string.Join(", ", Enumerable.Range(0, typeInfo.Row + _missingComponents).Select(i => i < typeInfo.Row ? $"value.{s_vectorComponents[i]}" : "0"))});");
|
||||||
}
|
}
|
||||||
sourceBuilder.Append($@"
|
sourceBuilder.Append($@"
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeName} As{typeSimpleName}(ref this global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}<{componentType}> value)
|
public unsafe static {typeName} As{typeSimpleName}(this global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}<{componentType}> value)
|
||||||
{{");
|
{{");
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
ref var address = ref global::System.Runtime.CompilerServices.Unsafe.As<global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}<{componentType}>, byte>(ref value);
|
ref var address = ref global::System.Runtime.CompilerServices.Unsafe.As<global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}<{componentType}>, byte>(ref value);
|
||||||
@@ -809,9 +803,9 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
}}");
|
}}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private string PerComponentAssignments(Func<string, string> func)
|
private string ComponentwiseAssignments(Func<string, string> func, string separator = ", ")
|
||||||
{
|
{
|
||||||
return string.Join(", ", s_vectorComponents.Take(typeInfo.Row).Select(func));
|
return string.Join(separator, s_vectorComponents.Take(typeInfo.Row).Select(func));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateMathMethod()
|
private void GenerateMathMethod()
|
||||||
@@ -888,16 +882,31 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
}}
|
}}
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
|
if (typeInfo.ComponentTypeSymbol.SpecialType == SpecialType.System_Boolean)
|
||||||
|
{
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Returns true if any component of the input {typeName} vector is true, false otherwise.</summary>
|
||||||
|
/// <param name=""v"">Vector of values to compare.</param>
|
||||||
|
/// <returns>True if any the components of v are true, false otherwise.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static bool any({typeFullName} v)
|
||||||
|
{{
|
||||||
|
return {ComponentwiseAssignments(c => $"v.{c}", " ||")};
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Returns true if all component of the input {typeName} vector is true, false otherwise.</summary>
|
||||||
|
/// <param name=""v"">Vector of values to compare.</param>
|
||||||
|
/// <returns>True if all the components of v are true, false otherwise.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static bool all({typeFullName} v)
|
||||||
|
{{
|
||||||
|
return {ComponentwiseAssignments(c => $"v.{c}", " && ")};
|
||||||
|
}}");
|
||||||
|
}
|
||||||
|
|
||||||
if (typeInfo.Arithmetic)
|
if (typeInfo.Arithmetic)
|
||||||
{
|
{
|
||||||
var componentTypePrefix = typeInfo.ComponentTypeSymbol.SpecialType switch
|
|
||||||
{
|
|
||||||
SpecialType.System_UInt16 or SpecialType.System_UInt32 or SpecialType.System_UInt64 => "u",
|
|
||||||
SpecialType.System_Single => "f",
|
|
||||||
SpecialType.System_Double => "d",
|
|
||||||
_ => string.Empty
|
|
||||||
};
|
|
||||||
|
|
||||||
StartRegion("Math Methods");
|
StartRegion("Math Methods");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -982,7 +991,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} select({typeFullName} falseValue, {typeFullName} trueValue, global::Misaki.HighPerformance.Mathematics.bool{typeInfo.Row} test)
|
public static {typeFullName} select({typeFullName} falseValue, {typeFullName} trueValue, global::Misaki.HighPerformance.Mathematics.bool{typeInfo.Row} test)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"test.{c} ? trueValue.{c} : falseValue.{c}")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"test.{c} ? trueValue.{c} : falseValue.{c}")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
if (typeInfo.ComponentTypeSymbol.SpecialType != SpecialType.System_UInt16
|
if (typeInfo.ComponentTypeSymbol.SpecialType != SpecialType.System_UInt16
|
||||||
@@ -996,21 +1005,42 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} sign({typeFullName} v)
|
public static {typeFullName} sign({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"sign(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"sign(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Returns true if any component of the input {typeName} vector is true, false otherwise.</summary>
|
||||||
|
/// <param name=""v"">Vector of values to compare.</param>
|
||||||
|
/// <returns>True if any the components of v are true, false otherwise.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static bool any({typeFullName} v)
|
||||||
|
{{
|
||||||
|
return {ComponentwiseAssignments(c => $"v.{c} != 0", " || ")};
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Returns true if all component of the input {typeName} vector is true, false otherwise.</summary>
|
||||||
|
/// <param name=""v"">Vector of values to compare.</param>
|
||||||
|
/// <returns>True if all the components of v are true, false otherwise.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static bool all({typeFullName} v)
|
||||||
|
{{
|
||||||
|
return {ComponentwiseAssignments(c => $"v.{c} != 0", " && ")};
|
||||||
|
}}");
|
||||||
|
|
||||||
// Only floating point types support these methods
|
// Only floating point types support these methods
|
||||||
if (typeInfo.ComponentTypeSymbol.SpecialType == SpecialType.System_Single || typeInfo.ComponentTypeSymbol.SpecialType == SpecialType.System_Double)
|
if (typeInfo.ComponentTypeSymbol.SpecialType == SpecialType.System_Single
|
||||||
|
|| typeInfo.ComponentTypeSymbol.SpecialType == SpecialType.System_Double)
|
||||||
{
|
{
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
/// <summary>Returns the result of a componentwise clamping of the {typeFullName} vector v into the interval [0, 1].</summary>
|
/// <summary>Returns the result of a componentwise clamping of the {typeName} vector v into the interval [0, 1].</summary>
|
||||||
/// <param name=""v"">Input value.</param>
|
/// <param name=""v"">Input value.</param>
|
||||||
/// <returns>The componentwise clamping of the input into the interval [0, 1].</returns>
|
/// <returns>The componentwise clamping of the input into the interval [0, 1].</returns>
|
||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} saturate({typeFullName} v)
|
public static {typeFullName} saturate({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return clamp(v, new {typeFullName}(0{componentTypePrefix}), new {typeFullName}(1{componentTypePrefix}));
|
return clamp(v, new {typeFullName}(0{_componentTypePrefix}), new {typeFullName}(1{_componentTypePrefix}));
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1090,7 +1120,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} tan({typeFullName} v)
|
public static {typeFullName} tan({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"tan(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"tan(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1100,7 +1130,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} tanh({typeFullName} v)
|
public static {typeFullName} tanh({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"tanh(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"tanh(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1110,7 +1140,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} atan({typeFullName} v)
|
public static {typeFullName} atan({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"atan(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"atan(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1121,7 +1151,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} atan2({typeFullName} x, {typeFullName} y)
|
public static {typeFullName} atan2({typeFullName} x, {typeFullName} y)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"atan2(x.{c}, y.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"atan2(x.{c}, y.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1142,7 +1172,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} cosh({typeFullName} v)
|
public static {typeFullName} cosh({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"cosh(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"cosh(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1152,7 +1182,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} acos({typeFullName} v)
|
public static {typeFullName} acos({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"acos(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"acos(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1173,7 +1203,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} sinh({typeFullName} v)
|
public static {typeFullName} sinh({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"sinh(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"sinh(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1183,7 +1213,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} asin({typeFullName} v)
|
public static {typeFullName} asin({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"asin(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"asin(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1226,7 +1256,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} round({typeFullName} v)
|
public static {typeFullName} round({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"round(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"round(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1247,7 +1277,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} exp2({typeFullName} v)
|
public static {typeFullName} exp2({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
var vector = global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Exp(v.AsVector{_vectorBitsSize}() * 0.693147180559945309{componentTypePrefix});
|
var vector = global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Exp(v.AsVector{_vectorBitsSize}() * 0.693147180559945309{_componentTypePrefix});
|
||||||
return vector.As{typeName}();
|
return vector.As{typeName}();
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
@@ -1258,7 +1288,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} exp10({typeFullName} v)
|
public static {typeFullName} exp10({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
var vector = global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Exp(v.AsVector{_vectorBitsSize}() * 2.302585092994045684{componentTypePrefix});
|
var vector = global::System.Runtime.Intrinsics.Vector{_vectorBitsSize}.Exp(v.AsVector{_vectorBitsSize}() * 2.302585092994045684{_componentTypePrefix});
|
||||||
return vector.As{typeName}();
|
return vector.As{typeName}();
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
@@ -1291,7 +1321,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} log10({typeFullName} v)
|
public static {typeFullName} log10({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"log10(v.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"log10(v.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1312,7 +1342,49 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} rsqrt({typeFullName} v)
|
public static {typeFullName} rsqrt({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return 1{componentTypePrefix} / sqrt(v);
|
return 1{_componentTypePrefix} / sqrt(v);
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Returns the length of a {typeName} vector.</summary>
|
||||||
|
/// <param name=""v"">Vector to use when computing length.</param>
|
||||||
|
/// <returns>Length of vector v.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static {componentTypeFullName} length({typeFullName} v)
|
||||||
|
{{
|
||||||
|
return sqrt(dot(v, v));
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Returns the squared length of a {typeName} vector.</summary>
|
||||||
|
/// <param name=""v"">Vector to use when computing squared length.</param>
|
||||||
|
/// <returns>Squared length of vector v.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static {componentTypeFullName} lengthsq({typeFullName} v)
|
||||||
|
{{
|
||||||
|
return dot(v, v);
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Returns the distance between two {typeName} vectors.</summary>
|
||||||
|
/// <param name=""x"">First vector to use in distance computation.</param>
|
||||||
|
/// <param name=""y"">Second vector to use in distance computation.</param>
|
||||||
|
/// <returns>The distance between x and y.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static {componentTypeFullName} distance({typeFullName} x, {typeFullName} y)
|
||||||
|
{{
|
||||||
|
return length(y - x);
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Returns the squared distance between two {typeName} vectors.</summary>
|
||||||
|
/// <param name=""x"">First vector to use in distance computation.</param>
|
||||||
|
/// <param name=""y"">Second vector to use in distance computation.</param>
|
||||||
|
/// <returns>The squared distance between x and y.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static {componentTypeFullName} distancesq({typeFullName} x, {typeFullName} y)
|
||||||
|
{{
|
||||||
|
return lengthsq(y - x);
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1343,7 +1415,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} rcp({typeFullName} v)
|
public static {typeFullName} rcp({typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return 1{componentTypePrefix} / v;
|
return 1{_componentTypePrefix} / v;
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1354,7 +1426,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} pow({typeFullName} x, {typeFullName} y)
|
public static {typeFullName} pow({typeFullName} x, {typeFullName} y)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"pow(x.{c}, y.{c})")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"pow(x.{c}, y.{c})")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1365,7 +1437,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} fmod({typeFullName} x, {typeFullName} y)
|
public static {typeFullName} fmod({typeFullName} x, {typeFullName} y)
|
||||||
{{
|
{{
|
||||||
return new {typeFullName}({PerComponentAssignments(c => $"x.{c} % y.{c}")});
|
return new {typeFullName}({ComponentwiseAssignments(c => $"x.{c} % y.{c}")});
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1418,7 +1490,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
public static {typeFullName} smoothstep({typeFullName} vMin, {typeFullName} vMax, {typeFullName} v)
|
public static {typeFullName} smoothstep({typeFullName} vMin, {typeFullName} vMax, {typeFullName} v)
|
||||||
{{
|
{{
|
||||||
var t = saturate((v - vMin) / (vMax - vMin));
|
var t = saturate((v - vMin) / (vMax - vMin));
|
||||||
return t * t * (3{componentTypePrefix} - (2{componentTypePrefix} * t));
|
return t * t * (3{_componentTypePrefix} - (2{_componentTypePrefix} * t));
|
||||||
}}");
|
}}");
|
||||||
|
|
||||||
sourceBuilder.AppendLine($@"
|
sourceBuilder.AppendLine($@"
|
||||||
@@ -1429,7 +1501,84 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
|||||||
{INLINE_METHOD_ATTRIBUTE}
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
public static {typeFullName} step({typeFullName} threshold, {typeFullName} v)
|
public static {typeFullName} step({typeFullName} threshold, {typeFullName} v)
|
||||||
{{
|
{{
|
||||||
return select(new {typeFullName}(0{componentTypePrefix}), new {typeFullName}(1{componentTypePrefix}), v == threshold);
|
return select(new {typeFullName}(0{_componentTypePrefix}), new {typeFullName}(1{_componentTypePrefix}), v == threshold);
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Given an incident vector i and a normal vector n, returns the reflection vector r = i - 2.0 * dot(i, n) * n.</summary>
|
||||||
|
/// <param name=""i"">Incident vector.</param>
|
||||||
|
/// <param name=""n"">Normal vector.</param>
|
||||||
|
/// <returns>Reflection vector.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static {typeFullName} reflect({typeFullName} i, {typeFullName} n)
|
||||||
|
{{
|
||||||
|
return i - 2{_componentTypePrefix} * n * dot(i, n);
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Returns the refraction vector given the incident vector i, the normal vector n and the refraction index.</summary>
|
||||||
|
/// <param name=""i"">Incident vector.</param>
|
||||||
|
/// <param name=""n"">Normal vector.</param>
|
||||||
|
/// <param name=""indexOfRefraction"">Index of refraction.</param>
|
||||||
|
/// <returns>Refraction vector.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static {typeFullName} refract({typeFullName} i, {typeFullName} n, {componentTypeFullName} indexOfRefraction)
|
||||||
|
{{
|
||||||
|
var ni = dot(n, i);
|
||||||
|
var k = 1.0f - indexOfRefraction * indexOfRefraction * (1{_componentTypePrefix} - ni * ni);
|
||||||
|
return select(new(0{_componentTypePrefix}), indexOfRefraction * i - (indexOfRefraction * ni + sqrt(k)) * n, k >= 0);
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>
|
||||||
|
/// Compute vector projection of a onto b.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Some finite vectors a and b could generate a non-finite result. This is most likely when a's components
|
||||||
|
/// are very large (close to Single.MaxValue) or when b's components are very small (close to FLT_MIN_NORMAL).
|
||||||
|
/// In these cases, you can call <see cref=""projectsafe({typeFullName},{typeFullName},{typeFullName})""/>
|
||||||
|
/// which will use a given default value if the result is not finite.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name=""a"">Vector to project.</param>
|
||||||
|
/// <param name=""ontoB"">Non-zero vector to project onto.</param>
|
||||||
|
/// <returns>Vector projection of a onto b.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static {typeFullName} project({typeFullName} a, {typeFullName} ontoB)
|
||||||
|
{{
|
||||||
|
return (dot(a, ontoB) / dot(ontoB, ontoB)) * ontoB;
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>
|
||||||
|
/// Compute vector projection of a onto b. If result is not finite, then return the default value instead.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This function performs extra checks to see if the result of projecting a onto b is finite. If you know that
|
||||||
|
/// your inputs will generate a finite result or you don't care if the result is finite, then you can call
|
||||||
|
/// <see cref=""project({typeFullName},{typeFullName})""/> instead which is faster than this function.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name=""a"">Vector to project.</param>
|
||||||
|
/// <param name=""ontoB"">Non-zero vector to project onto.</param>
|
||||||
|
/// <param name=""defaultValue"">Default value to return if projection is not finite.</param>
|
||||||
|
/// <returns>Vector projection of a onto b or the default value.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static {typeFullName} projectsafe({typeFullName} a, {typeFullName} ontoB, {typeFullName} defaultValue = default)
|
||||||
|
{{
|
||||||
|
var proj = project(a, ontoB);
|
||||||
|
|
||||||
|
return select(defaultValue, proj, all(isfinite(proj)));
|
||||||
|
}}");
|
||||||
|
|
||||||
|
sourceBuilder.AppendLine($@"
|
||||||
|
/// <summary>Conditionally flips a vector n if two vectors i and ng are pointing in the same direction. Returns n if dot(i, ng) < 0, -n otherwise.</summary>
|
||||||
|
/// <param name=""n"">Vector to conditionally flip.</param>
|
||||||
|
/// <param name=""i"">First vector in direction comparison.</param>
|
||||||
|
/// <param name=""ng"">Second vector in direction comparison.</param>
|
||||||
|
/// <returns>-n if i and ng point in the same direction; otherwise return n unchanged.</returns>
|
||||||
|
{INLINE_METHOD_ATTRIBUTE}
|
||||||
|
public static {typeFullName} faceforward({typeFullName} n, {typeFullName} i, {typeFullName} ng)
|
||||||
|
{{
|
||||||
|
return select(n, -n, dot(ng, i) >= 0.0f);
|
||||||
}}");
|
}}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Misaki.HighPerformance.Mathematics.CodeGen.Models
|
namespace Misaki.HighPerformance.Mathematics.CodeGen.Models
|
||||||
{
|
{
|
||||||
public record NumericTypeInfo
|
internal record NumericTypeInfo
|
||||||
{
|
{
|
||||||
public INamedTypeSymbol TypeSymbol
|
public INamedTypeSymbol TypeSymbol
|
||||||
{
|
{
|
||||||
|
|||||||
109
Misaki.HighPerformance.Mathematics.CodeGen/NumericType.cs
Normal file
109
Misaki.HighPerformance.Mathematics.CodeGen/NumericType.cs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Misaki.HighPerformance.Mathematics.CodeGen
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
|
||||||
|
public class NumericTypeAttribute : Attribute
|
||||||
|
{
|
||||||
|
public NumericTypeAttribute(Type componentType, int componentSize, int row, int column, string typePrefix, bool arithmetic = true, bool canInverse = true, Type? elementType = default, Type? vectorType = default)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)]
|
||||||
|
public class NumericConvertableAttribute : Attribute
|
||||||
|
{
|
||||||
|
public NumericConvertableAttribute(string template, params Type[] types)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum SupportedVectorMath
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Min = 1 << 0,
|
||||||
|
Max = 1 << 1,
|
||||||
|
Lerp = 1 << 2,
|
||||||
|
Unlerp = 1 << 3,
|
||||||
|
Remap = 1 << 4,
|
||||||
|
Mad = 1 << 5,
|
||||||
|
Clamp = 1 << 6,
|
||||||
|
Saturate = 1 << 7,
|
||||||
|
Abs = 1 << 8,
|
||||||
|
Dot = 1 << 9,
|
||||||
|
Tan = 1 << 10,
|
||||||
|
TanH = 1 << 11,
|
||||||
|
Atan = 1 << 12,
|
||||||
|
Atan2 = 1 << 13,
|
||||||
|
Cos = 1 << 14,
|
||||||
|
CosH = 1 << 15,
|
||||||
|
Acos = 1 << 16,
|
||||||
|
Sin = 1 << 17,
|
||||||
|
SinH = 1 << 18,
|
||||||
|
Asin = 1 << 19,
|
||||||
|
Floor = 1 << 20,
|
||||||
|
Ceil = 1 << 21,
|
||||||
|
Round = 1 << 22,
|
||||||
|
Trunc = 1 << 23,
|
||||||
|
Frac = 1 << 24,
|
||||||
|
Rcp = 1 << 25,
|
||||||
|
Sign = 1 << 26,
|
||||||
|
Pow = 1 << 27,
|
||||||
|
Exp = 1 << 28,
|
||||||
|
Exp2 = 1 << 29,
|
||||||
|
Exp10 = 1 << 30,
|
||||||
|
Log = 1 << 31,
|
||||||
|
Log2 = 1 << 32,
|
||||||
|
Log10 = 1 << 33,
|
||||||
|
Fmod = 1 << 34,
|
||||||
|
Modf = 1 << 35,
|
||||||
|
Sqrt = 1 << 36,
|
||||||
|
Rsqrt = 1 << 37,
|
||||||
|
Length = 1 << 38,
|
||||||
|
LengthSq = 1 << 39,
|
||||||
|
Distance = 1 << 40,
|
||||||
|
DistanceSq = 1 << 41,
|
||||||
|
Cross = 1 << 42,
|
||||||
|
SmoothStep = 1 << 43,
|
||||||
|
Select = 1 << 44,
|
||||||
|
Step = 1 << 45,
|
||||||
|
FaceForward = 1 << 46,
|
||||||
|
SinCos = 1 << 47,
|
||||||
|
Any = 1 << 48,
|
||||||
|
All = 1 << 49,
|
||||||
|
Normalize = 1 << 50,
|
||||||
|
Reflect = 1 << 51,
|
||||||
|
Refract = 1 << 52,
|
||||||
|
Project = 1 << 53,
|
||||||
|
CountBits = 1 << 54,
|
||||||
|
Lzcnt = 1 << 55,
|
||||||
|
Tzcnt = 1 << 56,
|
||||||
|
ReverseBits = 1 << 57,
|
||||||
|
Rol = 1 << 58,
|
||||||
|
Ror = 1 << 59,
|
||||||
|
CeilPow2 = 1 << 60,
|
||||||
|
CeilLog2 = 1 << 61,
|
||||||
|
FloorLog2 = 1 << 62,
|
||||||
|
Radians = 1 << 63,
|
||||||
|
Degrees = 1 << 64,
|
||||||
|
Cmin = 1 << 65,
|
||||||
|
Cmax = 1 << 66,
|
||||||
|
|
||||||
|
FloatingPointMask = ~0 & ~(CountBits | Lzcnt | Tzcnt | ReverseBits | Rol | Ror | CeilPow2 | CeilLog2 | FloorLog2),
|
||||||
|
IntegerMask = Min | Max | Mad | Clamp | Abs | Dot | Sign | Any | All | Select | CountBits | Lzcnt | Tzcnt | ReverseBits | Rol | Ror | CeilPow2 | CeilLog2 | FloorLog2 | Cmin | Cmax,
|
||||||
|
UnsignedIntegerMask = IntegerMask & ~(Sign),
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum SupportedMatrixMath
|
||||||
|
{
|
||||||
|
Transpose = 1 << 0,
|
||||||
|
Determinant = 1 << 1,
|
||||||
|
Inverse = 1 << 2,
|
||||||
|
Adjugate = 1 << 3,
|
||||||
|
Cofactor = 1 << 4,
|
||||||
|
Minor = 1 << 5,
|
||||||
|
OuterProduct = 1 << 6,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen
|
|||||||
// Create a provider that finds all types with NumericTypeAttribute
|
// Create a provider that finds all types with NumericTypeAttribute
|
||||||
var typesWithAttribute = context.SyntaxProvider
|
var typesWithAttribute = context.SyntaxProvider
|
||||||
.ForAttributeWithMetadataName(
|
.ForAttributeWithMetadataName(
|
||||||
fullyQualifiedMetadataName: _TARGET_ATTRIBUTE_NAME,
|
fullyQualifiedMetadataName: typeof(NumericTypeAttribute).FullName,
|
||||||
predicate: static (node, _) => node is ClassDeclarationSyntax or StructDeclarationSyntax,
|
predicate: static (node, _) => node is ClassDeclarationSyntax or StructDeclarationSyntax,
|
||||||
transform: static (context, _) => GetTypeInfo(context))
|
transform: static (context, _) => GetTypeInfo(context))
|
||||||
.Where(static typeInfo => typeInfo is not null);
|
.Where(static typeInfo => typeInfo is not null);
|
||||||
@@ -55,10 +55,10 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen
|
|||||||
|
|
||||||
// Get the attribute data
|
// Get the attribute data
|
||||||
var attribute = typeSymbol.GetAttributes()
|
var attribute = typeSymbol.GetAttributes()
|
||||||
.FirstOrDefault(a => a.AttributeClass?.ToDisplayString() == _TARGET_ATTRIBUTE_NAME);
|
.FirstOrDefault(a => a.AttributeClass?.ToDisplayString() == typeof(NumericTypeAttribute).FullName);
|
||||||
|
|
||||||
var convertableAttributes = typeSymbol.GetAttributes()
|
var convertableAttributes = typeSymbol.GetAttributes()
|
||||||
.Where(a => a.AttributeClass?.ToDisplayString() == _CONVERTABLE_ATTRIBUTE_NAME);
|
.Where(a => a.AttributeClass?.ToDisplayString() == typeof(NumericConvertableAttribute).FullName);
|
||||||
|
|
||||||
if (attribute == null)
|
if (attribute == null)
|
||||||
{
|
{
|
||||||
@@ -88,7 +88,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen
|
|||||||
.Select(v => (INamedTypeSymbol)v.Value!)
|
.Select(v => (INamedTypeSymbol)v.Value!)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
info.ConvertableTypes??= new();
|
info.ConvertableTypes ??= new();
|
||||||
info.ConvertableTypes[template] = types;
|
info.ConvertableTypes[template] = types;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
namespace Misaki.HighPerformance.Mathematics.Attributes;
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
|
|
||||||
internal class NumericTypeAttribute : Attribute
|
|
||||||
{
|
|
||||||
public NumericTypeAttribute(Type componentType, int componentSize, int row, int column, string typePrefix, bool arithmetic = true, bool canInverse = true, Type? elementType = default, Type? vectorType = default)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)]
|
|
||||||
internal class NumericConvertableAttribute : Attribute
|
|
||||||
{
|
|
||||||
public NumericConvertableAttribute(string template, params Type[] types)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -162,7 +162,7 @@ public struct Plane
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static float4 Normalize(float4 planeCoefficients)
|
public static float4 Normalize(float4 planeCoefficients)
|
||||||
{
|
{
|
||||||
float recipLength = math.rsqrt(math.lengthsq(planeCoefficients.xyz));
|
var recipLength = math.rsqrt(math.lengthsq(planeCoefficients.xyz));
|
||||||
return new Plane { normalAndDistance = planeCoefficients * recipLength };
|
return new Plane { normalAndDistance = planeCoefficients * recipLength };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,9 +214,9 @@ public struct Plane
|
|||||||
public static implicit operator float4(Plane plane) => plane.normalAndDistance;
|
public static implicit operator float4(Plane plane) => plane.normalAndDistance;
|
||||||
|
|
||||||
[Conditional("ENABLE_COLLECTIONS_CHECKS")]
|
[Conditional("ENABLE_COLLECTIONS_CHECKS")]
|
||||||
void CheckPlaneIsNormalized()
|
private void CheckPlaneIsNormalized()
|
||||||
{
|
{
|
||||||
float ll = math.lengthsq(Normal.xyz);
|
var ll = math.lengthsq(Normal.xyz);
|
||||||
const float lowerBound = 0.999f * 0.999f;
|
const float lowerBound = 0.999f * 0.999f;
|
||||||
const float upperBound = 1.001f * 1.001f;
|
const float upperBound = 1.001f * 1.001f;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Misaki.HighPerformance.Mathematics.CodeGen\Misaki.HighPerformance.Mathematics.CodeGen.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
<ProjectReference Include="..\Misaki.HighPerformance.Mathematics.CodeGen\Misaki.HighPerformance.Mathematics.CodeGen.csproj" OutputItemType="Analyzer" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Misaki.HighPerformance.Mathematics.Attributes;
|
using Misaki.HighPerformance.Mathematics.CodeGen;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Mathematics;
|
namespace Misaki.HighPerformance.Mathematics;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Misaki.HighPerformance.Mathematics.Attributes;
|
using Misaki.HighPerformance.Mathematics.CodeGen;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Mathematics;
|
namespace Misaki.HighPerformance.Mathematics;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
using Misaki.HighPerformance.Mathematics.Attributes;
|
using Misaki.HighPerformance.Mathematics.CodeGen;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Intrinsics;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Mathematics;
|
namespace Misaki.HighPerformance.Mathematics;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Misaki.HighPerformance.Mathematics.Attributes;
|
using Misaki.HighPerformance.Mathematics.CodeGen;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Mathematics;
|
namespace Misaki.HighPerformance.Mathematics;
|
||||||
|
|
||||||
|
|||||||
@@ -1890,34 +1890,6 @@ public static partial class math
|
|||||||
return abs(x);
|
return abs(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the length of a float2 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing length.</param>
|
|
||||||
/// <returns>Length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float length(float2 x)
|
|
||||||
{
|
|
||||||
return sqrt(dot(x, x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the length of a float3 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing length.</param>
|
|
||||||
/// <returns>Length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float length(float3 x)
|
|
||||||
{
|
|
||||||
return sqrt(dot(x, x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the length of a float4 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing length.</param>
|
|
||||||
/// <returns>Length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float length(float4 x)
|
|
||||||
{
|
|
||||||
return sqrt(dot(x, x));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the length of a double value. Equivalent to the absolute value.</summary>
|
/// <summary>Returns the length of a double value. Equivalent to the absolute value.</summary>
|
||||||
/// <param name="x">Value to use when computing squared length.</param>
|
/// <param name="x">Value to use when computing squared length.</param>
|
||||||
/// <returns>Squared length of x.</returns>
|
/// <returns>Squared length of x.</returns>
|
||||||
@@ -1927,34 +1899,6 @@ public static partial class math
|
|||||||
return abs(x);
|
return abs(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the length of a double2 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing squared length.</param>
|
|
||||||
/// <returns>Squared length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double length(double2 x)
|
|
||||||
{
|
|
||||||
return sqrt(dot(x, x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the length of a double3 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing squared length.</param>
|
|
||||||
/// <returns>Squared length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double length(double3 x)
|
|
||||||
{
|
|
||||||
return sqrt(dot(x, x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the length of a double4 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing squared length.</param>
|
|
||||||
/// <returns>Squared length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double length(double4 x)
|
|
||||||
{
|
|
||||||
return sqrt(dot(x, x));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the squared length of a float value. Equivalent to squaring the value.</summary>
|
/// <summary>Returns the squared length of a float value. Equivalent to squaring the value.</summary>
|
||||||
/// <param name="x">Value to use when computing squared length.</param>
|
/// <param name="x">Value to use when computing squared length.</param>
|
||||||
/// <returns>Squared length of x.</returns>
|
/// <returns>Squared length of x.</returns>
|
||||||
@@ -1964,34 +1908,6 @@ public static partial class math
|
|||||||
return x * x;
|
return x * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the squared length of a float2 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing squared length.</param>
|
|
||||||
/// <returns>Squared length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float lengthsq(float2 x)
|
|
||||||
{
|
|
||||||
return dot(x, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the squared length of a float3 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing squared length.</param>
|
|
||||||
/// <returns>Squared length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float lengthsq(float3 x)
|
|
||||||
{
|
|
||||||
return dot(x, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the squared length of a float4 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing squared length.</param>
|
|
||||||
/// <returns>Squared length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float lengthsq(float4 x)
|
|
||||||
{
|
|
||||||
return dot(x, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the squared length of a double value. Equivalent to squaring the value.</summary>
|
/// <summary>Returns the squared length of a double value. Equivalent to squaring the value.</summary>
|
||||||
/// <param name="x">Value to use when computing squared length.</param>
|
/// <param name="x">Value to use when computing squared length.</param>
|
||||||
/// <returns>Squared length of x.</returns>
|
/// <returns>Squared length of x.</returns>
|
||||||
@@ -2001,34 +1917,6 @@ public static partial class math
|
|||||||
return x * x;
|
return x * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the squared length of a double2 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing squared length.</param>
|
|
||||||
/// <returns>Squared length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double lengthsq(double2 x)
|
|
||||||
{
|
|
||||||
return dot(x, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the squared length of a double3 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing squared length.</param>
|
|
||||||
/// <returns>Squared length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double lengthsq(double3 x)
|
|
||||||
{
|
|
||||||
return dot(x, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the squared length of a double4 vector.</summary>
|
|
||||||
/// <param name="x">Vector to use when computing squared length.</param>
|
|
||||||
/// <returns>Squared length of vector x.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double lengthsq(double4 x)
|
|
||||||
{
|
|
||||||
return dot(x, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the distance between two float values.</summary>
|
/// <summary>Returns the distance between two float values.</summary>
|
||||||
/// <param name="x">First value to use in distance computation.</param>
|
/// <param name="x">First value to use in distance computation.</param>
|
||||||
/// <param name="y">Second value to use in distance computation.</param>
|
/// <param name="y">Second value to use in distance computation.</param>
|
||||||
@@ -2039,37 +1927,6 @@ public static partial class math
|
|||||||
return abs(y - x);
|
return abs(y - x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the distance between two float2 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float distance(float2 x, float2 y)
|
|
||||||
{
|
|
||||||
return length(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the distance between two float3 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float distance(float3 x, float3 y)
|
|
||||||
{
|
|
||||||
return length(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the distance between two float4 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float distance(float4 x, float4 y)
|
|
||||||
{
|
|
||||||
return length(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the distance between two double values.</summary>
|
/// <summary>Returns the distance between two double values.</summary>
|
||||||
/// <param name="x">First value to use in distance computation.</param>
|
/// <param name="x">First value to use in distance computation.</param>
|
||||||
/// <param name="y">Second value to use in distance computation.</param>
|
/// <param name="y">Second value to use in distance computation.</param>
|
||||||
@@ -2080,37 +1937,6 @@ public static partial class math
|
|||||||
return abs(y - x);
|
return abs(y - x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the distance between two double2 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double distance(double2 x, double2 y)
|
|
||||||
{
|
|
||||||
return length(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the distance between two double3 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double distance(double3 x, double3 y)
|
|
||||||
{
|
|
||||||
return length(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the distance between two double4 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double distance(double4 x, double4 y)
|
|
||||||
{
|
|
||||||
return length(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the squared distance between two float values.</summary>
|
/// <summary>Returns the squared distance between two float values.</summary>
|
||||||
/// <param name="x">First value to use in distance computation.</param>
|
/// <param name="x">First value to use in distance computation.</param>
|
||||||
/// <param name="y">Second value to use in distance computation.</param>
|
/// <param name="y">Second value to use in distance computation.</param>
|
||||||
@@ -2121,37 +1947,6 @@ public static partial class math
|
|||||||
return (y - x) * (y - x);
|
return (y - x) * (y - x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the squared distance between two float2 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The squared distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float distancesq(float2 x, float2 y)
|
|
||||||
{
|
|
||||||
return lengthsq(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the squared distance between two float3 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The squared distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float distancesq(float3 x, float3 y)
|
|
||||||
{
|
|
||||||
return lengthsq(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the squared distance between two float4 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The squared distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float distancesq(float4 x, float4 y)
|
|
||||||
{
|
|
||||||
return lengthsq(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the squared distance between two double values.</summary>
|
/// <summary>Returns the squared distance between two double values.</summary>
|
||||||
/// <param name="x">First value to use in distance computation.</param>
|
/// <param name="x">First value to use in distance computation.</param>
|
||||||
/// <param name="y">Second value to use in distance computation.</param>
|
/// <param name="y">Second value to use in distance computation.</param>
|
||||||
@@ -2162,37 +1957,6 @@ public static partial class math
|
|||||||
return (y - x) * (y - x);
|
return (y - x) * (y - x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the squared distance between two double2 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The squared distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double distancesq(double2 x, double2 y)
|
|
||||||
{
|
|
||||||
return lengthsq(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the squared distance between two double3 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The squared distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double distancesq(double3 x, double3 y)
|
|
||||||
{
|
|
||||||
return lengthsq(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the squared distance between two double4 vectors.</summary>
|
|
||||||
/// <param name="x">First vector to use in distance computation.</param>
|
|
||||||
/// <param name="y">Second vector to use in distance computation.</param>
|
|
||||||
/// <returns>The squared distance between x and y.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double distancesq(double4 x, double4 y)
|
|
||||||
{
|
|
||||||
return lengthsq(y - x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the cross product of two float3 vectors.</summary>
|
/// <summary>Returns the cross product of two float3 vectors.</summary>
|
||||||
/// <param name="x">First vector to use in cross product.</param>
|
/// <param name="x">First vector to use in cross product.</param>
|
||||||
/// <param name="y">Second vector to use in cross product.</param>
|
/// <param name="y">Second vector to use in cross product.</param>
|
||||||
@@ -2237,60 +2001,6 @@ public static partial class math
|
|||||||
return t * t * (3.0 - (2.0 * t));
|
return t * t * (3.0 - (2.0 * t));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns true if any component of the input bool2 vector is true, false otherwise.</summary>
|
|
||||||
/// <param name="x">Vector of values to compare.</param>
|
|
||||||
/// <returns>True if any the components of x are true, false otherwise.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool any(bool2 x)
|
|
||||||
{
|
|
||||||
return x.x || x.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns true if any component of the input bool3 vector is true, false otherwise.</summary>
|
|
||||||
/// <param name="x">Vector of values to compare.</param>
|
|
||||||
/// <returns>True if any the components of x are true, false otherwise.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool any(bool3 x)
|
|
||||||
{
|
|
||||||
return x.x || x.y || x.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns true if any components of the input bool4 vector is true, false otherwise.</summary>
|
|
||||||
/// <param name="x">Vector of values to compare.</param>
|
|
||||||
/// <returns>True if any the components of x are true, false otherwise.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool any(bool4 x)
|
|
||||||
{
|
|
||||||
return x.x || x.y || x.z || x.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns true if all components of the input bool2 vector are true, false otherwise.</summary>
|
|
||||||
/// <param name="x">Vector of values to compare.</param>
|
|
||||||
/// <returns>True if all the components of x are true, false otherwise.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool all(bool2 x)
|
|
||||||
{
|
|
||||||
return x.x && x.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns true if all components of the input bool3 vector are true, false otherwise.</summary>
|
|
||||||
/// <param name="x">Vector of values to compare.</param>
|
|
||||||
/// <returns>True if all the components of x are true, false otherwise.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool all(bool3 x)
|
|
||||||
{
|
|
||||||
return x.x && x.y && x.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns true if all components of the input bool4 vector are true, false otherwise.</summary>
|
|
||||||
/// <param name="x">Vector of values to compare.</param>
|
|
||||||
/// <returns>True if all the components of x are true, false otherwise.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool all(bool4 x)
|
|
||||||
{
|
|
||||||
return x.x && x.y && x.z && x.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns trueValue if test is true, falseValue otherwise.</summary>
|
/// <summary>Returns trueValue if test is true, falseValue otherwise.</summary>
|
||||||
/// <param name="falseValue">Value to use if test is false.</param>
|
/// <param name="falseValue">Value to use if test is false.</param>
|
||||||
/// <param name="trueValue">Value to use if test is true.</param>
|
/// <param name="trueValue">Value to use if test is true.</param>
|
||||||
@@ -2378,449 +2088,6 @@ public static partial class math
|
|||||||
return select(0.0, 1.0, x >= threshold);
|
return select(0.0, 1.0, x >= threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Given an incident vector i and a normal vector n, returns the reflection vector r = i - 2.0f * dot(i, n) * n.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <returns>Reflection vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float2 reflect(float2 i, float2 n)
|
|
||||||
{
|
|
||||||
return i - 2f * n * dot(i, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Given an incident vector i and a normal vector n, returns the reflection vector r = i - 2.0f * dot(i, n) * n.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <returns>Reflection vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float3 reflect(float3 i, float3 n)
|
|
||||||
{
|
|
||||||
return i - 2f * n * dot(i, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Given an incident vector i and a normal vector n, returns the reflection vector r = i - 2.0f * dot(i, n) * n.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <returns>Reflection vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float4 reflect(float4 i, float4 n)
|
|
||||||
{
|
|
||||||
return i - 2f * n * dot(i, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Given an incident vector i and a normal vector n, returns the reflection vector r = i - 2.0 * dot(i, n) * n.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <returns>Reflection vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double2 reflect(double2 i, double2 n)
|
|
||||||
{
|
|
||||||
return i - 2 * n * dot(i, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Given an incident vector i and a normal vector n, returns the reflection vector r = i - 2.0 * dot(i, n) * n.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <returns>Reflection vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double3 reflect(double3 i, double3 n)
|
|
||||||
{
|
|
||||||
return i - 2 * n * dot(i, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Given an incident vector i and a normal vector n, returns the reflection vector r = i - 2.0 * dot(i, n) * n.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <returns>Reflection vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double4 reflect(double4 i, double4 n)
|
|
||||||
{
|
|
||||||
return i - 2 * n * dot(i, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the refraction vector given the incident vector i, the normal vector n and the refraction index.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <param name="indexOfRefraction">Index of refraction.</param>
|
|
||||||
/// <returns>Refraction vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float2 refract(float2 i, float2 n, float indexOfRefraction)
|
|
||||||
{
|
|
||||||
var ni = dot(n, i);
|
|
||||||
var k = 1.0f - indexOfRefraction * indexOfRefraction * (1.0f - ni * ni);
|
|
||||||
return select(new(0.0f), indexOfRefraction * i - (indexOfRefraction * ni + sqrt(k)) * n, k >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the refraction vector given the incident vector i, the normal vector n and the refraction index.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <param name="indexOfRefraction">Index of refraction.</param>
|
|
||||||
/// <returns>Refraction vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float3 refract(float3 i, float3 n, float indexOfRefraction)
|
|
||||||
{
|
|
||||||
var ni = dot(n, i);
|
|
||||||
var k = 1.0f - indexOfRefraction * indexOfRefraction * (1.0f - ni * ni);
|
|
||||||
return select(new(0.0f), indexOfRefraction * i - (indexOfRefraction * ni + sqrt(k)) * n, k >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the refraction vector given the incident vector i, the normal vector n and the refraction index.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <param name="indexOfRefraction">Index of refraction.</param>
|
|
||||||
/// <returns>Refraction vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float4 refract(float4 i, float4 n, float indexOfRefraction)
|
|
||||||
{
|
|
||||||
var ni = dot(n, i);
|
|
||||||
var k = 1.0f - indexOfRefraction * indexOfRefraction * (1.0f - ni * ni);
|
|
||||||
return select(new(0.0f), indexOfRefraction * i - (indexOfRefraction * ni + sqrt(k)) * n, k >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the refraction vector given the incident vector i, the normal vector n and the refraction index.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <param name="indexOfRefraction">Index of refraction.</param>
|
|
||||||
/// <returns>Refraction vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double2 refract(double2 i, double2 n, double indexOfRefraction)
|
|
||||||
{
|
|
||||||
var ni = dot(n, i);
|
|
||||||
var k = 1.0 - indexOfRefraction * indexOfRefraction * (1.0 - ni * ni);
|
|
||||||
return select(new(0.0), indexOfRefraction * i - (indexOfRefraction * ni + sqrt(k)) * n, k >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the refraction vector given the incident vector i, the normal vector n and the refraction index.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <param name="indexOfRefraction">Index of refraction.</param>
|
|
||||||
/// <returns>Refraction vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double3 refract(double3 i, double3 n, double indexOfRefraction)
|
|
||||||
{
|
|
||||||
var ni = dot(n, i);
|
|
||||||
var k = 1.0 - indexOfRefraction * indexOfRefraction * (1.0 - ni * ni);
|
|
||||||
return select(new(0.0), indexOfRefraction * i - (indexOfRefraction * ni + sqrt(k)) * n, k >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Returns the refraction vector given the incident vector i, the normal vector n and the refraction index.</summary>
|
|
||||||
/// <param name="i">Incident vector.</param>
|
|
||||||
/// <param name="n">Normal vector.</param>
|
|
||||||
/// <param name="indexOfRefraction">Index of refraction.</param>
|
|
||||||
/// <returns>Refraction vector.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double4 refract(double4 i, double4 n, double indexOfRefraction)
|
|
||||||
{
|
|
||||||
var ni = dot(n, i);
|
|
||||||
var k = 1.0 - indexOfRefraction * indexOfRefraction * (1.0 - ni * ni);
|
|
||||||
return select(new(0.0), indexOfRefraction * i - (indexOfRefraction * ni + sqrt(k)) * n, k >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Some finite vectors a and b could generate a non-finite result. This is most likely when a's components
|
|
||||||
/// are very large (close to Single.MaxValue) or when b's components are very small (close to FLT_MIN_NORMAL).
|
|
||||||
/// In these cases, you can call <see cref="projectsafe(Unity.Mathematics.float2,Unity.Mathematics.float2,Unity.Mathematics.float2)"/>
|
|
||||||
/// which will use a given default value if the result is not finite.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <returns>Vector projection of a onto b.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float2 project(float2 a, float2 ontoB)
|
|
||||||
{
|
|
||||||
return (dot(a, ontoB) / dot(ontoB, ontoB)) * ontoB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Some finite vectors a and b could generate a non-finite result. This is most likely when a's components
|
|
||||||
/// are very large (close to Single.MaxValue) or when b's components are very small (close to FLT_MIN_NORMAL).
|
|
||||||
/// In these cases, you can call <see cref="projectsafe(Unity.Mathematics.float3,Unity.Mathematics.float3,Unity.Mathematics.float3)"/>
|
|
||||||
/// which will use a given default value if the result is not finite.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <returns>Vector projection of a onto b.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float3 project(float3 a, float3 ontoB)
|
|
||||||
{
|
|
||||||
return (dot(a, ontoB) / dot(ontoB, ontoB)) * ontoB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Some finite vectors a and b could generate a non-finite result. This is most likely when a's components
|
|
||||||
/// are very large (close to Single.MaxValue) or when b's components are very small (close to FLT_MIN_NORMAL).
|
|
||||||
/// In these cases, you can call <see cref="projectsafe(Unity.Mathematics.float4,Unity.Mathematics.float4,Unity.Mathematics.float4)"/>
|
|
||||||
/// which will use a given default value if the result is not finite.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <returns>Vector projection of a onto b.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float4 project(float4 a, float4 ontoB)
|
|
||||||
{
|
|
||||||
return (dot(a, ontoB) / dot(ontoB, ontoB)) * ontoB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b. If result is not finite, then return the default value instead.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This function performs extra checks to see if the result of projecting a onto b is finite. If you know that
|
|
||||||
/// your inputs will generate a finite result or you don't care if the result is finite, then you can call
|
|
||||||
/// <see cref="project(Unity.Mathematics.float2,Unity.Mathematics.float2)"/> instead which is faster than this
|
|
||||||
/// function.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <param name="defaultValue">Default value to return if projection is not finite.</param>
|
|
||||||
/// <returns>Vector projection of a onto b or the default value.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float2 projectsafe(float2 a, float2 ontoB, float2 defaultValue = new float2())
|
|
||||||
{
|
|
||||||
var proj = project(a, ontoB);
|
|
||||||
|
|
||||||
return select(defaultValue, proj, all(isfinite(proj)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b. If result is not finite, then return the default value instead.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This function performs extra checks to see if the result of projecting a onto b is finite. If you know that
|
|
||||||
/// your inputs will generate a finite result or you don't care if the result is finite, then you can call
|
|
||||||
/// <see cref="project(Unity.Mathematics.float3,Unity.Mathematics.float3)"/> instead which is faster than this
|
|
||||||
/// function.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <param name="defaultValue">Default value to return if projection is not finite.</param>
|
|
||||||
/// <returns>Vector projection of a onto b or the default value.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float3 projectsafe(float3 a, float3 ontoB, float3 defaultValue = new float3())
|
|
||||||
{
|
|
||||||
var proj = project(a, ontoB);
|
|
||||||
|
|
||||||
return select(defaultValue, proj, all(isfinite(proj)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b. If result is not finite, then return the default value instead.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This function performs extra checks to see if the result of projecting a onto b is finite. If you know that
|
|
||||||
/// your inputs will generate a finite result or you don't care if the result is finite, then you can call
|
|
||||||
/// <see cref="project(Unity.Mathematics.float4,Unity.Mathematics.float4)"/> instead which is faster than this
|
|
||||||
/// function.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <param name="defaultValue">Default value to return if projection is not finite.</param>
|
|
||||||
/// <returns>Vector projection of a onto b or the default value.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float4 projectsafe(float4 a, float4 ontoB, float4 defaultValue = new float4())
|
|
||||||
{
|
|
||||||
var proj = project(a, ontoB);
|
|
||||||
|
|
||||||
return select(defaultValue, proj, all(isfinite(proj)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Some finite vectors a and b could generate a non-finite result. This is most likely when a's components
|
|
||||||
/// are very large (close to Double.MaxValue) or when b's components are very small (close to DBL_MIN_NORMAL).
|
|
||||||
/// In these cases, you can call <see cref="projectsafe(Unity.Mathematics.double2,Unity.Mathematics.double2,Unity.Mathematics.double2)"/>
|
|
||||||
/// which will use a given default value if the result is not finite.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <returns>Vector projection of a onto b.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double2 project(double2 a, double2 ontoB)
|
|
||||||
{
|
|
||||||
return (dot(a, ontoB) / dot(ontoB, ontoB)) * ontoB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Some finite vectors a and b could generate a non-finite result. This is most likely when a's components
|
|
||||||
/// are very large (close to Double.MaxValue) or when b's components are very small (close to DBL_MIN_NORMAL).
|
|
||||||
/// In these cases, you can call <see cref="projectsafe(Unity.Mathematics.double3,Unity.Mathematics.double3,Unity.Mathematics.double3)"/>
|
|
||||||
/// which will use a given default value if the result is not finite.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <returns>Vector projection of a onto b.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double3 project(double3 a, double3 ontoB)
|
|
||||||
{
|
|
||||||
return (dot(a, ontoB) / dot(ontoB, ontoB)) * ontoB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Some finite vectors a and b could generate a non-finite result. This is most likely when a's components
|
|
||||||
/// are very large (close to Double.MaxValue) or when b's components are very small (close to DBL_MIN_NORMAL).
|
|
||||||
/// In these cases, you can call <see cref="projectsafe(Unity.Mathematics.double4,Unity.Mathematics.double4,Unity.Mathematics.double4)"/>
|
|
||||||
/// which will use a given default value if the result is not finite.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <returns>Vector projection of a onto b.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double4 project(double4 a, double4 ontoB)
|
|
||||||
{
|
|
||||||
return (dot(a, ontoB) / dot(ontoB, ontoB)) * ontoB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b. If result is not finite, then return the default value instead.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This function performs extra checks to see if the result of projecting a onto b is finite. If you know that
|
|
||||||
/// your inputs will generate a finite result or you don't care if the result is finite, then you can call
|
|
||||||
/// <see cref="project(Unity.Mathematics.double2,Unity.Mathematics.double2)"/> instead which is faster than this
|
|
||||||
/// function.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <param name="defaultValue">Default value to return if projection is not finite.</param>
|
|
||||||
/// <returns>Vector projection of a onto b or the default value.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double2 projectsafe(double2 a, double2 ontoB, double2 defaultValue = new double2())
|
|
||||||
{
|
|
||||||
var proj = project(a, ontoB);
|
|
||||||
|
|
||||||
return select(defaultValue, proj, all(isfinite(proj)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b. If result is not finite, then return the default value instead.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This function performs extra checks to see if the result of projecting a onto b is finite. If you know that
|
|
||||||
/// your inputs will generate a finite result or you don't care if the result is finite, then you can call
|
|
||||||
/// <see cref="project(Unity.Mathematics.double3,Unity.Mathematics.double3)"/> instead which is faster than this
|
|
||||||
/// function.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <param name="defaultValue">Default value to return if projection is not finite.</param>
|
|
||||||
/// <returns>Vector projection of a onto b or the default value.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double3 projectsafe(double3 a, double3 ontoB, double3 defaultValue = new double3())
|
|
||||||
{
|
|
||||||
var proj = project(a, ontoB);
|
|
||||||
|
|
||||||
return select(defaultValue, proj, all(isfinite(proj)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute vector projection of a onto b. If result is not finite, then return the default value instead.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This function performs extra checks to see if the result of projecting a onto b is finite. If you know that
|
|
||||||
/// your inputs will generate a finite result or you don't care if the result is finite, then you can call
|
|
||||||
/// <see cref="project(Unity.Mathematics.double4,Unity.Mathematics.double4)"/> instead which is faster than this
|
|
||||||
/// function.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="a">Vector to project.</param>
|
|
||||||
/// <param name="ontoB">Non-zero vector to project onto.</param>
|
|
||||||
/// <param name="defaultValue">Default value to return if projection is not finite.</param>
|
|
||||||
/// <returns>Vector projection of a onto b or the default value.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double4 projectsafe(double4 a, double4 ontoB, double4 defaultValue = new double4())
|
|
||||||
{
|
|
||||||
var proj = project(a, ontoB);
|
|
||||||
|
|
||||||
return select(defaultValue, proj, all(isfinite(proj)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Conditionally flips a vector n if two vectors i and ng are pointing in the same direction. Returns n if dot(i, ng) < 0, -n otherwise.</summary>
|
|
||||||
/// <param name="n">Vector to conditionally flip.</param>
|
|
||||||
/// <param name="i">First vector in direction comparison.</param>
|
|
||||||
/// <param name="ng">Second vector in direction comparison.</param>
|
|
||||||
/// <returns>-n if i and ng point in the same direction; otherwise return n unchanged.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float2 faceforward(float2 n, float2 i, float2 ng)
|
|
||||||
{
|
|
||||||
return select(n, -n, dot(ng, i) >= 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Conditionally flips a vector n if two vectors i and ng are pointing in the same direction. Returns n if dot(i, ng) < 0, -n otherwise.</summary>
|
|
||||||
/// <param name="n">Vector to conditionally flip.</param>
|
|
||||||
/// <param name="i">First vector in direction comparison.</param>
|
|
||||||
/// <param name="ng">Second vector in direction comparison.</param>
|
|
||||||
/// <returns>-n if i and ng point in the same direction; otherwise return n unchanged.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float3 faceforward(float3 n, float3 i, float3 ng)
|
|
||||||
{
|
|
||||||
return select(n, -n, dot(ng, i) >= 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Conditionally flips a vector n if two vectors i and ng are pointing in the same direction. Returns n if dot(i, ng) < 0, -n otherwise.</summary>
|
|
||||||
/// <param name="n">Vector to conditionally flip.</param>
|
|
||||||
/// <param name="i">First vector in direction comparison.</param>
|
|
||||||
/// <param name="ng">Second vector in direction comparison.</param>
|
|
||||||
/// <returns>-n if i and ng point in the same direction; otherwise return n unchanged.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static float4 faceforward(float4 n, float4 i, float4 ng)
|
|
||||||
{
|
|
||||||
return select(n, -n, dot(ng, i) >= 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Conditionally flips a vector n if two vectors i and ng are pointing in the same direction. Returns n if dot(i, ng) < 0, -n otherwise.</summary>
|
|
||||||
/// <param name="n">Vector to conditionally flip.</param>
|
|
||||||
/// <param name="i">First vector in direction comparison.</param>
|
|
||||||
/// <param name="ng">Second vector in direction comparison.</param>
|
|
||||||
/// <returns>-n if i and ng point in the same direction; otherwise return n unchanged.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double2 faceforward(double2 n, double2 i, double2 ng)
|
|
||||||
{
|
|
||||||
return select(n, -n, dot(ng, i) >= 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Conditionally flips a vector n if two vectors i and ng are pointing in the same direction. Returns n if dot(i, ng) < 0, -n otherwise.</summary>
|
|
||||||
/// <param name="n">Vector to conditionally flip.</param>
|
|
||||||
/// <param name="i">First vector in direction comparison.</param>
|
|
||||||
/// <param name="ng">Second vector in direction comparison.</param>
|
|
||||||
/// <returns>-n if i and ng point in the same direction; otherwise return n unchanged.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double3 faceforward(double3 n, double3 i, double3 ng)
|
|
||||||
{
|
|
||||||
return select(n, -n, dot(ng, i) >= 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Conditionally flips a vector n if two vectors i and ng are pointing in the same direction. Returns n if dot(i, ng) < 0, -n otherwise.</summary>
|
|
||||||
/// <param name="n">Vector to conditionally flip.</param>
|
|
||||||
/// <param name="i">First vector in direction comparison.</param>
|
|
||||||
/// <param name="ng">Second vector in direction comparison.</param>
|
|
||||||
/// <returns>-n if i and ng point in the same direction; otherwise return n unchanged.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static double4 faceforward(double4 n, double4 i, double4 ng)
|
|
||||||
{
|
|
||||||
return select(n, -n, dot(ng, i) >= 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Returns the sine and cosine of the input float value x through the out parameters s and c.</summary>
|
/// <summary>Returns the sine and cosine of the input float value x through the out parameters s and c.</summary>
|
||||||
/// <remarks>When Burst compiled, his method is faster than calling sin() and cos() separately.</remarks>
|
/// <remarks>When Burst compiled, his method is faster than calling sin() and cos() separately.</remarks>
|
||||||
/// <param name="x">Input angle in radians.</param>
|
/// <param name="x">Input angle in radians.</param>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public static class svd
|
|||||||
public const float EPSILON_NORMAL = 1e-30f;
|
public const float EPSILON_NORMAL = 1e-30f;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static void condSwap(bool c, ref float x, ref float y)
|
private static void condSwap(bool c, ref float x, ref float y)
|
||||||
{
|
{
|
||||||
var tmp = x;
|
var tmp = x;
|
||||||
x = math.select(x, y, c);
|
x = math.select(x, y, c);
|
||||||
@@ -23,7 +23,7 @@ public static class svd
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static void condNegSwap(bool c, ref float3 x, ref float3 y)
|
private static void condNegSwap(bool c, ref float3 x, ref float3 y)
|
||||||
{
|
{
|
||||||
var tmp = -x;
|
var tmp = -x;
|
||||||
x = math.select(x, y, c);
|
x = math.select(x, y, c);
|
||||||
@@ -31,14 +31,14 @@ public static class svd
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static quaternion condNegSwapQuat(bool c, quaternion q, float4 mask)
|
private static quaternion condNegSwapQuat(bool c, quaternion q, float4 mask)
|
||||||
{
|
{
|
||||||
const float halfSqrt2 = 0.707106781186548f;
|
const float halfSqrt2 = 0.707106781186548f;
|
||||||
return math.mul(q, math.select(quaternion.identity.value, mask * halfSqrt2, c));
|
return math.mul(q, math.select(quaternion.identity.value, mask * halfSqrt2, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static void sortSingularValues(ref float3x3 b, ref quaternion v)
|
private static void sortSingularValues(ref float3x3 b, ref quaternion v)
|
||||||
{
|
{
|
||||||
var l0 = math.lengthsq(b.c0);
|
var l0 = math.lengthsq(b.c0);
|
||||||
var l1 = math.lengthsq(b.c1);
|
var l1 = math.lengthsq(b.c1);
|
||||||
@@ -60,7 +60,7 @@ public static class svd
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static quaternion approxGivensQuat(float3 pq, float4 mask)
|
private static quaternion approxGivensQuat(float3 pq, float4 mask)
|
||||||
{
|
{
|
||||||
const float c8 = 0.923879532511287f; // cos(pi/8)
|
const float c8 = 0.923879532511287f; // cos(pi/8)
|
||||||
const float s8 = 0.38268343236509f; // sin(pi/8)
|
const float s8 = 0.38268343236509f; // sin(pi/8)
|
||||||
@@ -73,7 +73,7 @@ public static class svd
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static quaternion qrGivensQuat(float2 pq, float4 mask)
|
private static quaternion qrGivensQuat(float2 pq, float4 mask)
|
||||||
{
|
{
|
||||||
var l = math.sqrt(pq.x * pq.x + pq.y * pq.y);
|
var l = math.sqrt(pq.x * pq.x + pq.y * pq.y);
|
||||||
var sh = math.select(0f, pq.y, l > EPSILON_NORMAL_SQRT);
|
var sh = math.select(0f, pq.y, l > EPSILON_NORMAL_SQRT);
|
||||||
@@ -84,7 +84,7 @@ public static class svd
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static quaternion givensQRFactorization(float3x3 b, out float3x3 r)
|
private static quaternion givensQRFactorization(float3x3 b, out float3x3 r)
|
||||||
{
|
{
|
||||||
var u = qrGivensQuat(new float2(b.c0.x, b.c0.y), new float4(0f, 0f, 1f, 1f));
|
var u = qrGivensQuat(new float2(b.c0.x, b.c0.y), new float4(0f, 0f, 1f, 1f));
|
||||||
var qmt = new float3x3(math.conjugate(u));
|
var qmt = new float3x3(math.conjugate(u));
|
||||||
@@ -103,7 +103,7 @@ public static class svd
|
|||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
static quaternion jacobiIteration(ref float3x3 s, int iterations = 5)
|
private static quaternion jacobiIteration(ref float3x3 s, int iterations = 5)
|
||||||
{
|
{
|
||||||
float3x3 qm;
|
float3x3 qm;
|
||||||
quaternion q;
|
quaternion q;
|
||||||
@@ -131,7 +131,7 @@ public static class svd
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static float3 singularValuesDecomposition(float3x3 a, out quaternion u, out quaternion v)
|
private static float3 singularValuesDecomposition(float3x3 a, out quaternion u, out quaternion v)
|
||||||
{
|
{
|
||||||
u = quaternion.identity;
|
u = quaternion.identity;
|
||||||
v = quaternion.identity;
|
v = quaternion.identity;
|
||||||
@@ -147,7 +147,7 @@ public static class svd
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static float3 rcpsafe(float3 x, float epsilon = EPSILON_RCP) =>
|
private static float3 rcpsafe(float3 x, float epsilon = EPSILON_RCP) =>
|
||||||
math.select(math.rcp(x), float3.zero, math.abs(x) < epsilon);
|
math.select(math.rcp(x), float3.zero, math.abs(x) < epsilon);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Misaki.HighPerformance.Mathematics.Attributes;
|
using Misaki.HighPerformance.Mathematics.CodeGen;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Mathematics;
|
namespace Misaki.HighPerformance.Mathematics;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
using BenchmarkDotNet.Attributes;
|
using BenchmarkDotNet.Attributes;
|
||||||
using Misaki.HighPerformance.Mathematics;
|
using Misaki.HighPerformance.Mathematics;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.Intrinsics;
|
||||||
|
using System.Runtime.Intrinsics.X86;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Test.Benchmark;
|
namespace Misaki.HighPerformance.Test.Benchmark;
|
||||||
|
|
||||||
@@ -9,6 +12,11 @@ public class MathematicsBenchmark
|
|||||||
[Params(10)]
|
[Params(10)]
|
||||||
public int count = 10;
|
public int count = 10;
|
||||||
|
|
||||||
|
private unsafe static Vector128<float> CreateVector128(float2 value)
|
||||||
|
{
|
||||||
|
return Vector128.AsSingle(Sse2.LoadScalarVector128((double*)&value));
|
||||||
|
}
|
||||||
|
|
||||||
[Benchmark]
|
[Benchmark]
|
||||||
public void Vector2Add()
|
public void Vector2Add()
|
||||||
{
|
{
|
||||||
@@ -28,14 +36,18 @@ public class MathematicsBenchmark
|
|||||||
var a = new float2(1, 2);
|
var a = new float2(1, 2);
|
||||||
var b = new float2(5, 6);
|
var b = new float2(5, 6);
|
||||||
var result = new float2();
|
var result = new float2();
|
||||||
|
//var vr = CreateVector128(result);
|
||||||
|
//var va = CreateVector128(a);
|
||||||
|
//var vb = CreateVector128(b);
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
result += a + b;
|
result += a + b;
|
||||||
|
//vr = Sse.Add(va, vb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void Vector4Add()
|
public void Vector4Add()
|
||||||
{
|
{
|
||||||
var a = new Vector4(1, 2, 3, 4);
|
var a = new Vector4(1, 2, 3, 4);
|
||||||
@@ -48,7 +60,7 @@ public class MathematicsBenchmark
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void Float4Add()
|
public void Float4Add()
|
||||||
{
|
{
|
||||||
var a = new float4(1, 2, 3, 4);
|
var a = new float4(1, 2, 3, 4);
|
||||||
|
|||||||
@@ -18,23 +18,24 @@
|
|||||||
|
|
||||||
//Console.WriteLine($"Count should be {threadCount * 990}, actual: {map.Count}");
|
//Console.WriteLine($"Count should be {threadCount * 990}, actual: {map.Count}");
|
||||||
|
|
||||||
//using Misaki.HighPerformance.Test.Benchmark;
|
using Misaki.HighPerformance.Test.Benchmark;
|
||||||
|
|
||||||
//BenchmarkDotNet.Running.BenchmarkRunner.Run<MathematicsBenchmark>();
|
BenchmarkDotNet.Running.BenchmarkRunner.Run<MathematicsBenchmark>();
|
||||||
|
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
//using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
//using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
|
//using Misaki.HighPerformance.LowLevel.Utilities;
|
||||||
|
|
||||||
var scope = AllocationManager.CreateStackScope();
|
//using (AllocationManager.CreateStackScope())
|
||||||
var array = new UnsafeArray<int>(10, Allocator.Stack);
|
//{
|
||||||
for (var i = 0; i < array.Count; i++)
|
// var array = new UnsafeArray<int>(10, Allocator.Stack);
|
||||||
{
|
// for (var i = 0; i < array.Count; i++)
|
||||||
array[i] = i;
|
// {
|
||||||
}
|
// array[i] = i;
|
||||||
|
// }
|
||||||
|
|
||||||
foreach (var item in array)
|
// foreach (var item in array.AsSpan())
|
||||||
{
|
// {
|
||||||
Console.WriteLine(item);
|
// Console.WriteLine(item);
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
scope.Dispose();
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Misaki.HighPerformance.Mathematics;
|
using Misaki.HighPerformance.Mathematics;
|
||||||
|
|
||||||
namespace Misaki.HighPerformance.Test.UnitTest.Mathematics;
|
namespace Misaki.HighPerformance.Test.UnitTest.Mathematics;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public class DynamicArray<T> : IEnumerable<T>, IList<T>
|
|||||||
private int _count;
|
private int _count;
|
||||||
|
|
||||||
public ref T this[int index] => ref _array[index];
|
public ref T this[int index] => ref _array[index];
|
||||||
|
public ref T this[uint index] => ref _array[index];
|
||||||
|
|
||||||
public int Count => _count;
|
public int Count => _count;
|
||||||
public bool IsReadOnly => false;
|
public bool IsReadOnly => false;
|
||||||
@@ -48,7 +49,7 @@ public class DynamicArray<T> : IEnumerable<T>, IList<T>
|
|||||||
|
|
||||||
public IEnumerator<T> GetEnumerator()
|
public IEnumerator<T> GetEnumerator()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _count; i++)
|
for (var i = 0; i < _count; i++)
|
||||||
{
|
{
|
||||||
yield return _array[i];
|
yield return _array[i];
|
||||||
}
|
}
|
||||||
@@ -63,8 +64,9 @@ public class DynamicArray<T> : IEnumerable<T>, IList<T>
|
|||||||
{
|
{
|
||||||
if (_array.Length < min)
|
if (_array.Length < min)
|
||||||
{
|
{
|
||||||
int newCapacity = _array.Length == 0 ? 4 : _array.Length * 2;
|
var newCapacity = _array.Length == 0 ? 4 : _array.Length * 2;
|
||||||
if (newCapacity < min) newCapacity = min;
|
if (newCapacity < min)
|
||||||
|
newCapacity = min;
|
||||||
Array.Resize(ref _array, newCapacity);
|
Array.Resize(ref _array, newCapacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +104,7 @@ public class DynamicArray<T> : IEnumerable<T>, IList<T>
|
|||||||
|
|
||||||
public int IndexOf(T item)
|
public int IndexOf(T item)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _count; i++)
|
for (var i = 0; i < _count; i++)
|
||||||
{
|
{
|
||||||
if (EqualityComparer<T>.Default.Equals(_array[i], item))
|
if (EqualityComparer<T>.Default.Equals(_array[i], item))
|
||||||
{
|
{
|
||||||
@@ -120,7 +122,7 @@ public class DynamicArray<T> : IEnumerable<T>, IList<T>
|
|||||||
|
|
||||||
public bool Remove(T item)
|
public bool Remove(T item)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _count; i++)
|
for (var i = 0; i < _count; i++)
|
||||||
{
|
{
|
||||||
if (EqualityComparer<T>.Default.Equals(_array[i], item))
|
if (EqualityComparer<T>.Default.Equals(_array[i], item))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user