Skip to content

Commit

Permalink
C#: Replace Xform and XformInv with * operator
Browse files Browse the repository at this point in the history
- In cases where both `Xform`/`XformInv` and the `*` operator were
implemented the `Xform`/`XformInv` methods were removed in favor of the
`*` operator.
- In cases where the `Xform`/`XformInv` existed but not the `*` operator,
the `Xform`/`XformInv` methods were replaced with the `*` operator.
- In cases where no method existed, a new `*` operator has been
implemented to support the same operations that are supported in GDScript.
- Fixes the `Transform.Xform` and `Transform.XformInv` with `Rect2`
implementation to use a zero `Rect2` size to start expanding from
(which is how it's implemented in C++).
  • Loading branch information
raulsntos committed Aug 22, 2022
1 parent 8a1e598 commit 0b8b733
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 181 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public override void _PhysicsProcess(float delta)
// Get the input direction and handle the movement/deceleration.
// As good practice, you should replace UI actions with custom gameplay actions.
Vector2 inputDir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down");
Vector3 direction = Transform.basis.Xform(new Vector3(inputDir.x, 0, inputDir.y)).Normalized();
Vector3 direction = (Transform.basis * new Vector3(inputDir.x, 0, inputDir.y)).Normalized();
if (direction != Vector3.Zero)
{
velocity.x = direction.x * Speed;
Expand Down
70 changes: 35 additions & 35 deletions modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -618,41 +618,6 @@ public Basis Transposed()
return tr;
}

/// <summary>
/// Returns a vector transformed (multiplied) by the basis matrix.
/// </summary>
/// <seealso cref="XformInv(Vector3)"/>
/// <param name="v">A vector to transform.</param>
/// <returns>The transformed vector.</returns>
public Vector3 Xform(Vector3 v)
{
return new Vector3
(
Row0.Dot(v),
Row1.Dot(v),
Row2.Dot(v)
);
}

/// <summary>
/// Returns a vector transformed (multiplied) by the transposed basis matrix.
///
/// Note: This results in a multiplication by the inverse of the
/// basis matrix only if it represents a rotation-reflection.
/// </summary>
/// <seealso cref="Xform(Vector3)"/>
/// <param name="v">A vector to inversely transform.</param>
/// <returns>The inversely transformed vector.</returns>
public Vector3 XformInv(Vector3 v)
{
return new Vector3
(
Row0[0] * v.x + Row1[0] * v.y + Row2[0] * v.z,
Row0[1] * v.x + Row1[1] * v.y + Row2[1] * v.z,
Row0[2] * v.x + Row1[2] * v.y + Row2[2] * v.z
);
}

private static readonly Basis[] _orthoBases = {
new Basis(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f),
new Basis(0f, -1f, 0f, 1f, 0f, 0f, 0f, 0f, 1f),
Expand Down Expand Up @@ -856,6 +821,41 @@ public static Basis FromScale(Vector3 scale)
);
}

/// <summary>
/// Returns a Vector3 transformed (multiplied) by the basis matrix.
/// </summary>
/// <param name="basis">The basis matrix transformation to apply.</param>
/// <param name="vector">A Vector3 to transform.</param>
/// <returns>The transformed Vector3.</returns>
public static Vector3 operator *(Basis basis, Vector3 vector)
{
return new Vector3
(
basis.Row0.Dot(vector),
basis.Row1.Dot(vector),
basis.Row2.Dot(vector)
);
}

/// <summary>
/// Returns a Vector3 transformed (multiplied) by the transposed basis matrix.
///
/// Note: This results in a multiplication by the inverse of the
/// basis matrix only if it represents a rotation-reflection.
/// </summary>
/// <param name="vector">A Vector3 to inversely transform.</param>
/// <param name="basis">The basis matrix transformation to apply.</param>
/// <returns>The inversely transformed vector.</returns>
public static Vector3 operator *(Vector3 vector, Basis basis)
{
return new Vector3
(
basis.Row0[0] * vector.x + basis.Row1[0] * vector.y + basis.Row2[0] * vector.z,
basis.Row0[1] * vector.x + basis.Row1[1] * vector.y + basis.Row2[1] * vector.z,
basis.Row0[2] * vector.x + basis.Row1[2] * vector.y + basis.Row2[2] * vector.z
);
}

