summaryrefslogtreecommitdiff
path: root/modules/mono/glue/GodotSharp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/glue/GodotSharp')
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs59
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs202
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.generics.cs38
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs20
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs115
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs5
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs42
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs450
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs11
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs1138
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs117
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs6
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs58
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs6
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs72
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs10
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs37
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs80
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs107
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Variant.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs54
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs148
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs39
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs101
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs22
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs32
36 files changed, 1933 insertions, 1075 deletions
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs
index a2916d4ae8..0e46b63b59 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs
@@ -437,48 +437,25 @@ namespace Godot
/// <summary>
/// Returns <see langword="true"/> if the <see cref="AABB"/> overlaps with <paramref name="with"/>
/// (i.e. they have at least one point in common).
- ///
- /// If <paramref name="includeBorders"/> is <see langword="true"/>,
- /// they will also be considered overlapping if their borders touch,
- /// even without intersection.
/// </summary>
/// <param name="with">The other <see cref="AABB"/> to check for intersections with.</param>
- /// <param name="includeBorders">Whether or not to consider borders.</param>
/// <returns>
/// A <see langword="bool"/> for whether or not they are intersecting.
/// </returns>
- public readonly bool Intersects(AABB with, bool includeBorders = false)
+ public readonly bool Intersects(AABB with)
{
- if (includeBorders)
- {
- if (_position.x > with._position.x + with._size.x)
- return false;
- if (_position.x + _size.x < with._position.x)
- return false;
- if (_position.y > with._position.y + with._size.y)
- return false;
- if (_position.y + _size.y < with._position.y)
- return false;
- if (_position.z > with._position.z + with._size.z)
- return false;
- if (_position.z + _size.z < with._position.z)
- return false;
- }
- else
- {
- if (_position.x >= with._position.x + with._size.x)
- return false;
- if (_position.x + _size.x <= with._position.x)
- return false;
- if (_position.y >= with._position.y + with._size.y)
- return false;
- if (_position.y + _size.y <= with._position.y)
- return false;
- if (_position.z >= with._position.z + with._size.z)
- return false;
- if (_position.z + _size.z <= with._position.z)
- return false;
- }
+ if (_position.x >= with._position.x + with._size.x)
+ return false;
+ if (_position.x + _size.x <= with._position.x)
+ return false;
+ if (_position.y >= with._position.y + with._size.y)
+ return false;
+ if (_position.y + _size.y <= with._position.y)
+ return false;
+ if (_position.z >= with._position.z + with._size.z)
+ return false;
+ if (_position.z + _size.z <= with._position.z)
+ return false;
return true;
}
@@ -586,6 +563,16 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this <see cref="AABB"/> is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public readonly bool IsFinite()
+ {
+ return _position.IsFinite() && _size.IsFinite();
+ }
+
+ /// <summary>
/// Returns a larger <see cref="AABB"/> that contains this <see cref="AABB"/> and <paramref name="with"/>.
/// </summary>
/// <param name="with">The other <see cref="AABB"/>.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs
index acdae83d2e..81659f74de 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs
@@ -10,7 +10,7 @@ namespace Godot
/// collection of types that implement scripts; otherwise, retrieving the types requires lookup.
/// </summary>
[AttributeUsage(AttributeTargets.Assembly)]
- public class AssemblyHasScriptsAttribute : Attribute
+ public sealed class AssemblyHasScriptsAttribute : Attribute
{
/// <summary>
/// If the Godot scripts contained in the assembly require lookup
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs
index 23088378d1..0070223c95 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs
@@ -7,5 +7,5 @@ namespace Godot
/// that can be marshaled from/to a <see cref="Variant"/>.
/// </summary>
[AttributeUsage(AttributeTargets.GenericParameter)]
- public class MustBeVariantAttribute : Attribute { }
+ public sealed class MustBeVariantAttribute : Attribute { }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs
index afee926464..02a38d310e 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs
@@ -9,7 +9,7 @@ namespace Godot
/// By default, methods are not exposed to networking (and RPCs).
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
- public class RPCAttribute : Attribute
+ public sealed class RPCAttribute : Attribute
{
/// <summary>
/// RPC mode for the annotated method.
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs
index f05bcdac38..d363e14c5d 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs
@@ -6,7 +6,7 @@ namespace Godot
/// An attribute that contains the path to the object's script.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
- public class ScriptPathAttribute : Attribute
+ public sealed class ScriptPathAttribute : Attribute
{
/// <summary>
/// File path to the script.
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
index 38e68a89d5..0a08bb5df8 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
@@ -3,5 +3,5 @@ using System;
namespace Godot
{
[AttributeUsage(AttributeTargets.Delegate)]
- public class SignalAttribute : Attribute { }
+ public sealed class SignalAttribute : Attribute { }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs
index d2344389f4..4c56201727 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs
@@ -3,5 +3,5 @@ using System;
namespace Godot
{
[AttributeUsage(AttributeTargets.Class)]
- public class ToolAttribute : Attribute { }
+ public sealed class ToolAttribute : Attribute { }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
index 5d390a298d..2b139a78bd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
@@ -120,12 +120,12 @@ namespace Godot
}
/// <summary>
- /// The scale of this basis.
+ /// Assuming that the matrix is the combination of a rotation and scaling,
+ /// return the absolute value of scaling factors along each axis.
/// </summary>
- /// <value>Equivalent to the lengths of each column vector, but negative if the determinant is negative.</value>
- public Vector3 Scale
+ public readonly Vector3 Scale
{
- readonly get
+ get
{
real_t detSign = Mathf.Sign(Determinant());
return detSign * new Vector3
@@ -135,13 +135,6 @@ namespace Godot
Column2.Length()
);
}
- set
- {
- value /= Scale; // Value becomes what's called "delta_scale" in core.
- Column0 *= value.x;
- Column1 *= value.y;
- Column2 *= value.z;
- }
}
/// <summary>
@@ -493,12 +486,6 @@ namespace Godot
}
}
- /// <summary>
- /// Returns the basis's rotation in the form of a quaternion.
- /// See <see cref="GetEuler"/> if you need Euler angles, but keep in
- /// mind that quaternions should generally be preferred to Euler angles.
- /// </summary>
- /// <returns>A <see cref="Quaternion"/> representing the basis's rotation.</returns>
internal readonly Quaternion GetQuaternion()
{
real_t trace = Row0[0] + Row1[1] + Row2[2];
@@ -573,109 +560,6 @@ namespace Godot
}
/// <summary>
- /// Get rows by index. Rows are not very useful for user code,
- /// but are more efficient for some internal calculations.
- /// </summary>
- /// <param name="index">Which row.</param>
- /// <exception cref="ArgumentOutOfRangeException">
- /// <paramref name="index"/> is not 0, 1 or 2.
- /// </exception>
- /// <returns>One of <c>Row0</c>, <c>Row1</c>, or <c>Row2</c>.</returns>
- public readonly Vector3 GetRow(int index)
- {
- switch (index)
- {
- case 0:
- return Row0;
- case 1:
- return Row1;
- case 2:
- return Row2;
- default:
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
-
- /// <summary>
- /// Sets rows by index. Rows are not very useful for user code,
- /// but are more efficient for some internal calculations.
- /// </summary>
- /// <param name="index">Which row.</param>
- /// <param name="value">The vector to set the row to.</param>
- /// <exception cref="ArgumentOutOfRangeException">
- /// <paramref name="index"/> is not 0, 1 or 2.
- /// </exception>
- public void SetRow(int index, Vector3 value)
- {
- switch (index)
- {
- case 0:
- Row0 = value;
- return;
- case 1:
- Row1 = value;
- return;
- case 2:
- Row2 = value;
- return;
- default:
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
-
- /// <summary>
- /// This function considers a discretization of rotations into
- /// 24 points on unit sphere, lying along the vectors (x, y, z) with
- /// each component being either -1, 0, or 1, and returns the index
- /// of the point best representing the orientation of the object.
- /// It is mainly used by the <see cref="GridMap"/> editor.
- ///
- /// For further details, refer to the Godot source code.
- /// </summary>
- /// <returns>The orthogonal index.</returns>
- public readonly int GetOrthogonalIndex()
- {
- var orth = this;
-
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- {
- var row = orth.GetRow(i);
-
- real_t v = row[j];
-
- if (v > 0.5f)
- {
- v = 1.0f;
- }
- else if (v < -0.5f)
- {
- v = -1.0f;
- }
- else
- {
- v = 0f;
- }
-
- row[j] = v;
-
- orth.SetRow(i, row);
- }
- }
-
- for (int i = 0; i < 24; i++)
- {
- if (orth == _orthoBases[i])
- {
- return i;
- }
- }
-
- return 0;
- }
-
- /// <summary>
/// Returns the inverse of the matrix.
/// </summary>
/// <returns>The inverse matrix.</returns>
@@ -709,6 +593,16 @@ namespace Godot
);
}
+ /// <summary>
+ /// Returns <see langword="true"/> if this basis is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public readonly bool IsFinite()
+ {
+ return Row0.IsFinite() && Row1.IsFinite() && Row2.IsFinite();
+ }
+
internal readonly Basis Lerp(Basis to, real_t weight)
{
Basis b = this;
@@ -896,7 +790,7 @@ namespace Godot
/// <param name="quaternion">The quaternion to create the basis from.</param>
public Basis(Quaternion quaternion)
{
- real_t s = 2.0f / quaternion.LengthSquared;
+ real_t s = 2.0f / quaternion.LengthSquared();
real_t xs = quaternion.x * s;
real_t ys = quaternion.y * s;
@@ -925,26 +819,26 @@ namespace Godot
public Basis(Vector3 axis, real_t angle)
{
Vector3 axisSq = new Vector3(axis.x * axis.x, axis.y * axis.y, axis.z * axis.z);
- real_t cosine = Mathf.Cos(angle);
- Row0.x = axisSq.x + cosine * (1.0f - axisSq.x);
- Row1.y = axisSq.y + cosine * (1.0f - axisSq.y);
- Row2.z = axisSq.z + cosine * (1.0f - axisSq.z);
+ (real_t sin, real_t cos) = Mathf.SinCos(angle);
- real_t sine = Mathf.Sin(angle);
- real_t t = 1.0f - cosine;
+ Row0.x = axisSq.x + cos * (1.0f - axisSq.x);
+ Row1.y = axisSq.y + cos * (1.0f - axisSq.y);
+ Row2.z = axisSq.z + cos * (1.0f - axisSq.z);
+
+ real_t t = 1.0f - cos;
real_t xyzt = axis.x * axis.y * t;
- real_t zyxs = axis.z * sine;
+ real_t zyxs = axis.z * sin;
Row0.y = xyzt - zyxs;
Row1.x = xyzt + zyxs;
xyzt = axis.x * axis.z * t;
- zyxs = axis.y * sine;
+ zyxs = axis.y * sin;
Row0.z = xyzt + zyxs;
Row2.x = xyzt - zyxs;
xyzt = axis.y * axis.z * t;
- zyxs = axis.x * sine;
+ zyxs = axis.x * sin;
Row1.z = xyzt - zyxs;
Row2.y = xyzt + zyxs;
}
@@ -967,8 +861,20 @@ namespace Godot
// We need to assign the struct fields here first so we can't do it that way...
}
- // Arguments are named such that xy is equal to calling x.y
- internal Basis(real_t xx, real_t yx, real_t zx, real_t xy, real_t yy, real_t zy, real_t xz, real_t yz, real_t zz)
+ /// <summary>
+ /// Constructs a transformation matrix from the given components.
+ /// Arguments are named such that xy is equal to calling <c>x.y</c>.
+ /// </summary>
+ /// <param name="xx">The X component of the X column vector, accessed via <c>b.x.x</c> or <c>[0][0]</c>.</param>
+ /// <param name="yx">The X component of the Y column vector, accessed via <c>b.y.x</c> or <c>[1][0]</c>.</param>
+ /// <param name="zx">The X component of the Z column vector, accessed via <c>b.z.x</c> or <c>[2][0]</c>.</param>
+ /// <param name="xy">The Y component of the X column vector, accessed via <c>b.x.y</c> or <c>[0][1]</c>.</param>
+ /// <param name="yy">The Y component of the Y column vector, accessed via <c>b.y.y</c> or <c>[1][1]</c>.</param>
+ /// <param name="zy">The Y component of the Z column vector, accessed via <c>b.y.y</c> or <c>[2][1]</c>.</param>
+ /// <param name="xz">The Z component of the X column vector, accessed via <c>b.x.y</c> or <c>[0][2]</c>.</param>
+ /// <param name="yz">The Z component of the Y column vector, accessed via <c>b.y.y</c> or <c>[1][2]</c>.</param>
+ /// <param name="zz">The Z component of the Z column vector, accessed via <c>b.y.y</c> or <c>[2][2]</c>.</param>
+ public Basis(real_t xx, real_t yx, real_t zx, real_t xy, real_t yy, real_t zy, real_t xz, real_t yz, real_t zz)
{
Row0 = new Vector3(xx, yx, zx);
Row1 = new Vector3(xy, yy, zy);
@@ -982,19 +888,29 @@ namespace Godot
/// <param name="order">The order to compose the Euler angles.</param>
public static Basis FromEuler(Vector3 euler, EulerOrder order = EulerOrder.Yxz)
{
- real_t c, s;
-
- c = Mathf.Cos(euler.x);
- s = Mathf.Sin(euler.x);
- Basis xmat = new Basis(new Vector3(1, 0, 0), new Vector3(0, c, s), new Vector3(0, -s, c));
+ (real_t sin, real_t cos) = Mathf.SinCos(euler.x);
+ Basis xmat = new Basis
+ (
+ new Vector3(1, 0, 0),
+ new Vector3(0, cos, sin),
+ new Vector3(0, -sin, cos)
+ );
- c = Mathf.Cos(euler.y);
- s = Mathf.Sin(euler.y);
- Basis ymat = new Basis(new Vector3(c, 0, -s), new Vector3(0, 1, 0), new Vector3(s, 0, c));
+ (sin, cos) = Mathf.SinCos(euler.y);
+ Basis ymat = new Basis
+ (
+ new Vector3(cos, 0, -sin),
+ new Vector3(0, 1, 0),
+ new Vector3(sin, 0, cos)
+ );
- c = Mathf.Cos(euler.z);
- s = Mathf.Sin(euler.z);
- Basis zmat = new Basis(new Vector3(c, s, 0), new Vector3(-s, c, 0), new Vector3(0, 0, 1));
+ (sin, cos) = Mathf.SinCos(euler.z);
+ Basis zmat = new Basis
+ (
+ new Vector3(cos, sin, 0),
+ new Vector3(-sin, cos, 0),
+ new Vector3(0, 0, 1)
+ );
switch (order)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.generics.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.generics.cs
index ff385da1c9..3005582bea 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.generics.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.generics.cs
@@ -45,7 +45,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From(Action)"/>
- public static unsafe Callable From<T0>(
+ public static unsafe Callable From<[MustBeVariant] T0>(
Action<T0> action
)
{
@@ -64,7 +64,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From(Action)"/>
- public static unsafe Callable From<T0, T1>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1>(
Action<T0, T1> action
)
{
@@ -84,7 +84,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From(Action)"/>
- public static unsafe Callable From<T0, T1, T2>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2>(
Action<T0, T1, T2> action
)
{
@@ -105,7 +105,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From(Action)"/>
- public static unsafe Callable From<T0, T1, T2, T3>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3>(
Action<T0, T1, T2, T3> action
)
{
@@ -127,7 +127,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From(Action)"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4>(
Action<T0, T1, T2, T3, T4> action
)
{
@@ -150,7 +150,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From(Action)"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4, T5>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5>(
Action<T0, T1, T2, T3, T4, T5> action
)
{
@@ -174,7 +174,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From(Action)"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6>(
Action<T0, T1, T2, T3, T4, T5, T6> action
)
{
@@ -199,7 +199,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From(Action)"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, T7>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] T7>(
Action<T0, T1, T2, T3, T4, T5, T6, T7> action
)
{
@@ -225,7 +225,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From(Action)"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, T7, T8>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] T7, [MustBeVariant] T8>(
Action<T0, T1, T2, T3, T4, T5, T6, T7, T8> action
)
{
@@ -255,7 +255,7 @@ public readonly partial struct Callable
/// Constructs a new <see cref="Callable"/> for the given <paramref name="func"/>.
/// </summary>
/// <param name="func">Action method that will be called.</param>
- public static unsafe Callable From<TResult>(
+ public static unsafe Callable From<[MustBeVariant] TResult>(
Func<TResult> func
)
{
@@ -272,7 +272,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From{TResult}(Func{TResult})"/>
- public static unsafe Callable From<T0, TResult>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] TResult>(
Func<T0, TResult> func
)
{
@@ -291,7 +291,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From{TResult}(Func{TResult})"/>
- public static unsafe Callable From<T0, T1, TResult>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] TResult>(
Func<T0, T1, TResult> func
)
{
@@ -311,7 +311,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From{TResult}(Func{TResult})"/>
- public static unsafe Callable From<T0, T1, T2, TResult>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] TResult>(
Func<T0, T1, T2, TResult> func
)
{
@@ -332,7 +332,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From{TResult}(Func{TResult})"/>
- public static unsafe Callable From<T0, T1, T2, T3, TResult>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] TResult>(
Func<T0, T1, T2, T3, TResult> func
)
{
@@ -354,7 +354,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From{TResult}(Func{TResult})"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4, TResult>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] TResult>(
Func<T0, T1, T2, T3, T4, TResult> func
)
{
@@ -377,7 +377,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From{TResult}(Func{TResult})"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4, T5, TResult>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] TResult>(
Func<T0, T1, T2, T3, T4, T5, TResult> func
)
{
@@ -401,7 +401,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From{TResult}(Func{TResult})"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, TResult>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] TResult>(
Func<T0, T1, T2, T3, T4, T5, T6, TResult> func
)
{
@@ -426,7 +426,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From{TResult}(Func{TResult})"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, T7, TResult>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] T7, [MustBeVariant] TResult>(
Func<T0, T1, T2, T3, T4, T5, T6, T7, TResult> func
)
{
@@ -452,7 +452,7 @@ public readonly partial struct Callable
}
/// <inheritdoc cref="From{TResult}(Func{TResult})"/>
- public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, T7, T8, TResult>(
+ public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] T7, [MustBeVariant] T8, [MustBeVariant] TResult>(
Func<T0, T1, T2, T3, T4, T5, T6, T7, T8, TResult> func
)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index 4075a878d2..6a7863112a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -359,24 +359,6 @@ namespace Godot
}
/// <summary>
- /// Returns the result of the linear interpolation between
- /// this color and <paramref name="to"/> by color amount <paramref name="weight"/>.
- /// </summary>
- /// <param name="to">The destination color for interpolation.</param>
- /// <param name="weight">A color with components on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
- /// <returns>The resulting color of the interpolation.</returns>
- public readonly Color Lerp(Color to, Color weight)
- {
- return new Color
- (
- (float)Mathf.Lerp(r, to.r, weight.r),
- (float)Mathf.Lerp(g, to.g, weight.g),
- (float)Mathf.Lerp(b, to.b, weight.b),
- (float)Mathf.Lerp(a, to.a, weight.a)
- );
- }
-
- /// <summary>
/// Returns the color converted to the sRGB color space.
/// This method assumes the original color is in the linear color space.
/// See also <see cref="SrgbToLinear"/> which performs the opposite operation.
@@ -815,7 +797,7 @@ namespace Godot
{
if (saturation == 0)
{
- // Achromatic (grey)
+ // Achromatic (gray)
return new Color(value, value, value, alpha);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
index d94fbff331..0f97149130 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
@@ -399,7 +399,7 @@ namespace Godot
{
ulong objectId = reader.ReadUInt64();
// ReSharper disable once RedundantNameQualifier
- Godot.Object godotObject = GD.InstanceFromId(objectId);
+ Godot.Object godotObject = Godot.Object.InstanceFromId(objectId);
if (godotObject == null)
return false;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
index b5a8742d3d..505763e6a2 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
@@ -68,7 +68,15 @@ namespace Godot.Collections
}
/// <summary>
- /// Duplicates this <see cref="Dictionary"/>.
+ /// Returns a copy of the <see cref="Dictionary"/>.
+ /// If <paramref name="deep"/> is <see langword="true"/>, a deep copy is performed:
+ /// all nested arrays and dictionaries are duplicated and will not be shared with
+ /// the original dictionary. If <see langword="false"/>, a shallow copy is made and
+ /// references to the original nested arrays and dictionaries are kept, so that
+ /// modifying a sub-array or dictionary in the copy will also impact those
+ /// referenced in the source dictionary. Note that any <see cref="Object"/> derived
+ /// elements will be shallow copied regardless of the <paramref name="deep"/>
+ /// setting.
/// </summary>
/// <param name="deep">If <see langword="true"/>, performs a deep copy.</param>
/// <returns>A new Godot Dictionary.</returns>
@@ -80,6 +88,39 @@ namespace Godot.Collections
return CreateTakingOwnershipOfDisposableValue(newDictionary);
}
+ /// <summary>
+ /// Adds entries from <paramref name="dictionary"/> to this dictionary.
+ /// By default, duplicate keys are not copied over, unless <paramref name="overwrite"/>
+ /// is <see langword="true"/>.
+ /// </summary>
+ /// <param name="dictionary">Dictionary to copy entries from.</param>
+ /// <param name="overwrite">If duplicate keys should be copied over as well.</param>
+ public void Merge(Dictionary dictionary, bool overwrite = false)
+ {
+ var self = (godot_dictionary)NativeValue;
+ var other = (godot_dictionary)dictionary.NativeValue;
+ NativeFuncs.godotsharp_dictionary_merge(ref self, in other, overwrite.ToGodotBool());
+ }
+
+ /// <summary>
+ /// Compares this <see cref="Dictionary"/> against the <paramref name="other"/>
+ /// <see cref="Dictionary"/> recursively. Returns <see langword="true"/> if the
+ /// two dictionaries contain the same keys and values. The order of the entries
+ /// does not matter.
+ /// otherwise.
+ /// </summary>
+ /// <param name="other">The other dictionary to compare against.</param>
+ /// <returns>
+ /// <see langword="true"/> if the dictionaries contain the same keys and values,
+ /// <see langword="false"/> otherwise.
+ /// </returns>
+ public bool RecursiveEqual(Dictionary other)
+ {
+ var self = (godot_dictionary)NativeValue;
+ var otherVariant = (godot_dictionary)other.NativeValue;
+ return NativeFuncs.godotsharp_dictionary_recursive_equal(ref self, otherVariant).ToBool();
+ }
+
// IDictionary
/// <summary>
@@ -134,6 +175,9 @@ namespace Godot.Collections
/// <summary>
/// Returns the value at the given <paramref name="key"/>.
/// </summary>
+ /// <exception cref="KeyNotFoundException">
+ /// An entry for <paramref name="key"/> does not exist in the dictionary.
+ /// </exception>
/// <value>The value at the given <paramref name="key"/>.</value>
public Variant this[Variant key]
{
@@ -163,6 +207,9 @@ namespace Godot.Collections
/// Adds an value <paramref name="value"/> at key <paramref name="key"/>
/// to this <see cref="Dictionary"/>.
/// </summary>
+ /// <exception cref="ArgumentException">
+ /// An entry for <paramref name="key"/> already exists in the dictionary.
+ /// </exception>
/// <param name="key">The key at which to add the value.</param>
/// <param name="value">The value to add.</param>
public void Add(Variant key, Variant value)
@@ -181,7 +228,7 @@ namespace Godot.Collections
=> Add(item.Key, item.Value);
/// <summary>
- /// Erases all items from this <see cref="Dictionary"/>.
+ /// Clears the dictionary, removing all entries from it.
/// </summary>
public void Clear()
{
@@ -200,7 +247,7 @@ namespace Godot.Collections
return NativeFuncs.godotsharp_dictionary_contains_key(ref self, (godot_variant)key.NativeVar).ToBool();
}
- public bool Contains(KeyValuePair<Variant, Variant> item)
+ bool ICollection<KeyValuePair<Variant, Variant>>.Contains(KeyValuePair<Variant, Variant> item)
{
godot_variant variantKey = (godot_variant)item.Key.NativeVar;
var self = (godot_dictionary)NativeValue;
@@ -227,7 +274,7 @@ namespace Godot.Collections
return NativeFuncs.godotsharp_dictionary_remove_key(ref self, (godot_variant)key.NativeVar).ToBool();
}
- public bool Remove(KeyValuePair<Variant, Variant> item)
+ bool ICollection<KeyValuePair<Variant, Variant>>.Remove(KeyValuePair<Variant, Variant> item)
{
godot_variant variantKey = (godot_variant)item.Key.NativeVar;
var self = (godot_dictionary)NativeValue;
@@ -266,6 +313,14 @@ namespace Godot.Collections
bool ICollection<KeyValuePair<Variant, Variant>>.IsReadOnly => false;
+ /// <summary>
+ /// Gets the value for the given <paramref name="key"/> in the dictionary.
+ /// Returns <see langword="true"/> if an entry for the given key exists in
+ /// the dictionary; otherwise, returns <see langword="false"/>.
+ /// </summary>
+ /// <param name="key">The key of the element to get.</param>
+ /// <param name="value">The value at the given <paramref name="key"/>.</param>
+ /// <returns>If an entry was found for the given <paramref name="key"/>.</returns>
public bool TryGetValue(Variant key, out Variant value)
{
var self = (godot_dictionary)NativeValue;
@@ -283,7 +338,7 @@ namespace Godot.Collections
/// </summary>
/// <param name="array">The array to copy to.</param>
/// <param name="arrayIndex">The index to start at.</param>
- public void CopyTo(KeyValuePair<Variant, Variant>[] array, int arrayIndex)
+ void ICollection<KeyValuePair<Variant, Variant>>.CopyTo(KeyValuePair<Variant, Variant>[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException(nameof(array), "Value cannot be null.");
@@ -433,15 +488,49 @@ namespace Godot.Collections
}
/// <summary>
- /// Duplicates this <see cref="Dictionary{TKey, TValue}"/>.
+ /// Returns a copy of the <see cref="Dictionary{TKey, TValue}"/>.
+ /// If <paramref name="deep"/> is <see langword="true"/>, a deep copy is performed:
+ /// all nested arrays and dictionaries are duplicated and will not be shared with
+ /// the original dictionary. If <see langword="false"/>, a shallow copy is made and
+ /// references to the original nested arrays and dictionaries are kept, so that
+ /// modifying a sub-array or dictionary in the copy will also impact those
+ /// referenced in the source dictionary. Note that any <see cref="Object"/> derived
+ /// elements will be shallow copied regardless of the <paramref name="deep"/>
+ /// setting.
/// </summary>
- /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param>
- /// <returns>A new Godot Dictionary.</returns>
public Dictionary<TKey, TValue> Duplicate(bool deep = false)
{
return new Dictionary<TKey, TValue>(_underlyingDict.Duplicate(deep));
}
+ /// <summary>
+ /// Adds entries from <paramref name="dictionary"/> to this dictionary.
+ /// By default, duplicate keys are not copied over, unless <paramref name="overwrite"/>
+ /// is <see langword="true"/>.
+ /// </summary>
+ /// <param name="dictionary">Dictionary to copy entries from.</param>
+ /// <param name="overwrite">If duplicate keys should be copied over as well.</param>
+ public void Merge(Dictionary<TKey, TValue> dictionary, bool overwrite = false)
+ {
+ _underlyingDict.Merge(dictionary._underlyingDict, overwrite);
+ }
+
+ /// <summary>
+ /// Compares this <see cref="Dictionary{TKey, TValue}"/> against the <paramref name="other"/>
+ /// <see cref="Dictionary{TKey, TValue}"/> recursively. Returns <see langword="true"/> if the
+ /// two dictionaries contain the same keys and values. The order of the entries does not matter.
+ /// otherwise.
+ /// </summary>
+ /// <param name="other">The other dictionary to compare against.</param>
+ /// <returns>
+ /// <see langword="true"/> if the dictionaries contain the same keys and values,
+ /// <see langword="false"/> otherwise.
+ /// </returns>
+ public bool RecursiveEqual(Dictionary<TKey, TValue> other)
+ {
+ return _underlyingDict.RecursiveEqual(other._underlyingDict);
+ }
+
// IDictionary<TKey, TValue>
/// <summary>
@@ -565,11 +654,13 @@ namespace Godot.Collections
}
/// <summary>
- /// Gets the object at the given <paramref name="key"/>.
+ /// Gets the value for the given <paramref name="key"/> in the dictionary.
+ /// Returns <see langword="true"/> if an entry for the given key exists in
+ /// the dictionary; otherwise, returns <see langword="false"/>.
/// </summary>
/// <param name="key">The key of the element to get.</param>
/// <param name="value">The value at the given <paramref name="key"/>.</param>
- /// <returns>If an object was found for the given <paramref name="key"/>.</returns>
+ /// <returns>If an entry was found for the given <paramref name="key"/>.</returns>
public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
{
using var variantKey = VariantUtils.CreateFrom(key);
@@ -598,7 +689,7 @@ namespace Godot.Collections
=> Add(item.Key, item.Value);
/// <summary>
- /// Erases all the items from this <see cref="Dictionary{TKey, TValue}"/>.
+ /// Clears the dictionary, removing all entries from it.
/// </summary>
public void Clear() => _underlyingDict.Clear();
@@ -625,7 +716,7 @@ namespace Godot.Collections
/// </summary>
/// <param name="array">The array to copy to.</param>
/// <param name="arrayIndex">The index to start at.</param>
- public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+ void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException(nameof(array), "Value cannot be null.");
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs
index e6cb4171a7..e7370b2b05 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs
@@ -9,7 +9,10 @@ namespace Godot
internal static GodotTaskScheduler DefaultGodotTaskScheduler;
internal static void InitializeDefaultGodotTaskScheduler()
- => DefaultGodotTaskScheduler = new GodotTaskScheduler();
+ {
+ DefaultGodotTaskScheduler?.Dispose();
+ DefaultGodotTaskScheduler = new GodotTaskScheduler();
+ }
public static GodotSynchronizationContext SynchronizationContext => DefaultGodotTaskScheduler.Context;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs
index 4094ceeb22..a9f3f02856 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs
@@ -6,8 +6,46 @@ namespace Godot
public partial class Object
{
/// <summary>
- /// Returns whether <paramref name="instance"/> is a valid object
- /// (e.g. has not been deleted from memory).
+ /// Returns the <see cref="Object"/> that corresponds to <paramref name="instanceId"/>.
+ /// All Objects have a unique instance ID. See also <see cref="GetInstanceId"/>.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// public partial class MyNode : Node
+ /// {
+ /// public string Foo { get; set; } = "bar";
+ ///
+ /// public override void _Ready()
+ /// {
+ /// ulong id = GetInstanceId();
+ /// var inst = (MyNode)InstanceFromId(Id);
+ /// GD.Print(inst.Foo); // Prints bar
+ /// }
+ /// }
+ /// </code>
+ /// </example>
+ /// <param name="instanceId">Instance ID of the Object to retrieve.</param>
+ /// <returns>The <see cref="Object"/> instance.</returns>
+ public static Object InstanceFromId(ulong instanceId)
+ {
+ return InteropUtils.UnmanagedGetManaged(NativeFuncs.godotsharp_instance_from_id(instanceId));
+ }
+
+ /// <summary>
+ /// Returns <see langword="true"/> if the <see cref="Object"/> that corresponds
+ /// to <paramref name="id"/> is a valid object (e.g. has not been deleted from
+ /// memory). All Objects have a unique instance ID.
+ /// </summary>
+ /// <param name="id">The Object ID to check.</param>
+ /// <returns>If the instance with the given ID is a valid object.</returns>
+ public static bool IsInstanceIdValid(ulong id)
+ {
+ return IsInstanceValid(InstanceFromId(id));
+ }
+
+ /// <summary>
+ /// Returns <see langword="true"/> if <paramref name="instance"/> is a
+ /// valid <see cref="Object"/> (e.g. has not been deleted from memory).
/// </summary>
/// <param name="instance">The instance to check.</param>
/// <returns>If the instance is a valid object.</returns>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index e4b79e7ec4..9425b7424c 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Text;
using Godot.NativeInterop;
namespace Godot
@@ -10,36 +11,45 @@ namespace Godot
public static partial class GD
{
/// <summary>
- /// Decodes a byte array back to a <c>Variant</c> value.
- /// If <paramref name="allowObjects"/> is <see langword="true"/> decoding objects is allowed.
- ///
- /// WARNING: Deserialized object can contain code which gets executed.
- /// Do not set <paramref name="allowObjects"/> to <see langword="true"/>
- /// if the serialized object comes from untrusted sources to avoid
- /// potential security threats (remote code execution).
+ /// Decodes a byte array back to a <see cref="Variant"/> value, without decoding objects.
+ /// Note: If you need object deserialization, see <see cref="BytesToVarWithObjects"/>.
/// </summary>
- /// <param name="bytes">Byte array that will be decoded to a <c>Variant</c>.</param>
- /// <param name="allowObjects">If objects should be decoded.</param>
- /// <returns>The decoded <c>Variant</c>.</returns>
- public static Variant BytesToVar(Span<byte> bytes, bool allowObjects = false)
+ /// <param name="bytes">Byte array that will be decoded to a <see cref="Variant"/>.</param>
+ /// <returns>The decoded <see cref="Variant"/>.</returns>
+ public static Variant BytesToVar(Span<byte> bytes)
{
using var varBytes = Marshaling.ConvertSystemArrayToNativePackedByteArray(bytes);
- NativeFuncs.godotsharp_bytes_to_var(varBytes, allowObjects.ToGodotBool(), out godot_variant ret);
+ NativeFuncs.godotsharp_bytes_to_var(varBytes, godot_bool.False, out godot_variant ret);
return Variant.CreateTakingOwnershipOfDisposableValue(ret);
}
/// <summary>
- /// Converts from a <c>Variant</c> type to another in the best way possible.
+ /// Decodes a byte array back to a <see cref="Variant"/> value. Decoding objects is allowed.
+ /// Warning: Deserialized object can contain code which gets executed. Do not use this
+ /// option if the serialized object comes from untrusted sources to avoid potential security
+ /// threats (remote code execution).
+ /// </summary>
+ /// <param name="bytes">Byte array that will be decoded to a <see cref="Variant"/>.</param>
+ /// <returns>The decoded <see cref="Variant"/>.</returns>
+ public static Variant BytesToVarWithObjects(Span<byte> bytes)
+ {
+ using var varBytes = Marshaling.ConvertSystemArrayToNativePackedByteArray(bytes);
+ NativeFuncs.godotsharp_bytes_to_var(varBytes, godot_bool.True, out godot_variant ret);
+ return Variant.CreateTakingOwnershipOfDisposableValue(ret);
+ }
+
+ /// <summary>
+ /// Converts <paramref name="what"/> to <paramref name="type"/> in the best way possible.
/// The <paramref name="type"/> parameter uses the <see cref="Variant.Type"/> values.
/// </summary>
/// <example>
/// <code>
- /// var a = new Vector2(1, 0);
- /// // Prints 1
- /// GD.Print(a.Length());
- /// var b = GD.Convert(a, Variant.Type.String)
- /// // Prints 6 as "(1, 0)" is 6 characters
- /// GD.Print(b.Length);
+ /// Variant a = new Godot.Collections.Array { 4, 2.5, 1.2 };
+ /// GD.Print(a.VariantType == Variant.Type.Array); // Prints true
+ ///
+ /// var b = GD.Convert(a, Variant.Type.PackedByteArray);
+ /// GD.Print(b); // Prints [4, 2, 1]
+ /// GD.Print(b.VariantType == Variant.Type.Array); // Prints false
/// </code>
/// </example>
/// <returns>The <c>Variant</c> converted to the given <paramref name="type"/>.</returns>
@@ -50,28 +60,7 @@ namespace Godot
}
/// <summary>
- /// Converts from decibels to linear energy (audio).
- /// </summary>
- /// <seealso cref="LinearToDb(real_t)"/>
- /// <param name="db">Decibels to convert.</param>
- /// <returns>Audio volume as linear energy.</returns>
- public static real_t DbToLinear(real_t db)
- {
- return (real_t)Math.Exp(db * 0.11512925464970228420089957273422);
- }
-
- private static string[] GetPrintParams(object[] parameters)
- {
- if (parameters == null)
- {
- return new[] { "null" };
- }
-
- return Array.ConvertAll(parameters, x => x?.ToString() ?? "null");
- }
-
- /// <summary>
- /// Returns the integer hash of the variable passed.
+ /// Returns the integer hash of the passed <paramref name="var"/>.
/// </summary>
/// <example>
/// <code>
@@ -86,52 +75,6 @@ namespace Godot
}
/// <summary>
- /// Returns the <see cref="Object"/> that corresponds to <paramref name="instanceId"/>.
- /// All Objects have a unique instance ID.
- /// </summary>
- /// <example>
- /// <code>
- /// public class MyNode : Node
- /// {
- /// public string foo = "bar";
- ///
- /// public override void _Ready()
- /// {
- /// ulong id = GetInstanceId();
- /// var inst = (MyNode)GD.InstanceFromId(Id);
- /// GD.Print(inst.foo); // Prints bar
- /// }
- /// }
- /// </code>
- /// </example>
- /// <param name="instanceId">Instance ID of the Object to retrieve.</param>
- /// <returns>The <see cref="Object"/> instance.</returns>
- public static Object InstanceFromId(ulong instanceId)
- {
- return InteropUtils.UnmanagedGetManaged(NativeFuncs.godotsharp_instance_from_id(instanceId));
- }
-
- /// <summary>
- /// Converts from linear energy to decibels (audio).
- /// This can be used to implement volume sliders that behave as expected (since volume isn't linear).
- /// </summary>
- /// <seealso cref="DbToLinear(real_t)"/>
- /// <example>
- /// <code>
- /// // "slider" refers to a node that inherits Range such as HSlider or VSlider.
- /// // Its range must be configured to go from 0 to 1.
- /// // Change the bus name if you'd like to change the volume of a specific bus only.
- /// AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), GD.LinearToDb(slider.value));
- /// </code>
- /// </example>
- /// <param name="linear">The linear energy to convert.</param>
- /// <returns>Audio as decibels.</returns>
- public static real_t LinearToDb(real_t linear)
- {
- return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321);
- }
-
- /// <summary>
/// Loads a resource from the filesystem located at <paramref name="path"/>.
/// The resource is loaded on the method call (unless it's referenced already
/// elsewhere, e.g. in another script or in the scene), which might cause slight delay,
@@ -185,57 +128,96 @@ namespace Godot
return ResourceLoader.Load<T>(path);
}
- /// <summary>
- /// Pushes an error message to Godot's built-in debugger and to the OS terminal.
- ///
- /// Note: Errors printed this way will not pause project execution.
- /// </summary>
- /// <example>
- /// <code>
- /// GD.PushError("test_error"); // Prints "test error" to debugger and terminal as error call
- /// </code>
- /// </example>
- /// <param name="message">Error message.</param>
- public static void PushError(string message)
+ private static string AppendPrintParams(object[] parameters)
{
- using var godotStr = Marshaling.ConvertStringToNative(message);
- NativeFuncs.godotsharp_pusherror(godotStr);
+ if (parameters == null)
+ {
+ return "null";
+ }
+
+ var sb = new StringBuilder();
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ sb.Append(parameters[i]?.ToString() ?? "null");
+ }
+ return sb.ToString();
+ }
+
+ private static string AppendPrintParams(char separator, object[] parameters)
+ {
+ if (parameters == null)
+ {
+ return "null";
+ }
+
+ var sb = new StringBuilder();
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ if (i != 0)
+ sb.Append(separator);
+ sb.Append(parameters[i]?.ToString() ?? "null");
+ }
+ return sb.ToString();
}
/// <summary>
- /// Pushes a warning message to Godot's built-in debugger and to the OS terminal.
+ /// Prints a message to the console.
+ ///
+ /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/>
+ /// to print error and warning messages instead of <see cref="Print(string)"/>.
+ /// This distinguishes them from print messages used for debugging purposes,
+ /// while also displaying a stack trace when an error or warning is printed.
/// </summary>
- /// <example>
- /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call
- /// </example>
- /// <param name="message">Warning message.</param>
- public static void PushWarning(string message)
+ /// <param name="what">Message that will be printed.</param>
+ public static void Print(string what)
{
- using var godotStr = Marshaling.ConvertStringToNative(message);
- NativeFuncs.godotsharp_pushwarning(godotStr);
+ using var godotStr = Marshaling.ConvertStringToNative(what);
+ NativeFuncs.godotsharp_print(godotStr);
}
/// <summary>
/// Converts one or more arguments of any type to string in the best way possible
/// and prints them to the console.
///
- /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/>
+ /// Note: Consider using <see cref="PushError(object[])"/> and <see cref="PushWarning(object[])"/>
/// to print error and warning messages instead of <see cref="Print(object[])"/>.
/// This distinguishes them from print messages used for debugging purposes,
/// while also displaying a stack trace when an error or warning is printed.
/// </summary>
/// <example>
/// <code>
- /// var a = new int[] { 1, 2, 3 };
+ /// var a = new Godot.Collections.Array { 1, 2, 3 };
/// GD.Print("a", "b", a); // Prints ab[1, 2, 3]
/// </code>
/// </example>
/// <param name="what">Arguments that will be printed.</param>
public static void Print(params object[] what)
{
- string str = string.Concat(GetPrintParams(what));
- using var godotStr = Marshaling.ConvertStringToNative(str);
- NativeFuncs.godotsharp_print(godotStr);
+ Print(AppendPrintParams(what));
+ }
+
+ /// <summary>
+ /// Prints a message to the console.
+ /// The following BBCode tags are supported: b, i, u, s, indent, code, url, center,
+ /// right, color, bgcolor, fgcolor.
+ /// Color tags only support named colors such as <c>red</c>, not hexadecimal color codes.
+ /// Unsupported tags will be left as-is in standard output.
+ /// When printing to standard output, the supported subset of BBCode is converted to
+ /// ANSI escape codes for the terminal emulator to display. Displaying ANSI escape codes
+ /// is currently only supported on Linux and macOS. Support for ANSI escape codes may vary
+ /// across terminal emulators, especially for italic and strikethrough.
+ ///
+ /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/>
+ /// to print error and warning messages instead of <see cref="Print(string)"/> or
+ /// <see cref="PrintRich(string)"/>.
+ /// This distinguishes them from print messages used for debugging purposes,
+ /// while also displaying a stack trace when an error or warning is printed.
+ /// </summary>
+ /// <param name="what">Message that will be printed.</param>
+ public static void PrintRich(string what)
+ {
+ using var godotStr = Marshaling.ConvertStringToNative(what);
+ NativeFuncs.godotsharp_print_rich(godotStr);
}
/// <summary>
@@ -250,7 +232,7 @@ namespace Godot
/// is currently only supported on Linux and macOS. Support for ANSI escape codes may vary
/// across terminal emulators, especially for italic and strikethrough.
///
- /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/>
+ /// Note: Consider using <see cref="PushError(object[])"/> and <see cref="PushWarning(object[])"/>
/// to print error and warning messages instead of <see cref="Print(object[])"/> or
/// <see cref="PrintRich(object[])"/>.
/// This distinguishes them from print messages used for debugging purposes,
@@ -258,23 +240,23 @@ namespace Godot
/// </summary>
/// <example>
/// <code>
- /// GD.PrintRich("[b]Hello world![/b]"); // Prints out "Hello world!" in bold.
+ /// GD.PrintRich("[code][b]Hello world![/b][/code]"); // Prints out: [b]Hello world![/b]
/// </code>
/// </example>
/// <param name="what">Arguments that will be printed.</param>
public static void PrintRich(params object[] what)
{
- string str = string.Concat(GetPrintParams(what));
- using var godotStr = Marshaling.ConvertStringToNative(str);
- NativeFuncs.godotsharp_print_rich(godotStr);
+ PrintRich(AppendPrintParams(what));
}
/// <summary>
- /// Prints the current stack trace information to the console.
+ /// Prints a message to standard error line.
/// </summary>
- public static void PrintStack()
+ /// <param name="what">Message that will be printed.</param>
+ public static void PrintErr(string what)
{
- Print(System.Environment.StackTrace);
+ using var godotStr = Marshaling.ConvertStringToNative(what);
+ NativeFuncs.godotsharp_printerr(godotStr);
}
/// <summary>
@@ -288,31 +270,36 @@ namespace Godot
/// <param name="what">Arguments that will be printed.</param>
public static void PrintErr(params object[] what)
{
- string str = string.Concat(GetPrintParams(what));
- using var godotStr = Marshaling.ConvertStringToNative(str);
- NativeFuncs.godotsharp_printerr(godotStr);
+ PrintErr(AppendPrintParams(what));
}
/// <summary>
- /// Prints one or more arguments to strings in the best way possible to console.
- /// No newline is added at the end.
- ///
- /// Note: Due to limitations with Godot's built-in console, this only prints to the terminal.
- /// If you need to print in the editor, use another method, such as <see cref="Print(object[])"/>.
+ /// Prints a message to the OS terminal.
+ /// Unlike <see cref="Print(string)"/>, no newline is added at the end.
+ /// </summary>
+ /// <param name="what">Message that will be printed.</param>
+ public static void PrintRaw(string what)
+ {
+ using var godotStr = Marshaling.ConvertStringToNative(what);
+ NativeFuncs.godotsharp_printraw(godotStr);
+ }
+
+ /// <summary>
+ /// Prints one or more arguments to strings in the best way possible to the OS terminal.
+ /// Unlike <see cref="Print(object[])"/>, no newline is added at the end.
/// </summary>
/// <example>
/// <code>
/// GD.PrintRaw("A");
/// GD.PrintRaw("B");
- /// // Prints AB
+ /// GD.PrintRaw("C");
+ /// // Prints ABC to terminal
/// </code>
/// </example>
/// <param name="what">Arguments that will be printed.</param>
public static void PrintRaw(params object[] what)
{
- string str = string.Concat(GetPrintParams(what));
- using var godotStr = Marshaling.ConvertStringToNative(str);
- NativeFuncs.godotsharp_printraw(godotStr);
+ PrintRaw(AppendPrintParams(what));
}
/// <summary>
@@ -326,8 +313,8 @@ namespace Godot
/// <param name="what">Arguments that will be printed.</param>
public static void PrintS(params object[] what)
{
- string str = string.Join(' ', GetPrintParams(what));
- using var godotStr = Marshaling.ConvertStringToNative(str);
+ string message = AppendPrintParams(' ', what);
+ using var godotStr = Marshaling.ConvertStringToNative(message);
NativeFuncs.godotsharp_prints(godotStr);
}
@@ -342,12 +329,74 @@ namespace Godot
/// <param name="what">Arguments that will be printed.</param>
public static void PrintT(params object[] what)
{
- string str = string.Join('\t', GetPrintParams(what));
- using var godotStr = Marshaling.ConvertStringToNative(str);
+ string message = AppendPrintParams('\t', what);
+ using var godotStr = Marshaling.ConvertStringToNative(message);
NativeFuncs.godotsharp_printt(godotStr);
}
/// <summary>
+ /// Pushes an error message to Godot's built-in debugger and to the OS terminal.
+ ///
+ /// Note: Errors printed this way will not pause project execution.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PushError("test error"); // Prints "test error" to debugger and terminal as error call
+ /// </code>
+ /// </example>
+ /// <param name="message">Error message.</param>
+ public static void PushError(string message)
+ {
+ using var godotStr = Marshaling.ConvertStringToNative(message);
+ NativeFuncs.godotsharp_pusherror(godotStr);
+ }
+
+ /// <summary>
+ /// Pushes an error message to Godot's built-in debugger and to the OS terminal.
+ ///
+ /// Note: Errors printed this way will not pause project execution.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PushError("test_error"); // Prints "test error" to debugger and terminal as error call
+ /// </code>
+ /// </example>
+ /// <param name="what">Arguments that form the error message.</param>
+ public static void PushError(params object[] what)
+ {
+ PushError(AppendPrintParams(what));
+ }
+
+ /// <summary>
+ /// Pushes a warning message to Godot's built-in debugger and to the OS terminal.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call
+ /// </code>
+ /// </example>
+ /// <param name="message">Warning message.</param>
+ public static void PushWarning(string message)
+ {
+ using var godotStr = Marshaling.ConvertStringToNative(message);
+ NativeFuncs.godotsharp_pushwarning(godotStr);
+ }
+
+ /// <summary>
+ /// Pushes a warning message to Godot's built-in debugger and to the OS terminal.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call
+ /// </code>
+ /// </example>
+ /// <param name="what">Arguments that form the warning message.</param>
+ public static void PushWarning(params object[] what)
+ {
+ PushWarning(AppendPrintParams(what));
+ }
+
+ /// <summary>
/// Returns a random floating point value between <c>0.0</c> and <c>1.0</c> (inclusive).
/// </summary>
/// <example>
@@ -362,7 +411,9 @@ namespace Godot
}
/// <summary>
- /// Returns a normally-distributed pseudo-random number, using Box-Muller transform with the specified <c>mean</c> and a standard <c>deviation</c>.
+ /// Returns a normally-distributed pseudo-random floating point value
+ /// using Box-Muller transform with the specified <pararmref name="mean"/>
+ /// and a standard <paramref name="deviation"/>.
/// This is also called Gaussian distribution.
/// </summary>
/// <returns>A random normally-distributed <see langword="float"/> number.</returns>
@@ -373,7 +424,8 @@ namespace Godot
/// <summary>
/// Returns a random unsigned 32-bit integer.
- /// Use remainder to obtain a random value in the interval <c>[0, N - 1]</c> (where N is smaller than 2^32).
+ /// Use remainder to obtain a random value in the interval <c>[0, N - 1]</c>
+ /// (where N is smaller than 2^32).
/// </summary>
/// <example>
/// <code>
@@ -391,11 +443,11 @@ namespace Godot
/// <summary>
/// Randomizes the seed (or the internal state) of the random number generator.
- /// Current implementation reseeds using a number based on time.
+ /// The current implementation uses a number based on the device's time.
///
/// Note: This method is called automatically when the project is run.
- /// If you need to fix the seed to have reproducible results, use <see cref="Seed(ulong)"/>
- /// to initialize the random number generator.
+ /// If you need to fix the seed to have consistent, reproducible results,
+ /// use <see cref="Seed(ulong)"/> to initialize the random number generator.
/// </summary>
public static void Randomize()
{
@@ -403,12 +455,13 @@ namespace Godot
}
/// <summary>
- /// Returns a random floating point value on the interval between <paramref name="from"/>
+ /// Returns a random floating point value between <paramref name="from"/>
/// and <paramref name="to"/> (inclusive).
/// </summary>
/// <example>
/// <code>
- /// GD.PrintS(GD.RandRange(-10.0, 10.0), GD.RandRange(-10.0, 10.0)); // Prints e.g. -3.844535 7.45315
+ /// GD.RandRange(0.0, 20.5); // Returns e.g. 7.45315
+ /// GD.RandRange(-10.0, 10.0); // Returns e.g. -3.844535
/// </code>
/// </example>
/// <returns>A random <see langword="double"/> number inside the given range.</returns>
@@ -424,8 +477,8 @@ namespace Godot
/// </summary>
/// <example>
/// <code>
- /// GD.Print(GD.RandRange(0, 1)); // Prints 0 or 1
- /// GD.Print(GD.RandRange(-10, 1000)); // Prints any number from -10 to 1000
+ /// GD.RandRange(0, 1); // Returns either 0 or 1
+ /// GD.RandRange(-10, 1000); // Returns random integer between -10 and 1000
/// </code>
/// </example>
/// <returns>A random <see langword="int"/> number inside the given range.</returns>
@@ -435,8 +488,18 @@ namespace Godot
}
/// <summary>
- /// Returns a random unsigned 32-bit integer, using the given <paramref name="seed"/>.
+ /// Given a <paramref name="seed"/>, returns a randomized <see langword="uint"/>
+ /// value. The <paramref name="seed"/> may be modified.
+ /// Passing the same <paramref name="seed"/> consistently returns the same value.
+ ///
+ /// Note: "Seed" here refers to the internal state of the pseudo random number
+ /// generator, currently implemented as a 64 bit integer.
/// </summary>
+ /// <example>
+ /// <code>
+ /// var a = GD.RandFromSeed(4);
+ /// </code>
+ /// </example>
/// <param name="seed">
/// Seed to use to generate the random number.
/// If a different seed is used, its value will be modified.
@@ -449,7 +512,8 @@ namespace Godot
/// <summary>
/// Returns a <see cref="IEnumerable{T}"/> that iterates from
- /// <c>0</c> to <paramref name="end"/> in steps of <c>1</c>.
+ /// <c>0</c> (inclusive) to <paramref name="end"/> (exclusive)
+ /// in steps of <c>1</c>.
/// </summary>
/// <param name="end">The last index.</param>
public static IEnumerable<int> Range(int end)
@@ -459,7 +523,8 @@ namespace Godot
/// <summary>
/// Returns a <see cref="IEnumerable{T}"/> that iterates from
- /// <paramref name="start"/> to <paramref name="end"/> in steps of <c>1</c>.
+ /// <paramref name="start"/> (inclusive) to <paramref name="end"/> (exclusive)
+ /// in steps of <c>1</c>.
/// </summary>
/// <param name="start">The first index.</param>
/// <param name="end">The last index.</param>
@@ -470,13 +535,21 @@ namespace Godot
/// <summary>
/// Returns a <see cref="IEnumerable{T}"/> that iterates from
- /// <paramref name="start"/> to <paramref name="end"/> in steps of <paramref name="step"/>.
+ /// <paramref name="start"/> (inclusive) to <paramref name="end"/> (exclusive)
+ /// in steps of <paramref name="step"/>.
+ /// The argument <paramref name="step"/> can be negative, but not <c>0</c>.
/// </summary>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="step"/> is 0.
+ /// </exception>
/// <param name="start">The first index.</param>
/// <param name="end">The last index.</param>
/// <param name="step">The amount by which to increment the index on each iteration.</param>
public static IEnumerable<int> Range(int start, int end, int step)
{
+ if (step == 0)
+ throw new ArgumentException("step cannot be 0.", nameof(step));
+
if (end < start && step > 0)
yield break;
@@ -496,8 +569,20 @@ namespace Godot
}
/// <summary>
- /// Sets seed for the random number generator.
+ /// Sets seed for the random number generator to <paramref name="seed"/>.
+ /// Setting the seed manually can ensure consistent, repeatable results for
+ /// most random functions.
/// </summary>
+ /// <example>
+ /// <code>
+ /// ulong mySeed = (ulong)GD.Hash("Godot Rocks");
+ /// GD.Seed(mySeed);
+ /// var a = GD.Randf() + GD.Randi();
+ /// GD.Seed(mySeed);
+ /// var b = GD.Randf() + GD.Randi();
+ /// // a and b are now identical
+ /// </code>
+ /// </example>
/// <param name="seed">Seed that will be used.</param>
public static void Seed(ulong seed)
{
@@ -505,26 +590,14 @@ namespace Godot
}
/// <summary>
- /// Converts one or more arguments of any type to string in the best way possible.
- /// </summary>
- /// <param name="what">Arguments that will converted to string.</param>
- /// <returns>The string formed by the given arguments.</returns>
- public static string Str(params Variant[] what)
- {
- using var whatGodot = new Godot.Collections.Array(what);
- NativeFuncs.godotsharp_str((godot_array)whatGodot.NativeValue, out godot_string ret);
- using (ret)
- return Marshaling.ConvertStringToManaged(ret);
- }
-
- /// <summary>
- /// Converts a formatted string that was returned by <see cref="VarToStr(Variant)"/> to the original value.
+ /// Converts a formatted string that was returned by <see cref="VarToStr(Variant)"/>
+ /// to the original value.
/// </summary>
/// <example>
/// <code>
- /// string a = "{\"a\": 1, \"b\": 2 }";
- /// var b = (Godot.Collections.Dictionary)GD.StrToVar(a);
- /// GD.Print(b["a"]); // Prints 1
+ /// string a = "{ \"a\": 1, \"b\": 2 }"; // a is a string
+ /// var b = GD.StrToVar(a).AsGodotDictionary(); // b is a Dictionary
+ /// GD.Print(b["a"]); // Prints 1
/// </code>
/// </example>
/// <param name="str">String that will be converted to Variant.</param>
@@ -537,38 +610,49 @@ namespace Godot
}
/// <summary>
- /// Encodes a <c>Variant</c> value to a byte array.
- /// If <paramref name="fullObjects"/> is <see langword="true"/> encoding objects is allowed
- /// (and can potentially include code).
- /// Deserialization can be done with <see cref="BytesToVar(Span{byte}, bool)"/>.
+ /// Encodes a <see cref="Variant"/> value to a byte array, without encoding objects.
+ /// Deserialization can be done with <see cref="BytesToVar"/>.
+ /// Note: If you need object serialization, see <see cref="VarToBytesWithObjects"/>.
+ /// </summary>
+ /// <param name="var"><see cref="Variant"/> that will be encoded.</param>
+ /// <returns>The <see cref="Variant"/> encoded as an array of bytes.</returns>
+ public static byte[] VarToBytes(Variant var)
+ {
+ NativeFuncs.godotsharp_var_to_bytes((godot_variant)var.NativeVar, godot_bool.False, out var varBytes);
+ using (varBytes)
+ return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes);
+ }
+
+ /// <summary>
+ /// Encodes a <see cref="Variant"/>. Encoding objects is allowed (and can potentially
+ /// include executable code). Deserialization can be done with <see cref="BytesToVarWithObjects"/>.
/// </summary>
- /// <param name="var">Variant that will be encoded.</param>
- /// <param name="fullObjects">If objects should be serialized.</param>
- /// <returns>The <c>Variant</c> encoded as an array of bytes.</returns>
- public static byte[] VarToBytes(Variant var, bool fullObjects = false)
+ /// <param name="var"><see cref="Variant"/> that will be encoded.</param>
+ /// <returns>The <see cref="Variant"/> encoded as an array of bytes.</returns>
+ public static byte[] VarToBytesWithObjects(Variant var)
{
- NativeFuncs.godotsharp_var_to_bytes((godot_variant)var.NativeVar, fullObjects.ToGodotBool(), out var varBytes);
+ NativeFuncs.godotsharp_var_to_bytes((godot_variant)var.NativeVar, godot_bool.True, out var varBytes);
using (varBytes)
return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes);
}
/// <summary>
- /// Converts a <c>Variant</c> <paramref name="var"/> to a formatted string that
+ /// Converts a <see cref="Variant"/> <paramref name="var"/> to a formatted string that
/// can later be parsed using <see cref="StrToVar(string)"/>.
/// </summary>
/// <example>
/// <code>
/// var a = new Godot.Collections.Dictionary { ["a"] = 1, ["b"] = 2 };
/// GD.Print(GD.VarToStr(a));
- /// // Prints
+ /// // Prints:
/// // {
- /// // "a": 1,
- /// // "b": 2
+ /// // "a": 1,
+ /// // "b": 2
/// // }
/// </code>
/// </example>
/// <param name="var">Variant that will be converted to string.</param>
- /// <returns>The <c>Variant</c> encoded as a string.</returns>
+ /// <returns>The <see cref="Variant"/> encoded as a string.</returns>
public static string VarToStr(Variant var)
{
NativeFuncs.godotsharp_var_to_str((godot_variant)var.NativeVar, out godot_string ret);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs
index 1b599beab5..027eab30fc 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs
@@ -1,13 +1,13 @@
+using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
namespace Godot
{
- public class GodotSynchronizationContext : SynchronizationContext
+ public sealed class GodotSynchronizationContext : SynchronizationContext, IDisposable
{
- private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue =
- new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
+ private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue = new();
public override void Post(SendOrPostCallback d, object state)
{
@@ -24,5 +24,10 @@ namespace Godot
workItem.Key(workItem.Value);
}
}
+
+ public void Dispose()
+ {
+ _queue.Dispose();
+ }
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs
index 408bed71b2..f6c36455b2 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs
@@ -10,7 +10,7 @@ namespace Godot
/// GodotTaskScheduler contains a linked list of tasks to perform as a queue. Methods
/// within the class are used to control the queue and perform the contained tasks.
/// </summary>
- public class GodotTaskScheduler : TaskScheduler
+ public sealed class GodotTaskScheduler : TaskScheduler, IDisposable
{
/// <summary>
/// The current synchronization context.
@@ -108,5 +108,10 @@ namespace Godot
}
}
}
+
+ public void Dispose()
+ {
+ Context.Dispose();
+ }
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index 3f9e986f62..ca0032df73 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.CompilerServices;
namespace Godot
{
@@ -35,15 +36,18 @@ namespace Godot
public const real_t NaN = real_t.NaN;
// 0.0174532924f and 0.0174532925199433
- private const real_t _degToRadConst = (real_t)0.0174532925199432957692369077M;
+ private const float _degToRadConstF = (float)0.0174532925199432957692369077M;
+ private const double _degToRadConstD = (double)0.0174532925199432957692369077M;
// 57.29578f and 57.2957795130823
- private const real_t _radToDegConst = (real_t)57.295779513082320876798154814M;
+ private const float _radToDegConstF = (float)57.295779513082320876798154814M;
+ private const double _radToDegConstD = (double)57.295779513082320876798154814M;
/// <summary>
/// Returns the absolute value of <paramref name="s"/> (i.e. positive value).
/// </summary>
/// <param name="s">The input number.</param>
/// <returns>The absolute value of <paramref name="s"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Abs(int s)
{
return Math.Abs(s);
@@ -54,7 +58,19 @@ namespace Godot
/// </summary>
/// <param name="s">The input number.</param>
/// <returns>The absolute value of <paramref name="s"/>.</returns>
- public static real_t Abs(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Abs(float s)
+ {
+ return Math.Abs(s);
+ }
+
+ /// <summary>
+ /// Returns the absolute value of <paramref name="s"/> (i.e. positive value).
+ /// </summary>
+ /// <param name="s">The input number.</param>
+ /// <returns>The absolute value of <paramref name="s"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Abs(double s)
{
return Math.Abs(s);
}
@@ -67,9 +83,38 @@ namespace Godot
/// <returns>
/// An angle that would result in the given cosine value. On the range <c>0</c> to <c>Tau/2</c>.
/// </returns>
- public static real_t Acos(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Acos(float s)
{
- return (real_t)Math.Acos(s);
+ return MathF.Acos(s);
+ }
+
+ /// <summary>
+ /// Returns the arc cosine of <paramref name="s"/> in radians.
+ /// Use to get the angle of cosine <paramref name="s"/>.
+ /// </summary>
+ /// <param name="s">The input cosine value. Must be on the range of -1.0 to 1.0.</param>
+ /// <returns>
+ /// An angle that would result in the given cosine value. On the range <c>0</c> to <c>Tau/2</c>.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Acos(double s)
+ {
+ return Math.Acos(s);
+ }
+
+ /// <summary>
+ /// Returns the arc sine of <paramref name="s"/> in radians.
+ /// Use to get the angle of sine <paramref name="s"/>.
+ /// </summary>
+ /// <param name="s">The input sine value. Must be on the range of -1.0 to 1.0.</param>
+ /// <returns>
+ /// An angle that would result in the given sine value. On the range <c>-Tau/4</c> to <c>Tau/4</c>.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Asin(float s)
+ {
+ return MathF.Asin(s);
}
/// <summary>
@@ -80,9 +125,10 @@ namespace Godot
/// <returns>
/// An angle that would result in the given sine value. On the range <c>-Tau/4</c> to <c>Tau/4</c>.
/// </returns>
- public static real_t Asin(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Asin(double s)
{
- return (real_t)Math.Asin(s);
+ return Math.Asin(s);
}
/// <summary>
@@ -90,15 +136,51 @@ namespace Godot
/// Use to get the angle of tangent <paramref name="s"/>.
///
/// The method cannot know in which quadrant the angle should fall.
- /// See <see cref="Atan2(real_t, real_t)"/> if you have both <c>y</c> and <c>x</c>.
+ /// See <see cref="Atan2(float, float)"/> if you have both <c>y</c> and <c>x</c>.
/// </summary>
/// <param name="s">The input tangent value.</param>
/// <returns>
/// An angle that would result in the given tangent value. On the range <c>-Tau/4</c> to <c>Tau/4</c>.
/// </returns>
- public static real_t Atan(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Atan(float s)
{
- return (real_t)Math.Atan(s);
+ return MathF.Atan(s);
+ }
+
+ /// <summary>
+ /// Returns the arc tangent of <paramref name="s"/> in radians.
+ /// Use to get the angle of tangent <paramref name="s"/>.
+ ///
+ /// The method cannot know in which quadrant the angle should fall.
+ /// See <see cref="Atan2(double, double)"/> if you have both <c>y</c> and <c>x</c>.
+ /// </summary>
+ /// <param name="s">The input tangent value.</param>
+ /// <returns>
+ /// An angle that would result in the given tangent value. On the range <c>-Tau/4</c> to <c>Tau/4</c>.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Atan(double s)
+ {
+ return Math.Atan(s);
+ }
+
+ /// <summary>
+ /// Returns the arc tangent of <paramref name="y"/> and <paramref name="x"/> in radians.
+ /// Use to get the angle of the tangent of <c>y/x</c>. To compute the value, the method takes into
+ /// account the sign of both arguments in order to determine the quadrant.
+ ///
+ /// Important note: The Y coordinate comes first, by convention.
+ /// </summary>
+ /// <param name="y">The Y coordinate of the point to find the angle to.</param>
+ /// <param name="x">The X coordinate of the point to find the angle to.</param>
+ /// <returns>
+ /// An angle that would result in the given tangent value. On the range <c>-Tau/2</c> to <c>Tau/2</c>.
+ /// </returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Atan2(float y, float x)
+ {
+ return MathF.Atan2(y, x);
}
/// <summary>
@@ -113,9 +195,21 @@ namespace Godot
/// <returns>
/// An angle that would result in the given tangent value. On the range <c>-Tau/2</c> to <c>Tau/2</c>.
/// </returns>
- public static real_t Atan2(real_t y, real_t x)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Atan2(double y, double x)
+ {
+ return Math.Atan2(y, x);
+ }
+
+ /// <summary>
+ /// Rounds <paramref name="s"/> upward (towards positive infinity).
+ /// </summary>
+ /// <param name="s">The number to ceil.</param>
+ /// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Ceil(float s)
{
- return (real_t)Math.Atan2(y, x);
+ return MathF.Ceiling(s);
}
/// <summary>
@@ -123,9 +217,10 @@ namespace Godot
/// </summary>
/// <param name="s">The number to ceil.</param>
/// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns>
- public static real_t Ceil(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Ceil(double s)
{
- return (real_t)Math.Ceiling(s);
+ return Math.Ceiling(s);
}
/// <summary>
@@ -136,9 +231,10 @@ namespace Godot
/// <param name="min">The minimum allowed value.</param>
/// <param name="max">The maximum allowed value.</param>
/// <returns>The clamped value.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Clamp(int value, int min, int max)
{
- return value < min ? min : value > max ? max : value;
+ return Math.Clamp(value, min, max);
}
/// <summary>
@@ -149,9 +245,35 @@ namespace Godot
/// <param name="min">The minimum allowed value.</param>
/// <param name="max">The maximum allowed value.</param>
/// <returns>The clamped value.</returns>
- public static real_t Clamp(real_t value, real_t min, real_t max)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Clamp(float value, float min, float max)
{
- return value < min ? min : value > max ? max : value;
+ return Math.Clamp(value, min, max);
+ }
+
+ /// <summary>
+ /// Clamps a <paramref name="value"/> so that it is not less than <paramref name="min"/>
+ /// and not more than <paramref name="max"/>.
+ /// </summary>
+ /// <param name="value">The value to clamp.</param>
+ /// <param name="min">The minimum allowed value.</param>
+ /// <param name="max">The maximum allowed value.</param>
+ /// <returns>The clamped value.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Clamp(double value, double min, double max)
+ {
+ return Math.Clamp(value, min, max);
+ }
+
+ /// <summary>
+ /// Returns the cosine of angle <paramref name="s"/> in radians.
+ /// </summary>
+ /// <param name="s">The angle in radians.</param>
+ /// <returns>The cosine of that angle.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Cos(float s)
+ {
+ return MathF.Cos(s);
}
/// <summary>
@@ -159,9 +281,21 @@ namespace Godot
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The cosine of that angle.</returns>
- public static real_t Cos(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Cos(double s)
+ {
+ return Math.Cos(s);
+ }
+
+ /// <summary>
+ /// Returns the hyperbolic cosine of angle <paramref name="s"/> in radians.
+ /// </summary>
+ /// <param name="s">The angle in radians.</param>
+ /// <returns>The hyperbolic cosine of that angle.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Cosh(float s)
{
- return (real_t)Math.Cos(s);
+ return MathF.Cosh(s);
}
/// <summary>
@@ -169,9 +303,10 @@ namespace Godot
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The hyperbolic cosine of that angle.</returns>
- public static real_t Cosh(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Cosh(double s)
{
- return (real_t)Math.Cosh(s);
+ return Math.Cosh(s);
}
/// <summary>
@@ -184,7 +319,7 @@ namespace Godot
/// <param name="post">The value which after "to" value for interpolation.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The resulting value of the interpolation.</returns>
- public static real_t CubicInterpolate(real_t from, real_t to, real_t pre, real_t post, real_t weight)
+ public static float CubicInterpolate(float from, float to, float pre, float post, float weight)
{
return 0.5f *
((from * 2.0f) +
@@ -194,9 +329,55 @@ namespace Godot
}
/// <summary>
+ /// Cubic interpolates between two values by the factor defined in <paramref name="weight"/>
+ /// with pre and post values.
+ /// </summary>
+ /// <param name="from">The start value for interpolation.</param>
+ /// <param name="to">The destination value for interpolation.</param>
+ /// <param name="pre">The value which before "from" value for interpolation.</param>
+ /// <param name="post">The value which after "to" value for interpolation.</param>
+ /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <returns>The resulting value of the interpolation.</returns>
+ public static double CubicInterpolate(double from, double to, double pre, double post, double weight)
+ {
+ return 0.5 *
+ ((from * 2.0) +
+ (-pre + to) * weight +
+ (2.0 * pre - 5.0 * from + 4.0 * to - post) * (weight * weight) +
+ (-pre + 3.0 * from - 3.0 * to + post) * (weight * weight * weight));
+ }
+
+ /// <summary>
+ /// Cubic interpolates between two rotation values with shortest path
+ /// by the factor defined in <paramref name="weight"/> with pre and post values.
+ /// See also <see cref="LerpAngle(float, float, float)"/>.
+ /// </summary>
+ /// <param name="from">The start value for interpolation.</param>
+ /// <param name="to">The destination value for interpolation.</param>
+ /// <param name="pre">The value which before "from" value for interpolation.</param>
+ /// <param name="post">The value which after "to" value for interpolation.</param>
+ /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <returns>The resulting value of the interpolation.</returns>
+ public static float CubicInterpolateAngle(float from, float to, float pre, float post, float weight)
+ {
+ float fromRot = from % MathF.Tau;
+
+ float preDiff = (pre - fromRot) % MathF.Tau;
+ float preRot = fromRot + (2.0f * preDiff) % MathF.Tau - preDiff;
+
+ float toDiff = (to - fromRot) % MathF.Tau;
+ float toRot = fromRot + (2.0f * toDiff) % MathF.Tau - toDiff;
+
+ float postDiff = (post - toRot) % MathF.Tau;
+ float postRot = toRot + (2.0f * postDiff) % MathF.Tau - postDiff;
+
+ return CubicInterpolate(fromRot, toRot, preRot, postRot, weight);
+ }
+
+ /// <summary>
/// Cubic interpolates between two rotation values with shortest path
/// by the factor defined in <paramref name="weight"/> with pre and post values.
- /// See also <see cref="LerpAngle"/>.
+ /// See also <see cref="LerpAngle(double, double, double)"/>.
/// </summary>
/// <param name="from">The start value for interpolation.</param>
/// <param name="to">The destination value for interpolation.</param>
@@ -204,18 +385,18 @@ namespace Godot
/// <param name="post">The value which after "to" value for interpolation.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The resulting value of the interpolation.</returns>
- public static real_t CubicInterpolateAngle(real_t from, real_t to, real_t pre, real_t post, real_t weight)
+ public static double CubicInterpolateAngle(double from, double to, double pre, double post, double weight)
{
- real_t fromRot = from % Mathf.Tau;
+ double fromRot = from % Math.Tau;
- real_t preDiff = (pre - fromRot) % Mathf.Tau;
- real_t preRot = fromRot + (2.0f * preDiff) % Mathf.Tau - preDiff;
+ double preDiff = (pre - fromRot) % Math.Tau;
+ double preRot = fromRot + (2.0 * preDiff) % Math.Tau - preDiff;
- real_t toDiff = (to - fromRot) % Mathf.Tau;
- real_t toRot = fromRot + (2.0f * toDiff) % Mathf.Tau - toDiff;
+ double toDiff = (to - fromRot) % Math.Tau;
+ double toRot = fromRot + (2.0 * toDiff) % Math.Tau - toDiff;
- real_t postDiff = (post - toRot) % Mathf.Tau;
- real_t postRot = toRot + (2.0f * postDiff) % Mathf.Tau - postDiff;
+ double postDiff = (post - toRot) % Math.Tau;
+ double postRot = toRot + (2.0 * postDiff) % Math.Tau - postDiff;
return CubicInterpolate(fromRot, toRot, preRot, postRot, weight);
}
@@ -223,7 +404,8 @@ namespace Godot
/// <summary>
/// Cubic interpolates between two values by the factor defined in <paramref name="weight"/>
/// with pre and post values.
- /// It can perform smoother interpolation than <see cref="CubicInterpolate"/>
+ /// It can perform smoother interpolation than
+ /// <see cref="CubicInterpolate(float, float, float, float, float)"/>
/// by the time values.
/// </summary>
/// <param name="from">The start value for interpolation.</param>
@@ -235,23 +417,52 @@ namespace Godot
/// <param name="preT"></param>
/// <param name="postT"></param>
/// <returns>The resulting value of the interpolation.</returns>
- public static real_t CubicInterpolateInTime(real_t from, real_t to, real_t pre, real_t post, real_t weight, real_t toT, real_t preT, real_t postT)
+ public static float CubicInterpolateInTime(float from, float to, float pre, float post, float weight, float toT, float preT, float postT)
{
/* Barry-Goldman method */
- real_t t = Lerp(0.0f, toT, weight);
- real_t a1 = Lerp(pre, from, preT == 0 ? 0.0f : (t - preT) / -preT);
- real_t a2 = Lerp(from, to, toT == 0 ? 0.5f : t / toT);
- real_t a3 = Lerp(to, post, postT - toT == 0 ? 1.0f : (t - toT) / (postT - toT));
- real_t b1 = Lerp(a1, a2, toT - preT == 0 ? 0.0f : (t - preT) / (toT - preT));
- real_t b2 = Lerp(a2, a3, postT == 0 ? 1.0f : t / postT);
+ float t = Lerp(0.0f, toT, weight);
+ float a1 = Lerp(pre, from, preT == 0 ? 0.0f : (t - preT) / -preT);
+ float a2 = Lerp(from, to, toT == 0 ? 0.5f : t / toT);
+ float a3 = Lerp(to, post, postT - toT == 0 ? 1.0f : (t - toT) / (postT - toT));
+ float b1 = Lerp(a1, a2, toT - preT == 0 ? 0.0f : (t - preT) / (toT - preT));
+ float b2 = Lerp(a2, a3, postT == 0 ? 1.0f : t / postT);
return Lerp(b1, b2, toT == 0 ? 0.5f : t / toT);
}
/// <summary>
+ /// Cubic interpolates between two values by the factor defined in <paramref name="weight"/>
+ /// with pre and post values.
+ /// It can perform smoother interpolation than
+ /// <see cref="CubicInterpolate(double, double, double, double, double)"/>
+ /// by the time values.
+ /// </summary>
+ /// <param name="from">The start value for interpolation.</param>
+ /// <param name="to">The destination value for interpolation.</param>
+ /// <param name="pre">The value which before "from" value for interpolation.</param>
+ /// <param name="post">The value which after "to" value for interpolation.</param>
+ /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <param name="toT"></param>
+ /// <param name="preT"></param>
+ /// <param name="postT"></param>
+ /// <returns>The resulting value of the interpolation.</returns>
+ public static double CubicInterpolateInTime(double from, double to, double pre, double post, double weight, double toT, double preT, double postT)
+ {
+ /* Barry-Goldman method */
+ double t = Lerp(0.0, toT, weight);
+ double a1 = Lerp(pre, from, preT == 0 ? 0.0 : (t - preT) / -preT);
+ double a2 = Lerp(from, to, toT == 0 ? 0.5 : t / toT);
+ double a3 = Lerp(to, post, postT - toT == 0 ? 1.0 : (t - toT) / (postT - toT));
+ double b1 = Lerp(a1, a2, toT - preT == 0 ? 0.0 : (t - preT) / (toT - preT));
+ double b2 = Lerp(a2, a3, postT == 0 ? 1.0 : t / postT);
+ return Lerp(b1, b2, toT == 0 ? 0.5 : t / toT);
+ }
+
+ /// <summary>
/// Cubic interpolates between two rotation values with shortest path
/// by the factor defined in <paramref name="weight"/> with pre and post values.
- /// See also <see cref="LerpAngle"/>.
- /// It can perform smoother interpolation than <see cref="CubicInterpolateAngle"/>
+ /// See also <see cref="LerpAngle(float, float, float)"/>.
+ /// It can perform smoother interpolation than
+ /// <see cref="CubicInterpolateAngle(float, float, float, float, float)"/>
/// by the time values.
/// </summary>
/// <param name="from">The start value for interpolation.</param>
@@ -263,24 +474,78 @@ namespace Godot
/// <param name="preT"></param>
/// <param name="postT"></param>
/// <returns>The resulting value of the interpolation.</returns>
- public static real_t CubicInterpolateAngleInTime(real_t from, real_t to, real_t pre, real_t post, real_t weight,
- real_t toT, real_t preT, real_t postT)
+ public static float CubicInterpolateAngleInTime(float from, float to, float pre, float post, float weight, float toT, float preT, float postT)
{
- real_t fromRot = from % Mathf.Tau;
+ float fromRot = from % MathF.Tau;
- real_t preDiff = (pre - fromRot) % Mathf.Tau;
- real_t preRot = fromRot + (2.0f * preDiff) % Mathf.Tau - preDiff;
+ float preDiff = (pre - fromRot) % MathF.Tau;
+ float preRot = fromRot + (2.0f * preDiff) % MathF.Tau - preDiff;
- real_t toDiff = (to - fromRot) % Mathf.Tau;
- real_t toRot = fromRot + (2.0f * toDiff) % Mathf.Tau - toDiff;
+ float toDiff = (to - fromRot) % MathF.Tau;
+ float toRot = fromRot + (2.0f * toDiff) % MathF.Tau - toDiff;
- real_t postDiff = (post - toRot) % Mathf.Tau;
- real_t postRot = toRot + (2.0f * postDiff) % Mathf.Tau - postDiff;
+ float postDiff = (post - toRot) % MathF.Tau;
+ float postRot = toRot + (2.0f * postDiff) % MathF.Tau - postDiff;
return CubicInterpolateInTime(fromRot, toRot, preRot, postRot, weight, toT, preT, postT);
}
/// <summary>
+ /// Cubic interpolates between two rotation values with shortest path
+ /// by the factor defined in <paramref name="weight"/> with pre and post values.
+ /// See also <see cref="LerpAngle(double, double, double)"/>.
+ /// It can perform smoother interpolation than
+ /// <see cref="CubicInterpolateAngle(double, double, double, double, double)"/>
+ /// by the time values.
+ /// </summary>
+ /// <param name="from">The start value for interpolation.</param>
+ /// <param name="to">The destination value for interpolation.</param>
+ /// <param name="pre">The value which before "from" value for interpolation.</param>
+ /// <param name="post">The value which after "to" value for interpolation.</param>
+ /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <param name="toT"></param>
+ /// <param name="preT"></param>
+ /// <param name="postT"></param>
+ /// <returns>The resulting value of the interpolation.</returns>
+ public static double CubicInterpolateAngleInTime(double from, double to, double pre, double post, double weight, double toT, double preT, double postT)
+ {
+ double fromRot = from % Math.Tau;
+
+ double preDiff = (pre - fromRot) % Math.Tau;
+ double preRot = fromRot + (2.0 * preDiff) % Math.Tau - preDiff;
+
+ double toDiff = (to - fromRot) % Math.Tau;
+ double toRot = fromRot + (2.0 * toDiff) % Math.Tau - toDiff;
+
+ double postDiff = (post - toRot) % Math.Tau;
+ double postRot = toRot + (2.0 * postDiff) % Math.Tau - postDiff;
+
+ return CubicInterpolateInTime(fromRot, toRot, preRot, postRot, weight, toT, preT, postT);
+ }
+
+ /// <summary>
+ /// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by
+ /// the given <paramref name="control1"/>, <paramref name="control2"/>, and <paramref name="end"/> points.
+ /// </summary>
+ /// <param name="start">The start value for the interpolation.</param>
+ /// <param name="control1">Control point that defines the bezier curve.</param>
+ /// <param name="control2">Control point that defines the bezier curve.</param>
+ /// <param name="end">The destination value for the interpolation.</param>
+ /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <returns>The resulting value of the interpolation.</returns>
+ public static float BezierInterpolate(float start, float control1, float control2, float end, float t)
+ {
+ // Formula from Wikipedia article on Bezier curves
+ float omt = 1.0f - t;
+ float omt2 = omt * omt;
+ float omt3 = omt2 * omt;
+ float t2 = t * t;
+ float t3 = t2 * t;
+
+ return start * omt3 + control1 * omt2 * t * 3.0f + control2 * omt * t2 * 3.0f + end * t3;
+ }
+
+ /// <summary>
/// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by
/// the given <paramref name="control1"/>, <paramref name="control2"/>, and <paramref name="end"/> points.
/// </summary>
@@ -290,16 +555,16 @@ namespace Godot
/// <param name="end">The destination value for the interpolation.</param>
/// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The resulting value of the interpolation.</returns>
- public static real_t BezierInterpolate(real_t start, real_t control1, real_t control2, real_t end, real_t t)
+ public static double BezierInterpolate(double start, double control1, double control2, double end, double t)
{
// Formula from Wikipedia article on Bezier curves
- real_t omt = 1 - t;
- real_t omt2 = omt * omt;
- real_t omt3 = omt2 * omt;
- real_t t2 = t * t;
- real_t t3 = t2 * t;
+ double omt = 1.0 - t;
+ double omt2 = omt * omt;
+ double omt3 = omt2 * omt;
+ double t2 = t * t;
+ double t3 = t2 * t;
- return start * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3;
+ return start * omt3 + control1 * omt2 * t * 3.0 + control2 * omt * t2 * 3.0 + end * t3;
}
/// <summary>
@@ -312,25 +577,78 @@ namespace Godot
/// <param name="end">The destination value for the interpolation.</param>
/// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The resulting value of the interpolation.</returns>
- public static real_t BezierDerivative(real_t start, real_t control1, real_t control2, real_t end, real_t t)
+ public static float BezierDerivative(float start, float control1, float control2, float end, float t)
{
// Formula from Wikipedia article on Bezier curves
- real_t omt = 1 - t;
- real_t omt2 = omt * omt;
- real_t t2 = t * t;
+ float omt = 1.0f - t;
+ float omt2 = omt * omt;
+ float t2 = t * t;
- real_t d = (control1 - start) * 3 * omt2 + (control2 - control1) * 6 * omt * t + (end - control2) * 3 * t2;
+ float d = (control1 - start) * 3.0f * omt2 + (control2 - control1) * 6.0f * omt * t + (end - control2) * 3.0f * t2;
return d;
}
/// <summary>
+ /// Returns the derivative at the given <paramref name="t"/> on a one dimensional Bezier curve defined by
+ /// the given <paramref name="control1"/>, <paramref name="control2"/>, and <paramref name="end"/> points.
+ /// </summary>
+ /// <param name="start">The start value for the interpolation.</param>
+ /// <param name="control1">Control point that defines the bezier curve.</param>
+ /// <param name="control2">Control point that defines the bezier curve.</param>
+ /// <param name="end">The destination value for the interpolation.</param>
+ /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <returns>The resulting value of the interpolation.</returns>
+ public static double BezierDerivative(double start, double control1, double control2, double end, double t)
+ {
+ // Formula from Wikipedia article on Bezier curves
+ double omt = 1.0 - t;
+ double omt2 = omt * omt;
+ double t2 = t * t;
+
+ double d = (control1 - start) * 3.0 * omt2 + (control2 - control1) * 6.0 * omt * t + (end - control2) * 3.0 * t2;
+ return d;
+ }
+
+ /// <summary>
+ /// Converts from decibels to linear energy (audio).
+ /// </summary>
+ /// <seealso cref="LinearToDb(float)"/>
+ /// <param name="db">Decibels to convert.</param>
+ /// <returns>Audio volume as linear energy.</returns>
+ public static float DbToLinear(float db)
+ {
+ return MathF.Exp(db * 0.11512925464970228420089957273422f);
+ }
+
+ /// <summary>
+ /// Converts from decibels to linear energy (audio).
+ /// </summary>
+ /// <seealso cref="LinearToDb(double)"/>
+ /// <param name="db">Decibels to convert.</param>
+ /// <returns>Audio volume as linear energy.</returns>
+ public static double DbToLinear(double db)
+ {
+ return Math.Exp(db * 0.11512925464970228420089957273422);
+ }
+
+ /// <summary>
+ /// Converts an angle expressed in degrees to radians.
+ /// </summary>
+ /// <param name="deg">An angle expressed in degrees.</param>
+ /// <returns>The same angle expressed in radians.</returns>
+ public static float DegToRad(float deg)
+ {
+ return deg * _degToRadConstF;
+ }
+
+ /// <summary>
/// Converts an angle expressed in degrees to radians.
/// </summary>
/// <param name="deg">An angle expressed in degrees.</param>
/// <returns>The same angle expressed in radians.</returns>
- public static real_t DegToRad(real_t deg)
+ public static double DegToRad(double deg)
{
- return deg * _degToRadConst;
+ return deg * _degToRadConstD;
}
/// <summary>
@@ -343,38 +661,94 @@ namespace Godot
/// <c>0</c> is constant, <c>1</c> is linear, <c>0</c> to <c>1</c> is ease-in, <c>1</c> or more is ease-out.
/// </param>
/// <returns>The eased value.</returns>
- public static real_t Ease(real_t s, real_t curve)
+ public static float Ease(float s, float curve)
{
- if (s < 0f)
+ if (s < 0.0f)
{
- s = 0f;
+ s = 0.0f;
}
else if (s > 1.0f)
{
s = 1.0f;
}
- if (curve > 0f)
+ if (curve > 0.0f)
{
if (curve < 1.0f)
{
- return 1.0f - Pow(1.0f - s, 1.0f / curve);
+ return 1.0f - MathF.Pow(1.0f - s, 1.0f / curve);
}
- return Pow(s, curve);
+ return MathF.Pow(s, curve);
}
- if (curve < 0f)
+ if (curve < 0.0f)
{
if (s < 0.5f)
{
- return Pow(s * 2.0f, -curve) * 0.5f;
+ return MathF.Pow(s * 2.0f, -curve) * 0.5f;
+ }
+
+ return ((1.0f - MathF.Pow(1.0f - ((s - 0.5f) * 2.0f), -curve)) * 0.5f) + 0.5f;
+ }
+
+ return 0.0f;
+ }
+
+ /// <summary>
+ /// Easing function, based on exponent. The <paramref name="curve"/> values are:
+ /// <c>0</c> is constant, <c>1</c> is linear, <c>0</c> to <c>1</c> is ease-in, <c>1</c> or more is ease-out.
+ /// Negative values are in-out/out-in.
+ /// </summary>
+ /// <param name="s">The value to ease.</param>
+ /// <param name="curve">
+ /// <c>0</c> is constant, <c>1</c> is linear, <c>0</c> to <c>1</c> is ease-in, <c>1</c> or more is ease-out.
+ /// </param>
+ /// <returns>The eased value.</returns>
+ public static double Ease(double s, double curve)
+ {
+ if (s < 0.0)
+ {
+ s = 0.0;
+ }
+ else if (s > 1.0)
+ {
+ s = 1.0;
+ }
+
+ if (curve > 0)
+ {
+ if (curve < 1.0)
+ {
+ return 1.0 - Math.Pow(1.0 - s, 1.0 / curve);
+ }
+
+ return Math.Pow(s, curve);
+ }
+
+ if (curve < 0.0)
+ {
+ if (s < 0.5)
+ {
+ return Math.Pow(s * 2.0, -curve) * 0.5;
}
- return ((1.0f - Pow(1.0f - ((s - 0.5f) * 2.0f), -curve)) * 0.5f) + 0.5f;
+ return ((1.0 - Math.Pow(1.0 - ((s - 0.5) * 2.0), -curve)) * 0.5) + 0.5;
}
- return 0f;
+ return 0.0;
+ }
+
+ /// <summary>
+ /// The natural exponential function. It raises the mathematical
+ /// constant <c>e</c> to the power of <paramref name="s"/> and returns it.
+ /// </summary>
+ /// <param name="s">The exponent to raise <c>e</c> to.</param>
+ /// <returns><c>e</c> raised to the power of <paramref name="s"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Exp(float s)
+ {
+ return MathF.Exp(s);
}
/// <summary>
@@ -383,9 +757,21 @@ namespace Godot
/// </summary>
/// <param name="s">The exponent to raise <c>e</c> to.</param>
/// <returns><c>e</c> raised to the power of <paramref name="s"/>.</returns>
- public static real_t Exp(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Exp(double s)
+ {
+ return Math.Exp(s);
+ }
+
+ /// <summary>
+ /// Rounds <paramref name="s"/> downward (towards negative infinity).
+ /// </summary>
+ /// <param name="s">The number to floor.</param>
+ /// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Floor(float s)
{
- return (real_t)Math.Exp(s);
+ return MathF.Floor(s);
}
/// <summary>
@@ -393,14 +779,32 @@ namespace Godot
/// </summary>
/// <param name="s">The number to floor.</param>
/// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns>
- public static real_t Floor(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Floor(double s)
+ {
+ return Math.Floor(s);
+ }
+
+ /// <summary>
+ /// Returns a normalized value considering the given range.
+ /// This is the opposite of <see cref="Lerp(float, float, float)"/>.
+ /// </summary>
+ /// <param name="from">The start value for interpolation.</param>
+ /// <param name="to">The destination value for interpolation.</param>
+ /// <param name="weight">The interpolated value.</param>
+ /// <returns>
+ /// The resulting value of the inverse interpolation.
+ /// The returned value will be between 0.0 and 1.0 if <paramref name="weight"/> is
+ /// between <paramref name="from"/> and <paramref name="to"/> (inclusive).
+ /// </returns>
+ public static float InverseLerp(float from, float to, float weight)
{
- return (real_t)Math.Floor(s);
+ return (weight - from) / (to - from);
}
/// <summary>
/// Returns a normalized value considering the given range.
- /// This is the opposite of <see cref="Lerp(real_t, real_t, real_t)"/>.
+ /// This is the opposite of <see cref="Lerp(double, double, double)"/>.
/// </summary>
/// <param name="from">The start value for interpolation.</param>
/// <param name="to">The destination value for interpolation.</param>
@@ -410,7 +814,7 @@ namespace Godot
/// The returned value will be between 0.0 and 1.0 if <paramref name="weight"/> is
/// between <paramref name="from"/> and <paramref name="to"/> (inclusive).
/// </returns>
- public static real_t InverseLerp(real_t from, real_t to, real_t weight)
+ public static double InverseLerp(double from, double to, double weight)
{
return (weight - from) / (to - from);
}
@@ -423,7 +827,7 @@ namespace Godot
/// <param name="a">One of the values.</param>
/// <param name="b">The other value.</param>
/// <returns>A <see langword="bool"/> for whether or not the two values are approximately equal.</returns>
- public static bool IsEqualApprox(real_t a, real_t b)
+ public static bool IsEqualApprox(float a, float b)
{
// Check for exact equality first, required to handle "infinity" values.
if (a == b)
@@ -431,12 +835,71 @@ namespace Godot
return true;
}
// Then check for approximate equality.
- real_t tolerance = Epsilon * Abs(a);
- if (tolerance < Epsilon)
+ float tolerance = _epsilonF * Math.Abs(a);
+ if (tolerance < _epsilonF)
{
- tolerance = Epsilon;
+ tolerance = _epsilonF;
}
- return Abs(a - b) < tolerance;
+ return Math.Abs(a - b) < tolerance;
+ }
+
+ /// <summary>
+ /// Returns <see langword="true"/> if <paramref name="a"/> and <paramref name="b"/> are approximately equal
+ /// to each other.
+ /// The comparison is done using a tolerance calculation with <see cref="Epsilon"/>.
+ /// </summary>
+ /// <param name="a">One of the values.</param>
+ /// <param name="b">The other value.</param>
+ /// <returns>A <see langword="bool"/> for whether or not the two values are approximately equal.</returns>
+ public static bool IsEqualApprox(double a, double b)
+ {
+ // Check for exact equality first, required to handle "infinity" values.
+ if (a == b)
+ {
+ return true;
+ }
+ // Then check for approximate equality.
+ double tolerance = _epsilonD * Math.Abs(a);
+ if (tolerance < _epsilonD)
+ {
+ tolerance = _epsilonD;
+ }
+ return Math.Abs(a - b) < tolerance;
+ }
+
+ /// <summary>
+ /// Returns whether <paramref name="s"/> is a finite value, i.e. it is not
+ /// <see cref="NaN"/>, positive infinite, or negative infinity.
+ /// </summary>
+ /// <param name="s">The value to check.</param>
+ /// <returns>A <see langword="bool"/> for whether or not the value is a finite value.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsFinite(float s)
+ {
+ return float.IsFinite(s);
+ }
+
+ /// <summary>
+ /// Returns whether <paramref name="s"/> is a finite value, i.e. it is not
+ /// <see cref="NaN"/>, positive infinite, or negative infinity.
+ /// </summary>
+ /// <param name="s">The value to check.</param>
+ /// <returns>A <see langword="bool"/> for whether or not the value is a finite value.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsFinite(double s)
+ {
+ return double.IsFinite(s);
+ }
+
+ /// <summary>
+ /// Returns whether <paramref name="s"/> is an infinity value (either positive infinity or negative infinity).
+ /// </summary>
+ /// <param name="s">The value to check.</param>
+ /// <returns>A <see langword="bool"/> for whether or not the value is an infinity value.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsInf(float s)
+ {
+ return float.IsInfinity(s);
}
/// <summary>
@@ -444,9 +907,10 @@ namespace Godot
/// </summary>
/// <param name="s">The value to check.</param>
/// <returns>A <see langword="bool"/> for whether or not the value is an infinity value.</returns>
- public static bool IsInf(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsInf(double s)
{
- return real_t.IsInfinity(s);
+ return double.IsInfinity(s);
}
/// <summary>
@@ -454,33 +918,75 @@ namespace Godot
/// </summary>
/// <param name="s">The value to check.</param>
/// <returns>A <see langword="bool"/> for whether or not the value is a <c>NaN</c> value.</returns>
- public static bool IsNaN(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsNaN(float s)
+ {
+ return float.IsNaN(s);
+ }
+
+ /// <summary>
+ /// Returns whether <paramref name="s"/> is a <c>NaN</c> ("Not a Number" or invalid) value.
+ /// </summary>
+ /// <param name="s">The value to check.</param>
+ /// <returns>A <see langword="bool"/> for whether or not the value is a <c>NaN</c> value.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsNaN(double s)
+ {
+ return double.IsNaN(s);
+ }
+
+ /// <summary>
+ /// Returns <see langword="true"/> if <paramref name="s"/> is zero or almost zero.
+ /// The comparison is done using a tolerance calculation with <see cref="Epsilon"/>.
+ ///
+ /// This method is faster than using <see cref="IsEqualApprox(float, float)"/> with
+ /// one value as zero.
+ /// </summary>
+ /// <param name="s">The value to check.</param>
+ /// <returns>A <see langword="bool"/> for whether or not the value is nearly zero.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsZeroApprox(float s)
{
- return real_t.IsNaN(s);
+ return Math.Abs(s) < _epsilonF;
}
/// <summary>
- /// Returns <see langword="true"/> if <paramref name="s"/> is approximately zero.
+ /// Returns <see langword="true"/> if <paramref name="s"/> is zero or almost zero.
/// The comparison is done using a tolerance calculation with <see cref="Epsilon"/>.
///
- /// This method is faster than using <see cref="IsEqualApprox(real_t, real_t)"/> with one value as zero.
+ /// This method is faster than using <see cref="IsEqualApprox(double, double)"/> with
+ /// one value as zero.
/// </summary>
/// <param name="s">The value to check.</param>
/// <returns>A <see langword="bool"/> for whether or not the value is nearly zero.</returns>
- public static bool IsZeroApprox(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsZeroApprox(double s)
+ {
+ return Math.Abs(s) < _epsilonD;
+ }
+
+ /// <summary>
+ /// Linearly interpolates between two values by a normalized value.
+ /// This is the opposite <see cref="InverseLerp(float, float, float)"/>.
+ /// </summary>
+ /// <param name="from">The start value for interpolation.</param>
+ /// <param name="to">The destination value for interpolation.</param>
+ /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <returns>The resulting value of the interpolation.</returns>
+ public static float Lerp(float from, float to, float weight)
{
- return Abs(s) < Epsilon;
+ return from + ((to - from) * weight);
}
/// <summary>
/// Linearly interpolates between two values by a normalized value.
- /// This is the opposite <see cref="InverseLerp(real_t, real_t, real_t)"/>.
+ /// This is the opposite <see cref="InverseLerp(double, double, double)"/>.
/// </summary>
/// <param name="from">The start value for interpolation.</param>
/// <param name="to">The destination value for interpolation.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The resulting value of the interpolation.</returns>
- public static real_t Lerp(real_t from, real_t to, real_t weight)
+ public static double Lerp(double from, double to, double weight)
{
return from + ((to - from) * weight);
}
@@ -488,30 +994,101 @@ namespace Godot
/// <summary>
/// Linearly interpolates between two angles (in radians) by a normalized value.
///
- /// Similar to <see cref="Lerp(real_t, real_t, real_t)"/>,
+ /// Similar to <see cref="Lerp(float, float, float)"/>,
+ /// but interpolates correctly when the angles wrap around <see cref="Tau"/>.
+ /// </summary>
+ /// <param name="from">The start angle for interpolation.</param>
+ /// <param name="to">The destination angle for interpolation.</param>
+ /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <returns>The resulting angle of the interpolation.</returns>
+ public static float LerpAngle(float from, float to, float weight)
+ {
+ float difference = (to - from) % MathF.Tau;
+ float distance = ((2 * difference) % MathF.Tau) - difference;
+ return from + (distance * weight);
+ }
+
+ /// <summary>
+ /// Linearly interpolates between two angles (in radians) by a normalized value.
+ ///
+ /// Similar to <see cref="Lerp(double, double, double)"/>,
/// but interpolates correctly when the angles wrap around <see cref="Tau"/>.
/// </summary>
/// <param name="from">The start angle for interpolation.</param>
/// <param name="to">The destination angle for interpolation.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The resulting angle of the interpolation.</returns>
- public static real_t LerpAngle(real_t from, real_t to, real_t weight)
+ public static double LerpAngle(double from, double to, double weight)
{
- real_t difference = (to - from) % Mathf.Tau;
- real_t distance = ((2 * difference) % Mathf.Tau) - difference;
+ double difference = (to - from) % Math.Tau;
+ double distance = ((2 * difference) % Math.Tau) - difference;
return from + (distance * weight);
}
/// <summary>
+ /// Converts from linear energy to decibels (audio).
+ /// This can be used to implement volume sliders that behave as expected (since volume isn't linear).
+ /// </summary>
+ /// <seealso cref="DbToLinear(float)"/>
+ /// <example>
+ /// <code>
+ /// // "slider" refers to a node that inherits Range such as HSlider or VSlider.
+ /// // Its range must be configured to go from 0 to 1.
+ /// // Change the bus name if you'd like to change the volume of a specific bus only.
+ /// AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), GD.LinearToDb(slider.value));
+ /// </code>
+ /// </example>
+ /// <param name="linear">The linear energy to convert.</param>
+ /// <returns>Audio as decibels.</returns>
+ public static float LinearToDb(float linear)
+ {
+ return MathF.Log(linear) * 8.6858896380650365530225783783321f;
+ }
+
+ /// <summary>
+ /// Converts from linear energy to decibels (audio).
+ /// This can be used to implement volume sliders that behave as expected (since volume isn't linear).
+ /// </summary>
+ /// <seealso cref="DbToLinear(double)"/>
+ /// <example>
+ /// <code>
+ /// // "slider" refers to a node that inherits Range such as HSlider or VSlider.
+ /// // Its range must be configured to go from 0 to 1.
+ /// // Change the bus name if you'd like to change the volume of a specific bus only.
+ /// AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), GD.LinearToDb(slider.value));
+ /// </code>
+ /// </example>
+ /// <param name="linear">The linear energy to convert.</param>
+ /// <returns>Audio as decibels.</returns>
+ public static double LinearToDb(double linear)
+ {
+ return Math.Log(linear) * 8.6858896380650365530225783783321;
+ }
+
+ /// <summary>
+ /// Natural logarithm. The amount of time needed to reach a certain level of continuous growth.
+ ///
+ /// Note: This is not the same as the "log" function on most calculators, which uses a base 10 logarithm.
+ /// </summary>
+ /// <param name="s">The input value.</param>
+ /// <returns>The natural log of <paramref name="s"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Log(float s)
+ {
+ return MathF.Log(s);
+ }
+
+ /// <summary>
/// Natural logarithm. The amount of time needed to reach a certain level of continuous growth.
///
/// Note: This is not the same as the "log" function on most calculators, which uses a base 10 logarithm.
/// </summary>
/// <param name="s">The input value.</param>
/// <returns>The natural log of <paramref name="s"/>.</returns>
- public static real_t Log(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Log(double s)
{
- return (real_t)Math.Log(s);
+ return Math.Log(s);
}
/// <summary>
@@ -520,9 +1097,22 @@ namespace Godot
/// <param name="a">One of the values.</param>
/// <param name="b">The other value.</param>
/// <returns>Whichever of the two values is higher.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Max(int a, int b)
{
- return a > b ? a : b;
+ return Math.Max(a, b);
+ }
+
+ /// <summary>
+ /// Returns the maximum of two values.
+ /// </summary>
+ /// <param name="a">One of the values.</param>
+ /// <param name="b">The other value.</param>
+ /// <returns>Whichever of the two values is higher.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Max(float a, float b)
+ {
+ return Math.Max(a, b);
}
/// <summary>
@@ -531,9 +1121,10 @@ namespace Godot
/// <param name="a">One of the values.</param>
/// <param name="b">The other value.</param>
/// <returns>Whichever of the two values is higher.</returns>
- public static real_t Max(real_t a, real_t b)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Max(double a, double b)
{
- return a > b ? a : b;
+ return Math.Max(a, b);
}
/// <summary>
@@ -542,9 +1133,22 @@ namespace Godot
/// <param name="a">One of the values.</param>
/// <param name="b">The other value.</param>
/// <returns>Whichever of the two values is lower.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Min(int a, int b)
{
- return a < b ? a : b;
+ return Math.Min(a, b);
+ }
+
+ /// <summary>
+ /// Returns the minimum of two values.
+ /// </summary>
+ /// <param name="a">One of the values.</param>
+ /// <param name="b">The other value.</param>
+ /// <returns>Whichever of the two values is lower.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Min(float a, float b)
+ {
+ return Math.Min(a, b);
}
/// <summary>
@@ -553,9 +1157,27 @@ namespace Godot
/// <param name="a">One of the values.</param>
/// <param name="b">The other value.</param>
/// <returns>Whichever of the two values is lower.</returns>
- public static real_t Min(real_t a, real_t b)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Min(double a, double b)
+ {
+ return Math.Min(a, b);
+ }
+
+ /// <summary>
+ /// Moves <paramref name="from"/> toward <paramref name="to"/> by the <paramref name="delta"/> value.
+ ///
+ /// Use a negative <paramref name="delta"/> value to move away.
+ /// </summary>
+ /// <param name="from">The start value.</param>
+ /// <param name="to">The value to move towards.</param>
+ /// <param name="delta">The amount to move by.</param>
+ /// <returns>The value after moving.</returns>
+ public static float MoveToward(float from, float to, float delta)
{
- return a < b ? a : b;
+ if (Math.Abs(to - from) <= delta)
+ return to;
+
+ return from + (Math.Sign(to - from) * delta);
}
/// <summary>
@@ -567,12 +1189,12 @@ namespace Godot
/// <param name="to">The value to move towards.</param>
/// <param name="delta">The amount to move by.</param>
/// <returns>The value after moving.</returns>
- public static real_t MoveToward(real_t from, real_t to, real_t delta)
+ public static double MoveToward(double from, double to, double delta)
{
- if (Abs(to - from) <= delta)
+ if (Math.Abs(to - from) <= delta)
return to;
- return from + (Sign(to - from) * delta);
+ return from + (Math.Sign(to - from) * delta);
}
/// <summary>
@@ -614,9 +1236,25 @@ namespace Godot
/// <param name="a">The dividend, the primary input.</param>
/// <param name="b">The divisor. The output is on the range [0, <paramref name="b"/>).</param>
/// <returns>The resulting output.</returns>
- public static real_t PosMod(real_t a, real_t b)
+ public static float PosMod(float a, float b)
+ {
+ float c = a % b;
+ if ((c < 0 && b > 0) || (c > 0 && b < 0))
+ {
+ c += b;
+ }
+ return c;
+ }
+
+ /// <summary>
+ /// Performs a canonical Modulus operation, where the output is on the range [0, <paramref name="b"/>).
+ /// </summary>
+ /// <param name="a">The dividend, the primary input.</param>
+ /// <param name="b">The divisor. The output is on the range [0, <paramref name="b"/>).</param>
+ /// <returns>The resulting output.</returns>
+ public static double PosMod(double a, double b)
{
- real_t c = a % b;
+ double c = a % b;
if ((c < 0 && b > 0) || (c > 0 && b < 0))
{
c += b;
@@ -630,9 +1268,33 @@ namespace Godot
/// <param name="x">The base.</param>
/// <param name="y">The exponent.</param>
/// <returns><paramref name="x"/> raised to the power of <paramref name="y"/>.</returns>
- public static real_t Pow(real_t x, real_t y)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Pow(float x, float y)
+ {
+ return MathF.Pow(x, y);
+ }
+
+ /// <summary>
+ /// Returns the result of <paramref name="x"/> raised to the power of <paramref name="y"/>.
+ /// </summary>
+ /// <param name="x">The base.</param>
+ /// <param name="y">The exponent.</param>
+ /// <returns><paramref name="x"/> raised to the power of <paramref name="y"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Pow(double x, double y)
+ {
+ return Math.Pow(x, y);
+ }
+
+ /// <summary>
+ /// Converts an angle expressed in radians to degrees.
+ /// </summary>
+ /// <param name="rad">An angle expressed in radians.</param>
+ /// <returns>The same angle expressed in degrees.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float RadToDeg(float rad)
{
- return (real_t)Math.Pow(x, y);
+ return rad * _radToDegConstF;
}
/// <summary>
@@ -640,9 +1302,25 @@ namespace Godot
/// </summary>
/// <param name="rad">An angle expressed in radians.</param>
/// <returns>The same angle expressed in degrees.</returns>
- public static real_t RadToDeg(real_t rad)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double RadToDeg(double rad)
+ {
+ return rad * _radToDegConstD;
+ }
+
+ /// <summary>
+ /// Maps a <paramref name="value"/> from [<paramref name="inFrom"/>, <paramref name="inTo"/>]
+ /// to [<paramref name="outFrom"/>, <paramref name="outTo"/>].
+ /// </summary>
+ /// <param name="value">The value to map.</param>
+ /// <param name="inFrom">The start value for the input interpolation.</param>
+ /// <param name="inTo">The destination value for the input interpolation.</param>
+ /// <param name="outFrom">The start value for the output interpolation.</param>
+ /// <param name="outTo">The destination value for the output interpolation.</param>
+ /// <returns>The resulting mapped value mapped.</returns>
+ public static float Remap(float value, float inFrom, float inTo, float outFrom, float outTo)
{
- return rad * _radToDegConst;
+ return Lerp(outFrom, outTo, InverseLerp(inFrom, inTo, value));
}
/// <summary>
@@ -655,7 +1333,7 @@ namespace Godot
/// <param name="outFrom">The start value for the output interpolation.</param>
/// <param name="outTo">The destination value for the output interpolation.</param>
/// <returns>The resulting mapped value mapped.</returns>
- public static real_t Remap(real_t value, real_t inFrom, real_t inTo, real_t outFrom, real_t outTo)
+ public static double Remap(double value, double inFrom, double inTo, double outFrom, double outTo)
{
return Lerp(outFrom, outTo, InverseLerp(inFrom, inTo, value));
}
@@ -666,9 +1344,22 @@ namespace Godot
/// </summary>
/// <param name="s">The number to round.</param>
/// <returns>The rounded number.</returns>
- public static real_t Round(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Round(float s)
+ {
+ return MathF.Round(s);
+ }
+
+ /// <summary>
+ /// Rounds <paramref name="s"/> to the nearest whole number,
+ /// with halfway cases rounded towards the nearest multiple of two.
+ /// </summary>
+ /// <param name="s">The number to round.</param>
+ /// <returns>The rounded number.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Round(double s)
{
- return (real_t)Math.Round(s);
+ return Math.Round(s);
}
/// <summary>
@@ -677,11 +1368,22 @@ namespace Godot
/// </summary>
/// <param name="s">The input number.</param>
/// <returns>One of three possible values: <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Sign(int s)
{
- if (s == 0)
- return 0;
- return s < 0 ? -1 : 1;
+ return Math.Sign(s);
+ }
+
+ /// <summary>
+ /// Returns the sign of <paramref name="s"/>: <c>-1</c> or <c>1</c>.
+ /// Returns <c>0</c> if <paramref name="s"/> is <c>0</c>.
+ /// </summary>
+ /// <param name="s">The input number.</param>
+ /// <returns>One of three possible values: <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Sign(float s)
+ {
+ return Math.Sign(s);
}
/// <summary>
@@ -690,11 +1392,21 @@ namespace Godot
/// </summary>
/// <param name="s">The input number.</param>
/// <returns>One of three possible values: <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
- public static int Sign(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Sign(double s)
+ {
+ return Math.Sign(s);
+ }
+
+ /// <summary>
+ /// Returns the sine of angle <paramref name="s"/> in radians.
+ /// </summary>
+ /// <param name="s">The angle in radians.</param>
+ /// <returns>The sine of that angle.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Sin(float s)
{
- if (s == 0)
- return 0;
- return s < 0 ? -1 : 1;
+ return MathF.Sin(s);
}
/// <summary>
@@ -702,9 +1414,21 @@ namespace Godot
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The sine of that angle.</returns>
- public static real_t Sin(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Sin(double s)
+ {
+ return Math.Sin(s);
+ }
+
+ /// <summary>
+ /// Returns the hyperbolic sine of angle <paramref name="s"/> in radians.
+ /// </summary>
+ /// <param name="s">The angle in radians.</param>
+ /// <returns>The hyperbolic sine of that angle.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Sinh(float s)
{
- return (real_t)Math.Sin(s);
+ return MathF.Sinh(s);
}
/// <summary>
@@ -712,27 +1436,47 @@ namespace Godot
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The hyperbolic sine of that angle.</returns>
- public static real_t Sinh(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Sinh(double s)
+ {
+ return Math.Sinh(s);
+ }
+
+ /// <summary>
+ /// Returns a number smoothly interpolated between <paramref name="from"/> and <paramref name="to"/>,
+ /// based on the <paramref name="weight"/>. Similar to <see cref="Lerp(float, float, float)"/>,
+ /// but interpolates faster at the beginning and slower at the end.
+ /// </summary>
+ /// <param name="from">The start value for interpolation.</param>
+ /// <param name="to">The destination value for interpolation.</param>
+ /// <param name="weight">A value representing the amount of interpolation.</param>
+ /// <returns>The resulting value of the interpolation.</returns>
+ public static float SmoothStep(float from, float to, float weight)
{
- return (real_t)Math.Sinh(s);
+ if (IsEqualApprox(from, to))
+ {
+ return from;
+ }
+ float x = Math.Clamp((weight - from) / (to - from), 0.0f, 1.0f);
+ return x * x * (3 - (2 * x));
}
/// <summary>
/// Returns a number smoothly interpolated between <paramref name="from"/> and <paramref name="to"/>,
- /// based on the <paramref name="weight"/>. Similar to <see cref="Lerp(real_t, real_t, real_t)"/>,
+ /// based on the <paramref name="weight"/>. Similar to <see cref="Lerp(double, double, double)"/>,
/// but interpolates faster at the beginning and slower at the end.
/// </summary>
/// <param name="from">The start value for interpolation.</param>
/// <param name="to">The destination value for interpolation.</param>
/// <param name="weight">A value representing the amount of interpolation.</param>
/// <returns>The resulting value of the interpolation.</returns>
- public static real_t SmoothStep(real_t from, real_t to, real_t weight)
+ public static double SmoothStep(double from, double to, double weight)
{
if (IsEqualApprox(from, to))
{
return from;
}
- real_t x = Clamp((weight - from) / (to - from), (real_t)0.0, (real_t)1.0);
+ double x = Math.Clamp((weight - from) / (to - from), 0.0, 1.0);
return x * x * (3 - (2 * x));
}
@@ -743,9 +1487,23 @@ namespace Godot
/// </summary>
/// <param name="s">The input number. Must not be negative.</param>
/// <returns>The square root of <paramref name="s"/>.</returns>
- public static real_t Sqrt(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Sqrt(float s)
+ {
+ return MathF.Sqrt(s);
+ }
+
+ /// <summary>
+ /// Returns the square root of <paramref name="s"/>, where <paramref name="s"/> is a non-negative number.
+ ///
+ /// If you need negative inputs, use <see cref="System.Numerics.Complex"/>.
+ /// </summary>
+ /// <param name="s">The input number. Must not be negative.</param>
+ /// <returns>The square root of <paramref name="s"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Sqrt(double s)
{
- return (real_t)Math.Sqrt(s);
+ return Math.Sqrt(s);
}
/// <summary>
@@ -755,7 +1513,7 @@ namespace Godot
/// </summary>
/// <param name="step">The input value.</param>
/// <returns>The position of the first non-zero digit.</returns>
- public static int StepDecimals(real_t step)
+ public static int StepDecimals(double step)
{
double[] sd = new double[]
{
@@ -769,7 +1527,7 @@ namespace Godot
0.00000009999,
0.000000009999,
};
- double abs = Abs(step);
+ double abs = Math.Abs(step);
double decs = abs - (int)abs; // Strip away integer part
for (int i = 0; i < sd.Length; i++)
{
@@ -788,11 +1546,28 @@ namespace Godot
/// <param name="s">The value to snap.</param>
/// <param name="step">The step size to snap to.</param>
/// <returns>The snapped value.</returns>
- public static real_t Snapped(real_t s, real_t step)
+ public static float Snapped(float s, float step)
+ {
+ if (step != 0f)
+ {
+ return MathF.Floor((s / step) + 0.5f) * step;
+ }
+
+ return s;
+ }
+
+ /// <summary>
+ /// Snaps float value <paramref name="s"/> to a given <paramref name="step"/>.
+ /// This can also be used to round a floating point number to an arbitrary number of decimals.
+ /// </summary>
+ /// <param name="s">The value to snap.</param>
+ /// <param name="step">The step size to snap to.</param>
+ /// <returns>The snapped value.</returns>
+ public static double Snapped(double s, double step)
{
if (step != 0f)
{
- return Floor((s / step) + 0.5f) * step;
+ return Math.Floor((s / step) + 0.5f) * step;
}
return s;
@@ -803,9 +1578,32 @@ namespace Godot
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The tangent of that angle.</returns>
- public static real_t Tan(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Tan(float s)
+ {
+ return MathF.Tan(s);
+ }
+
+ /// <summary>
+ /// Returns the tangent of angle <paramref name="s"/> in radians.
+ /// </summary>
+ /// <param name="s">The angle in radians.</param>
+ /// <returns>The tangent of that angle.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Tan(double s)
+ {
+ return Math.Tan(s);
+ }
+
+ /// <summary>
+ /// Returns the hyperbolic tangent of angle <paramref name="s"/> in radians.
+ /// </summary>
+ /// <param name="s">The angle in radians.</param>
+ /// <returns>The hyperbolic tangent of that angle.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Tanh(float s)
{
- return (real_t)Math.Tan(s);
+ return MathF.Tanh(s);
}
/// <summary>
@@ -813,9 +1611,10 @@ namespace Godot
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The hyperbolic tangent of that angle.</returns>
- public static real_t Tanh(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Tanh(double s)
{
- return (real_t)Math.Tanh(s);
+ return Math.Tanh(s);
}
/// <summary>
@@ -841,15 +1640,35 @@ namespace Godot
/// Wraps <paramref name="value"/> between <paramref name="min"/> and <paramref name="max"/>.
/// Usable for creating loop-alike behavior or infinite surfaces.
/// If <paramref name="min"/> is <c>0</c>, this is equivalent
- /// to <see cref="PosMod(real_t, real_t)"/>, so prefer using that instead.
+ /// to <see cref="PosMod(float, float)"/>, so prefer using that instead.
+ /// </summary>
+ /// <param name="value">The value to wrap.</param>
+ /// <param name="min">The minimum allowed value and lower bound of the range.</param>
+ /// <param name="max">The maximum allowed value and upper bound of the range.</param>
+ /// <returns>The wrapped value.</returns>
+ public static float Wrap(float value, float min, float max)
+ {
+ float range = max - min;
+ if (IsZeroApprox(range))
+ {
+ return min;
+ }
+ return min + ((((value - min) % range) + range) % range);
+ }
+
+ /// <summary>
+ /// Wraps <paramref name="value"/> between <paramref name="min"/> and <paramref name="max"/>.
+ /// Usable for creating loop-alike behavior or infinite surfaces.
+ /// If <paramref name="min"/> is <c>0</c>, this is equivalent
+ /// to <see cref="PosMod(double, double)"/>, so prefer using that instead.
/// </summary>
/// <param name="value">The value to wrap.</param>
/// <param name="min">The minimum allowed value and lower bound of the range.</param>
/// <param name="max">The maximum allowed value and upper bound of the range.</param>
/// <returns>The wrapped value.</returns>
- public static real_t Wrap(real_t value, real_t min, real_t max)
+ public static double Wrap(double value, double min, double max)
{
- real_t range = max - min;
+ double range = max - min;
if (IsZeroApprox(range))
{
return min;
@@ -857,9 +1676,23 @@ namespace Godot
return min + ((((value - min) % range) + range) % range);
}
- private static real_t Fract(real_t value)
+ /// <summary>
+ /// Returns the <paramref name="value"/> wrapped between <c>0</c> and the <paramref name="length"/>.
+ /// If the limit is reached, the next value the function returned is decreased to the <c>0</c> side
+ /// or increased to the <paramref name="length"/> side (like a triangle wave).
+ /// If <paramref name="length"/> is less than zero, it becomes positive.
+ /// </summary>
+ /// <param name="value">The value to pingpong.</param>
+ /// <param name="length">The maximum value of the function.</param>
+ /// <returns>The ping-ponged value.</returns>
+ public static float PingPong(float value, float length)
{
- return value - (real_t)Math.Floor(value);
+ return (length != 0.0f) ? Math.Abs(Fract((value - length) / (length * 2.0f)) * length * 2.0f - length) : 0.0f;
+
+ static float Fract(float value)
+ {
+ return value - MathF.Floor(value);
+ }
}
/// <summary>
@@ -871,9 +1704,14 @@ namespace Godot
/// <param name="value">The value to pingpong.</param>
/// <param name="length">The maximum value of the function.</param>
/// <returns>The ping-ponged value.</returns>
- public static real_t PingPong(real_t value, real_t length)
+ public static double PingPong(double value, double length)
{
- return (length != (real_t)0.0) ? Abs(Fract((value - length) / (length * (real_t)2.0)) * length * (real_t)2.0 - length) : (real_t)0.0;
+ return (length != 0.0) ? Math.Abs(Fract((value - length) / (length * 2.0)) * length * 2.0 - length) : 0.0;
+
+ static double Fract(double value)
+ {
+ return value - Math.Floor(value);
+ }
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs
index ea05c1547c..cc2d61f58d 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs
@@ -1,4 +1,8 @@
using System;
+using System.Runtime.CompilerServices;
+
+// This file contains extra members for the Mathf class that aren't part of Godot's Core API.
+// Math API that is also part of Core should go into Mathf.cs.
namespace Godot
{
@@ -16,14 +20,18 @@ namespace Godot
/// </summary>
public const real_t Sqrt2 = (real_t)1.4142135623730950488016887242M; // 1.4142136f and 1.414213562373095
+ // Epsilon size should depend on the precision used.
+ private const float _epsilonF = 1e-06f;
+ private const double _epsilonD = 1e-14;
+
/// <summary>
/// A very small number used for float comparison with error tolerance.
/// 1e-06 with single-precision floats, but 1e-14 if <c>REAL_T_IS_DOUBLE</c>.
/// </summary>
#if REAL_T_IS_DOUBLE
- public const real_t Epsilon = 1e-14; // Epsilon size should depend on the precision used.
+ public const real_t Epsilon = _epsilonD;
#else
- public const real_t Epsilon = 1e-06f;
+ public const real_t Epsilon = _epsilonF;
#endif
/// <summary>
@@ -31,7 +39,8 @@ namespace Godot
/// </summary>
/// <param name="s">The input value.</param>
/// <returns>The amount of digits.</returns>
- public static int DecimalCount(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int DecimalCount(double s)
{
return DecimalCount((decimal)s);
}
@@ -41,6 +50,7 @@ namespace Godot
/// </summary>
/// <param name="s">The input <see langword="decimal"/> value.</param>
/// <returns>The amount of digits.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int DecimalCount(decimal s)
{
return BitConverter.GetBytes(decimal.GetBits(s)[3])[2];
@@ -49,11 +59,25 @@ namespace Godot
/// <summary>
/// Rounds <paramref name="s"/> upward (towards positive infinity).
///
- /// This is the same as <see cref="Ceil(real_t)"/>, but returns an <see langword="int"/>.
+ /// This is the same as <see cref="Ceil(float)"/>, but returns an <see langword="int"/>.
/// </summary>
/// <param name="s">The number to ceil.</param>
/// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns>
- public static int CeilToInt(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int CeilToInt(float s)
+ {
+ return (int)MathF.Ceiling(s);
+ }
+
+ /// <summary>
+ /// Rounds <paramref name="s"/> upward (towards positive infinity).
+ ///
+ /// This is the same as <see cref="Ceil(double)"/>, but returns an <see langword="int"/>.
+ /// </summary>
+ /// <param name="s">The number to ceil.</param>
+ /// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int CeilToInt(double s)
{
return (int)Math.Ceiling(s);
}
@@ -61,11 +85,25 @@ namespace Godot
/// <summary>
/// Rounds <paramref name="s"/> downward (towards negative infinity).
///
- /// This is the same as <see cref="Floor(real_t)"/>, but returns an <see langword="int"/>.
+ /// This is the same as <see cref="Floor(float)"/>, but returns an <see langword="int"/>.
/// </summary>
/// <param name="s">The number to floor.</param>
/// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns>
- public static int FloorToInt(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int FloorToInt(float s)
+ {
+ return (int)MathF.Floor(s);
+ }
+
+ /// <summary>
+ /// Rounds <paramref name="s"/> downward (towards negative infinity).
+ ///
+ /// This is the same as <see cref="Floor(double)"/>, but returns an <see langword="int"/>.
+ /// </summary>
+ /// <param name="s">The number to floor.</param>
+ /// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int FloorToInt(double s)
{
return (int)Math.Floor(s);
}
@@ -73,26 +111,81 @@ namespace Godot
/// <summary>
/// Rounds <paramref name="s"/> to the nearest whole number.
///
- /// This is the same as <see cref="Round(real_t)"/>, but returns an <see langword="int"/>.
+ /// This is the same as <see cref="Round(float)"/>, but returns an <see langword="int"/>.
+ /// </summary>
+ /// <param name="s">The number to round.</param>
+ /// <returns>The rounded number.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int RoundToInt(float s)
+ {
+ return (int)MathF.Round(s);
+ }
+
+ /// <summary>
+ /// Rounds <paramref name="s"/> to the nearest whole number.
+ ///
+ /// This is the same as <see cref="Round(double)"/>, but returns an <see langword="int"/>.
/// </summary>
/// <param name="s">The number to round.</param>
/// <returns>The rounded number.</returns>
- public static int RoundToInt(real_t s)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int RoundToInt(double s)
{
return (int)Math.Round(s);
}
/// <summary>
+ /// Returns the sine and cosine of angle <paramref name="s"/> in radians.
+ /// </summary>
+ /// <param name="s">The angle in radians.</param>
+ /// <returns>The sine and cosine of that angle.</returns>
+ public static (float Sin, float Cos) SinCos(float s)
+ {
+ return MathF.SinCos(s);
+ }
+
+ /// <summary>
+ /// Returns the sine and cosine of angle <paramref name="s"/> in radians.
+ /// </summary>
+ /// <param name="s">The angle in radians.</param>
+ /// <returns>The sine and cosine of that angle.</returns>
+ public static (double Sin, double Cos) SinCos(double s)
+ {
+ return Math.SinCos(s);
+ }
+
+ /// <summary>
+ /// Returns <see langword="true"/> if <paramref name="a"/> and <paramref name="b"/> are approximately
+ /// equal to each other.
+ /// The comparison is done using the provided tolerance value.
+ /// If you want the tolerance to be calculated for you, use <see cref="IsEqualApprox(float, float)"/>.
+ /// </summary>
+ /// <param name="a">One of the values.</param>
+ /// <param name="b">The other value.</param>
+ /// <param name="tolerance">The pre-calculated tolerance value.</param>
+ /// <returns>A <see langword="bool"/> for whether or not the two values are equal.</returns>
+ public static bool IsEqualApprox(float a, float b, float tolerance)
+ {
+ // Check for exact equality first, required to handle "infinity" values.
+ if (a == b)
+ {
+ return true;
+ }
+ // Then check for approximate equality.
+ return Math.Abs(a - b) < tolerance;
+ }
+
+ /// <summary>
/// Returns <see langword="true"/> if <paramref name="a"/> and <paramref name="b"/> are approximately
/// equal to each other.
/// The comparison is done using the provided tolerance value.
- /// If you want the tolerance to be calculated for you, use <see cref="IsEqualApprox(real_t, real_t)"/>.
+ /// If you want the tolerance to be calculated for you, use <see cref="IsEqualApprox(double, double)"/>.
/// </summary>
/// <param name="a">One of the values.</param>
/// <param name="b">The other value.</param>
/// <param name="tolerance">The pre-calculated tolerance value.</param>
/// <returns>A <see langword="bool"/> for whether or not the two values are equal.</returns>
- public static bool IsEqualApprox(real_t a, real_t b, real_t tolerance)
+ public static bool IsEqualApprox(double a, double b, double tolerance)
{
// Check for exact equality first, required to handle "infinity" values.
if (a == b)
@@ -100,7 +193,7 @@ namespace Godot
return true;
}
// Then check for approximate equality.
- return Abs(a - b) < tolerance;
+ return Math.Abs(a - b) < tolerance;
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
index 0d9a698af0..11e600ca0b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
@@ -310,7 +310,7 @@ namespace Godot.NativeInterop
public static Signal ConvertSignalToManaged(in godot_signal p_signal)
{
- var owner = GD.InstanceFromId(p_signal.ObjectId);
+ var owner = Godot.Object.InstanceFromId(p_signal.ObjectId);
var name = StringName.CreateTakingOwnershipOfDisposableValue(
NativeFuncs.godotsharp_string_name_new_copy(p_signal.Name));
return new Signal(owner, name);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
index 57488bd586..66c94166ae 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
@@ -409,6 +409,10 @@ namespace Godot.NativeInterop
public static partial void godotsharp_dictionary_duplicate(ref godot_dictionary p_self, godot_bool p_deep,
out godot_dictionary r_dest);
+ public static partial void godotsharp_dictionary_merge(ref godot_dictionary p_self, in godot_dictionary p_dictionary, godot_bool p_overwrite);
+
+ public static partial godot_bool godotsharp_dictionary_recursive_equal(ref godot_dictionary p_self, in godot_dictionary p_other);
+
public static partial godot_bool godotsharp_dictionary_remove_key(ref godot_dictionary p_self,
in godot_variant p_key);
@@ -494,8 +498,6 @@ namespace Godot.NativeInterop
internal static partial void godotsharp_weakref(IntPtr p_obj, out godot_ref r_weak_ref);
- internal static partial void godotsharp_str(in godot_array p_what, out godot_string r_ret);
-
internal static partial void godotsharp_str_to_var(in godot_string p_str, out godot_variant r_ret);
internal static partial void godotsharp_var_to_bytes(in godot_variant p_what, godot_bool p_full_objects,
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
index 9c9258dd9e..bb306ddaea 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
@@ -260,7 +260,7 @@ namespace Godot.NativeInterop
=> from != null ? CreateFromArray((godot_array)from.NativeValue) : default;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static godot_variant CreateFromArray<T>(Array<T>? from)
+ public static godot_variant CreateFromArray<[MustBeVariant] T>(Array<T>? from)
=> from != null ? CreateFromArray((godot_array)((Collections.Array)from).NativeValue) : default;
public static godot_variant CreateFromDictionary(godot_dictionary from)
@@ -274,7 +274,7 @@ namespace Godot.NativeInterop
=> from != null ? CreateFromDictionary((godot_dictionary)from.NativeValue) : default;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static godot_variant CreateFromDictionary<TKey, TValue>(Dictionary<TKey, TValue>? from)
+ public static godot_variant CreateFromDictionary<[MustBeVariant] TKey, [MustBeVariant] TValue>(Dictionary<TKey, TValue>? from)
=> from != null ? CreateFromDictionary((godot_dictionary)((Dictionary)from).NativeValue) : default;
public static godot_variant CreateFromStringName(godot_string_name from)
@@ -526,7 +526,7 @@ namespace Godot.NativeInterop
=> Collections.Array.CreateTakingOwnershipOfDisposableValue(ConvertToNativeArray(p_var));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Array<T> ConvertToArray<T>(in godot_variant p_var)
+ public static Array<T> ConvertToArray<[MustBeVariant] T>(in godot_variant p_var)
=> Array<T>.CreateTakingOwnershipOfDisposableValue(ConvertToNativeArray(p_var));
public static godot_dictionary ConvertToNativeDictionary(in godot_variant p_var)
@@ -539,7 +539,7 @@ namespace Godot.NativeInterop
=> Dictionary.CreateTakingOwnershipOfDisposableValue(ConvertToNativeDictionary(p_var));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Dictionary<TKey, TValue> ConvertToDictionary<TKey, TValue>(in godot_variant p_var)
+ public static Dictionary<TKey, TValue> ConvertToDictionary<[MustBeVariant] TKey, [MustBeVariant] TValue>(in godot_variant p_var)
=> Dictionary<TKey, TValue>.CreateTakingOwnershipOfDisposableValue(ConvertToNativeDictionary(p_var));
public static byte[] ConvertAsPackedByteArrayToSystemArray(in godot_variant p_var)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
index 42c6b0a37e..8a125e3c73 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
@@ -15,7 +15,7 @@ namespace Godot
private Vector3 _normal;
/// <summary>
- /// The normal of the plane, which must be normalized.
+ /// The normal of the plane, which must be a unit vector.
/// In the scalar equation of the plane <c>ax + by + cz = d</c>, this is
/// the vector <c>(a, b, c)</c>, where <c>d</c> is the <see cref="D"/> property.
/// </summary>
@@ -85,23 +85,6 @@ namespace Godot
public real_t D { get; set; }
/// <summary>
- /// The center of the plane, the point where the normal line intersects the plane.
- /// </summary>
- /// <value>Equivalent to <see cref="Normal"/> multiplied by <see cref="D"/>.</value>
- public Vector3 Center
- {
- readonly get
- {
- return _normal * D;
- }
- set
- {
- _normal = value.Normalized();
- D = value.Length();
- }
- }
-
- /// <summary>
/// Returns the shortest distance from this plane to the position <paramref name="point"/>.
/// </summary>
/// <param name="point">The position to use for the calculation.</param>
@@ -112,6 +95,16 @@ namespace Godot
}
/// <summary>
+ /// Returns the center of the plane, the point on the plane closest to the origin.
+ /// The point where the normal line going through the origin intersects the plane.
+ /// </summary>
+ /// <value>Equivalent to <see cref="Normal"/> multiplied by <see cref="D"/>.</value>
+ public readonly Vector3 GetCenter()
+ {
+ return _normal * D;
+ }
+
+ /// <summary>
/// Returns <see langword="true"/> if point is inside the plane.
/// Comparison uses a custom minimum tolerance threshold.
/// </summary>
@@ -155,7 +148,7 @@ namespace Godot
/// <param name="from">The start of the ray.</param>
/// <param name="dir">The direction of the ray, normalized.</param>
/// <returns>The intersection, or <see langword="null"/> if none is found.</returns>
- public readonly Vector3? IntersectRay(Vector3 from, Vector3 dir)
+ public readonly Vector3? IntersectsRay(Vector3 from, Vector3 dir)
{
real_t den = _normal.Dot(dir);
@@ -183,7 +176,7 @@ namespace Godot
/// <param name="begin">The start of the line segment.</param>
/// <param name="end">The end of the line segment.</param>
/// <returns>The intersection, or <see langword="null"/> if none is found.</returns>
- public readonly Vector3? IntersectSegment(Vector3 begin, Vector3 end)
+ public readonly Vector3? IntersectsSegment(Vector3 begin, Vector3 end)
{
Vector3 segment = begin - end;
real_t den = _normal.Dot(segment);
@@ -205,6 +198,16 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this plane is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public readonly bool IsFinite()
+ {
+ return _normal.IsFinite() && Mathf.IsFinite(D);
+ }
+
+ /// <summary>
/// Returns <see langword="true"/> if <paramref name="point"/> is located above the plane.
/// </summary>
/// <param name="point">The point to check.</param>
@@ -280,10 +283,21 @@ namespace Godot
}
/// <summary>
+ /// Constructs a <see cref="Plane"/> from a <paramref name="normal"/> vector.
+ /// The plane will intersect the origin.
+ /// </summary>
+ /// <param name="normal">The normal of the plane, must be a unit vector.</param>
+ public Plane(Vector3 normal)
+ {
+ _normal = normal;
+ D = 0;
+ }
+
+ /// <summary>
/// Constructs a <see cref="Plane"/> from a <paramref name="normal"/> vector and
/// the plane's distance to the origin <paramref name="d"/>.
/// </summary>
- /// <param name="normal">The normal of the plane, must be normalized.</param>
+ /// <param name="normal">The normal of the plane, must be a unit vector.</param>
/// <param name="d">The plane's distance from the origin. This value is typically non-negative.</param>
public Plane(Vector3 normal, real_t d)
{
@@ -295,7 +309,7 @@ namespace Godot
/// Constructs a <see cref="Plane"/> from a <paramref name="normal"/> vector and
/// a <paramref name="point"/> on the plane.
/// </summary>
- /// <param name="normal">The normal of the plane, must be normalized.</param>
+ /// <param name="normal">The normal of the plane, must be a unit vector.</param>
/// <param name="point">The point on the plane.</param>
public Plane(Vector3 normal, Vector3 point)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs
index fd37f8d9e8..f11b3c553a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs
@@ -381,14 +381,14 @@ namespace Godot
}
real_t radians = Mathf.DegToRad(fovyDegrees / (real_t)2.0);
real_t deltaZ = zFar - zNear;
- real_t sine = Mathf.Sin(radians);
+ (real_t sin, real_t cos) = Mathf.SinCos(radians);
- if ((deltaZ == 0) || (sine == 0) || (aspect == 0))
+ if ((deltaZ == 0) || (sin == 0) || (aspect == 0))
{
return Zero;
}
- real_t cotangent = Mathf.Cos(radians) / sine;
+ real_t cotangent = cos / sin;
Projection proj = Projection.Identity;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
index bd0dea0c1c..8e4f9178f7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
@@ -97,27 +97,6 @@ namespace Godot
}
/// <summary>
- /// Returns the length (magnitude) of the quaternion.
- /// </summary>
- /// <seealso cref="LengthSquared"/>
- /// <value>Equivalent to <c>Mathf.Sqrt(LengthSquared)</c>.</value>
- public readonly real_t Length
- {
- get { return Mathf.Sqrt(LengthSquared); }
- }
-
- /// <summary>
- /// Returns the squared length (squared magnitude) of the quaternion.
- /// This method runs faster than <see cref="Length"/>, so prefer it if
- /// you need to compare quaternions or need the squared length for some formula.
- /// </summary>
- /// <value>Equivalent to <c>Dot(this)</c>.</value>
- public readonly real_t LengthSquared
- {
- get { return Dot(this); }
- }
-
- /// <summary>
/// Returns the angle between this quaternion and <paramref name="to"/>.
/// This is the magnitude of the angle you would need to rotate
/// by to get from one to the other.
@@ -340,12 +319,22 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this quaternion is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public readonly bool IsFinite()
+ {
+ return Mathf.IsFinite(x) && Mathf.IsFinite(y) && Mathf.IsFinite(z) && Mathf.IsFinite(w);
+ }
+
+ /// <summary>
/// Returns whether the quaternion is normalized or not.
/// </summary>
/// <returns>A <see langword="bool"/> for whether the quaternion is normalized or not.</returns>
public readonly bool IsNormalized()
{
- return Mathf.Abs(LengthSquared - 1) <= Mathf.Epsilon;
+ return Mathf.Abs(LengthSquared() - 1) <= Mathf.Epsilon;
}
public readonly Quaternion Log()
@@ -355,12 +344,33 @@ namespace Godot
}
/// <summary>
+ /// Returns the length (magnitude) of the quaternion.
+ /// </summary>
+ /// <seealso cref="LengthSquared"/>
+ /// <value>Equivalent to <c>Mathf.Sqrt(LengthSquared)</c>.</value>
+ public readonly real_t Length()
+ {
+ return Mathf.Sqrt(LengthSquared());
+ }
+
+ /// <summary>
+ /// Returns the squared length (squared magnitude) of the quaternion.
+ /// This method runs faster than <see cref="Length"/>, so prefer it if
+ /// you need to compare quaternions or need the squared length for some formula.
+ /// </summary>
+ /// <value>Equivalent to <c>Dot(this)</c>.</value>
+ public readonly real_t LengthSquared()
+ {
+ return Dot(this);
+ }
+
+ /// <summary>
/// Returns a copy of the quaternion, normalized to unit length.
/// </summary>
/// <returns>The normalized quaternion.</returns>
public readonly Quaternion Normalized()
{
- return this / Length;
+ return this / Length();
}
/// <summary>
@@ -532,14 +542,13 @@ namespace Godot
}
else
{
- real_t sinAngle = Mathf.Sin(angle * 0.5f);
- real_t cosAngle = Mathf.Cos(angle * 0.5f);
- real_t s = sinAngle / d;
+ (real_t sin, real_t cos) = Mathf.SinCos(angle * 0.5f);
+ real_t s = sin / d;
x = axis.x * s;
y = axis.y * s;
z = axis.z * s;
- w = cosAngle;
+ w = cos;
}
}
@@ -583,12 +592,9 @@ namespace Godot
// Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
// a3 is the angle of the first rotation, following the notation in this reference.
- real_t cosA1 = Mathf.Cos(halfA1);
- real_t sinA1 = Mathf.Sin(halfA1);
- real_t cosA2 = Mathf.Cos(halfA2);
- real_t sinA2 = Mathf.Sin(halfA2);
- real_t cosA3 = Mathf.Cos(halfA3);
- real_t sinA3 = Mathf.Sin(halfA3);
+ (real_t sinA1, real_t cosA1) = Mathf.SinCos(halfA1);
+ (real_t sinA2, real_t cosA2) = Mathf.SinCos(halfA2);
+ (real_t sinA3, real_t cosA3) = Mathf.SinCos(halfA3);
return new Quaternion(
(sinA1 * cosA2 * sinA3) + (cosA1 * sinA2 * cosA3),
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
index b0e0e75a34..1a8696d3bc 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
@@ -101,6 +101,16 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this <see cref="Rect2"/> is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public bool IsFinite()
+ {
+ return _position.IsFinite() && _size.IsFinite();
+ }
+
+ /// <summary>
/// Returns <see langword="true"/> if this <see cref="Rect2"/> completely encloses another one.
/// </summary>
/// <param name="b">The other <see cref="Rect2"/> that may be enclosed.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
index faee81a98a..cf8939a859 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
@@ -275,38 +275,19 @@ namespace Godot
/// <summary>
/// Returns <see langword="true"/> if the <see cref="Rect2i"/> overlaps with <paramref name="b"/>
/// (i.e. they have at least one point in common).
- ///
- /// If <paramref name="includeBorders"/> is <see langword="true"/>,
- /// they will also be considered overlapping if their borders touch,
- /// even without intersection.
/// </summary>
/// <param name="b">The other <see cref="Rect2i"/> to check for intersections with.</param>
- /// <param name="includeBorders">Whether or not to consider borders.</param>
/// <returns>A <see langword="bool"/> for whether or not they are intersecting.</returns>
- public readonly bool Intersects(Rect2i b, bool includeBorders = false)
+ public readonly bool Intersects(Rect2i b)
{
- if (includeBorders)
- {
- if (_position.x > b._position.x + b._size.x)
- return false;
- if (_position.x + _size.x < b._position.x)
- return false;
- if (_position.y > b._position.y + b._size.y)
- return false;
- if (_position.y + _size.y < b._position.y)
- return false;
- }
- else
- {
- if (_position.x >= b._position.x + b._size.x)
- return false;
- if (_position.x + _size.x <= b._position.x)
- return false;
- if (_position.y >= b._position.y + b._size.y)
- return false;
- if (_position.y + _size.y <= b._position.y)
- return false;
- }
+ if (_position.x >= b._position.x + b._size.x)
+ return false;
+ if (_position.x + _size.x <= b._position.x)
+ return false;
+ if (_position.y >= b._position.y + b._size.y)
+ return false;
+ if (_position.y + _size.y <= b._position.y)
+ return false;
return true;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
index 756f71e5b2..1dfa83ffc6 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Godot
@@ -32,42 +33,20 @@ namespace Godot
public Vector2 origin;
/// <summary>
- /// The rotation of this transformation matrix.
+ /// Returns the transform's rotation (in radians).
/// </summary>
- /// <value>Getting is equivalent to calling <see cref="Mathf.Atan2(real_t, real_t)"/> with the values of <see cref="x"/>.</value>
- public real_t Rotation
- {
- readonly get
- {
- return Mathf.Atan2(x.y, x.x);
- }
- set
- {
- Vector2 scale = Scale;
- x.x = y.y = Mathf.Cos(value);
- x.y = y.x = Mathf.Sin(value);
- y.x *= -1;
- Scale = scale;
- }
- }
+ public readonly real_t Rotation => Mathf.Atan2(x.y, x.x);
/// <summary>
- /// The scale of this transformation matrix.
+ /// Returns the scale.
/// </summary>
- /// <value>Equivalent to the lengths of each column vector, but Y is negative if the determinant is negative.</value>
- public Vector2 Scale
+ public readonly Vector2 Scale
{
- readonly get
+ get
{
real_t detSign = Mathf.Sign(BasisDeterminant());
return new Vector2(x.Length(), detSign * y.Length());
}
- set
- {
- value /= Scale; // Value becomes what's called "delta_scale" in core.
- x *= value.x;
- y *= value.y;
- }
}
/// <summary>
@@ -170,6 +149,7 @@ namespace Godot
/// and is usually considered invalid.
/// </summary>
/// <returns>The determinant of the basis matrix.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
private readonly real_t BasisDeterminant()
{
return (x.x * y.y) - (x.y * y.x);
@@ -217,8 +197,10 @@ namespace Godot
Vector2 s2 = transform.Scale;
// Slerp rotation
- var v1 = new Vector2(Mathf.Cos(r1), Mathf.Sin(r1));
- var v2 = new Vector2(Mathf.Cos(r2), Mathf.Sin(r2));
+ (real_t sin1, real_t cos1) = Mathf.SinCos(r1);
+ (real_t sin2, real_t cos2) = Mathf.SinCos(r2);
+ var v1 = new Vector2(cos1, sin1);
+ var v2 = new Vector2(cos2, sin2);
real_t dot = v1.Dot(v2);
@@ -235,7 +217,8 @@ namespace Godot
{
real_t angle = weight * Mathf.Acos(dot);
Vector2 v3 = (v2 - (v1 * dot)).Normalized();
- v = (v1 * Mathf.Cos(angle)) + (v3 * Mathf.Sin(angle));
+ (real_t sine, real_t cos) = Mathf.SinCos(angle);
+ v = (v1 * sine) + (v3 * cos);
}
// Extract parameters
@@ -271,6 +254,16 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this transform is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public readonly bool IsFinite()
+ {
+ return x.IsFinite() && y.IsFinite() && origin.IsFinite();
+ }
+
+ /// <summary>
/// Returns the transform with the basis orthogonal (90 degrees),
/// and normalized axis vectors (scale of 1 or -1).
/// </summary>
@@ -423,7 +416,7 @@ namespace Godot
/// <summary>
/// Constructs a transformation matrix from the given components.
- /// Arguments are named such that xy is equal to calling x.y
+ /// Arguments are named such that xy is equal to calling <c>x.y</c>.
/// </summary>
/// <param name="xx">The X component of the X column vector, accessed via <c>t.x.x</c> or <c>[0][0]</c>.</param>
/// <param name="xy">The Y component of the X column vector, accessed via <c>t.x.y</c> or <c>[0][1]</c>.</param>
@@ -446,13 +439,34 @@ namespace Godot
/// <param name="origin">The origin vector, or column index 2.</param>
public Transform2D(real_t rotation, Vector2 origin)
{
- x.x = y.y = Mathf.Cos(rotation);
- x.y = y.x = Mathf.Sin(rotation);
+ (real_t sin, real_t cos) = Mathf.SinCos(rotation);
+ x.x = y.y = cos;
+ x.y = y.x = sin;
y.x *= -1;
this.origin = origin;
}
/// <summary>
+ /// Constructs a transformation matrix from a <paramref name="rotation"/> value,
+ /// <paramref name="scale"/> vector, <paramref name="skew"/> value, and
+ /// <paramref name="origin"/> vector.
+ /// </summary>
+ /// <param name="rotation">The rotation of the new transform, in radians.</param>
+ /// <param name="scale">The scale of the new transform.</param>
+ /// <param name="skew">The skew of the new transform, in radians.</param>
+ /// <param name="origin">The origin vector, or column index 2.</param>
+ public Transform2D(real_t rotation, Vector2 scale, real_t skew, Vector2 origin)
+ {
+ (real_t rotationSin, real_t rotationCos) = Mathf.SinCos(rotation);
+ (real_t rotationSkewSin, real_t rotationSkewCos) = Mathf.SinCos(rotation + skew);
+ x.x = rotationCos * scale.x;
+ y.y = rotationSkewCos * scale.y;
+ y.x = -rotationSkewSin * scale.y;
+ x.y = rotationSin * scale.x;
+ this.origin = origin;
+ }
+
+ /// <summary>
/// Composes these two transformation matrices by multiplying them
/// together. This has the effect of transforming the second transform
/// (the child) by the first transform (the parent).
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
index 39167bd116..ce5f98a6fc 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
@@ -115,16 +115,30 @@ namespace Godot
}
/// <summary>
- /// Interpolates this transform to the other <paramref name="transform"/> by <paramref name="weight"/>.
+ /// Returns a transform interpolated between this transform and another
+ /// <paramref name="transform"/> by a given <paramref name="weight"/>
+ /// (on the range of 0.0 to 1.0).
/// </summary>
/// <param name="transform">The other transform.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated transform.</returns>
public readonly Transform3D InterpolateWith(Transform3D transform, real_t weight)
{
- Basis retBasis = basis.Lerp(transform.basis, weight);
- Vector3 retOrigin = origin.Lerp(transform.origin, weight);
- return new Transform3D(retBasis, retOrigin);
+ Vector3 sourceScale = basis.Scale;
+ Quaternion sourceRotation = basis.GetRotationQuaternion();
+ Vector3 sourceLocation = origin;
+
+ Vector3 destinationScale = transform.basis.Scale;
+ Quaternion destinationRotation = transform.basis.GetRotationQuaternion();
+ Vector3 destinationLocation = transform.origin;
+
+ var interpolated = new Transform3D();
+ Quaternion quaternion = sourceRotation.Slerp(destinationRotation, weight).Normalized();
+ Vector3 scale = sourceScale.Lerp(destinationScale, weight);
+ interpolated.basis.SetQuaternionScale(quaternion, scale);
+ interpolated.origin = sourceLocation.Lerp(destinationLocation, weight);
+
+ return interpolated;
}
/// <summary>
@@ -140,6 +154,16 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this transform is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public readonly bool IsFinite()
+ {
+ return basis.IsFinite() && origin.IsFinite();
+ }
+
+ /// <summary>
/// Returns a copy of the transform rotated such that its
/// -Z axis (forward) points towards the <paramref name="target"/> position.
///
@@ -223,34 +247,6 @@ namespace Godot
return new Transform3D(basis * tmpBasis, origin);
}
- /// <summary>
- /// Returns a transform spherically interpolated between this transform and
- /// another <paramref name="transform"/> by <paramref name="weight"/>.
- /// </summary>
- /// <param name="transform">The other transform.</param>
- /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
- /// <returns>The interpolated transform.</returns>
- public readonly Transform3D SphericalInterpolateWith(Transform3D transform, real_t weight)
- {
- /* not sure if very "efficient" but good enough? */
-
- Vector3 sourceScale = basis.Scale;
- Quaternion sourceRotation = basis.GetRotationQuaternion();
- Vector3 sourceLocation = origin;
-
- Vector3 destinationScale = transform.basis.Scale;
- Quaternion destinationRotation = transform.basis.GetRotationQuaternion();
- Vector3 destinationLocation = transform.origin;
-
- var interpolated = new Transform3D();
- Quaternion quaternion = sourceRotation.Slerp(destinationRotation, weight).Normalized();
- Vector3 scale = sourceScale.Lerp(destinationScale, weight);
- interpolated.basis.SetQuaternionScale(quaternion, scale);
- interpolated.origin = sourceLocation.Lerp(destinationLocation, weight);
-
- return interpolated;
- }
-
private void SetLookAt(Vector3 eye, Vector3 target, Vector3 up)
{
// Make rotation matrix
@@ -346,15 +342,25 @@ namespace Godot
}
/// <summary>
- /// Constructs a transformation matrix from the given <paramref name="quaternion"/>
- /// and <paramref name="origin"/> vector.
+ /// Constructs a transformation matrix from the given components.
+ /// Arguments are named such that xy is equal to calling <c>basis.x.y</c>.
/// </summary>
- /// <param name="quaternion">The <see cref="Quaternion"/> to create the basis from.</param>
- /// <param name="origin">The origin vector, or column index 3.</param>
- public Transform3D(Quaternion quaternion, Vector3 origin)
+ /// <param name="xx">The X component of the X column vector, accessed via <c>t.basis.x.x</c> or <c>[0][0]</c>.</param>
+ /// <param name="yx">The X component of the Y column vector, accessed via <c>t.basis.y.x</c> or <c>[1][0]</c>.</param>
+ /// <param name="zx">The X component of the Z column vector, accessed via <c>t.basis.z.x</c> or <c>[2][0]</c>.</param>
+ /// <param name="xy">The Y component of the X column vector, accessed via <c>t.basis.x.y</c> or <c>[0][1]</c>.</param>
+ /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.basis.y.y</c> or <c>[1][1]</c>.</param>
+ /// <param name="zy">The Y component of the Z column vector, accessed via <c>t.basis.y.y</c> or <c>[2][1]</c>.</param>
+ /// <param name="xz">The Z component of the X column vector, accessed via <c>t.basis.x.y</c> or <c>[0][2]</c>.</param>
+ /// <param name="yz">The Z component of the Y column vector, accessed via <c>t.basis.y.y</c> or <c>[1][2]</c>.</param>
+ /// <param name="zz">The Z component of the Z column vector, accessed via <c>t.basis.y.y</c> or <c>[2][2]</c>.</param>
+ /// <param name="ox">The X component of the origin vector, accessed via <c>t.origin.x</c> or <c>[2][0]</c>.</param>
+ /// <param name="oy">The Y component of the origin vector, accessed via <c>t.origin.y</c> or <c>[2][1]</c>.</param>
+ /// <param name="oz">The Z component of the origin vector, accessed via <c>t.origin.z</c> or <c>[2][2]</c>.</param>
+ public Transform3D(real_t xx, real_t yx, real_t zx, real_t xy, real_t yy, real_t zy, real_t xz, real_t yz, real_t zz, real_t ox, real_t oy, real_t oz)
{
- basis = new Basis(quaternion);
- this.origin = origin;
+ basis = new Basis(xx, yx, zx, xy, yy, zy, xz, yz, zz);
+ origin = new Vector3(ox, oy, oz);
}
/// <summary>
@@ -370,6 +376,29 @@ namespace Godot
}
/// <summary>
+ /// Constructs a transformation matrix from the given <paramref name="projection"/>
+ /// by trimming the last row of the projection matrix (<c>projection.x.w</c>,
+ /// <c>projection.y.w</c>, <c>projection.z.w</c>, and <c>projection.w.w</c>
+ /// are not copied over).
+ /// </summary>
+ /// <param name="projection">The <see cref="Projection"/> to create the transform from.</param>
+ public Transform3D(Projection projection)
+ {
+ basis = new Basis
+ (
+ projection.x.x, projection.y.x, projection.z.x,
+ projection.x.y, projection.y.y, projection.z.y,
+ projection.x.z, projection.y.z, projection.z.z
+ );
+ origin = new Vector3
+ (
+ projection.w.x,
+ projection.w.y,
+ projection.w.z
+ );
+ }
+
+ /// <summary>
/// Composes these two transformation matrices by multiplying them
/// together. This has the effect of transforming the second transform
/// (the child) by the first transform (the parent).
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Variant.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Variant.cs
index da12309217..0ac2e2969c 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Variant.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Variant.cs
@@ -328,11 +328,11 @@ public partial struct Variant : IDisposable
VariantUtils.ConvertToSystemArrayOfGodotObject<T>((godot_variant)NativeVar);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Collections.Dictionary<TKey, TValue> AsGodotDictionary<TKey, TValue>() =>
+ public Collections.Dictionary<TKey, TValue> AsGodotDictionary<[MustBeVariant] TKey, [MustBeVariant] TValue>() =>
VariantUtils.ConvertToDictionary<TKey, TValue>((godot_variant)NativeVar);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Collections.Array<T> AsGodotArray<T>() =>
+ public Collections.Array<T> AsGodotArray<[MustBeVariant] T>() =>
VariantUtils.ConvertToArray<T>((godot_variant)NativeVar);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -647,11 +647,11 @@ public partial struct Variant : IDisposable
public static Variant CreateFrom(Godot.Object[] from) => from;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant CreateFrom<TKey, TValue>(Collections.Dictionary<TKey, TValue> from) =>
+ public static Variant CreateFrom<[MustBeVariant] TKey, [MustBeVariant] TValue>(Collections.Dictionary<TKey, TValue> from) =>
CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromDictionary(from));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant CreateFrom<T>(Collections.Array<T> from) =>
+ public static Variant CreateFrom<[MustBeVariant] T>(Collections.Array<T> from) =>
CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromArray(from));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index 4c60080ee9..07cb34cadd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -334,6 +334,16 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this vector is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public readonly bool IsFinite()
+ {
+ return Mathf.IsFinite(x) && Mathf.IsFinite(y);
+ }
+
+ /// <summary>
/// Returns <see langword="true"/> if the vector is normalized, and <see langword="false"/> otherwise.
/// </summary>
/// <returns>A <see langword="bool"/> indicating whether or not the vector is normalized.</returns>
@@ -380,24 +390,6 @@ namespace Godot
}
/// <summary>
- /// Returns the result of the linear interpolation between
- /// this vector and <paramref name="to"/> by the vector amount <paramref name="weight"/>.
- /// </summary>
- /// <param name="to">The destination vector for interpolation.</param>
- /// <param name="weight">
- /// A vector with components on the range of 0.0 to 1.0, representing the amount of interpolation.
- /// </param>
- /// <returns>The resulting vector of the interpolation.</returns>
- public readonly Vector2 Lerp(Vector2 to, Vector2 weight)
- {
- return new Vector2
- (
- Mathf.Lerp(x, to.x, weight.x),
- Mathf.Lerp(y, to.y, weight.y)
- );
- }
-
- /// <summary>
/// Returns the vector with a maximum length by limiting its length to <paramref name="length"/>.
/// </summary>
/// <param name="length">The length to limit to.</param>
@@ -529,11 +521,12 @@ namespace Godot
/// <returns>The rotated vector.</returns>
public readonly Vector2 Rotated(real_t angle)
{
- real_t sine = Mathf.Sin(angle);
- real_t cosi = Mathf.Cos(angle);
- return new Vector2(
- x * cosi - y * sine,
- x * sine + y * cosi);
+ (real_t sin, real_t cos) = Mathf.SinCos(angle);
+ return new Vector2
+ (
+ x * cos - y * sin,
+ x * sin + y * cos
+ );
}
/// <summary>
@@ -683,7 +676,8 @@ namespace Godot
/// <returns>The resulting vector.</returns>
public static Vector2 FromAngle(real_t angle)
{
- return new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
+ (real_t sin, real_t cos) = Mathf.SinCos(angle);
+ return new Vector2(cos, sin);
}
/// <summary>
@@ -989,6 +983,18 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this vector's values are approximately zero,
+ /// by running <see cref="Mathf.IsZeroApprox(real_t)"/> on each component.
+ /// This method is faster than using <see cref="IsEqualApprox"/> with one value
+ /// as a zero vector.
+ /// </summary>
+ /// <returns>Whether or not the vector is approximately zero.</returns>
+ public readonly bool IsZeroApprox()
+ {
+ return Mathf.IsZeroApprox(x) && Mathf.IsZeroApprox(y);
+ }
+
+ /// <summary>
/// Serves as the hash function for <see cref="Vector2"/>.
/// </summary>
/// <returns>A hash code for this vector.</returns>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
index 91be548a21..740fedec66 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
@@ -95,38 +95,6 @@ namespace Godot
}
/// <summary>
- /// Returns this vector's angle with respect to the X axis, or (1, 0) vector, in radians.
- ///
- /// Equivalent to the result of <see cref="Mathf.Atan2(real_t, real_t)"/> when
- /// called with the vector's <see cref="y"/> and <see cref="x"/> as parameters: <c>Mathf.Atan2(v.y, v.x)</c>.
- /// </summary>
- /// <returns>The angle of this vector, in radians.</returns>
- public readonly real_t Angle()
- {
- return Mathf.Atan2(y, x);
- }
-
- /// <summary>
- /// Returns the angle to the given vector, in radians.
- /// </summary>
- /// <param name="to">The other vector to compare this vector to.</param>
- /// <returns>The angle between the two vectors, in radians.</returns>
- public readonly real_t AngleTo(Vector2i to)
- {
- return Mathf.Atan2(Cross(to), Dot(to));
- }
-
- /// <summary>
- /// Returns the angle between the line connecting the two points and the X axis, in radians.
- /// </summary>
- /// <param name="to">The other vector to compare this vector to.</param>
- /// <returns>The angle between the two vectors, in radians.</returns>
- public readonly real_t AngleToPoint(Vector2i to)
- {
- return Mathf.Atan2(to.y - y, to.x - x);
- }
-
- /// <summary>
/// Returns the aspect ratio of this vector, the ratio of <see cref="x"/> to <see cref="y"/>.
/// </summary>
/// <returns>The <see cref="x"/> component divided by the <see cref="y"/> component.</returns>
@@ -153,48 +121,6 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and <paramref name="with"/>.
- /// </summary>
- /// <param name="with">The other vector.</param>
- /// <returns>The cross product vector.</returns>
- public readonly int Cross(Vector2i with)
- {
- return x * with.y - y * with.x;
- }
-
- /// <summary>
- /// Returns the squared distance between this vector and <paramref name="to"/>.
- /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
- /// you need to compare vectors or need the squared distance for some formula.
- /// </summary>
- /// <param name="to">The other vector to use.</param>
- /// <returns>The squared distance between the two vectors.</returns>
- public readonly int DistanceSquaredTo(Vector2i to)
- {
- return (to - this).LengthSquared();
- }
-
- /// <summary>
- /// Returns the distance between this vector and <paramref name="to"/>.
- /// </summary>
- /// <param name="to">The other vector to use.</param>
- /// <returns>The distance between the two vectors.</returns>
- public readonly real_t DistanceTo(Vector2i to)
- {
- return (to - this).Length();
- }
-
- /// <summary>
- /// Returns the dot product of this vector and <paramref name="with"/>.
- /// </summary>
- /// <param name="with">The other vector to use.</param>
- /// <returns>The dot product of the two vectors.</returns>
- public readonly int Dot(Vector2i with)
- {
- return x * with.x + y * with.y;
- }
-
- /// <summary>
/// Returns the length (magnitude) of this vector.
/// </summary>
/// <seealso cref="LengthSquared"/>
@@ -242,38 +168,6 @@ namespace Godot
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components
- /// and <paramref name="mod"/>.
- /// </summary>
- /// <param name="mod">A value representing the divisor of the operation.</param>
- /// <returns>
- /// A vector with each component <see cref="Mathf.PosMod(int, int)"/> by <paramref name="mod"/>.
- /// </returns>
- public readonly Vector2i PosMod(int mod)
- {
- Vector2i v = this;
- v.x = Mathf.PosMod(v.x, mod);
- v.y = Mathf.PosMod(v.y, mod);
- return v;
- }
-
- /// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components
- /// and <paramref name="modv"/>'s components.
- /// </summary>
- /// <param name="modv">A vector representing the divisors of the operation.</param>
- /// <returns>
- /// A vector with each component <see cref="Mathf.PosMod(int, int)"/> by <paramref name="modv"/>'s components.
- /// </returns>
- public readonly Vector2i PosMod(Vector2i modv)
- {
- Vector2i v = this;
- v.x = Mathf.PosMod(v.x, modv.x);
- v.y = Mathf.PosMod(v.y, modv.y);
- return v;
- }
-
- /// <summary>
/// Returns a vector with each component set to one or negative one, depending
/// on the signs of this vector's components, or zero if the component is zero,
/// by calling <see cref="Mathf.Sign(int)"/> on each component.
@@ -287,16 +181,6 @@ namespace Godot
return v;
}
- /// <summary>
- /// Returns a perpendicular vector rotated 90 degrees counter-clockwise
- /// compared to the original, with the same length.
- /// </summary>
- /// <returns>The perpendicular vector.</returns>
- public readonly Vector2i Orthogonal()
- {
- return new Vector2i(y, -x);
- }
-
// Constants
private static readonly Vector2i _zero = new Vector2i(0, 0);
private static readonly Vector2i _one = new Vector2i(1, 1);
@@ -467,7 +351,7 @@ namespace Godot
/// with the components of the given <see langword="int"/>.
/// This operation uses truncated division, which is often not desired
/// as it does not work well with negative numbers.
- /// Consider using <see cref="PosMod(int)"/> instead
+ /// Consider using <see cref="Mathf.PosMod(int, int)"/> instead
/// if you want to handle negative numbers.
/// </summary>
/// <example>
@@ -490,7 +374,7 @@ namespace Godot
/// with the components of the given <see cref="Vector2i"/>.
/// This operation uses truncated division, which is often not desired
/// as it does not work well with negative numbers.
- /// Consider using <see cref="PosMod(Vector2i)"/> instead
+ /// Consider using <see cref="Mathf.PosMod(int, int)"/> instead
/// if you want to handle negative numbers.
/// </summary>
/// <example>
@@ -509,34 +393,6 @@ namespace Godot
}
/// <summary>
- /// Performs a bitwise AND operation with this <see cref="Vector2i"/>
- /// and the given <see langword="int"/>.
- /// </summary>
- /// <param name="vec">The vector to AND with.</param>
- /// <param name="and">The integer to AND with.</param>
- /// <returns>The result of the bitwise AND.</returns>
- public static Vector2i operator &(Vector2i vec, int and)
- {
- vec.x &= and;
- vec.y &= and;
- return vec;
- }
-
- /// <summary>
- /// Performs a bitwise AND operation with this <see cref="Vector2i"/>
- /// and the given <see cref="Vector2i"/>.
- /// </summary>
- /// <param name="vec">The left vector to AND with.</param>
- /// <param name="andv">The right vector to AND with.</param>
- /// <returns>The result of the bitwise AND.</returns>
- public static Vector2i operator &(Vector2i vec, Vector2i andv)
- {
- vec.x &= andv.x;
- vec.y &= andv.y;
- return vec;
- }
-
- /// <summary>
/// Returns <see langword="true"/> if the vectors are equal.
/// </summary>
/// <param name="left">The left vector.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index fefdee33a5..b017ba5853 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -331,6 +331,16 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this vector is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public readonly bool IsFinite()
+ {
+ return Mathf.IsFinite(x) && Mathf.IsFinite(y) && Mathf.IsFinite(z);
+ }
+
+ /// <summary>
/// Returns <see langword="true"/> if the vector is normalized, and <see langword="false"/> otherwise.
/// </summary>
/// <returns>A <see langword="bool"/> indicating whether or not the vector is normalized.</returns>
@@ -386,23 +396,6 @@ namespace Godot
}
/// <summary>
- /// Returns the result of the linear interpolation between
- /// this vector and <paramref name="to"/> by the vector amount <paramref name="weight"/>.
- /// </summary>
- /// <param name="to">The destination vector for interpolation.</param>
- /// <param name="weight">A vector with components on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
- /// <returns>The resulting vector of the interpolation.</returns>
- public readonly Vector3 Lerp(Vector3 to, Vector3 weight)
- {
- return new Vector3
- (
- Mathf.Lerp(x, to.x, weight.x),
- Mathf.Lerp(y, to.y, weight.y),
- Mathf.Lerp(z, to.z, weight.z)
- );
- }
-
- /// <summary>
/// Returns the vector with a maximum length by limiting its length to <paramref name="length"/>.
/// </summary>
/// <param name="length">The length to limit to.</param>
@@ -1060,6 +1053,18 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this vector's values are approximately zero,
+ /// by running <see cref="Mathf.IsZeroApprox(real_t)"/> on each component.
+ /// This method is faster than using <see cref="IsEqualApprox"/> with one value
+ /// as a zero vector.
+ /// </summary>
+ /// <returns>Whether or not the vector is approximately zero.</returns>
+ public readonly bool IsZeroApprox()
+ {
+ return Mathf.IsZeroApprox(x) && Mathf.IsZeroApprox(y) && Mathf.IsZeroApprox(z);
+ }
+
+ /// <summary>
/// Serves as the hash function for <see cref="Vector3"/>.
/// </summary>
/// <returns>A hash code for this vector.</returns>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
index e631a9f443..de0c6d27e7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
@@ -129,39 +129,6 @@ namespace Godot
}
/// <summary>
- /// Returns the squared distance between this vector and <paramref name="to"/>.
- /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
- /// you need to compare vectors or need the squared distance for some formula.
- /// </summary>
- /// <param name="to">The other vector to use.</param>
- /// <returns>The squared distance between the two vectors.</returns>
- public readonly int DistanceSquaredTo(Vector3i to)
- {
- return (to - this).LengthSquared();
- }
-
- /// <summary>
- /// Returns the distance between this vector and <paramref name="to"/>.
- /// </summary>
- /// <seealso cref="DistanceSquaredTo(Vector3i)"/>
- /// <param name="to">The other vector to use.</param>
- /// <returns>The distance between the two vectors.</returns>
- public readonly real_t DistanceTo(Vector3i to)
- {
- return (to - this).Length();
- }
-
- /// <summary>
- /// Returns the dot product of this vector and <paramref name="with"/>.
- /// </summary>
- /// <param name="with">The other vector to use.</param>
- /// <returns>The dot product of the two vectors.</returns>
- public readonly int Dot(Vector3i with)
- {
- return x * with.x + y * with.y + z * with.z;
- }
-
- /// <summary>
/// Returns the length (magnitude) of this vector.
/// </summary>
/// <seealso cref="LengthSquared"/>
@@ -211,40 +178,6 @@ namespace Godot
}
/// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components
- /// and <paramref name="mod"/>.
- /// </summary>
- /// <param name="mod">A value representing the divisor of the operation.</param>
- /// <returns>
- /// A vector with each component <see cref="Mathf.PosMod(int, int)"/> by <paramref name="mod"/>.
- /// </returns>
- public readonly Vector3i PosMod(int mod)
- {
- Vector3i v = this;
- v.x = Mathf.PosMod(v.x, mod);
- v.y = Mathf.PosMod(v.y, mod);
- v.z = Mathf.PosMod(v.z, mod);
- return v;
- }
-
- /// <summary>
- /// Returns a vector composed of the <see cref="Mathf.PosMod(int, int)"/> of this vector's components
- /// and <paramref name="modv"/>'s components.
- /// </summary>
- /// <param name="modv">A vector representing the divisors of the operation.</param>
- /// <returns>
- /// A vector with each component <see cref="Mathf.PosMod(int, int)"/> by <paramref name="modv"/>'s components.
- /// </returns>
- public readonly Vector3i PosMod(Vector3i modv)
- {
- Vector3i v = this;
- v.x = Mathf.PosMod(v.x, modv.x);
- v.y = Mathf.PosMod(v.y, modv.y);
- v.z = Mathf.PosMod(v.z, modv.z);
- return v;
- }
-
- /// <summary>
/// Returns a vector with each component set to one or negative one, depending
/// on the signs of this vector's components, or zero if the component is zero,
/// by calling <see cref="Mathf.Sign(int)"/> on each component.
@@ -455,7 +388,7 @@ namespace Godot
/// with the components of the given <see langword="int"/>.
/// This operation uses truncated division, which is often not desired
/// as it does not work well with negative numbers.
- /// Consider using <see cref="PosMod(int)"/> instead
+ /// Consider using <see cref="Mathf.PosMod(int, int)"/> instead
/// if you want to handle negative numbers.
/// </summary>
/// <example>
@@ -479,7 +412,7 @@ namespace Godot
/// with the components of the given <see cref="Vector3i"/>.
/// This operation uses truncated division, which is often not desired
/// as it does not work well with negative numbers.
- /// Consider using <see cref="PosMod(Vector3i)"/> instead
+ /// Consider using <see cref="Mathf.PosMod(int, int)"/> instead
/// if you want to handle negative numbers.
/// </summary>
/// <example>
@@ -499,36 +432,6 @@ namespace Godot
}
/// <summary>
- /// Performs a bitwise AND operation with this <see cref="Vector3i"/>
- /// and the given <see langword="int"/>.
- /// </summary>
- /// <param name="vec">The vector to AND with.</param>
- /// <param name="and">The integer to AND with.</param>
- /// <returns>The result of the bitwise AND.</returns>
- public static Vector3i operator &(Vector3i vec, int and)
- {
- vec.x &= and;
- vec.y &= and;
- vec.z &= and;
- return vec;
- }
-
- /// <summary>
- /// Performs a bitwise AND operation with this <see cref="Vector3i"/>
- /// and the given <see cref="Vector3i"/>.
- /// </summary>
- /// <param name="vec">The left vector to AND with.</param>
- /// <param name="andv">The right vector to AND with.</param>
- /// <returns>The result of the bitwise AND.</returns>
- public static Vector3i operator &(Vector3i vec, Vector3i andv)
- {
- vec.x &= andv.x;
- vec.y &= andv.y;
- vec.z &= andv.z;
- return vec;
- }
-
- /// <summary>
/// Returns <see langword="true"/> if the vectors are equal.
/// </summary>
/// <param name="left">The left vector.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs
index 3191e8adc0..0f4528bb40 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs
@@ -280,6 +280,16 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this vector is finite, by calling
+ /// <see cref="Mathf.IsFinite"/> on each component.
+ /// </summary>
+ /// <returns>Whether this vector is finite or not.</returns>
+ public readonly bool IsFinite()
+ {
+ return Mathf.IsFinite(x) && Mathf.IsFinite(y) && Mathf.IsFinite(z) && Mathf.IsFinite(w);
+ }
+
+ /// <summary>
/// Returns <see langword="true"/> if the vector is normalized, and <see langword="false"/> otherwise.
/// </summary>
/// <returns>A <see langword="bool"/> indicating whether or not the vector is normalized.</returns>
@@ -857,6 +867,18 @@ namespace Godot
}
/// <summary>
+ /// Returns <see langword="true"/> if this vector's values are approximately zero,
+ /// by running <see cref="Mathf.IsZeroApprox(real_t)"/> on each component.
+ /// This method is faster than using <see cref="IsEqualApprox"/> with one value
+ /// as a zero vector.
+ /// </summary>
+ /// <returns>Whether or not the vector is approximately zero.</returns>
+ public readonly bool IsZeroApprox()
+ {
+ return Mathf.IsZeroApprox(x) && Mathf.IsZeroApprox(y) && Mathf.IsZeroApprox(z) && Mathf.IsZeroApprox(w);
+ }
+
+ /// <summary>
/// Serves as the hash function for <see cref="Vector4"/>.
/// </summary>
/// <returns>A hash code for this vector.</returns>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs
index 8146991fd7..00ecc64856 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs
@@ -433,38 +433,6 @@ namespace Godot
}
/// <summary>
- /// Performs a bitwise AND operation with this <see cref="Vector4i"/>
- /// and the given <see langword="int"/>.
- /// </summary>
- /// <param name="vec">The vector to AND with.</param>
- /// <param name="and">The integer to AND with.</param>
- /// <returns>The result of the bitwise AND.</returns>
- public static Vector4i operator &(Vector4i vec, int and)
- {
- vec.x &= and;
- vec.y &= and;
- vec.z &= and;
- vec.w &= and;
- return vec;
- }
-
- /// <summary>
- /// Performs a bitwise AND operation with this <see cref="Vector4i"/>
- /// and the given <see cref="Vector4i"/>.
- /// </summary>
- /// <param name="vec">The left vector to AND with.</param>
- /// <param name="andv">The right vector to AND with.</param>
- /// <returns>The result of the bitwise AND.</returns>
- public static Vector4i operator &(Vector4i vec, Vector4i andv)
- {
- vec.x &= andv.x;
- vec.y &= andv.y;
- vec.z &= andv.z;
- vec.w &= andv.w;
- return vec;
- }
-
- /// <summary>
/// Returns <see langword="true"/> if the vectors are equal.
/// </summary>
/// <param name="left">The left vector.</param>