Graphic mat 44 is now generic; TextRegex source gen will use goto instead of do{}while()
This commit is contained in:
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Root Type="DevExpress.CodeRush.Formatting.UI.Options.BracesOptionsContainer">
|
||||||
|
<Options Language="C#">
|
||||||
|
<Options>
|
||||||
|
<Item Id="{3920243c-1bac-46ce-960d-e4186d99c187}" Type="DevExpress.CodeRush.Formatting.UI.Options.Conversion.PropertyBracesOption">
|
||||||
|
<WrapOpenBrace>
|
||||||
|
<Option>Wrap</Option>
|
||||||
|
</WrapOpenBrace>
|
||||||
|
<WrapCloseBrace>
|
||||||
|
<Option>Wrap</Option>
|
||||||
|
</WrapCloseBrace>
|
||||||
|
</Item>
|
||||||
|
<Item Id="{692dd27b-3066-4dd3-beac-516a569f5203}" Type="DevExpress.CodeRush.Formatting.UI.Options.Conversion.SimplePropertyBracesOption">
|
||||||
|
<WrapOpenBrace>
|
||||||
|
<Option>Wrap</Option>
|
||||||
|
</WrapOpenBrace>
|
||||||
|
<WrapCloseBrace>
|
||||||
|
<Option>Wrap</Option>
|
||||||
|
</WrapCloseBrace>
|
||||||
|
</Item>
|
||||||
|
</Options>
|
||||||
|
</Options>
|
||||||
|
</Root>
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
[*]
|
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[*.{bat,cmd,ps1}]
|
|
||||||
end_of_line = crlf
|
|
||||||
|
|
||||||
[*.cs]
|
|
||||||
# CS1591: 缺少对公共可见类型或成员的 XML 注释
|
|
||||||
dotnet_diagnostic.CS1591.severity = suggestion
|
|
||||||
@@ -15,11 +15,11 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
{
|
{
|
||||||
|
|
||||||
private bool _isLookAtAvailable;
|
private bool _isLookAtAvailable;
|
||||||
internal GraphicsMatrix _lookAt;
|
internal GMatrix44<float> _lookAt;
|
||||||
internal GraphicsMatrix _projection;
|
internal GMatrix44<float> _projection;
|
||||||
internal GraphicsMatrix cameraAtt;
|
internal GMatrix44<float> cameraAtt;
|
||||||
internal GraphicsMatrix rotation;
|
internal GMatrix44<float> rotation;
|
||||||
internal GraphicsMatrix rotationAtt;
|
internal GMatrix44<float> rotationAtt;
|
||||||
internal Radius _pitch;
|
internal Radius _pitch;
|
||||||
internal Radius _row;
|
internal Radius _row;
|
||||||
internal Radius _yaw;
|
internal Radius _yaw;
|
||||||
@@ -27,13 +27,13 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
|
|
||||||
public Camera()
|
public Camera()
|
||||||
{
|
{
|
||||||
cameraAtt = GraphicsMatrix.Unit;
|
cameraAtt = GMatrix44<float>.Unit;
|
||||||
_target = Vec3<float>.Zero;
|
_target = Vec3<float>.Zero;
|
||||||
up = Vec3<float>.Zero;
|
up = Vec3<float>.Zero;
|
||||||
_isLookAtAvailable = false;
|
_isLookAtAvailable = false;
|
||||||
_lookAt = GraphicsMatrix.Unit;
|
_lookAt = GMatrix44<float>.Unit;
|
||||||
rotationAtt = GraphicsMatrix.Unit;
|
rotationAtt = GMatrix44<float>.Unit;
|
||||||
_projection = new GraphicsMatrix();
|
_projection = new GMatrix44<float>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Camera(
|
public Camera(
|
||||||
@@ -43,32 +43,32 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
)
|
)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
rotationAtt = GraphicsMatrix.Unit;
|
rotationAtt = GMatrix44<float>.Unit;
|
||||||
cameraAtt = new GraphicsMatrix();
|
cameraAtt = new GMatrix44<float>();
|
||||||
SetViewDirection(position, target, up);
|
SetViewDirection(position, target, up);
|
||||||
_pitch = Radius.Zero;
|
_pitch = Radius.Zero;
|
||||||
_row = Radius.Zero;
|
_row = Radius.Zero;
|
||||||
_yaw = Radius.Zero;
|
_yaw = Radius.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GraphicsMatrix Projection => _projection;
|
public GMatrix44<float> Projection => _projection;
|
||||||
|
|
||||||
public GraphicsMatrix View
|
public GMatrix44<float> View
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_isLookAtAvailable) {
|
if (_isLookAtAvailable) {
|
||||||
return _lookAt;
|
return _lookAt;
|
||||||
}
|
}
|
||||||
GraphicsMatrix move = GraphicsMatrix.Unit;
|
GMatrix44<float> move = GMatrix44<float>.Unit;
|
||||||
move.column[3] -= cameraAtt.column[3];
|
move[3] = move[3] - cameraAtt[3];
|
||||||
_lookAt = rotationAtt.Transpose * move;
|
_lookAt = rotationAtt.Transpose * move;
|
||||||
_isLookAtAvailable = true;
|
_isLookAtAvailable = true;
|
||||||
return _lookAt;
|
return _lookAt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GraphicsMatrix CameraMatrix()
|
public GMatrix44<float> CameraMatrix()
|
||||||
{
|
{
|
||||||
return Projection * View;
|
return Projection * View;
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
float distance
|
float distance
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cameraAtt.column[3].Z -= distance;
|
cameraAtt[3, 2] -= distance;
|
||||||
_isLookAtAvailable = false;
|
_isLookAtAvailable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
float distance
|
float distance
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cameraAtt.column[3].X -= distance;
|
cameraAtt[3, 0] -= distance;
|
||||||
_isLookAtAvailable = false;
|
_isLookAtAvailable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
float distance
|
float distance
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cameraAtt.column[3].Y -= distance;
|
cameraAtt[3, 1] -= distance;
|
||||||
_isLookAtAvailable = false;
|
_isLookAtAvailable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,9 +104,9 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
Vec3<float> direction = position - target;
|
Vec3<float> direction = position - target;
|
||||||
if ((position == cameraAtt.column[3].XYZ) &&
|
if ((position == new Vec3<float>(cameraAtt[3, 0], cameraAtt[3, 1], cameraAtt[3, 2])) &&
|
||||||
(this.up == up) &&
|
(this.up == up) &&
|
||||||
(cameraAtt.column[3].XYZ == direction)) {
|
(new Vec3<float>(cameraAtt[3, 0], cameraAtt[3, 1], cameraAtt[3, 2]) == direction)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (direction.GetLength() == 0)
|
if (direction.GetLength() == 0)
|
||||||
@@ -126,10 +126,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
|
|
||||||
Vec3<float> right = Linear.Orthogonalize(Vec3.Cross(up, direction));
|
Vec3<float> right = Linear.Orthogonalize(Vec3.Cross(up, direction));
|
||||||
|
|
||||||
cameraAtt.column[0].XYZ = right;
|
cameraAtt[0] = new Vec4<float>(right, 0);
|
||||||
cameraAtt.column[1].XYZ = up;
|
cameraAtt[1] = new Vec4<float>(up, 0);
|
||||||
cameraAtt.column[2].XYZ = direction;
|
cameraAtt[2] = new Vec4<float>(direction, 0);
|
||||||
cameraAtt.column[3].XYZ = position;
|
cameraAtt[3] = new Vec4<float>(position, 1);
|
||||||
|
|
||||||
InternalPitch();
|
InternalPitch();
|
||||||
InternalRow();
|
InternalRow();
|
||||||
@@ -152,13 +152,13 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
width = MathF.Abs(GeometryScaler.Tan(fovRadius / 2) * near * 2),
|
width = MathF.Abs(GeometryScaler.Tan(fovRadius / 2) * near * 2),
|
||||||
height = (width * size.Y) / size.X;
|
height = (width * size.Y) / size.X;
|
||||||
|
|
||||||
_projection.column[0].X = (2 * near) / width;
|
_projection[0].X = (2 * near) / width;
|
||||||
_projection.column[1].Y = (2 * near) / height;
|
_projection[1].Y = (2 * near) / height;
|
||||||
_projection.column[2].X = (2 * offsetX) / width;
|
_projection[2].X = (2 * offsetX) / width;
|
||||||
_projection.column[2].Y = (2 * offsetY) / height;
|
_projection[2].Y = (2 * offsetY) / height;
|
||||||
_projection.column[2].Z = (far + near) / (near - far);
|
_projection[2].Z = (far + near) / (near - far);
|
||||||
_projection.column[2].W = -1;
|
_projection[2].W = -1;
|
||||||
_projection.column[3].Z = (2 * near * far) / (near - far);
|
_projection[3].Z = (2 * near * far) / (near - far);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Test(
|
public void Test(
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
// -----------------------------------------------------------------------------
|
|
||||||
// file="EBO"
|
|
||||||
// Project: StgSharp
|
|
||||||
// Copyright (c) Nitload.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace Nitload.Graphics.OpenGL
|
|
||||||
{
|
|
||||||
/// <summary>A set of OpenGL element-buffer handles.</summary>
|
|
||||||
public sealed record class ElementBuffer(
|
|
||||||
GlHandle[] Handles
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
public int Count => Handles.Length;
|
|
||||||
|
|
||||||
public GlHandle this[int index] => Handles[index];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// -----------------------------------------------------------------------------
|
|
||||||
// file="FBO"
|
|
||||||
// Project: StgSharp
|
|
||||||
// Copyright (c) Nitload.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace Nitload.Graphics.OpenGL
|
|
||||||
{
|
|
||||||
/// <summary>A set of OpenGL framebuffer handles.</summary>
|
|
||||||
public sealed record class FrameBuffer(
|
|
||||||
GlHandle[] Handles
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
public int Count => Handles.Length;
|
|
||||||
|
|
||||||
public GlHandle this[int index] => Handles[index];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// -----------------------------------------------------------------------------
|
|
||||||
// file="RBO"
|
|
||||||
// Project: StgSharp
|
|
||||||
// Copyright (c) Nitload.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace Nitload.Graphics.OpenGL
|
|
||||||
{
|
|
||||||
/// <summary>A set of OpenGL renderbuffer handles.</summary>
|
|
||||||
public sealed record class RenderBuffer(
|
|
||||||
GlHandle[] Handles
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
public int Count => Handles.Length;
|
|
||||||
|
|
||||||
public GlHandle this[int index] => Handles[index];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
// -----------------------------------------------------------------------------
|
|
||||||
// file="TextureGL"
|
|
||||||
// Project: StgSharp
|
|
||||||
// Copyright (c) Nitload.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace Nitload.Graphics.OpenGL
|
|
||||||
{
|
|
||||||
/// <summary>A set of OpenGL texture handles.</summary>
|
|
||||||
public sealed record class TextureGL(
|
|
||||||
GlHandle[] Handles
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
public int Count => Handles.Length;
|
|
||||||
|
|
||||||
public GlHandle this[int index] => Handles[index];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly record struct TextureProperty(
|
|
||||||
TextureFilter FilterOnMagnify,
|
|
||||||
TextureFilter FilterOnMinify,
|
|
||||||
TextureWrap WrapOnHorizontal,
|
|
||||||
TextureWrap WrapOnVertical
|
|
||||||
);
|
|
||||||
|
|
||||||
#pragma warning disable CA1008
|
|
||||||
public enum TextureFilter
|
|
||||||
#pragma warning restore CA1008
|
|
||||||
{
|
|
||||||
|
|
||||||
Nearest = glConst.NEAREST,
|
|
||||||
Linear = glConst.LINEAR,
|
|
||||||
NearestLinearMipmap = glConst.NEAREST_MIPMAP_LINEAR,
|
|
||||||
LinearLinearMipmap = glConst.LINEAR_MIPMAP_LINEAR,
|
|
||||||
NearestNearestMipmap = glConst.NEAREST_MIPMAP_NEAREST,
|
|
||||||
LinearNearestMipmap = glConst.LINEAR_MIPMAP_NEAREST,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning disable CA1008
|
|
||||||
public enum TextureWrap
|
|
||||||
#pragma warning restore CA1008
|
|
||||||
{
|
|
||||||
|
|
||||||
Repeat = glConst.REPEAT,
|
|
||||||
MirroredRepeat = glConst.MIRRORED_REPEAT,
|
|
||||||
ClampToEdge = glConst.CLAMP_TO_EDGE,
|
|
||||||
ClampToBorder = glConst.CLAMP_TO_BORDER,
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// -----------------------------------------------------------------------------
|
|
||||||
// file="VAO"
|
|
||||||
// Project: StgSharp
|
|
||||||
// Copyright (c) Nitload.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace Nitload.Graphics.OpenGL
|
|
||||||
{
|
|
||||||
/// <summary>A set of OpenGL vertex-array handles.</summary>
|
|
||||||
public sealed record class VertexArray(
|
|
||||||
GlHandle[] Handles
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
public int Count => Handles.Length;
|
|
||||||
|
|
||||||
public GlHandle this[int index] => Handles[index];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// -----------------------------------------------------------------------------
|
|
||||||
// file="VBO"
|
|
||||||
// Project: StgSharp
|
|
||||||
// Copyright (c) Nitload.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace Nitload.Graphics.OpenGL
|
|
||||||
{
|
|
||||||
/// <summary>A set of OpenGL vertex-buffer handles.</summary>
|
|
||||||
public sealed record class VertexBuffer(
|
|
||||||
GlHandle[] Handles
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
public int Count => Handles.Length;
|
|
||||||
|
|
||||||
public GlHandle this[int index] => Handles[index];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1783,9 +1783,12 @@ namespace Nitload.Graphics.OpenGL
|
|||||||
/// <para>See <see href="https://docs.gl/gl4/glUniform">docs.gl</see>.</para>
|
/// <para>See <see href="https://docs.gl/gl4/glUniform">docs.gl</see>.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Uniform(int location, bool transpose, GraphicsMatrix value)
|
public void Uniform(int location, bool transpose, GMatrix44<float> value)
|
||||||
{
|
{
|
||||||
__context->glUniformMatrix4fv(location, 1, transpose ? (byte)1 : (byte)0, (float*)&value);
|
fixed (GMatrix44<float>* __value = &value)
|
||||||
|
{
|
||||||
|
__context->glUniformMatrix4fv(location, 1, transpose ? (byte)1 : (byte)0, (float*)__value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1794,9 +1797,9 @@ namespace Nitload.Graphics.OpenGL
|
|||||||
/// <para>See <see href="https://docs.gl/gl4/glUniform">docs.gl</see>.</para>
|
/// <para>See <see href="https://docs.gl/gl4/glUniform">docs.gl</see>.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Uniform(int location, bool transpose, ReadOnlySpan<GraphicsMatrix> values)
|
public void Uniform(int location, bool transpose, ReadOnlySpan<GMatrix44<float>> values)
|
||||||
{
|
{
|
||||||
fixed (GraphicsMatrix* __value = values)
|
fixed (GMatrix44<float>* __value = values)
|
||||||
{
|
{
|
||||||
__context->glUniformMatrix4fv(location, values.Length, transpose ? (byte)1 : (byte)0, (float*)__value);
|
__context->glUniformMatrix4fv(location, values.Length, transpose ? (byte)1 : (byte)0, (float*)__value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -631,9 +631,12 @@ namespace Nitload.Graphics.OpenGL
|
|||||||
/// <para>See <see href="https://docs.gl/gl4/glProgramUniform">docs.gl</see>.</para>
|
/// <para>See <see href="https://docs.gl/gl4/glProgramUniform">docs.gl</see>.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void ProgramUniform(GlHandle program, int location, bool transpose, GraphicsMatrix value)
|
public void ProgramUniform(GlHandle program, int location, bool transpose, GMatrix44<float> value)
|
||||||
{
|
{
|
||||||
__context->glProgramUniformMatrix4fv(program.Value, location, 1, transpose ? (byte)1 : (byte)0, (float*)&value);
|
fixed (GMatrix44<float>* __value = &value)
|
||||||
|
{
|
||||||
|
__context->glProgramUniformMatrix4fv(program.Value, location, 1, transpose ? (byte)1 : (byte)0, (float*)__value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -642,9 +645,9 @@ namespace Nitload.Graphics.OpenGL
|
|||||||
/// <para>See <see href="https://docs.gl/gl4/glProgramUniform">docs.gl</see>.</para>
|
/// <para>See <see href="https://docs.gl/gl4/glProgramUniform">docs.gl</see>.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void ProgramUniform(GlHandle program, int location, bool transpose, ReadOnlySpan<GraphicsMatrix> values)
|
public void ProgramUniform(GlHandle program, int location, bool transpose, ReadOnlySpan<GMatrix44<float>> values)
|
||||||
{
|
{
|
||||||
fixed (GraphicsMatrix* __value = values)
|
fixed (GMatrix44<float>* __value = values)
|
||||||
{
|
{
|
||||||
__context->glProgramUniformMatrix4fv(program.Value, location, values.Length, transpose ? (byte)1 : (byte)0, (float*)__value);
|
__context->glProgramUniformMatrix4fv(program.Value, location, values.Length, transpose ? (byte)1 : (byte)0, (float*)__value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,41 +16,61 @@ namespace Nitload.Geometries
|
|||||||
|
|
||||||
private bool globalCoordAvailable;
|
private bool globalCoordAvailable;
|
||||||
private CoordinationBase localCoordination;
|
private CoordinationBase localCoordination;
|
||||||
private GraphicsMatrix coordMat;
|
private GMatrix44<float> coordMat;
|
||||||
|
|
||||||
public CoordinationBase(
|
public CoordinationBase(
|
||||||
CoordinationBase localCoordination
|
CoordinationBase localCoordination
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.localCoordination = localCoordination;
|
this.localCoordination = localCoordination;
|
||||||
coordMat = new GraphicsMatrix();
|
coordMat = new GMatrix44<float>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Point LocalOrigin
|
public virtual Point LocalOrigin
|
||||||
{
|
{
|
||||||
get => new Point(coordMat.column[3].XYZ);
|
get => new Point(new Vec3<float>(coordMat[3, 0], coordMat[3, 1], coordMat[3, 2]));
|
||||||
internal set => coordMat.column[3].XYZ = value.Coord;
|
internal set
|
||||||
|
{
|
||||||
|
coordMat[3, 0] = value.Coord.X;
|
||||||
|
coordMat[3, 1] = value.Coord.Y;
|
||||||
|
coordMat[3, 2] = value.Coord.Z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Vec3<float> LocalX
|
public virtual Vec3<float> LocalX
|
||||||
{
|
{
|
||||||
get => coordMat.column[3].XYZ;
|
get => new Vec3<float>(coordMat[3, 0], coordMat[3, 1], coordMat[3, 2]);
|
||||||
internal set => coordMat.column[3].XYZ = value;
|
internal set
|
||||||
|
{
|
||||||
|
coordMat[3, 0] = value.X;
|
||||||
|
coordMat[3, 1] = value.Y;
|
||||||
|
coordMat[3, 2] = value.Z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Vec3<float> LocalY
|
public virtual Vec3<float> LocalY
|
||||||
{
|
{
|
||||||
get => coordMat.column[3].XYZ;
|
get => new Vec3<float>(coordMat[3, 0], coordMat[3, 1], coordMat[3, 2]);
|
||||||
internal set => coordMat.column[3].XYZ = value;
|
internal set
|
||||||
|
{
|
||||||
|
coordMat[3, 0] = value.X;
|
||||||
|
coordMat[3, 1] = value.Y;
|
||||||
|
coordMat[3, 2] = value.Z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Vec3<float> LocalZ
|
public virtual Vec3<float> LocalZ
|
||||||
{
|
{
|
||||||
get => coordMat.column[3].XYZ;
|
get => new Vec3<float>(coordMat[3, 0], coordMat[3, 1], coordMat[3, 2]);
|
||||||
set => coordMat.column[3].XYZ = value;
|
set
|
||||||
|
{
|
||||||
|
coordMat[3, 0] = value.X;
|
||||||
|
coordMat[3, 1] = value.Y;
|
||||||
|
coordMat[3, 2] = value.Z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ref GraphicsMatrix CoordMat => ref coordMat;
|
protected ref GMatrix44<float> CoordMat => ref coordMat;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ namespace Nitload.Geometries
|
|||||||
)
|
)
|
||||||
: base(local)
|
: base(local)
|
||||||
{
|
{
|
||||||
CoordMat = GraphicsMatrix.Unit;
|
CoordMat = GMatrix44<float>.Unit;
|
||||||
|
|
||||||
CoordMat.column[0] = new Vec4<float>(xAxis, 0);
|
CoordMat[0] = new Vec4<float>(xAxis, 0);
|
||||||
CoordMat.column[1] = new Vec4<float>(yAxis, 0);
|
CoordMat[1] = new Vec4<float>(yAxis, 0);
|
||||||
CoordMat.column[2] = new Vec4<float>(Linear.Normalize(Vec3.Cross(xAxis, yAxis)), 0);
|
CoordMat[2] = new Vec4<float>(Linear.Normalize(Vec3.Cross(xAxis, yAxis)), 0);
|
||||||
|
|
||||||
LocalOrigin = origin;
|
LocalOrigin = origin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,9 +41,7 @@ namespace Nitload.Geometries
|
|||||||
|
|
||||||
public Vec3<float> CenterPositionGlobal { get; internal set; }
|
public Vec3<float> CenterPositionGlobal { get; internal set; }
|
||||||
|
|
||||||
public Vec3<float> Coord//
|
public Vec3<float> Coord { get => GlobalBuffer.CoordAndRotationList[BufferId].XYZ; set
|
||||||
{ get => GlobalBuffer.CoordAndRotationList[BufferId].XYZ;//
|
|
||||||
set
|
|
||||||
{
|
{
|
||||||
Vec4<float> v = new(value, 0);
|
Vec4<float> v = new(value, 0);
|
||||||
GlobalBuffer.CoordAndRotationList[BufferId] = v;
|
GlobalBuffer.CoordAndRotationList[BufferId] = v;
|
||||||
|
|||||||
@@ -0,0 +1,190 @@
|
|||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// file="GMatrix44_T"
|
||||||
|
// Project: StgSharp
|
||||||
|
// Copyright (c) Nitload.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using Nitload.Mathematics;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Intrinsics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Nitload.Mathematics.Numeric.Graphics
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 16)]
|
||||||
|
public struct GMatrix44<T> where T : unmanaged, INumber<T>
|
||||||
|
{
|
||||||
|
|
||||||
|
private Buffer _buffer;
|
||||||
|
|
||||||
|
public Vec4<T> this[
|
||||||
|
int x
|
||||||
|
]
|
||||||
|
{
|
||||||
|
readonly get => _buffer[x];
|
||||||
|
set => _buffer[x] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T this[
|
||||||
|
int x,
|
||||||
|
int y
|
||||||
|
]
|
||||||
|
{
|
||||||
|
readonly get => _buffer[x][y];
|
||||||
|
set => _buffer[x][y] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GMatrix44<T> Unit
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
GMatrix44<T> result = new();
|
||||||
|
result[0] = new Vec4<T>(T.One, T.Zero, T.Zero, T.Zero);
|
||||||
|
result[1] = new Vec4<T>(T.Zero, T.One, T.Zero, T.Zero);
|
||||||
|
result[2] = new Vec4<T>(T.Zero, T.Zero, T.One, T.Zero);
|
||||||
|
result[3] = new Vec4<T>(T.Zero, T.Zero, T.Zero, T.One);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GMatrix44<T> Transpose
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
GMatrix44<T> transpose = new();
|
||||||
|
|
||||||
|
// Native SK transpose is intentionally deferred until the module
|
||||||
|
// startup path can guarantee that GlobalContext has been initialized.
|
||||||
|
|
||||||
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
|
{
|
||||||
|
Vector128<T> row0Source = _buffer[0].AsVector128Unsafe();
|
||||||
|
Vector128<T> row1Source = _buffer[1].AsVector128Unsafe();
|
||||||
|
Vector128<T> row2Source = _buffer[2].AsVector128Unsafe();
|
||||||
|
Vector128<T> row3Source = _buffer[3].AsVector128Unsafe();
|
||||||
|
Vector128<int> row0 = Unsafe.As<Vector128<T>, Vector128<int>>(ref row0Source);
|
||||||
|
Vector128<int> row1 = Unsafe.As<Vector128<T>, Vector128<int>>(ref row1Source);
|
||||||
|
Vector128<int> row2 = Unsafe.As<Vector128<T>, Vector128<int>>(ref row2Source);
|
||||||
|
Vector128<int> row3 = Unsafe.As<Vector128<T>, Vector128<int>>(ref row3Source);
|
||||||
|
|
||||||
|
Vector128<int> pairMask = Vector128.Create(-1, 0, -1, 0);
|
||||||
|
Vector128<int> firstPairMask = Vector128.Create(-1, -1, 0, 0);
|
||||||
|
Vector128<int> lowShuffle = Vector128.Create(0, 0, 1, 1);
|
||||||
|
Vector128<int> highShuffle = Vector128.Create(2, 2, 3, 3);
|
||||||
|
Vector128<int> secondLaneShuffle = Vector128.Create(2, 3, 2, 3);
|
||||||
|
|
||||||
|
Vector128<int> pair01Low = Vector128.ConditionalSelect(
|
||||||
|
pairMask,
|
||||||
|
Vector128.Shuffle(row0, lowShuffle),
|
||||||
|
Vector128.Shuffle(row1, lowShuffle));
|
||||||
|
Vector128<int> pair23Low = Vector128.ConditionalSelect(
|
||||||
|
pairMask,
|
||||||
|
Vector128.Shuffle(row2, lowShuffle),
|
||||||
|
Vector128.Shuffle(row3, lowShuffle));
|
||||||
|
Vector128<int> pair01High = Vector128.ConditionalSelect(
|
||||||
|
pairMask,
|
||||||
|
Vector128.Shuffle(row0, highShuffle),
|
||||||
|
Vector128.Shuffle(row1, highShuffle));
|
||||||
|
Vector128<int> pair23High = Vector128.ConditionalSelect(
|
||||||
|
pairMask,
|
||||||
|
Vector128.Shuffle(row2, highShuffle),
|
||||||
|
Vector128.Shuffle(row3, highShuffle));
|
||||||
|
|
||||||
|
Vector128<int> result0 = Vector128.ConditionalSelect(
|
||||||
|
firstPairMask, pair01Low, pair23Low);
|
||||||
|
Vector128<int> result1 = Vector128.ConditionalSelect(
|
||||||
|
firstPairMask,
|
||||||
|
Vector128.Shuffle(pair01Low, secondLaneShuffle),
|
||||||
|
Vector128.Shuffle(pair23Low, secondLaneShuffle));
|
||||||
|
Vector128<int> result2 = Vector128.ConditionalSelect(
|
||||||
|
firstPairMask, pair01High, pair23High);
|
||||||
|
Vector128<int> result3 = Vector128.ConditionalSelect(
|
||||||
|
firstPairMask,
|
||||||
|
Vector128.Shuffle(pair01High, secondLaneShuffle),
|
||||||
|
Vector128.Shuffle(pair23High, secondLaneShuffle));
|
||||||
|
transpose._buffer[0] = Vec4.FromVector128Unsafe(
|
||||||
|
Unsafe.As<Vector128<int>, Vector128<T>>(ref result0));
|
||||||
|
transpose._buffer[1] = Vec4.FromVector128Unsafe(
|
||||||
|
Unsafe.As<Vector128<int>, Vector128<T>>(ref result1));
|
||||||
|
transpose._buffer[2] = Vec4.FromVector128Unsafe(
|
||||||
|
Unsafe.As<Vector128<int>, Vector128<T>>(ref result2));
|
||||||
|
transpose._buffer[3] = Vec4.FromVector128Unsafe(
|
||||||
|
Unsafe.As<Vector128<int>, Vector128<T>>(ref result3));
|
||||||
|
return transpose;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Unsafe.SizeOf<T>() == 8)
|
||||||
|
{
|
||||||
|
Vector256<T> row0Source = _buffer[0].AsVector256Unsafe();
|
||||||
|
Vector256<T> row1Source = _buffer[1].AsVector256Unsafe();
|
||||||
|
Vector256<T> row2Source = _buffer[2].AsVector256Unsafe();
|
||||||
|
Vector256<T> row3Source = _buffer[3].AsVector256Unsafe();
|
||||||
|
Vector256<long> row0 = Unsafe.As<Vector256<T>, Vector256<long>>(ref row0Source);
|
||||||
|
Vector256<long> row1 = Unsafe.As<Vector256<T>, Vector256<long>>(ref row1Source);
|
||||||
|
Vector256<long> row2 = Unsafe.As<Vector256<T>, Vector256<long>>(ref row2Source);
|
||||||
|
Vector256<long> row3 = Unsafe.As<Vector256<T>, Vector256<long>>(ref row3Source);
|
||||||
|
|
||||||
|
Vector256<long> pairMask = Vector256.Create(-1L, 0L, -1L, 0L);
|
||||||
|
Vector256<long> firstPairMask = Vector256.Create(-1L, -1L, 0L, 0L);
|
||||||
|
Vector256<long> firstShuffle = Vector256.Create(0L, 0L, 1L, 1L);
|
||||||
|
Vector256<long> secondShuffle = Vector256.Create(2L, 2L, 3L, 3L);
|
||||||
|
Vector256<long> pair01First = Vector256.ConditionalSelect(
|
||||||
|
pairMask,
|
||||||
|
Vector256.Shuffle(row0, firstShuffle),
|
||||||
|
Vector256.Shuffle(row1, firstShuffle));
|
||||||
|
Vector256<long> pair23First = Vector256.ConditionalSelect(
|
||||||
|
pairMask,
|
||||||
|
Vector256.Shuffle(row2, firstShuffle),
|
||||||
|
Vector256.Shuffle(row3, firstShuffle));
|
||||||
|
Vector256<long> pair01Second = Vector256.ConditionalSelect(
|
||||||
|
pairMask,
|
||||||
|
Vector256.Shuffle(row0, secondShuffle),
|
||||||
|
Vector256.Shuffle(row1, secondShuffle));
|
||||||
|
Vector256<long> pair23Second = Vector256.ConditionalSelect(
|
||||||
|
pairMask,
|
||||||
|
Vector256.Shuffle(row2, secondShuffle),
|
||||||
|
Vector256.Shuffle(row3, secondShuffle));
|
||||||
|
Vector256<long> result0 = Vector256.ConditionalSelect(
|
||||||
|
firstPairMask, pair01First, pair23First);
|
||||||
|
Vector256<long> result1 = Vector256.ConditionalSelect(
|
||||||
|
firstPairMask,
|
||||||
|
Vector256.Shuffle(pair01First, secondShuffle),
|
||||||
|
Vector256.Shuffle(pair23First, secondShuffle));
|
||||||
|
Vector256<long> result2 = Vector256.ConditionalSelect(
|
||||||
|
firstPairMask, pair01Second, pair23Second);
|
||||||
|
Vector256<long> result3 = Vector256.ConditionalSelect(
|
||||||
|
firstPairMask,
|
||||||
|
Vector256.Shuffle(pair01Second, secondShuffle),
|
||||||
|
Vector256.Shuffle(pair23Second, secondShuffle));
|
||||||
|
transpose._buffer[0] = Vec4.FromVector256Unsafe(
|
||||||
|
Unsafe.As<Vector256<long>, Vector256<T>>(ref result0));
|
||||||
|
transpose._buffer[1] = Vec4.FromVector256Unsafe(
|
||||||
|
Unsafe.As<Vector256<long>, Vector256<T>>(ref result1));
|
||||||
|
transpose._buffer[2] = Vec4.FromVector256Unsafe(
|
||||||
|
Unsafe.As<Vector256<long>, Vector256<T>>(ref result2));
|
||||||
|
transpose._buffer[3] = Vec4.FromVector256Unsafe(
|
||||||
|
Unsafe.As<Vector256<long>, Vector256<T>>(ref result3));
|
||||||
|
return transpose;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[InlineArray(4)]
|
||||||
|
private struct Buffer
|
||||||
|
{
|
||||||
|
|
||||||
|
public Vec4<T> _column;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,261 +0,0 @@
|
|||||||
// -----------------------------------------------------------------------------
|
|
||||||
// file="GraphicsMatrix"
|
|
||||||
// Project: StgSharp
|
|
||||||
// Copyright (c) Nitload.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
using Nitload.Mathematics;
|
|
||||||
using Nitload.Mathematics.Internal;
|
|
||||||
using Nitload.Mathematics.Numeric;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Numerics;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Runtime.Intrinsics.X86;
|
|
||||||
|
|
||||||
namespace Nitload.Mathematics.Numeric.Graphics
|
|
||||||
{
|
|
||||||
[StructLayout(LayoutKind.Explicit, Size = 16 * sizeof(float), Pack = 16)]
|
|
||||||
public unsafe struct GraphicsMatrix : IEquatable<GraphicsMatrix>
|
|
||||||
{
|
|
||||||
|
|
||||||
[FieldOffset(0 * sizeof(float))] internal Column column;
|
|
||||||
|
|
||||||
[FieldOffset(0)] internal ColumnSet4 mat;
|
|
||||||
[FieldOffset(0)] internal MatrixKernel<float> kernel;
|
|
||||||
|
|
||||||
internal GraphicsMatrix(
|
|
||||||
ColumnSet4 mat
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Unsafe.SkipInit(out this);
|
|
||||||
this.mat = mat;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal GraphicsMatrix(
|
|
||||||
Vector4 vec0,
|
|
||||||
Vector4 vec1,
|
|
||||||
Vector4 vec2,
|
|
||||||
Vector4 vec3
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Unsafe.SkipInit(out this);
|
|
||||||
mat.colum0 = vec0;
|
|
||||||
mat.colum1 = vec1;
|
|
||||||
mat.colum2 = vec2;
|
|
||||||
mat.colum3 = vec3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GraphicsMatrix()
|
|
||||||
{
|
|
||||||
Unsafe.SkipInit(out this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe GraphicsMatrix(
|
|
||||||
float a00,
|
|
||||||
float a01,
|
|
||||||
float a02,
|
|
||||||
float a03,
|
|
||||||
float a10,
|
|
||||||
float a11,
|
|
||||||
float a12,
|
|
||||||
float a13,
|
|
||||||
float a20,
|
|
||||||
float a21,
|
|
||||||
float a22,
|
|
||||||
float a23,
|
|
||||||
float a30,
|
|
||||||
float a31,
|
|
||||||
float a32,
|
|
||||||
float a33
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Unsafe.SkipInit(out this);
|
|
||||||
mat.colum0 = new Vector4(a00, a10, a20, a30);
|
|
||||||
mat.colum1 = new Vector4(a01, a11, a21, a31);
|
|
||||||
mat.colum2 = new Vector4(a02, a12, a22, a32);
|
|
||||||
mat.colum3 = new Vector4(a03, a13, a23, a33);
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe float this[
|
|
||||||
int rowNum,
|
|
||||||
int columNum
|
|
||||||
]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
if (rowNum is > 3 or < 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(columNum));
|
|
||||||
}
|
|
||||||
if (columNum is > 3 or < 0) {
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(columNum));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return kernel[rowNum + (4 * columNum)];
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
if (rowNum is > 3 or < 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(columNum));
|
|
||||||
}
|
|
||||||
if (columNum is > 3 or < 0) {
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(columNum));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
kernel[rowNum + (4 * columNum)] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public GraphicsMatrix Transpose
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
GraphicsMatrix transpose = new();
|
|
||||||
InternalTranspose(ref transpose);
|
|
||||||
return transpose;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GraphicsMatrix Unit => new GraphicsMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0,
|
|
||||||
0, 0, 0, 1);
|
|
||||||
|
|
||||||
public static GraphicsMatrix WNegativeUnit => new GraphicsMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0,
|
|
||||||
0, 1, 0, 0, 0, 0, -1);
|
|
||||||
|
|
||||||
public static GraphicsMatrix XNegativeUnit => new GraphicsMatrix(-1, 0, 0, 0, 0, 1, 0, 0, 0,
|
|
||||||
0, 1, 0, 0, 0, 0, 1);
|
|
||||||
|
|
||||||
public static GraphicsMatrix YNegativeUnit => new GraphicsMatrix(1, 0, 0, 0, 0, -1, 0, 0, 0,
|
|
||||||
0, 1, 0, 0, 0, 0, 1);
|
|
||||||
|
|
||||||
public static GraphicsMatrix ZNegativeUnit => new GraphicsMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0,
|
|
||||||
0, -1, 0, 0, 0, 0, 1);
|
|
||||||
|
|
||||||
public ReadOnlySpan<float> AsSpan()
|
|
||||||
{
|
|
||||||
return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<ColumnSet4, float>(ref mat), 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(
|
|
||||||
object? obj
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return (obj is GraphicsMatrix x) && Equals(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(
|
|
||||||
GraphicsMatrix other
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return mat.Equals(other.mat);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return HashCode.Combine(mat.colum0.GetHashCode(), mat.colum1.GetHashCode(),
|
|
||||||
mat.colum2.GetHashCode(), mat.colum3.GetHashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
internal unsafe void InternalTranspose(
|
|
||||||
ref GraphicsMatrix transpose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const int f32 = 0;
|
|
||||||
fixed (MatrixKernel<float>* source = &this.kernel, target = &transpose.kernel) {
|
|
||||||
NumericalModule.GlobalContext.mat_sk[f32].Call(MatrixIntrinsicHandle.Transpose,
|
|
||||||
null, (MatrixKernel*)source,
|
|
||||||
(MatrixKernel*)target, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static unsafe GraphicsMatrix operator -(
|
|
||||||
GraphicsMatrix left,
|
|
||||||
GraphicsMatrix right
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GraphicsMatrix ret = new();
|
|
||||||
int f32 = MatrixElementType.F32.IntrinsicNode;
|
|
||||||
NumericalModule.GlobalContext.mat_sk[f32].Call(MatrixIntrinsicHandle.Sub,
|
|
||||||
(MatrixKernel*)&left.kernel,
|
|
||||||
(MatrixKernel*)&right.kernel,
|
|
||||||
(MatrixKernel*)&ret.kernel, 1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(
|
|
||||||
GraphicsMatrix left,
|
|
||||||
GraphicsMatrix right
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return !(left == right);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static unsafe GraphicsMatrix operator *(
|
|
||||||
GraphicsMatrix mat,
|
|
||||||
float value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int f32 = MatrixElementType.F32.IntrinsicNode;
|
|
||||||
return new GraphicsMatrix(mat.mat.colum0 * value, mat.mat.colum1 * value,
|
|
||||||
mat.mat.colum2 * value, mat.mat.colum3 * value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static GraphicsMatrix operator *(
|
|
||||||
GraphicsMatrix left,
|
|
||||||
GraphicsMatrix right
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GraphicsMatrix ret = new();
|
|
||||||
int f32 = MatrixElementType.F32.IntrinsicNode;
|
|
||||||
NumericalModule.GlobalContext.mat_sk[f32].Call(MatrixIntrinsicHandle.Fma,
|
|
||||||
(MatrixKernel*)&left,
|
|
||||||
(MatrixKernel*)&right,
|
|
||||||
(MatrixKernel*)&ret, 0);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static unsafe GraphicsMatrix operator +(
|
|
||||||
GraphicsMatrix left,
|
|
||||||
GraphicsMatrix right
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GraphicsMatrix ret = new();
|
|
||||||
int f32 = MatrixElementType.F32.IntrinsicNode;
|
|
||||||
NumericalModule.GlobalContext.mat_sk[f32].Call(MatrixIntrinsicHandle.Add,
|
|
||||||
(MatrixKernel*)&left,
|
|
||||||
(MatrixKernel*)&right,
|
|
||||||
(MatrixKernel*)&ret, 1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator ==(
|
|
||||||
GraphicsMatrix left,
|
|
||||||
GraphicsMatrix right
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return left.Equals(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
[InlineArray(4)]
|
|
||||||
internal struct Column
|
|
||||||
{
|
|
||||||
|
|
||||||
private Vec4<float> value;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -15,13 +15,61 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
public static class Vec3
|
public static class Vec3
|
||||||
{
|
{
|
||||||
|
|
||||||
public static bool IsParallel<T>(Vec3<T> left, Vec3<T> right) where T: unmanaged,INumber<T>
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Vec3<double> ConvertToDouble(
|
||||||
|
Vec3<long> source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FromVector256Unsafe(Vector256.ConvertToDouble(source.AsVector256Safe()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Vec3<double> ConvertToDouble(
|
||||||
|
Vec3<ulong> source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FromVector256Unsafe(Vector256.ConvertToDouble(source.AsVector256Safe()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Vec3<float> ConvertToSingle(
|
||||||
|
Vec3<int> source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FromVector128Unsafe(Vector128.ConvertToSingle(source.AsVector128Safe()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Vec3<float> ConvertToSingle(
|
||||||
|
Vec3<uint> source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FromVector128Unsafe(Vector128.ConvertToSingle(source.AsVector128Safe()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3<T> FromSpan<T>(
|
||||||
|
ReadOnlySpan<T> span
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
|
{
|
||||||
|
if (span.Length < 3) {
|
||||||
|
throw new ArgumentException("Span length must be at least 3.", nameof(span));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new(span[0], span[1], span[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsParallel<T>(
|
||||||
|
Vec3<T> left,
|
||||||
|
Vec3<T> right
|
||||||
|
) where T : unmanaged,INumber<T>
|
||||||
{
|
{
|
||||||
return Cross(left, right).Equals(T.Zero);
|
return Cross(left, right).Equals(T.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vector128<T> AsVector128Safe<T>(this Vec3<T> source) where T: unmanaged, INumber<T>
|
internal static Vector128<T> AsVector128Safe<T>(
|
||||||
|
this Vec3<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
Vector128<T> result = Vector128<T>.Zero;
|
Vector128<T> result = Vector128<T>.Zero;
|
||||||
Unsafe.WriteUnaligned(ref Unsafe.As<Vector128<T>, byte>(ref result), source);
|
Unsafe.WriteUnaligned(ref Unsafe.As<Vector128<T>, byte>(ref result), source);
|
||||||
@@ -29,7 +77,9 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vector128<T> AsVector128Unsafe<T>(this Vec3<T> source) where T: unmanaged, INumber<T>
|
internal static Vector128<T> AsVector128Unsafe<T>(
|
||||||
|
this Vec3<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
Unsafe.SkipInit(out Vector128<T> result);
|
Unsafe.SkipInit(out Vector128<T> result);
|
||||||
Unsafe.WriteUnaligned(ref Unsafe.As<Vector128<T>, byte>(ref result), source);
|
Unsafe.WriteUnaligned(ref Unsafe.As<Vector128<T>, byte>(ref result), source);
|
||||||
@@ -37,7 +87,9 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vector256<T> AsVector256Safe<T>(this Vec3<T> source) where T: unmanaged, INumber<T>
|
internal static Vector256<T> AsVector256Safe<T>(
|
||||||
|
this Vec3<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
Vector256<T> result = Vector256<T>.Zero;
|
Vector256<T> result = Vector256<T>.Zero;
|
||||||
Unsafe.WriteUnaligned(ref Unsafe.As<Vector256<T>, byte>(ref result), source);
|
Unsafe.WriteUnaligned(ref Unsafe.As<Vector256<T>, byte>(ref result), source);
|
||||||
@@ -45,7 +97,9 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vector256<T> AsVector256Unsafe<T>(this Vec3<T> source) where T: unmanaged, INumber<T>
|
internal static Vector256<T> AsVector256Unsafe<T>(
|
||||||
|
this Vec3<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
Unsafe.SkipInit(out Vector256<T> result);
|
Unsafe.SkipInit(out Vector256<T> result);
|
||||||
Unsafe.WriteUnaligned(ref Unsafe.As<Vector256<T>, byte>(ref result), source);
|
Unsafe.WriteUnaligned(ref Unsafe.As<Vector256<T>, byte>(ref result), source);
|
||||||
@@ -53,45 +107,28 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vec3<T> FromVector128Unsafe<T>(Vector128<T> source) where T: unmanaged, INumber<T>
|
internal static Vec3<T> FromVector128Unsafe<T>(
|
||||||
|
Vector128<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
return Unsafe.As<Vector128<T>, Vec3<T>>(ref source);
|
return Unsafe.As<Vector128<T>, Vec3<T>>(ref source);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vec3<T> FromVector256Unsafe<T>(Vector256<T> source) where T: unmanaged, INumber<T>
|
internal static Vec3<T> FromVector256Unsafe<T>(
|
||||||
|
Vector256<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
return Unsafe.As<Vector256<T>, Vec3<T>>(ref source);
|
return Unsafe.As<Vector256<T>, Vec3<T>>(ref source);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static Vec3<float> ConvertToSingle(Vec3<int> source)
|
|
||||||
{
|
|
||||||
return FromVector128Unsafe(Vector128.ConvertToSingle(source.AsVector128Safe()));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static Vec3<float> ConvertToSingle(Vec3<uint> source)
|
|
||||||
{
|
|
||||||
return FromVector128Unsafe(Vector128.ConvertToSingle(source.AsVector128Safe()));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static Vec3<double> ConvertToDouble(Vec3<long> source)
|
|
||||||
{
|
|
||||||
return FromVector256Unsafe(Vector256.ConvertToDouble(source.AsVector256Safe()));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static Vec3<double> ConvertToDouble(Vec3<ulong> source)
|
|
||||||
{
|
|
||||||
return FromVector256Unsafe(Vector256.ConvertToDouble(source.AsVector256Safe()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#region cross
|
#region cross
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vec3<T> Cross<T>(Vec3<T> left, Vec3<T> right) where T: unmanaged, INumber<T>
|
public static Vec3<T> Cross<T>(
|
||||||
|
Vec3<T> left,
|
||||||
|
Vec3<T> right
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
if (typeof(T) == typeof(float))
|
if (typeof(T) == typeof(float))
|
||||||
{
|
{
|
||||||
@@ -140,7 +177,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static Vec3<double> CrossDouble(Vec3<double> left, Vec3<double> right)
|
private static Vec3<double> CrossDouble(
|
||||||
|
Vec3<double> left,
|
||||||
|
Vec3<double> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Vector256<double> l = left.AsVector256Safe();
|
Vector256<double> l = left.AsVector256Safe();
|
||||||
Vector256<double> r = right.AsVector256Safe();
|
Vector256<double> r = right.AsVector256Safe();
|
||||||
@@ -151,7 +191,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static Vec3<int> CrossInt32(Vec3<int> left, Vec3<int> right)
|
private static Vec3<int> CrossInt32(
|
||||||
|
Vec3<int> left,
|
||||||
|
Vec3<int> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Vector128<int> l = left.AsVector128Safe();
|
Vector128<int> l = left.AsVector128Safe();
|
||||||
Vector128<int> r = right.AsVector128Safe();
|
Vector128<int> r = right.AsVector128Safe();
|
||||||
@@ -162,7 +205,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static Vec3<float> CrossSingle(Vec3<float> left, Vec3<float> right)
|
private static Vec3<float> CrossSingle(
|
||||||
|
Vec3<float> left,
|
||||||
|
Vec3<float> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Vector128<float> l = left.AsVector128Safe();
|
Vector128<float> l = left.AsVector128Safe();
|
||||||
Vector128<float> r = right.AsVector128Safe();
|
Vector128<float> r = right.AsVector128Safe();
|
||||||
@@ -173,7 +219,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static Vec3<uint> CrossUInt32(Vec3<uint> left, Vec3<uint> right)
|
private static Vec3<uint> CrossUInt32(
|
||||||
|
Vec3<uint> left,
|
||||||
|
Vec3<uint> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Vector128<uint> l = left.AsVector128Safe();
|
Vector128<uint> l = left.AsVector128Safe();
|
||||||
Vector128<uint> r = right.AsVector128Safe();
|
Vector128<uint> r = right.AsVector128Safe();
|
||||||
@@ -184,7 +233,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static Vec3<ulong> CrossUInt64(Vec3<ulong> left, Vec3<ulong> right)
|
private static Vec3<ulong> CrossUInt64(
|
||||||
|
Vec3<ulong> left,
|
||||||
|
Vec3<ulong> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Vector256<ulong> l = left.AsVector256Safe();
|
Vector256<ulong> l = left.AsVector256Safe();
|
||||||
Vector256<ulong> r = right.AsVector256Safe();
|
Vector256<ulong> r = right.AsVector256Safe();
|
||||||
@@ -195,7 +247,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static Vec3<long> CrossInt64(Vec3<long> left, Vec3<long> right)
|
private static Vec3<long> CrossInt64(
|
||||||
|
Vec3<long> left,
|
||||||
|
Vec3<long> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Vector256<long> l = left.AsVector256Safe();
|
Vector256<long> l = left.AsVector256Safe();
|
||||||
Vector256<long> r = right.AsVector256Safe();
|
Vector256<long> r = right.AsVector256Safe();
|
||||||
|
|||||||
@@ -28,14 +28,21 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
public T Y;
|
public T Y;
|
||||||
public T Z;
|
public T Z;
|
||||||
|
|
||||||
public Vec3(Vec2<T> xy, T z)
|
public Vec3(
|
||||||
|
Vec2<T> xy,
|
||||||
|
T z
|
||||||
|
)
|
||||||
{
|
{
|
||||||
X = xy.X;
|
X = xy.X;
|
||||||
Y = xy.Y;
|
Y = xy.Y;
|
||||||
Z = z;
|
Z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3(T x, T y, T z)
|
public Vec3(
|
||||||
|
T x,
|
||||||
|
T y,
|
||||||
|
T z
|
||||||
|
)
|
||||||
{
|
{
|
||||||
X = x;
|
X = x;
|
||||||
Y = y;
|
Y = y;
|
||||||
@@ -73,7 +80,9 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
public static Vec3<T> UnitZ => new(T.Zero, T.Zero, T.One);
|
public static Vec3<T> UnitZ => new(T.Zero, T.Zero, T.One);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly T Dot(Vec3<T> right)
|
public readonly T Dot(
|
||||||
|
Vec3<T> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 8)
|
if (Unsafe.SizeOf<T>() == 8)
|
||||||
{
|
{
|
||||||
@@ -89,31 +98,28 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly bool Equals(Vec3<T> other)
|
public readonly bool Equals(
|
||||||
|
Vec3<T> other
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4) {
|
|
||||||
return this.AsVector128Safe() == other.AsVector128Safe();
|
return this.AsVector128Safe() == other.AsVector128Safe();
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8) {
|
||||||
if (Unsafe.SizeOf<T>() == 8) {
|
|
||||||
return this.AsVector256Safe() == other.AsVector256Safe();
|
return this.AsVector256Safe() == other.AsVector256Safe();
|
||||||
}
|
}
|
||||||
|
#pragma warning disable CA1065
|
||||||
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
|
#pragma warning restore CA1065
|
||||||
}
|
}
|
||||||
|
|
||||||
public override readonly bool Equals(object? obj)
|
public override readonly bool Equals(
|
||||||
|
object? obj
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return obj is Vec3<T> other && Equals(other);
|
return obj is Vec3<T> other && Equals(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec3<T> FromSpan(ReadOnlySpan<T> span)
|
|
||||||
{
|
|
||||||
if (span.Length < 3) {
|
|
||||||
throw new ArgumentException("Span length must be at least 3.", nameof(span));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new(span[0], span[1], span[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly IEnumerator<T> GetEnumerator()
|
public readonly IEnumerator<T> GetEnumerator()
|
||||||
{
|
{
|
||||||
yield return X;
|
yield return X;
|
||||||
@@ -132,33 +138,40 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
return T.Max(X, T.Max(Y, Z));
|
return T.Max(X, T.Max(Y, Z));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsParallel(Vec3<T> left, Vec3<T> right)
|
public static bool IsParallel(
|
||||||
|
Vec3<T> left,
|
||||||
|
Vec3<T> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return Vec3.Cross(left, right) == Zero;
|
return Vec3.Cross(left, right) == Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vec3<T> operator -(Vec3<T> value)
|
public static Vec3<T> operator -(
|
||||||
|
Vec3<T> value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4) {
|
|
||||||
return Vec3.FromVector128Unsafe(Vector128<T>.Zero - value.AsVector128Unsafe());
|
return Vec3.FromVector128Unsafe(Vector128<T>.Zero - value.AsVector128Unsafe());
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8) {
|
||||||
if (Unsafe.SizeOf<T>() == 8) {
|
|
||||||
return Vec3.FromVector256Unsafe(Vector256<T>.Zero - value.AsVector256Unsafe());
|
return Vec3.FromVector256Unsafe(Vector256<T>.Zero - value.AsVector256Unsafe());
|
||||||
}
|
}
|
||||||
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vec3<T> operator -(Vec3<T> left, Vec3<T> right)
|
public static Vec3<T> operator -(
|
||||||
|
Vec3<T> left,
|
||||||
|
Vec3<T> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4)
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
{
|
{
|
||||||
Vector128<T> left_v128 = left.AsVector128Unsafe();
|
Vector128<T> left_v128 = left.AsVector128Unsafe();
|
||||||
Vector128<T> right_v128 = right.AsVector128Unsafe();
|
Vector128<T> right_v128 = right.AsVector128Unsafe();
|
||||||
return Vec3.FromVector128Unsafe(left_v128 - right_v128);
|
return Vec3.FromVector128Unsafe(left_v128 - right_v128);
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8)
|
||||||
if (Unsafe.SizeOf<T>() == 8)
|
|
||||||
{
|
{
|
||||||
Vector256<T> left_v256 = left.AsVector256Unsafe();
|
Vector256<T> left_v256 = left.AsVector256Unsafe();
|
||||||
Vector256<T> right_v256 = right.AsVector256Unsafe();
|
Vector256<T> right_v256 = right.AsVector256Unsafe();
|
||||||
@@ -168,21 +181,26 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool operator !=(Vec3<T> left, Vec3<T> right)
|
public static bool operator !=(
|
||||||
|
Vec3<T> left,
|
||||||
|
Vec3<T> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return !left.Equals(right);
|
return !left.Equals(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vec3<T> operator *(Vec3<T> vector, T scalar)
|
public static Vec3<T> operator *(
|
||||||
|
Vec3<T> vector,
|
||||||
|
T scalar
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4)
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
{
|
{
|
||||||
Vector128<T> vector_v128 = vector.AsVector128Unsafe();
|
Vector128<T> vector_v128 = vector.AsVector128Unsafe();
|
||||||
Vector128<T> scalar_v128 = Vector128.Create(scalar);
|
Vector128<T> scalar_v128 = Vector128.Create(scalar);
|
||||||
return Vec3.FromVector128Unsafe(vector_v128 * scalar_v128);
|
return Vec3.FromVector128Unsafe(vector_v128 * scalar_v128);
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8)
|
||||||
if (Unsafe.SizeOf<T>() == 8)
|
|
||||||
{
|
{
|
||||||
Vector256<T> vector_v256 = vector.AsVector256Unsafe();
|
Vector256<T> vector_v256 = vector.AsVector256Unsafe();
|
||||||
Vector256<T> scalar_v256 = Vector256.Create(scalar);
|
Vector256<T> scalar_v256 = Vector256.Create(scalar);
|
||||||
@@ -192,27 +210,35 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vec3<T> operator *(T scalar, Vec3<T> vector)
|
public static Vec3<T> operator *(
|
||||||
|
T scalar,
|
||||||
|
Vec3<T> vector
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return vector * scalar;
|
return vector * scalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static T operator *(Vec3<T> left, Vec3<T> right)
|
public static T operator *(
|
||||||
|
Vec3<T> left,
|
||||||
|
Vec3<T> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return left.Dot(right);
|
return left.Dot(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vec3<T> operator /(Vec3<T> vector, T scalar)
|
public static Vec3<T> operator /(
|
||||||
|
Vec3<T> vector,
|
||||||
|
T scalar
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4)
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
{
|
{
|
||||||
Vector128<T> vector_v128 = vector.AsVector128Unsafe();
|
Vector128<T> vector_v128 = vector.AsVector128Unsafe();
|
||||||
Vector128<T> scalar_v128 = Vector128.Create(scalar);
|
Vector128<T> scalar_v128 = Vector128.Create(scalar);
|
||||||
return Vec3.FromVector128Unsafe(vector_v128 / scalar_v128);
|
return Vec3.FromVector128Unsafe(vector_v128 / scalar_v128);
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8)
|
||||||
if (Unsafe.SizeOf<T>() == 8)
|
|
||||||
{
|
{
|
||||||
Vector256<T> vector_v256 = vector.AsVector256Unsafe();
|
Vector256<T> vector_v256 = vector.AsVector256Unsafe();
|
||||||
Vector256<T> scalar_v256 = Vector256.Create(scalar);
|
Vector256<T> scalar_v256 = Vector256.Create(scalar);
|
||||||
@@ -222,15 +248,17 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vec3<T> operator +(Vec3<T> left, Vec3<T> right)
|
public static Vec3<T> operator +(
|
||||||
|
Vec3<T> left,
|
||||||
|
Vec3<T> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4)
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
{
|
{
|
||||||
Vector128<T> left_v128 = left.AsVector128Unsafe();
|
Vector128<T> left_v128 = left.AsVector128Unsafe();
|
||||||
Vector128<T> right_v128 = right.AsVector128Unsafe();
|
Vector128<T> right_v128 = right.AsVector128Unsafe();
|
||||||
return Vec3.FromVector128Unsafe(left_v128 + right_v128);
|
return Vec3.FromVector128Unsafe(left_v128 + right_v128);
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8)
|
||||||
if (Unsafe.SizeOf<T>() == 8)
|
|
||||||
{
|
{
|
||||||
Vector256<T> left_v256 = left.AsVector256Unsafe();
|
Vector256<T> left_v256 = left.AsVector256Unsafe();
|
||||||
Vector256<T> right_v256 = right.AsVector256Unsafe();
|
Vector256<T> right_v256 = right.AsVector256Unsafe();
|
||||||
@@ -240,13 +268,18 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool operator ==(Vec3<T> left, Vec3<T> right)
|
public static bool operator ==(
|
||||||
|
Vec3<T> left,
|
||||||
|
Vec3<T> right
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return left.Equals(right);
|
return left.Equals(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator Vec3<T>((T X, T Y, T Z) tuple)
|
public static implicit operator Vec3<T>(
|
||||||
|
(T X, T Y, T Z) tuple
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return new(tuple.X, tuple.Y, tuple.Z);
|
return new(tuple.X, tuple.Y, tuple.Z);
|
||||||
}
|
}
|
||||||
@@ -256,5 +289,13 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
return GetEnumerator();
|
return GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[InlineArray(3)]
|
||||||
|
private struct Buffer
|
||||||
|
{
|
||||||
|
|
||||||
|
internal T _element;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
|
|
||||||
namespace Nitload.Mathematics.Numeric.Graphics
|
namespace Nitload.Mathematics.Numeric.Graphics
|
||||||
@@ -15,7 +16,55 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
{
|
{
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vector128<T> AsVector128Unsafe<T>(this Vec4<T> source) where T: unmanaged, INumber<T>
|
public static Vec4<double> ConvertToDouble(
|
||||||
|
Vec4<long> source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FromVector256Unsafe(Vector256.ConvertToDouble(source.AsVector256Unsafe()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Vec4<double> ConvertToDouble(
|
||||||
|
Vec4<ulong> source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FromVector256Unsafe(Vector256.ConvertToDouble(source.AsVector256Unsafe()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Vec4<float> ConvertToSingle(
|
||||||
|
Vec4<int> source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FromVector128Unsafe(Vector128.ConvertToSingle(source.AsVector128Unsafe()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Vec4<float> ConvertToSingle(
|
||||||
|
Vec4<uint> source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FromVector128Unsafe(Vector128.ConvertToSingle(source.AsVector128Unsafe()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec4<T> FromSpan<T>(
|
||||||
|
ReadOnlySpan<T> span
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
|
{
|
||||||
|
if (span.Length < 4) {
|
||||||
|
throw new ArgumentException("Span length must be at least 4.", nameof(span));
|
||||||
|
}
|
||||||
|
|
||||||
|
Unsafe.SkipInit(out Vec4<T> result);
|
||||||
|
Span<T> target = MemoryMarshal.CreateSpan(ref Unsafe.As<Vec4<T>, T>(ref result), 4);
|
||||||
|
span[..4].CopyTo(target);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal static Vector128<T> AsVector128Unsafe<T>(
|
||||||
|
this Vec4<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
Unsafe.SkipInit(out Vector128<T> result);
|
Unsafe.SkipInit(out Vector128<T> result);
|
||||||
Unsafe.WriteUnaligned(ref Unsafe.As<Vector128<T>, byte>(ref result), source);
|
Unsafe.WriteUnaligned(ref Unsafe.As<Vector128<T>, byte>(ref result), source);
|
||||||
@@ -23,7 +72,9 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vector256<T> AsVector256Unsafe<T>(this Vec4<T> source) where T: unmanaged, INumber<T>
|
internal static Vector256<T> AsVector256Unsafe<T>(
|
||||||
|
this Vec4<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
Unsafe.SkipInit(out Vector256<T> result);
|
Unsafe.SkipInit(out Vector256<T> result);
|
||||||
Unsafe.WriteUnaligned(ref Unsafe.As<Vector256<T>, byte>(ref result), source);
|
Unsafe.WriteUnaligned(ref Unsafe.As<Vector256<T>, byte>(ref result), source);
|
||||||
@@ -31,40 +82,20 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vec4<T> FromVector128Unsafe<T>(Vector128<T> source) where T: unmanaged, INumber<T>
|
internal static Vec4<T> FromVector128Unsafe<T>(
|
||||||
|
Vector128<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
return Unsafe.As<Vector128<T>, Vec4<T>>(ref source);
|
return Unsafe.As<Vector128<T>, Vec4<T>>(ref source);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static Vec4<T> FromVector256Unsafe<T>(Vector256<T> source) where T: unmanaged, INumber<T>
|
internal static Vec4<T> FromVector256Unsafe<T>(
|
||||||
|
Vector256<T> source
|
||||||
|
) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
return Unsafe.As<Vector256<T>, Vec4<T>>(ref source);
|
return Unsafe.As<Vector256<T>, Vec4<T>>(ref source);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static Vec4<float> ConvertToSingle(Vec4<int> source)
|
|
||||||
{
|
|
||||||
return FromVector128Unsafe(Vector128.ConvertToSingle(source.AsVector128Unsafe()));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static Vec4<float> ConvertToSingle(Vec4<uint> source)
|
|
||||||
{
|
|
||||||
return FromVector128Unsafe(Vector128.ConvertToSingle(source.AsVector128Unsafe()));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static Vec4<double> ConvertToDouble(Vec4<long> source)
|
|
||||||
{
|
|
||||||
return FromVector256Unsafe(Vector256.ConvertToDouble(source.AsVector256Unsafe()));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static Vec4<double> ConvertToDouble(Vec4<ulong> source)
|
|
||||||
{
|
|
||||||
return FromVector256Unsafe(Vector256.ConvertToDouble(source.AsVector256Unsafe()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,7 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
public struct Vec4<T> : IUnmanagedVector<Vec4<T>> where T : unmanaged, INumber<T>
|
public struct Vec4<T> : IUnmanagedVector<Vec4<T>> where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
public T W;
|
private Buffer _buffer;
|
||||||
|
|
||||||
public T X;
|
|
||||||
public T Y;
|
|
||||||
public T Z;
|
|
||||||
|
|
||||||
public Vec4(
|
public Vec4(
|
||||||
Vec3<T> v3,
|
Vec3<T> v3,
|
||||||
@@ -50,9 +46,41 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
W = w;
|
W = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T this[
|
||||||
|
int index
|
||||||
|
]
|
||||||
|
{
|
||||||
|
get => _buffer[index];
|
||||||
|
set => _buffer[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T X
|
||||||
|
{
|
||||||
|
get => _buffer[0];
|
||||||
|
set => _buffer[0] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Y
|
||||||
|
{
|
||||||
|
get => _buffer[1];
|
||||||
|
set => _buffer[1] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Z
|
||||||
|
{
|
||||||
|
get => _buffer[2];
|
||||||
|
set => _buffer[2] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T W
|
||||||
|
{
|
||||||
|
get => _buffer[3];
|
||||||
|
set => _buffer[3] = value;
|
||||||
|
}
|
||||||
|
|
||||||
public Vec2<T> XY
|
public Vec2<T> XY
|
||||||
{
|
{
|
||||||
get => Unsafe.As<T, Vec2<T>>(ref X);
|
get => Unsafe.As<T, Vec2<T>>(ref _buffer[0]);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
X = value.X;
|
X = value.X;
|
||||||
@@ -62,11 +90,60 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
|
|
||||||
public Vec3<T> XYZ
|
public Vec3<T> XYZ
|
||||||
{
|
{
|
||||||
get => Unsafe.As<T, Vec3<T>>(ref X);
|
get => Unsafe.As<T, Vec3<T>>(ref _buffer[0]);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
T w = W;
|
T w = W;
|
||||||
Unsafe.As<T, Vec3<T>>(ref X) = value;
|
Unsafe.As<T, Vec3<T>>(ref _buffer[0]) = value;
|
||||||
|
W = w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3<T> ZXY
|
||||||
|
{
|
||||||
|
readonly get
|
||||||
|
{
|
||||||
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
|
{
|
||||||
|
Vector128<T> source = this.AsVector128Unsafe();
|
||||||
|
Vector128<int> bits = Unsafe.As<Vector128<T>, Vector128<int>>(ref source);
|
||||||
|
Vector128<int> result = Vector128.Shuffle(bits, Vector128.Create(2, 0, 1, 3));
|
||||||
|
Vector128<T> shuffled = Unsafe.As<Vector128<int>, Vector128<T>>(ref result);
|
||||||
|
return Vec3.FromVector128Unsafe(shuffled);
|
||||||
|
}
|
||||||
|
if (Unsafe.SizeOf<T>() == 8)
|
||||||
|
{
|
||||||
|
Vector256<T> source = this.AsVector256Unsafe();
|
||||||
|
Vector256<long> bits = Unsafe.As<Vector256<T>, Vector256<long>>(ref source);
|
||||||
|
Vector256<long> result = Vector256.Shuffle(bits, Vector256.Create(2L, 0L, 1L,
|
||||||
|
3L));
|
||||||
|
Vector256<T> shuffled = Unsafe.As<Vector256<long>, Vector256<T>>(ref result);
|
||||||
|
return Vec3.FromVector256Unsafe(shuffled);
|
||||||
|
}
|
||||||
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
T w = W;
|
||||||
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
|
{
|
||||||
|
Vector128<T> source = value.AsVector128Unsafe();
|
||||||
|
Vector128<int> bits = Unsafe.As<Vector128<T>, Vector128<int>>(ref source);
|
||||||
|
Vector128<int> result = Vector128.Shuffle(bits, Vector128.Create(1, 2, 0, 3));
|
||||||
|
Vector128<T> shuffled = Unsafe.As<Vector128<int>, Vector128<T>>(ref result);
|
||||||
|
Unsafe.As<T, Vec3<T>>(ref _buffer[0]) = Vec3.FromVector128Unsafe(shuffled);
|
||||||
|
} else if (Unsafe.SizeOf<T>() == 8)
|
||||||
|
{
|
||||||
|
Vector256<T> source = value.AsVector256Unsafe();
|
||||||
|
Vector256<long> bits = Unsafe.As<Vector256<T>, Vector256<long>>(ref source);
|
||||||
|
Vector256<long> result = Vector256.Shuffle(bits, Vector256.Create(1L, 2L, 0L,
|
||||||
|
3L));
|
||||||
|
Vector256<T> shuffled = Unsafe.As<Vector256<long>, Vector256<T>>(ref result);
|
||||||
|
Unsafe.As<T, Vec3<T>>(ref _buffer[0]) = Vec3.FromVector256Unsafe(shuffled);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
|
}
|
||||||
W = w;
|
W = w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +163,7 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
|
|
||||||
public ReadOnlySpan<T> AsSpan()
|
public ReadOnlySpan<T> AsSpan()
|
||||||
{
|
{
|
||||||
return MemoryMarshal.CreateReadOnlySpan(ref X, 4);
|
return MemoryMarshal.CreateReadOnlySpan(ref _buffer[0], 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -98,8 +175,7 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
{
|
{
|
||||||
Vec4<T> product = Vec4.FromVector128Unsafe(this.AsVector128Unsafe() * right.AsVector128Unsafe());
|
Vec4<T> product = Vec4.FromVector128Unsafe(this.AsVector128Unsafe() * right.AsVector128Unsafe());
|
||||||
return product.X + product.Y + product.Z + product.W;
|
return product.X + product.Y + product.Z + product.W;
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8)
|
||||||
if (Unsafe.SizeOf<T>() == 8)
|
|
||||||
{
|
{
|
||||||
Vec4<T> product = Vec4.FromVector256Unsafe(this.AsVector256Unsafe() * right.AsVector256Unsafe());
|
Vec4<T> product = Vec4.FromVector256Unsafe(this.AsVector256Unsafe() * right.AsVector256Unsafe());
|
||||||
return product.X + product.Y + product.Z + product.W;
|
return product.X + product.Y + product.Z + product.W;
|
||||||
@@ -114,20 +190,6 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
return (obj is Vec4<T> v) && (v == this);
|
return (obj is Vec4<T> v) && (v == this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec4<T> FromSpan(
|
|
||||||
ReadOnlySpan<T> span
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (span.Length < 4) {
|
|
||||||
throw new ArgumentException("Span length must be at least 4.", nameof(span));
|
|
||||||
}
|
|
||||||
|
|
||||||
Unsafe.SkipInit(out Vec4<T> result);
|
|
||||||
Span<T> target = MemoryMarshal.CreateSpan(ref result.X, 4);
|
|
||||||
span[..4].CopyTo(target);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ReadOnlySpan<T>.Enumerator GetEnumerator()
|
public ReadOnlySpan<T>.Enumerator GetEnumerator()
|
||||||
{
|
{
|
||||||
@@ -139,16 +201,41 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
return HashCode.Combine(X, Y, Z, W);
|
return HashCode.Combine(X, Y, Z, W);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vec4<T> Shuffle(
|
||||||
|
int t0,
|
||||||
|
int t1,
|
||||||
|
int t2,
|
||||||
|
int t3
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
|
{
|
||||||
|
Vector128<T> v = this.AsVector128Unsafe();
|
||||||
|
Vector128<int> bits = Unsafe.As<Vector128<T>, Vector128<int>>(ref v);
|
||||||
|
Vector128<int> result = Vector128.Shuffle(bits, Vector128.Create(t0, t1, t2, t3));
|
||||||
|
return Vec4.FromVector128Unsafe(Unsafe.As<Vector128<int>, Vector128<T>>(ref result));
|
||||||
|
} else if (Unsafe.SizeOf<T>() == 8)
|
||||||
|
{
|
||||||
|
Vector256<T> v = this.AsVector256Unsafe();
|
||||||
|
Vector256<long> bits = Unsafe.As<Vector256<T>, Vector256<long>>(ref v);
|
||||||
|
Vector256<long> result = Vector256.Shuffle(bits, Vector256.Create(t0, t1, t2, t3));
|
||||||
|
return Vec4.FromVector256Unsafe(Unsafe.As<Vector256<long>, Vector256<T>>(ref result));
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vec4<T> operator -(
|
public static Vec4<T> operator -(
|
||||||
Vec4<T> left,
|
Vec4<T> left,
|
||||||
Vec4<T> right
|
Vec4<T> right
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4) {
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
|
{
|
||||||
return Vec4.FromVector128Unsafe(left.AsVector128Unsafe() - right.AsVector128Unsafe());
|
return Vec4.FromVector128Unsafe(left.AsVector128Unsafe() - right.AsVector128Unsafe());
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8) {
|
||||||
if (Unsafe.SizeOf<T>() == 8) {
|
|
||||||
return Vec4.FromVector256Unsafe(left.AsVector256Unsafe() - right.AsVector256Unsafe());
|
return Vec4.FromVector256Unsafe(left.AsVector256Unsafe() - right.AsVector256Unsafe());
|
||||||
}
|
}
|
||||||
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
@@ -168,10 +255,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
T scalar
|
T scalar
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4) {
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
|
{
|
||||||
return Vec4.FromVector128Unsafe(vector.AsVector128Unsafe() * Vector128.Create(scalar));
|
return Vec4.FromVector128Unsafe(vector.AsVector128Unsafe() * Vector128.Create(scalar));
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8) {
|
||||||
if (Unsafe.SizeOf<T>() == 8) {
|
|
||||||
return Vec4.FromVector256Unsafe(vector.AsVector256Unsafe() * Vector256.Create(scalar));
|
return Vec4.FromVector256Unsafe(vector.AsVector256Unsafe() * Vector256.Create(scalar));
|
||||||
}
|
}
|
||||||
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
@@ -186,6 +273,14 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
return vector * scalar;
|
return vector * scalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vec4<T> operator *(
|
||||||
|
GMatrix44<T> mat,
|
||||||
|
Vec4<T> vec
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (mat[0] * vec.X) + (mat[1] * vec.Y) + (mat[2] * vec.Z) + (mat[3] * vec.W);
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static T operator *(
|
public static T operator *(
|
||||||
Vec4<T> left,
|
Vec4<T> left,
|
||||||
@@ -201,10 +296,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
T scalar
|
T scalar
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4) {
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
|
{
|
||||||
return Vec4.FromVector128Unsafe(vector.AsVector128Unsafe() / Vector128.Create(scalar));
|
return Vec4.FromVector128Unsafe(vector.AsVector128Unsafe() / Vector128.Create(scalar));
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8) {
|
||||||
if (Unsafe.SizeOf<T>() == 8) {
|
|
||||||
return Vec4.FromVector256Unsafe(vector.AsVector256Unsafe() / Vector256.Create(scalar));
|
return Vec4.FromVector256Unsafe(vector.AsVector256Unsafe() / Vector256.Create(scalar));
|
||||||
}
|
}
|
||||||
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
@@ -216,10 +311,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
Vec4<T> right
|
Vec4<T> right
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4) {
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
|
{
|
||||||
return Vec4.FromVector128Unsafe(left.AsVector128Unsafe() + right.AsVector128Unsafe());
|
return Vec4.FromVector128Unsafe(left.AsVector128Unsafe() + right.AsVector128Unsafe());
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8) {
|
||||||
if (Unsafe.SizeOf<T>() == 8) {
|
|
||||||
return Vec4.FromVector256Unsafe(left.AsVector256Unsafe() + right.AsVector256Unsafe());
|
return Vec4.FromVector256Unsafe(left.AsVector256Unsafe() + right.AsVector256Unsafe());
|
||||||
}
|
}
|
||||||
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
throw GraphicVector.ThrowUnsupportedTypeException<T>();
|
||||||
@@ -230,10 +325,10 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
Vec4<T> right
|
Vec4<T> right
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (Unsafe.SizeOf<T>() == 4) {
|
if (Unsafe.SizeOf<T>() == 4)
|
||||||
|
{
|
||||||
return left.AsVector128Unsafe() == right.AsVector128Unsafe();
|
return left.AsVector128Unsafe() == right.AsVector128Unsafe();
|
||||||
}
|
} else if (Unsafe.SizeOf<T>() == 8) {
|
||||||
if (Unsafe.SizeOf<T>() == 8) {
|
|
||||||
return left.AsVector256Unsafe() == right.AsVector256Unsafe();
|
return left.AsVector256Unsafe() == right.AsVector256Unsafe();
|
||||||
}
|
}
|
||||||
#pragma warning disable CA1065
|
#pragma warning disable CA1065
|
||||||
@@ -241,5 +336,13 @@ namespace Nitload.Mathematics.Numeric.Graphics
|
|||||||
#pragma warning restore CA1065
|
#pragma warning restore CA1065
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[InlineArray(4)]
|
||||||
|
private struct Buffer
|
||||||
|
{
|
||||||
|
|
||||||
|
private T _element;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// file="TextRegexSourceGen.ExitLabel"
|
||||||
|
// Project: StgSharp
|
||||||
|
// Copyright (c) Nitload.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Nitload.RegularAnalysis.Text
|
||||||
|
{
|
||||||
|
internal partial class TextRegexSourceGen
|
||||||
|
{
|
||||||
|
|
||||||
|
internal enum ExitMode
|
||||||
|
{
|
||||||
|
|
||||||
|
Break,
|
||||||
|
Continue,
|
||||||
|
Goto,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal readonly record struct ExitLabel
|
||||||
|
{
|
||||||
|
|
||||||
|
public ExitLabel(
|
||||||
|
ExitMode mode,
|
||||||
|
int order
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Mode = mode;
|
||||||
|
LabelOrder = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExitMode Mode { get; init; }
|
||||||
|
|
||||||
|
public int LabelOrder { get; init; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -183,6 +183,8 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
RegexAstNode current = node.Right;
|
RegexAstNode current = node.Right;
|
||||||
|
// TODO(NGRA-NAMING): Reserve exclusive names for future ALT cursor/capture snapshots;
|
||||||
|
// their lifetime extends through retry labels, not just the candidate's emitted block.
|
||||||
string exit_label = context.RequestExitLabel();
|
string exit_label = context.RequestExitLabel();
|
||||||
|
|
||||||
// TODO(NGRA): Walk every normalized ALT candidate exactly once. The final traversal
|
// TODO(NGRA): Walk every normalized ALT candidate exactly once. The final traversal
|
||||||
@@ -229,9 +231,10 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
|
|
||||||
// TODO(NGRA): Advance by code.Length rather than one character and
|
// TODO(NGRA): Advance by code.Length rather than one character and
|
||||||
// preserve the ALT rollback cursor on failure.
|
// preserve the ALT rollback cursor on failure.
|
||||||
_ = sc.AppendLine(@$"if({context.RemainSpan}.{MemoryExtensions.StartsWith}({FormatStringLiteral(code)}))")
|
string liteal = FormatStringLiteral(code);
|
||||||
|
_ = sc.AppendLine(@$"if({context.RemainSpan}.{MemoryExtensions.StartsWith}({liteal}))")
|
||||||
.AppendLine("{")
|
.AppendLine("{")
|
||||||
.AppendLine($@"{context.RemainSpan} = {context.RemainSpan}.Slice(1);")
|
.AppendLine($@"{context.RemainSpan} = {context.RemainSpan}.Slice({code.Length});")
|
||||||
.AppendLine($@"goto {exit_label};")
|
.AppendLine($@"goto {exit_label};")
|
||||||
.AppendLine("}");
|
.AppendLine("}");
|
||||||
|
|
||||||
@@ -269,6 +272,9 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
|
|
||||||
RegexGroupPayload config = node.PayloadAs<RegexGroupPayload>();
|
RegexGroupPayload config = node.PayloadAs<RegexGroupPayload>();
|
||||||
|
|
||||||
|
// TODO(NGRA-NAMING): Reserve exclusive names for generated group snapshots and capture
|
||||||
|
// temporaries. A capture's user-provided name is not a unique generated local name.
|
||||||
|
|
||||||
// TODO(NGRA): Select the owned group body using Empty-sentinel checks, snapshot its
|
// TODO(NGRA): Select the owned group body using Empty-sentinel checks, snapshot its
|
||||||
// start cursor, and restore it when the child matcher fails.
|
// start cursor, and restore it when the child matcher fails.
|
||||||
if (left is not null)
|
if (left is not null)
|
||||||
@@ -343,7 +349,8 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
int max,
|
int max,
|
||||||
bool is_greedy,
|
bool is_greedy,
|
||||||
[NotNull] in SequenceEmitter<string> sc,
|
[NotNull] in SequenceEmitter<string> sc,
|
||||||
in SourceGenContext context
|
in SourceGenContext context,
|
||||||
|
string exit_label
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (min < 0 || (max >= 0 && max < min)) {
|
if (min < 0 || (max >= 0 && max < min)) {
|
||||||
@@ -359,16 +366,16 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
char expected = literal[0];
|
char expected = literal[0];
|
||||||
string expected_literal = FormatCharLiteral(expected);
|
string expected_literal = FormatCharLiteral(expected);
|
||||||
string remain_span = context.RemainSpan;
|
string remain_span = context.RemainSpan;
|
||||||
int scratch_scope_index = context.RentScratchScopeIndex();
|
// TODO(NGRA-NAMING): Allocate required_rest, required_matched, required_chunk_index,
|
||||||
|
// and additional_count through the exclusive-name pool, including loop-local names.
|
||||||
|
int scratch_scope_index = context.RequestScratchScopeIndex();
|
||||||
string required_rest = $"__required_rest_{scratch_scope_index}";
|
string required_rest = $"__required_rest_{scratch_scope_index}";
|
||||||
string required_matched = $"__required_matched_{scratch_scope_index}";
|
string required_matched = $"__required_matched_{scratch_scope_index}";
|
||||||
string required_chunk_index = $"__required_chunk_index_{scratch_scope_index}";
|
string required_chunk_index = $"__required_chunk_index_{scratch_scope_index}";
|
||||||
string additional_count = $"__additional_count_{scratch_scope_index}";
|
string additional_count = $"__additional_count_{scratch_scope_index}";
|
||||||
|
|
||||||
// TODO(NGRA): Move ownership of this work region to the enclosing CONCAT or match
|
// TODO(NGRA): Replace this local COUNT exit with the inherited failure ExitLabel.
|
||||||
// method. Until then, break demonstrates the local failure path but cannot prevent a
|
// The temporary goto preserves the former local exit but still lets siblings execute.
|
||||||
// later sibling node from being emitted and executed.
|
|
||||||
_ = sc.AppendLine("do").AppendLine("{");
|
|
||||||
|
|
||||||
if (min <= flattened_unit_count_threshold)
|
if (min <= flattened_unit_count_threshold)
|
||||||
{
|
{
|
||||||
@@ -377,7 +384,7 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
string required_prefix = new(expected, min);
|
string required_prefix = new(expected, min);
|
||||||
_ = sc.AppendLine($"if (!{remain_span}.{nameof(MemoryExtensions.StartsWith)}({FormatStringLiteral(required_prefix)}))")
|
_ = sc.AppendLine($"if (!{remain_span}.{nameof(MemoryExtensions.StartsWith)}({FormatStringLiteral(required_prefix)}))")
|
||||||
.AppendLine("{")
|
.AppendLine("{")
|
||||||
.AppendLine("break;")
|
.AppendLine($"goto {exit_label};")
|
||||||
.AppendLine("}")
|
.AppendLine("}")
|
||||||
.AppendLine($"{remain_span} = {remain_span}.Slice({min});");
|
.AppendLine($"{remain_span} = {remain_span}.Slice({min});");
|
||||||
}
|
}
|
||||||
@@ -392,7 +399,7 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
|
|
||||||
_ = sc.AppendLine($"if ({remain_span}.Length < {min})")
|
_ = sc.AppendLine($"if ({remain_span}.Length < {min})")
|
||||||
.AppendLine("{")
|
.AppendLine("{")
|
||||||
.AppendLine("break;")
|
.AppendLine($"goto {exit_label};")
|
||||||
.AppendLine("}")
|
.AppendLine("}")
|
||||||
.AppendLine($"{ROS_char} {required_rest} = {remain_span};")
|
.AppendLine($"{ROS_char} {required_rest} = {remain_span};")
|
||||||
.AppendLine($"bool {required_matched} = true;")
|
.AppendLine($"bool {required_matched} = true;")
|
||||||
@@ -417,7 +424,7 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
|
|
||||||
_ = sc.AppendLine($"if (!{required_matched})")
|
_ = sc.AppendLine($"if (!{required_matched})")
|
||||||
.AppendLine("{")
|
.AppendLine("{")
|
||||||
.AppendLine("break;")
|
.AppendLine($"goto {exit_label};")
|
||||||
.AppendLine("}")
|
.AppendLine("}")
|
||||||
.AppendLine($"{remain_span} = {remain_span}.Slice({min});");
|
.AppendLine($"{remain_span} = {remain_span}.Slice({min});");
|
||||||
}
|
}
|
||||||
@@ -445,8 +452,6 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
_ = sc.AppendLine("// TODO(NGRA): Retry the lazy COUNT tail from its continuation.");
|
_ = sc.AppendLine("// TODO(NGRA): Retry the lazy COUNT tail from its continuation.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = sc.AppendLine("} while (false);");
|
|
||||||
context.ReturnScratchScopeIndex(scratch_scope_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateUnitSetCount(
|
private static void GenerateUnitSetCount(
|
||||||
@@ -472,33 +477,52 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
|
|
||||||
IReadOnlyList<RegexCharSet> charset = payload.Set;
|
IReadOnlyList<RegexCharSet> charset = payload.Set;
|
||||||
string remain_span = context.RemainSpan;
|
string remain_span = context.RemainSpan;
|
||||||
int scratch_scope_index = context.RentScratchScopeIndex();
|
// TODO(NGRA-NAMING): Allocate required_matched and additional_count through the
|
||||||
|
// exclusive-name pool. Reserve required_rest/required_chunk_index if emitted later.
|
||||||
|
int scratch_scope_index = context.RequestScratchScopeIndex();
|
||||||
string required_rest = $"__required_rest_{scratch_scope_index}";
|
string required_rest = $"__required_rest_{scratch_scope_index}";
|
||||||
string required_matched = $"__required_matched_{scratch_scope_index}";
|
string required_matched = $"__required_matched_{scratch_scope_index}";
|
||||||
string required_chunk_index = $"__required_chunk_index_{scratch_scope_index}";
|
string required_chunk_index = $"__required_chunk_index_{scratch_scope_index}";
|
||||||
string additional_count = $"__additional_count_{scratch_scope_index}";
|
string additional_count = $"__additional_count_{scratch_scope_index}";
|
||||||
|
|
||||||
|
|
||||||
// TODO(NGRA): Move ownership of this work region to the enclosing CONCAT or match
|
// TODO(NGRA): Route a failed minimum check through the inherited failure ExitLabel.
|
||||||
// method. Until then, break demonstrates the local failure path but cannot prevent a
|
// The break below only stops charset scanning and must remain local to that loop.
|
||||||
// later sibling node from being emitted and executed.
|
|
||||||
bool accept = payload.Accept;
|
bool accept = payload.Accept;
|
||||||
RegexCharSet _set = charset[0];
|
RegexCharSet _set = charset[0];
|
||||||
_ = sc.AppendLine($"{ROS_char} {required_matched} = {remain_span}")
|
_ = sc.AppendLine($"{ROS_char} {required_matched} = {remain_span}")
|
||||||
.AppendLine($"int {additional_count} = 0;")
|
.AppendLine($"int {additional_count} = 0;")
|
||||||
.AppendLine()
|
.AppendLine($"for(; {additional_count} < {max}; {additional_count} ++)")
|
||||||
.AppendLine() //TODO loop head
|
.AppendLine("{");
|
||||||
.AppendLine($"if({(accept ? string.Empty : "!(")} {GenerateCharSetExpression(_set)} ||");
|
if (charset.Count == 1)
|
||||||
|
{
|
||||||
|
// single charset rule
|
||||||
|
_ = sc.AppendLine($"if({(accept ? string.Empty : "!(")} {GenerateCharSetExpression(_set)})");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// multi charset rule
|
||||||
|
_ = sc.AppendLine($"if({(accept ? string.Empty : "!(")} {GenerateCharSetExpression(_set)} ||");
|
||||||
for (int i = 1; i < charset.Count - 1; i++)
|
for (int i = 1; i < charset.Count - 1; i++)
|
||||||
{
|
{
|
||||||
_set = charset[i];
|
_set = charset[i];
|
||||||
_ = sc.AppendLine($" {GenerateCharSetExpression(_set)} ||");
|
_ = sc.AppendLine($" {GenerateCharSetExpression(_set)} ||");
|
||||||
}
|
}
|
||||||
_set = charset[^1];
|
_set = charset[^1];
|
||||||
_ = sc.AppendLine($" {GenerateCharSetExpression(_set)} ){(accept ? string.Empty : ')')}")
|
_ = sc.AppendLine($" {GenerateCharSetExpression(_set)} ){(accept ? string.Empty : ')')}");
|
||||||
.AppendLine("{")
|
}
|
||||||
|
_ = sc .AppendLine("{")
|
||||||
.AppendLine($@"{context.RemainSpan} = {context.RemainSpan}.Slice(1);")
|
.AppendLine($@"{context.RemainSpan} = {context.RemainSpan}.Slice(1);")
|
||||||
|
.AppendLine("}")
|
||||||
|
.AppendLine("else")
|
||||||
|
.AppendLine("{")
|
||||||
.AppendLine($@"break;")
|
.AppendLine($@"break;")
|
||||||
|
.AppendLine("}")
|
||||||
|
.AppendLine("}")
|
||||||
|
.AppendLine($"if({additional_count} < {min})")
|
||||||
|
.AppendLine("{")
|
||||||
|
.AppendLine("}")
|
||||||
|
.AppendLine("else")
|
||||||
|
.AppendLine("{")
|
||||||
.AppendLine("}");
|
.AppendLine("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,7 +532,8 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
int max,
|
int max,
|
||||||
bool is_greedy,
|
bool is_greedy,
|
||||||
[NotNull] in SequenceEmitter<string> sc,
|
[NotNull] in SequenceEmitter<string> sc,
|
||||||
in SourceGenContext context
|
in SourceGenContext context,
|
||||||
|
string exit_label
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (min < 0 || (max >= 0 && max < min)) {
|
if (min < 0 || (max >= 0 && max < min)) {
|
||||||
@@ -523,7 +548,10 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
|
|
||||||
string expected_literal = FormatStringLiteral(literal);
|
string expected_literal = FormatStringLiteral(literal);
|
||||||
string remain_span = context.RemainSpan;
|
string remain_span = context.RemainSpan;
|
||||||
int scratch_scope_index = context.RentScratchScopeIndex();
|
// TODO(NGRA-NAMING): Allocate required_rest, required_matched, required_chunk_index,
|
||||||
|
// required_count, and additional_count through the exclusive-name pool. Flattened
|
||||||
|
// sibling COUNT nodes share the declaration space even after their exit labels.
|
||||||
|
int scratch_scope_index = context.RequestScratchScopeIndex();
|
||||||
string required_rest = $"__required_rest_{scratch_scope_index}";
|
string required_rest = $"__required_rest_{scratch_scope_index}";
|
||||||
string required_matched = $"__required_matched_{scratch_scope_index}";
|
string required_matched = $"__required_matched_{scratch_scope_index}";
|
||||||
string required_chunk_index = $"__required_chunk_index_{scratch_scope_index}";
|
string required_chunk_index = $"__required_chunk_index_{scratch_scope_index}";
|
||||||
@@ -531,10 +559,8 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
string additional_count = $"__additional_count_{scratch_scope_index}";
|
string additional_count = $"__additional_count_{scratch_scope_index}";
|
||||||
string starts_with = $"{nameof(MemoryExtensions.StartsWith)}";
|
string starts_with = $"{nameof(MemoryExtensions.StartsWith)}";
|
||||||
|
|
||||||
// TODO(NGRA): Move ownership of this work region to the enclosing CONCAT or match
|
// TODO(NGRA): Replace this local COUNT exit with the inherited failure ExitLabel.
|
||||||
// method. Until then, break demonstrates the local failure path but cannot prevent a
|
// The temporary goto preserves the former local exit but still lets siblings execute.
|
||||||
// later sibling node from being emitted and executed.
|
|
||||||
_ = sc.AppendLine("do").AppendLine("{");
|
|
||||||
|
|
||||||
if (literal.Length > flattened_unit_count_threshold)
|
if (literal.Length > flattened_unit_count_threshold)
|
||||||
{
|
{
|
||||||
@@ -549,7 +575,7 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
.AppendLine("}")
|
.AppendLine("}")
|
||||||
.AppendLine($"if ({required_count} != {min})")
|
.AppendLine($"if ({required_count} != {min})")
|
||||||
.AppendLine("{")
|
.AppendLine("{")
|
||||||
.AppendLine("break;")
|
.AppendLine($"goto {exit_label};")
|
||||||
.AppendLine("}")
|
.AppendLine("}")
|
||||||
.AppendLine($"{remain_span} = {required_rest};");
|
.AppendLine($"{remain_span} = {required_rest};");
|
||||||
} else if (min <= flattened_unit_count_threshold / literal.Length)
|
} else if (min <= flattened_unit_count_threshold / literal.Length)
|
||||||
@@ -563,7 +589,7 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
string required_prefix = required_prefix_span.ToString();
|
string required_prefix = required_prefix_span.ToString();
|
||||||
_ = sc.AppendLine($"if (!{remain_span}.{starts_with}({FormatStringLiteral(required_prefix)}))")
|
_ = sc.AppendLine($"if (!{remain_span}.{starts_with}({FormatStringLiteral(required_prefix)}))")
|
||||||
.AppendLine("{")
|
.AppendLine("{")
|
||||||
.AppendLine("break;")
|
.AppendLine($"goto {exit_label};")
|
||||||
.AppendLine("}")
|
.AppendLine("}")
|
||||||
.AppendLine($"{remain_span} = {remain_span}.Slice({min * literal.Length});");
|
.AppendLine($"{remain_span} = {remain_span}.Slice({min * literal.Length});");
|
||||||
}
|
}
|
||||||
@@ -612,7 +638,7 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
|
|
||||||
_ = sc.AppendLine($"if (!{required_matched})")
|
_ = sc.AppendLine($"if (!{required_matched})")
|
||||||
.AppendLine("{")
|
.AppendLine("{")
|
||||||
.AppendLine("break;")
|
.AppendLine($"goto {exit_label};")
|
||||||
.AppendLine("}")
|
.AppendLine("}")
|
||||||
.AppendLine($"{remain_span} = {required_rest};");
|
.AppendLine($"{remain_span} = {required_rest};");
|
||||||
}
|
}
|
||||||
@@ -640,8 +666,6 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
_ = sc.AppendLine("// TODO(NGRA): Retry the lazy COUNT tail from its continuation.");
|
_ = sc.AppendLine("// TODO(NGRA): Retry the lazy COUNT tail from its continuation.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = sc.AppendLine("} while (false);");
|
|
||||||
context.ReturnScratchScopeIndex(scratch_scope_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateCount(
|
private static void GenerateCount(
|
||||||
@@ -659,6 +683,8 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
int min = payload.Min;
|
int min = payload.Min;
|
||||||
int max = payload.Max;
|
int max = payload.Max;
|
||||||
bool is_greedy = payload.IsGreedy;
|
bool is_greedy = payload.IsGreedy;
|
||||||
|
// TODO(NGRA-NAMING): Reserve exclusive names for future repetition/rollback state
|
||||||
|
// across complex COUNT retries; recursive children must use the same method pool.
|
||||||
string exit_label = context.RequestExitLabel();
|
string exit_label = context.RequestExitLabel();
|
||||||
if ((value.Label & RegexElementLabel.SEQUENCE) == 0)
|
if ((value.Label & RegexElementLabel.SEQUENCE) == 0)
|
||||||
{
|
{
|
||||||
@@ -670,15 +696,16 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
switch (value.Label & RegexElementLabel.SEQUENCE)
|
switch (value.Label & RegexElementLabel.SEQUENCE)
|
||||||
{
|
{
|
||||||
case RegexElementLabel.UNIT:
|
case RegexElementLabel.UNIT:
|
||||||
GenerateUnitCount(value, min, max, is_greedy, sc, context);
|
GenerateUnitCount(value, min, max, is_greedy, sc, context, exit_label);
|
||||||
break;
|
break;
|
||||||
case RegexElementLabel.UNIT_SET:
|
case RegexElementLabel.UNIT_SET:
|
||||||
|
GenerateUnitSetCount(value, min, max, is_greedy, sc, context);
|
||||||
|
|
||||||
// TODO(NGRA): Emit a bounded/unbounded charset counting loop, preferably
|
// TODO(NGRA): Emit a bounded/unbounded charset counting loop, preferably
|
||||||
// using IndexOfAnyExcept where the charset shape permits it.
|
// using IndexOfAnyExcept where the charset shape permits it.
|
||||||
break;
|
break;
|
||||||
case RegexElementLabel.UNIT_SPAN:
|
case RegexElementLabel.UNIT_SPAN:
|
||||||
GenerateUnitSpanCount(value, min, max, is_greedy, sc, context);
|
GenerateUnitSpanCount(value, min, max, is_greedy, sc, context, exit_label);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Method level state is limited to the active cursor and the result of the most recent
|
/// Method level state is limited to the active cursor and the result of the most recent
|
||||||
/// instruction. Everything else is either a region slot, a line slot, a capture slot, or
|
/// instruction. Everything else is either a region slot, a line slot, a capture slot, or
|
||||||
/// a block scoped scratch variable. Scratch indices remain unique while rented and are
|
/// a scratch variable. Scratch indices remain unique throughout the generated method;
|
||||||
/// recycled after their generated lexical scope has closed.
|
/// flattened regions cannot release their names for reuse by later nodes.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
internal sealed class SourceGenContext
|
internal sealed class SourceGenContext
|
||||||
{
|
{
|
||||||
@@ -40,8 +40,6 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
|
|
||||||
private int _scratch_scope_count;
|
private int _scratch_scope_count;
|
||||||
|
|
||||||
private readonly Stack<int> _free_scratch_scope_indices = [];
|
|
||||||
|
|
||||||
public string RemainSpan { get; } = _remain_span;
|
public string RemainSpan { get; } = _remain_span;
|
||||||
|
|
||||||
public string FirstOfRemain { get; } = $@"{_remain_span}[0]";
|
public string FirstOfRemain { get; } = $@"{_remain_span}[0]";
|
||||||
@@ -57,36 +55,22 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
|
|
||||||
public string RequestExitLabel()
|
public string RequestExitLabel()
|
||||||
{
|
{
|
||||||
|
// TODO(NGRA-NAMING): Route ALT and COUNT labels through the method-wide label pool.
|
||||||
|
// Keep every emitted label exclusive until method generation is complete.
|
||||||
string code = $@"_exit_alt_{_exit_alt_count}";
|
string code = $@"_exit_alt_{_exit_alt_count}";
|
||||||
_exit_alt_count++;
|
_exit_alt_count++;
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int RentScratchScopeIndex()
|
public int RequestScratchScopeIndex()
|
||||||
{
|
{
|
||||||
if (_free_scratch_scope_indices.TryPop(out int recycled_index)) {
|
// TODO(NGRA-NAMING): Integrate scratch names with the method-wide exclusive-name
|
||||||
return recycled_index;
|
// allocator. Until then, reserve each suffix permanently for this method.
|
||||||
}
|
|
||||||
|
|
||||||
int index = _scratch_scope_count;
|
int index = _scratch_scope_count;
|
||||||
_scratch_scope_count++;
|
_scratch_scope_count++;
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReturnScratchScopeIndex(
|
|
||||||
int index
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ((uint)index >= (uint)_scratch_scope_count) {
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
|
||||||
}
|
|
||||||
if (_free_scratch_scope_indices.Contains(index)) {
|
|
||||||
throw new InvalidOperationException($"Scratch scope {index} was returned twice.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_free_scratch_scope_indices.Push(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
string static_modifier;
|
string static_modifier;
|
||||||
|
|
||||||
int brace_count = 0;
|
int brace_count = 0;
|
||||||
do
|
while (type is not null)
|
||||||
{
|
{
|
||||||
_ = file_name_sb.Append(CultureInfo.InvariantCulture, $@"{type.TypeName}.");
|
_ = file_name_sb.Append(CultureInfo.InvariantCulture, $@"{type.TypeName}.");
|
||||||
string declare_type = type.DeclType switch
|
string declare_type = type.DeclType switch
|
||||||
@@ -74,7 +74,7 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
.AppendLine("{");
|
.AppendLine("{");
|
||||||
brace_count++;
|
brace_count++;
|
||||||
type = type.InnerType!;
|
type = type.InnerType!;
|
||||||
} while (type is not null);
|
}
|
||||||
|
|
||||||
static_modifier = gen_source.IsMethodStatic ? "static" : string.Empty;
|
static_modifier = gen_source.IsMethodStatic ? "static" : string.Empty;
|
||||||
_ = ce.AppendLine(@$"{ToKeyword(gen_source.MethodAccessibility)} {static_modifier} {Text_Regex} {gen_source.MethodName}({ROS_char} {regex_gen_context.InputString})")
|
_ = ce.AppendLine(@$"{ToKeyword(gen_source.MethodAccessibility)} {static_modifier} {Text_Regex} {gen_source.MethodName}({ROS_char} {regex_gen_context.InputString})")
|
||||||
@@ -90,8 +90,7 @@ namespace Nitload.RegularAnalysis.Text
|
|||||||
brace_count = 0;
|
brace_count = 0;
|
||||||
foreach (string line in ce)
|
foreach (string line in ce)
|
||||||
{
|
{
|
||||||
bool is_right_brace = (line == "}") ||
|
bool is_right_brace = line == "}";
|
||||||
line.StartsWith("} while", StringComparison.InvariantCulture);
|
|
||||||
brace_count -= is_right_brace ? 1 : 0;
|
brace_count -= is_right_brace ? 1 : 0;
|
||||||
for (int i = 0; i < brace_count; i++) {
|
for (int i = 0; i < brace_count; i++) {
|
||||||
_ = code_source.Append(" ");
|
_ = code_source.Append(" ");
|
||||||
|
|||||||
@@ -232,13 +232,13 @@ namespace StgSharp.GenerateGL.Generation
|
|||||||
List<ManagedParameterDefinition> singleParameters = new List<ManagedParameterDefinition>(prefix)
|
List<ManagedParameterDefinition> singleParameters = new List<ManagedParameterDefinition>(prefix)
|
||||||
{
|
{
|
||||||
new ManagedParameterDefinition("bool", "transpose", transposeSource),
|
new ManagedParameterDefinition("bool", "transpose", transposeSource),
|
||||||
new ManagedParameterDefinition("GraphicsMatrix", "value", valueSource),
|
new ManagedParameterDefinition("GMatrix44<float>", "value", valueSource),
|
||||||
};
|
};
|
||||||
List<ManagedParameterDefinition> spanParameters = new List<ManagedParameterDefinition>(prefix)
|
List<ManagedParameterDefinition> spanParameters = new List<ManagedParameterDefinition>(prefix)
|
||||||
{
|
{
|
||||||
new ManagedParameterDefinition("bool", "transpose", transposeSource),
|
new ManagedParameterDefinition("bool", "transpose", transposeSource),
|
||||||
new ManagedParameterDefinition(
|
new ManagedParameterDefinition(
|
||||||
"ReadOnlySpan<GraphicsMatrix>",
|
"ReadOnlySpan<GMatrix44<float>>",
|
||||||
"values",
|
"values",
|
||||||
valueSource),
|
valueSource),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -740,7 +740,7 @@ namespace StgSharp.GenerateGL.Generation
|
|||||||
string matrixName = EscapeIdentifier(matrix.Name);
|
string matrixName = EscapeIdentifier(matrix.Name);
|
||||||
if (invocation.IsSpan)
|
if (invocation.IsSpan)
|
||||||
{
|
{
|
||||||
builder.Append(" fixed (GraphicsMatrix* __value = ");
|
builder.Append(" fixed (GMatrix44<float>* __value = ");
|
||||||
builder.Append(matrixName);
|
builder.Append(matrixName);
|
||||||
builder.Append(")\n");
|
builder.Append(")\n");
|
||||||
builder.Append(" {\n");
|
builder.Append(" {\n");
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ The generator merges a family only when it can validate the resulting signatures
|
|||||||
| `glUniform1*v` | `Uniform(..., ReadOnlySpan<T>)` |
|
| `glUniform1*v` | `Uniform(..., ReadOnlySpan<T>)` |
|
||||||
| `glUniform4*v` | `Uniform(..., ReadOnlySpan<Vec4<T>>)` |
|
| `glUniform4*v` | `Uniform(..., ReadOnlySpan<Vec4<T>>)` |
|
||||||
| `glUniform2*v` and `glUniform3*v` | Omitted because `Vec2` and `Vec3` storage is not a tightly packed C array |
|
| `glUniform2*v` and `glUniform3*v` | Omitted because `Vec2` and `Vec3` storage is not a tightly packed C array |
|
||||||
| `glUniformMatrix4fv` | `Uniform(..., GraphicsMatrix)` and matrix-span overloads |
|
| `glUniformMatrix4fv` | `Uniform(..., GMatrix44<float>)` and matrix-span overloads |
|
||||||
| Other matrix sizes and double matrices | Omitted because only the graphics-oriented 4x4 float layout is defined |
|
| Other matrix sizes and double matrices | Omitted because only the graphics-oriented 4x4 float layout is defined |
|
||||||
| `glGetBooleanv`, `glGetFloatv`, `glGetIntegerv`, and related queries | `GetValue(..., Span<T>)` |
|
| `glGetBooleanv`, `glGetFloatv`, `glGetIntegerv`, and related queries | `GetValue(..., Span<T>)` |
|
||||||
| `glVertexAttrib1f/2f/3f/4f` and equivalent scalar forms | `VertexAttribute(...)`; component count is expressed by the parameter list |
|
| `glVertexAttrib1f/2f/3f/4f` and equivalent scalar forms | `VertexAttribute(...)`; component count is expressed by the parameter list |
|
||||||
|
|||||||
Reference in New Issue
Block a user