/// <summary>
/// Returns <see langword="true"/> if the basis matrices are exactly
/// equal. Note: Due to floating-point precision errors, consider using
Expand Down
65 changes: 41 additions & 24 deletions modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ public real_t GetLodMultiplier()

public int GetPixelsPerMeter(int forPixelWidth)
{
Vector3 result = Xform(new Vector3(1, 0, -1));
Vector3 result = this * new Vector3(1, 0, -1);

return (int)((result.x * (real_t)0.5 + (real_t)0.5) * forPixelWidth);
}
Expand Down Expand Up @@ -588,21 +588,53 @@ public bool IsOrthogonal()
}

/// <summary>
/// Returns a vector transformed (multiplied) by this projection.
/// Returns a Vector4 transformed (multiplied) by the projection.
/// </summary>
/// <param name="proj">The projection to apply.</param>
/// <param name="v">A vector to transform.</param>
/// <returns>The transformed vector.</returns>
public static Vector4 operator *(Projection proj, Vector4 v)
/// <param name="vector">A Vector4 to transform.</param>
/// <returns>The transformed Vector4.</returns>
public static Vector4 operator *(Projection proj, Vector4 vector)
{
return new Vector4(
proj.x.x * v.x + proj.y.x * v.y + proj.z.x * v.z + proj.w.x * v.w,
proj.x.y * v.x + proj.y.y * v.y + proj.z.y * v.z + proj.w.y * v.w,
proj.x.z * v.x + proj.y.z * v.y + proj.z.z * v.z + proj.w.z * v.w,
proj.x.w * v.x + proj.y.w * v.y + proj.z.w * v.z + proj.w.w * v.w
proj.x.x * vector.x + proj.y.x * vector.y + proj.z.x * vector.z + proj.w.x * vector.w,
proj.x.y * vector.x + proj.y.y * vector.y + proj.z.y * vector.z + proj.w.y * vector.w,
proj.x.z * vector.x + proj.y.z * vector.y + proj.z.z * vector.z + proj.w.z * vector.w,
proj.x.w * vector.x + proj.y.w * vector.y + proj.z.w * vector.z + proj.w.w * vector.w
);
}

/// <summary>
/// Returns a Vector4 transformed (multiplied) by the inverse projection.
/// </summary>
/// <param name="proj">The projection to apply.</param>
/// <param name="vector">A Vector4 to transform.</param>
/// <returns>The inversely transformed Vector4.</returns>
public static Vector4 operator *(Vector4 vector, Projection proj)
{
return new Vector4(
proj.x.x * vector.x + proj.x.y * vector.y + proj.x.z * vector.z + proj.x.w * vector.w,
proj.y.x * vector.x + proj.y.y * vector.y + proj.y.z * vector.z + proj.y.w * vector.w,
proj.z.x * vector.x + proj.z.y * vector.y + proj.z.z * vector.z + proj.z.w * vector.w,
proj.w.x * vector.x + proj.w.y * vector.y + proj.w.z * vector.z + proj.w.w * vector.w
);
}

/// <summary>
/// Returns a Vector3 transformed (multiplied) by the projection.
/// </summary>
/// <param name="proj">The projection to apply.</param>
/// <param name="vector">A Vector3 to transform.</param>
/// <returns>The transformed Vector3.</returns>
public static Vector3 operator *(Projection proj, Vector3 vector)
{
Vector3 ret = new Vector3(
proj.x.x * vector.x + proj.y.x * vector.y + proj.z.x * vector.z + proj.w.x,
proj.x.y * vector.x + proj.y.y * vector.y + proj.z.y * vector.z + proj.w.y,
proj.x.z * vector.x + proj.y.z * vector.y + proj.z.z * vector.z + proj.w.z
);
return ret / (proj.x.w * vector.x + proj.y.w * vector.y + proj.z.w * vector.z + proj.w.w);
}

/// <summary>
/// Returns <see langword="true"/> if the projections are exactly equal.
/// </summary>
Expand Down Expand Up @@ -714,21 +746,6 @@ public Vector4 this[int column]
}
}

/// <summary>
/// Returns a vector transformed (multiplied) by this projection.
/// </summary>
/// <param name="v">A vector to transform.</param>
/// <returns>The transformed vector.</returns>
private Vector3 Xform(Vector3 v)
{
Vector3 ret = new Vector3(
x.x * v.x + y.x * v.y + z.x * v.z + w.x,
x.y * v.x + y.y * v.y + z.y * v.z + w.y,
x.z * v.x + y.z * v.y + z.z * v.z + w.z
);
return ret / (x.w * v.x + y.w * v.y + z.w * v.z + w.w);
}

// Constants
private static readonly Projection _zero = new Projection(
new Vector4(0, 0, 0, 0),
Expand Down
80 changes: 30 additions & 50 deletions modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -313,24 +313,6 @@ public Quaternion Slerpni(Quaternion to, real_t weight)
);
}

/// <summary>
/// Returns a vector transformed (multiplied) by this quaternion.
/// </summary>
/// <param name="v">A vector to transform.</param>
/// <returns>The transformed vector.</returns>
public Vector3 Xform(Vector3 v)
{
#if DEBUG
if (!IsNormalized())
{
throw new InvalidOperationException("Quaternion is not normalized");
}
#endif
var u = new Vector3(x, y, z);
Vector3 uv = u.Cross(v);
return v + (((uv * w) + u.Cross(uv)) * 2);
}

// Constants
private static readonly Quaternion _identity = new Quaternion(0, 0, 0, 1);

Expand Down Expand Up @@ -460,6 +442,36 @@ public Quaternion(Vector3 axis, real_t angle)
);
}

/// <summary>
/// Returns a Vector3 rotated (multiplied) by the quaternion.
/// </summary>
/// <param name="quaternion">The quaternion to rotate by.</param>
/// <param name="vector">A Vector3 to transform.</param>
/// <returns>The rotated Vector3.</returns>
public static Vector3 operator *(Quaternion quaternion, Vector3 vector)
{
#if DEBUG
if (!quaternion.IsNormalized())
{
throw new InvalidOperationException("Quaternion is not normalized");
}
#endif
var u = new Vector3(quaternion.x, quaternion.y, quaternion.z);
Vector3 uv = u.Cross(vector);
return vector + (((uv * quaternion.w) + u.Cross(uv)) * 2);
}

/// <summary>
/// Returns a Vector3 rotated (multiplied) by the inverse quaternion.
/// </summary>
/// <param name="vector">A Vector3 to inversely rotate.</param>
/// <param name="quaternion">The quaternion to rotate by.</param>
/// <returns>The inversely rotated Vector3.</returns>
public static Vector3 operator *(Vector3 vector, Quaternion quaternion)
{
return quaternion.Inverse() * vector;
}

/// <summary>
/// Adds each component of the left <see cref="Quaternion"/>
/// to the right <see cref="Quaternion"/>. This operation is not
Expand Down Expand Up @@ -502,38 +514,6 @@ public Quaternion(Vector3 axis, real_t angle)
return new Quaternion(-quat.x, -quat.y, -quat.z, -quat.w);
}

/// <summary>
/// Rotates (multiplies) the <see cref="Vector3"/>
/// by the given <see cref="Quaternion"/>.
/// </summary>
/// <param name="quat">The quaternion to rotate by.</param>
/// <param name="vec">The vector to rotate.</param>
/// <returns>The rotated vector.</returns>
public static Vector3 operator *(Quaternion quat, Vector3 vec)
{
#if DEBUG
if (!quat.IsNormalized())
{
throw new InvalidOperationException("Quaternion is not normalized.");
}
#endif
var u = new Vector3(quat.x, quat.y, quat.z);
Vector3 uv = u.Cross(vec);
return vec + (((uv * quat.w) + u.Cross(uv)) * 2);
}

/// <summary>
/// Inversely rotates (multiplies) the <see cref="Vector3"/>
/// by the given <see cref="Quaternion"/>.
/// </summary>
/// <param name="vec">The vector to rotate.</param>
/// <param name="quat">The quaternion to rotate by.</param>
/// <returns>The inversely rotated vector.</returns>
public static Vector3 operator *(Vector3 vec, Quaternion quat)
{
return quat.Inverse() * vec;
}

/// <summary>
/// Multiplies each component of the <see cref="Quaternion"/>
/// by the given <see cref="real_t"/>. This operation is not
Expand Down
35 changes: 5 additions & 30 deletions modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -384,31 +384,6 @@ public Transform2D TranslatedLocal(Vector2 offset)
return copy;
}

/// <summary>
/// Returns a vector transformed (multiplied) by this transformation matrix.
/// </summary>
/// <seealso cref="XformInv(Vector2)"/>
/// <param name="v">A vector to transform.</param>
/// <returns>The transformed vector.</returns>
[Obsolete("Xform is deprecated. Use the multiplication operator (Transform2D * Vector2) instead.")]
public Vector2 Xform(Vector2 v)
{
return new Vector2(Tdotx(v), Tdoty(v)) + origin;
}

/// <summary>
/// Returns a vector transformed (multiplied) by the inverse transformation matrix.
/// </summary>
/// <seealso cref="Xform(Vector2)"/>
/// <param name="v">A vector to inversely transform.</param>
/// <returns>The inversely transformed vector.</returns>
[Obsolete("XformInv is deprecated. Use the multiplication operator (Vector2 * Transform2D) instead.")]
public Vector2 XformInv(Vector2 v)
{
Vector2 vInv = v - origin;
return new Vector2(x.Dot(vInv), y.Dot(vInv));
}

// Constants
private static readonly Transform2D _identity = new Transform2D(1, 0, 0, 1, 0, 0);
private static readonly Transform2D _flipX = new Transform2D(-1, 0, 0, 1, 0, 0);
Expand Down Expand Up @@ -502,7 +477,7 @@ public Transform2D(real_t rotation, Vector2 origin)
}

/// <summary>
/// Returns a Vector2 transformed (multiplied) by transformation matrix.
/// Returns a Vector2 transformed (multiplied) by the transformation matrix.
/// </summary>
/// <param name="transform">The transformation to apply.</param>
/// <param name="vector">A Vector2 to transform.</param>
Expand All @@ -525,7 +500,7 @@ public Transform2D(real_t rotation, Vector2 origin)
}

/// <summary>
/// Returns a Rect2 transformed (multiplied) by transformation matrix.
/// Returns a Rect2 transformed (multiplied) by the transformation matrix.
/// </summary>
/// <param name="transform">The transformation to apply.</param>
/// <param name="rect">A Rect2 to transform.</param>
Expand All @@ -536,7 +511,7 @@ public Transform2D(real_t rotation, Vector2 origin)
Vector2 toX = transform.x * rect.Size.x;
Vector2 toY = transform.y * rect.Size.y;

return new Rect2(pos, rect.Size).Expand(pos + toX).Expand(pos + toY).Expand(pos + toX + toY);
return new Rect2(pos, new Vector2()).Expand(pos + toX).Expand(pos + toY).Expand(pos + toX + toY);
}

/// <summary>
Expand All @@ -552,11 +527,11 @@ public Transform2D(real_t rotation, Vector2 origin)
Vector2 to2 = new Vector2(rect.Position.x + rect.Size.x, rect.Position.y + rect.Size.y) * transform;
Vector2 to3 = new Vector2(rect.Position.x + rect.Size.x, rect.Position.y) * transform;

return new Rect2(pos, rect.Size).Expand(to1).Expand(to2).Expand(to3);
return new Rect2(pos, new Vector2()).Expand(to1).Expand(to2).Expand(to3);
}

/// <summary>
/// Returns a copy of the given Vector2[] transformed (multiplied) by transformation matrix.
/// Returns a copy of the given Vector2[] transformed (multiplied) by the transformation matrix.
/// </summary>
/// <param name="transform">The transformation to apply.</param>
/// <param name="array">A Vector2[] to transform.</param>
Expand Down
Loading

0 comments on commit 0b8b733

Please sign in to comment.