Merge pull request #55923 from bluenote10/feature/consistent_transform_operations
Fix consistency of translated/scaled/rotated in Transform2D and Transform3D
This commit is contained in:
commit
a49cf9fe90
|
@ -217,16 +217,22 @@ Transform2D Transform2D::operator*(const Transform2D &p_transform) const {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Transform2D Transform2D::basis_scaled(const Size2 &p_scale) const {
|
||||||
|
Transform2D copy = *this;
|
||||||
|
copy.scale_basis(p_scale);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
Transform2D Transform2D::scaled(const Size2 &p_scale) const {
|
Transform2D Transform2D::scaled(const Size2 &p_scale) const {
|
||||||
|
// Equivalent to left multiplication
|
||||||
Transform2D copy = *this;
|
Transform2D copy = *this;
|
||||||
copy.scale(p_scale);
|
copy.scale(p_scale);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform2D Transform2D::basis_scaled(const Size2 &p_scale) const {
|
Transform2D Transform2D::scaled_local(const Size2 &p_scale) const {
|
||||||
Transform2D copy = *this;
|
// Equivalent to right multiplication
|
||||||
copy.scale_basis(p_scale);
|
return Transform2D(columns[0] * p_scale.x, columns[1] * p_scale.y, columns[2]);
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform2D Transform2D::untranslated() const {
|
Transform2D Transform2D::untranslated() const {
|
||||||
|
@ -235,16 +241,24 @@ Transform2D Transform2D::untranslated() const {
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Transform2D Transform2D::translated(const Vector2 &p_offset) const {
|
||||||
|
// Equivalent to left multiplication
|
||||||
|
return Transform2D(columns[0], columns[1], columns[2] + p_offset);
|
||||||
|
}
|
||||||
|
|
||||||
Transform2D Transform2D::translated_local(const Vector2 &p_offset) const {
|
Transform2D Transform2D::translated_local(const Vector2 &p_offset) const {
|
||||||
Transform2D copy = *this;
|
// Equivalent to right multiplication
|
||||||
copy.translate_local(p_offset);
|
return Transform2D(columns[0], columns[1], columns[2] + basis_xform(p_offset));
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform2D Transform2D::rotated(const real_t p_angle) const {
|
Transform2D Transform2D::rotated(const real_t p_angle) const {
|
||||||
Transform2D copy = *this;
|
// Equivalent to left multiplication
|
||||||
copy.rotate(p_angle);
|
return Transform2D(p_angle, Vector2()) * (*this);
|
||||||
return copy;
|
}
|
||||||
|
|
||||||
|
Transform2D Transform2D::rotated_local(const real_t p_angle) const {
|
||||||
|
// Equivalent to right multiplication
|
||||||
|
return (*this) * Transform2D(p_angle, Vector2()); // Could be optimized, because origin transform can be skipped.
|
||||||
}
|
}
|
||||||
|
|
||||||
real_t Transform2D::basis_determinant() const {
|
real_t Transform2D::basis_determinant() const {
|
||||||
|
|
|
@ -85,10 +85,13 @@ struct _NO_DISCARD_ Transform2D {
|
||||||
_FORCE_INLINE_ const Vector2 &get_origin() const { return columns[2]; }
|
_FORCE_INLINE_ const Vector2 &get_origin() const { return columns[2]; }
|
||||||
_FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { columns[2] = p_origin; }
|
_FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { columns[2] = p_origin; }
|
||||||
|
|
||||||
Transform2D scaled(const Size2 &p_scale) const;
|
|
||||||
Transform2D basis_scaled(const Size2 &p_scale) const;
|
Transform2D basis_scaled(const Size2 &p_scale) const;
|
||||||
|
Transform2D scaled(const Size2 &p_scale) const;
|
||||||
|
Transform2D scaled_local(const Size2 &p_scale) const;
|
||||||
|
Transform2D translated(const Vector2 &p_offset) const;
|
||||||
Transform2D translated_local(const Vector2 &p_offset) const;
|
Transform2D translated_local(const Vector2 &p_offset) const;
|
||||||
Transform2D rotated(const real_t p_angle) const;
|
Transform2D rotated(const real_t p_angle) const;
|
||||||
|
Transform2D rotated_local(const real_t p_angle) const;
|
||||||
|
|
||||||
Transform2D untranslated() const;
|
Transform2D untranslated() const;
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,15 @@ void Transform3D::rotate(const Vector3 &p_axis, real_t p_angle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform3D Transform3D::rotated(const Vector3 &p_axis, real_t p_angle) const {
|
Transform3D Transform3D::rotated(const Vector3 &p_axis, real_t p_angle) const {
|
||||||
return Transform3D(Basis(p_axis, p_angle), Vector3()) * (*this);
|
// Equivalent to left multiplication
|
||||||
|
Basis p_basis(p_axis, p_angle);
|
||||||
|
return Transform3D(p_basis * basis, p_basis.xform(origin));
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform3D Transform3D::rotated_local(const Vector3 &p_axis, real_t p_angle) const {
|
||||||
|
// Equivalent to right multiplication
|
||||||
|
Basis p_basis(p_axis, p_angle);
|
||||||
|
return Transform3D(basis * p_basis, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform3D::rotate_basis(const Vector3 &p_axis, real_t p_angle) {
|
void Transform3D::rotate_basis(const Vector3 &p_axis, real_t p_angle) {
|
||||||
|
@ -120,9 +128,13 @@ void Transform3D::scale(const Vector3 &p_scale) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform3D Transform3D::scaled(const Vector3 &p_scale) const {
|
Transform3D Transform3D::scaled(const Vector3 &p_scale) const {
|
||||||
Transform3D t = *this;
|
// Equivalent to left multiplication
|
||||||
t.scale(p_scale);
|
return Transform3D(basis.scaled(p_scale), origin * p_scale);
|
||||||
return t;
|
}
|
||||||
|
|
||||||
|
Transform3D Transform3D::scaled_local(const Vector3 &p_scale) const {
|
||||||
|
// Equivalent to right multiplication
|
||||||
|
return Transform3D(basis.scaled_local(p_scale), origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform3D::scale_basis(const Vector3 &p_scale) {
|
void Transform3D::scale_basis(const Vector3 &p_scale) {
|
||||||
|
@ -139,10 +151,14 @@ void Transform3D::translate_local(const Vector3 &p_translation) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Transform3D Transform3D::translated(const Vector3 &p_translation) const {
|
||||||
|
// Equivalent to left multiplication
|
||||||
|
return Transform3D(basis, origin + p_translation);
|
||||||
|
}
|
||||||
|
|
||||||
Transform3D Transform3D::translated_local(const Vector3 &p_translation) const {
|
Transform3D Transform3D::translated_local(const Vector3 &p_translation) const {
|
||||||
Transform3D t = *this;
|
// Equivalent to right multiplication
|
||||||
t.translate_local(p_translation);
|
return Transform3D(basis, origin + basis.xform(p_translation));
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform3D::orthonormalize() {
|
void Transform3D::orthonormalize() {
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct _NO_DISCARD_ Transform3D {
|
||||||
Transform3D affine_inverse() const;
|
Transform3D affine_inverse() const;
|
||||||
|
|
||||||
Transform3D rotated(const Vector3 &p_axis, real_t p_angle) const;
|
Transform3D rotated(const Vector3 &p_axis, real_t p_angle) const;
|
||||||
|
Transform3D rotated_local(const Vector3 &p_axis, real_t p_angle) const;
|
||||||
|
|
||||||
void rotate(const Vector3 &p_axis, real_t p_angle);
|
void rotate(const Vector3 &p_axis, real_t p_angle);
|
||||||
void rotate_basis(const Vector3 &p_axis, real_t p_angle);
|
void rotate_basis(const Vector3 &p_axis, real_t p_angle);
|
||||||
|
@ -55,9 +56,11 @@ struct _NO_DISCARD_ Transform3D {
|
||||||
|
|
||||||
void scale(const Vector3 &p_scale);
|
void scale(const Vector3 &p_scale);
|
||||||
Transform3D scaled(const Vector3 &p_scale) const;
|
Transform3D scaled(const Vector3 &p_scale) const;
|
||||||
|
Transform3D scaled_local(const Vector3 &p_scale) const;
|
||||||
void scale_basis(const Vector3 &p_scale);
|
void scale_basis(const Vector3 &p_scale);
|
||||||
void translate_local(real_t p_tx, real_t p_ty, real_t p_tz);
|
void translate_local(real_t p_tx, real_t p_ty, real_t p_tz);
|
||||||
void translate_local(const Vector3 &p_translation);
|
void translate_local(const Vector3 &p_translation);
|
||||||
|
Transform3D translated(const Vector3 &p_translation) const;
|
||||||
Transform3D translated_local(const Vector3 &p_translation) const;
|
Transform3D translated_local(const Vector3 &p_translation) const;
|
||||||
|
|
||||||
const Basis &get_basis() const { return basis; }
|
const Basis &get_basis() const { return basis; }
|
||||||
|
|
|
@ -1882,7 +1882,10 @@ static void _register_variant_builtin_methods() {
|
||||||
bind_method(Transform2D, get_skew, sarray(), varray());
|
bind_method(Transform2D, get_skew, sarray(), varray());
|
||||||
bind_method(Transform2D, orthonormalized, sarray(), varray());
|
bind_method(Transform2D, orthonormalized, sarray(), varray());
|
||||||
bind_method(Transform2D, rotated, sarray("angle"), varray());
|
bind_method(Transform2D, rotated, sarray("angle"), varray());
|
||||||
|
bind_method(Transform2D, rotated_local, sarray("angle"), varray());
|
||||||
bind_method(Transform2D, scaled, sarray("scale"), varray());
|
bind_method(Transform2D, scaled, sarray("scale"), varray());
|
||||||
|
bind_method(Transform2D, scaled_local, sarray("scale"), varray());
|
||||||
|
bind_method(Transform2D, translated, sarray("offset"), varray());
|
||||||
bind_method(Transform2D, translated_local, sarray("offset"), varray());
|
bind_method(Transform2D, translated_local, sarray("offset"), varray());
|
||||||
bind_method(Transform2D, basis_xform, sarray("v"), varray());
|
bind_method(Transform2D, basis_xform, sarray("v"), varray());
|
||||||
bind_method(Transform2D, basis_xform_inv, sarray("v"), varray());
|
bind_method(Transform2D, basis_xform_inv, sarray("v"), varray());
|
||||||
|
@ -1947,7 +1950,10 @@ static void _register_variant_builtin_methods() {
|
||||||
bind_method(Transform3D, affine_inverse, sarray(), varray());
|
bind_method(Transform3D, affine_inverse, sarray(), varray());
|
||||||
bind_method(Transform3D, orthonormalized, sarray(), varray());
|
bind_method(Transform3D, orthonormalized, sarray(), varray());
|
||||||
bind_method(Transform3D, rotated, sarray("axis", "angle"), varray());
|
bind_method(Transform3D, rotated, sarray("axis", "angle"), varray());
|
||||||
|
bind_method(Transform3D, rotated_local, sarray("axis", "angle"), varray());
|
||||||
bind_method(Transform3D, scaled, sarray("scale"), varray());
|
bind_method(Transform3D, scaled, sarray("scale"), varray());
|
||||||
|
bind_method(Transform3D, scaled_local, sarray("scale"), varray());
|
||||||
|
bind_method(Transform3D, translated, sarray("offset"), varray());
|
||||||
bind_method(Transform3D, translated_local, sarray("offset"), varray());
|
bind_method(Transform3D, translated_local, sarray("offset"), varray());
|
||||||
bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
|
bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
|
||||||
bind_method(Transform3D, spherical_interpolate_with, sarray("xform", "weight"), varray());
|
bind_method(Transform3D, spherical_interpolate_with, sarray("xform", "weight"), varray());
|
||||||
|
|
|
@ -141,14 +141,40 @@
|
||||||
<return type="Transform2D" />
|
<return type="Transform2D" />
|
||||||
<argument index="0" name="angle" type="float" />
|
<argument index="0" name="angle" type="float" />
|
||||||
<description>
|
<description>
|
||||||
Returns a copy of the transform rotated by the given [code]angle[/code] (in radians), using matrix multiplication.
|
Returns a copy of the transform rotated by the given [code]angle[/code] (in radians).
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding rotation transform [code]R[/code] from the left, i.e., [code]R * X[/code].
|
||||||
|
This can be seen as transforming with respect to the global/parent frame.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="rotated_local" qualifiers="const">
|
||||||
|
<return type="Transform2D" />
|
||||||
|
<argument index="0" name="angle" type="float" />
|
||||||
|
<description>
|
||||||
|
Returns a copy of the transform rotated by the given [code]angle[/code] (in radians).
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding rotation transform [code]R[/code] from the right, i.e., [code]X * R[/code].
|
||||||
|
This can be seen as transforming with respect to the local frame.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="scaled" qualifiers="const">
|
<method name="scaled" qualifiers="const">
|
||||||
<return type="Transform2D" />
|
<return type="Transform2D" />
|
||||||
<argument index="0" name="scale" type="Vector2" />
|
<argument index="0" name="scale" type="Vector2" />
|
||||||
<description>
|
<description>
|
||||||
Returns a copy of the transform scaled by the given [code]scale[/code] factor, using matrix multiplication.
|
Returns a copy of the transform scaled by the given [code]scale[/code] factor.
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding scaling transform [code]S[/code] from the left, i.e., [code]S * X[/code].
|
||||||
|
This can be seen as transforming with respect to the global/parent frame.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="scaled_local" qualifiers="const">
|
||||||
|
<return type="Transform2D" />
|
||||||
|
<argument index="0" name="scale" type="Vector2" />
|
||||||
|
<description>
|
||||||
|
Returns a copy of the transform scaled by the given [code]scale[/code] factor.
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding scaling transform [code]S[/code] from the right, i.e., [code]X * S[/code].
|
||||||
|
This can be seen as transforming with respect to the local frame.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="set_rotation">
|
<method name="set_rotation">
|
||||||
|
@ -173,12 +199,24 @@
|
||||||
Sets the transform's skew (in radians).
|
Sets the transform's skew (in radians).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="translated" qualifiers="const">
|
||||||
|
<return type="Transform2D" />
|
||||||
|
<argument index="0" name="offset" type="Vector2" />
|
||||||
|
<description>
|
||||||
|
Returns a copy of the transform translated by the given [code]offset[/code].
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding translation transform [code]T[/code] from the left, i.e., [code]T * X[/code].
|
||||||
|
This can be seen as transforming with respect to the global/parent frame.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="translated_local" qualifiers="const">
|
<method name="translated_local" qualifiers="const">
|
||||||
<return type="Transform2D" />
|
<return type="Transform2D" />
|
||||||
<argument index="0" name="offset" type="Vector2" />
|
<argument index="0" name="offset" type="Vector2" />
|
||||||
<description>
|
<description>
|
||||||
Returns a copy of the transform translated by the given [code]offset[/code], relative to the transform's basis vectors.
|
Returns a copy of the transform translated by the given [code]offset[/code].
|
||||||
Unlike [method rotated] and [method scaled], this does not use matrix multiplication.
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding translation transform [code]T[/code] from the right, i.e., [code]X * T[/code].
|
||||||
|
This can be seen as transforming with respect to the local frame.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
|
|
@ -102,14 +102,43 @@
|
||||||
<argument index="0" name="axis" type="Vector3" />
|
<argument index="0" name="axis" type="Vector3" />
|
||||||
<argument index="1" name="angle" type="float" />
|
<argument index="1" name="angle" type="float" />
|
||||||
<description>
|
<description>
|
||||||
Returns a copy of the transform rotated around the given [code]axis[/code] by the given [code]angle[/code] (in radians), using matrix multiplication. The [code]axis[/code] must be a normalized vector.
|
Returns a copy of the transform rotated around the given [code]axis[/code] by the given [code]angle[/code] (in radians).
|
||||||
|
The [code]axis[/code] must be a normalized vector.
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding rotation transform [code]R[/code] from the left, i.e., [code]R * X[/code].
|
||||||
|
This can be seen as transforming with respect to the global/parent frame.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="rotated_local" qualifiers="const">
|
||||||
|
<return type="Transform3D" />
|
||||||
|
<argument index="0" name="axis" type="Vector3" />
|
||||||
|
<argument index="1" name="angle" type="float" />
|
||||||
|
<description>
|
||||||
|
Returns a copy of the transform rotated around the given [code]axis[/code] by the given [code]angle[/code] (in radians).
|
||||||
|
The [code]axis[/code] must be a normalized vector.
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding rotation transform [code]R[/code] from the right, i.e., [code]X * R[/code].
|
||||||
|
This can be seen as transforming with respect to the local frame.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="scaled" qualifiers="const">
|
<method name="scaled" qualifiers="const">
|
||||||
<return type="Transform3D" />
|
<return type="Transform3D" />
|
||||||
<argument index="0" name="scale" type="Vector3" />
|
<argument index="0" name="scale" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Returns a copy of the transform with its basis and origin scaled by the given [code]scale[/code] factor, using matrix multiplication.
|
Returns a copy of the transform scaled by the given [code]scale[/code] factor.
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding scaling transform [code]S[/code] from the left, i.e., [code]S * X[/code].
|
||||||
|
This can be seen as transforming with respect to the global/parent frame.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="scaled_local" qualifiers="const">
|
||||||
|
<return type="Transform3D" />
|
||||||
|
<argument index="0" name="scale" type="Vector3" />
|
||||||
|
<description>
|
||||||
|
Returns a copy of the transform scaled by the given [code]scale[/code] factor.
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding scaling transform [code]S[/code] from the right, i.e., [code]X * S[/code].
|
||||||
|
This can be seen as transforming with respect to the local frame.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="spherical_interpolate_with" qualifiers="const">
|
<method name="spherical_interpolate_with" qualifiers="const">
|
||||||
|
@ -120,12 +149,24 @@
|
||||||
Returns a transform spherically interpolated between this transform and another by a given [code]weight[/code] (on the range of 0.0 to 1.0).
|
Returns a transform spherically interpolated between this transform and another by a given [code]weight[/code] (on the range of 0.0 to 1.0).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="translated" qualifiers="const">
|
||||||
|
<return type="Transform3D" />
|
||||||
|
<argument index="0" name="offset" type="Vector3" />
|
||||||
|
<description>
|
||||||
|
Returns a copy of the transform translated by the given [code]offset[/code].
|
||||||
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding translation transform [code]T[/code] from the left, i.e., [code]T * X[/code].
|
||||||
|
This can be seen as transforming with respect to the global/parent frame.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="translated_local" qualifiers="const">
|
<method name="translated_local" qualifiers="const">
|
||||||
<return type="Transform3D" />
|
<return type="Transform3D" />
|
||||||
<argument index="0" name="offset" type="Vector3" />
|
<argument index="0" name="offset" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Returns a copy of the transform translated by the given [code]offset[/code], relative to the transform's basis vectors.
|
Returns a copy of the transform translated by the given [code]offset[/code].
|
||||||
Unlike [method rotated] and [method scaled], this does not use matrix multiplication.
|
This method is an optimized version of multiplying the given transform [code]X[/code]
|
||||||
|
with a corresponding translation transform [code]T[/code] from the right, i.e., [code]X * T[/code].
|
||||||
|
This can be seen as transforming with respect to the local frame.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
|
|
@ -297,7 +297,9 @@ namespace Godot
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rotates the transform by <paramref name="angle"/> (in radians), using matrix multiplication.
|
/// Rotates the transform by <paramref name="angle"/> (in radians).
|
||||||
|
/// The operation is done in the parent/global frame, equivalent to
|
||||||
|
/// multiplying the matrix from the left.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="angle">The angle to rotate, in radians.</param>
|
/// <param name="angle">The angle to rotate, in radians.</param>
|
||||||
/// <returns>The rotated transformation matrix.</returns>
|
/// <returns>The rotated transformation matrix.</returns>
|
||||||
|
@ -307,7 +309,21 @@ namespace Godot
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scales the transform by the given scaling factor, using matrix multiplication.
|
/// Rotates the transform by <paramref name="angle"/> (in radians).
|
||||||
|
/// The operation is done in the local frame, equivalent to
|
||||||
|
/// multiplying the matrix from the right.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="angle">The angle to rotate, in radians.</param>
|
||||||
|
/// <returns>The rotated transformation matrix.</returns>
|
||||||
|
public Transform2D RotatedLocal(real_t angle)
|
||||||
|
{
|
||||||
|
return new Transform2D(angle, new Vector2()) * this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scales the transform by the given scaling factor.
|
||||||
|
/// The operation is done in the parent/global frame, equivalent to
|
||||||
|
/// multiplying the matrix from the left.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="scale">The scale to introduce.</param>
|
/// <param name="scale">The scale to introduce.</param>
|
||||||
/// <returns>The scaled transformation matrix.</returns>
|
/// <returns>The scaled transformation matrix.</returns>
|
||||||
|
@ -320,6 +336,21 @@ namespace Godot
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scales the transform by the given scaling factor.
|
||||||
|
/// The operation is done in the local frame, equivalent to
|
||||||
|
/// multiplying the matrix from the right.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scale">The scale to introduce.</param>
|
||||||
|
/// <returns>The scaled transformation matrix.</returns>
|
||||||
|
public Transform2D ScaledLocal(Vector2 scale)
|
||||||
|
{
|
||||||
|
Transform2D copy = this;
|
||||||
|
copy.x *= scale;
|
||||||
|
copy.y *= scale;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
private real_t Tdotx(Vector2 with)
|
private real_t Tdotx(Vector2 with)
|
||||||
{
|
{
|
||||||
return (this[0, 0] * with[0]) + (this[1, 0] * with[1]);
|
return (this[0, 0] * with[0]) + (this[1, 0] * with[1]);
|
||||||
|
@ -331,11 +362,23 @@ namespace Godot
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Translates the transform by the given <paramref name="offset"/>,
|
/// Translates the transform by the given <paramref name="offset"/>.
|
||||||
/// relative to the transform's basis vectors.
|
/// The operation is done in the parent/global frame, equivalent to
|
||||||
///
|
/// multiplying the matrix from the left.
|
||||||
/// Unlike <see cref="Rotated"/> and <see cref="Scaled"/>,
|
/// </summary>
|
||||||
/// this does not use matrix multiplication.
|
/// <param name="offset">The offset to translate by.</param>
|
||||||
|
/// <returns>The translated matrix.</returns>
|
||||||
|
public Transform2D Translated(Vector2 offset)
|
||||||
|
{
|
||||||
|
Transform2D copy = this;
|
||||||
|
copy.origin += offset;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Translates the transform by the given <paramref name="offset"/>.
|
||||||
|
/// The operation is done in the local frame, equivalent to
|
||||||
|
/// multiplying the matrix from the right.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="offset">The offset to translate by.</param>
|
/// <param name="offset">The offset to translate by.</param>
|
||||||
/// <returns>The translated matrix.</returns>
|
/// <returns>The translated matrix.</returns>
|
||||||
|
|
|
@ -186,8 +186,10 @@ namespace Godot
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rotates the transform around the given <paramref name="axis"/> by <paramref name="angle"/> (in radians),
|
/// Rotates the transform around the given <paramref name="axis"/> by <paramref name="angle"/> (in radians).
|
||||||
/// using matrix multiplication. The axis must be a normalized vector.
|
/// The axis must be a normalized vector.
|
||||||
|
/// The operation is done in the parent/global frame, equivalent to
|
||||||
|
/// multiplying the matrix from the left.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="axis">The axis to rotate around. Must be normalized.</param>
|
/// <param name="axis">The axis to rotate around. Must be normalized.</param>
|
||||||
/// <param name="angle">The angle to rotate, in radians.</param>
|
/// <param name="angle">The angle to rotate, in radians.</param>
|
||||||
|
@ -198,7 +200,24 @@ namespace Godot
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scales the transform by the given 3D scaling factor, using matrix multiplication.
|
/// Rotates the transform around the given <paramref name="axis"/> by <paramref name="angle"/> (in radians).
|
||||||
|
/// The axis must be a normalized vector.
|
||||||
|
/// The operation is done in the local frame, equivalent to
|
||||||
|
/// multiplying the matrix from the right.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="axis">The axis to rotate around. Must be normalized.</param>
|
||||||
|
/// <param name="angle">The angle to rotate, in radians.</param>
|
||||||
|
/// <returns>The rotated transformation matrix.</returns>
|
||||||
|
public Transform3D RotatedLocal(Vector3 axis, real_t angle)
|
||||||
|
{
|
||||||
|
Basis tmpBasis = new Basis(axis, angle);
|
||||||
|
return new Transform3D(basis * tmpBasis, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scales the transform by the given 3D <paramref name="scale"/> factor.
|
||||||
|
/// The operation is done in the parent/global frame, equivalent to
|
||||||
|
/// multiplying the matrix from the left.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="scale">The scale to introduce.</param>
|
/// <param name="scale">The scale to introduce.</param>
|
||||||
/// <returns>The scaled transformation matrix.</returns>
|
/// <returns>The scaled transformation matrix.</returns>
|
||||||
|
@ -207,6 +226,19 @@ namespace Godot
|
||||||
return new Transform3D(basis.Scaled(scale), origin * scale);
|
return new Transform3D(basis.Scaled(scale), origin * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scales the transform by the given 3D <paramref name="scale"/> factor.
|
||||||
|
/// The operation is done in the local frame, equivalent to
|
||||||
|
/// multiplying the matrix from the right.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scale">The scale to introduce.</param>
|
||||||
|
/// <returns>The scaled transformation matrix.</returns>
|
||||||
|
public Transform3D ScaledLocal(Vector3 scale)
|
||||||
|
{
|
||||||
|
Basis tmpBasis = new Basis(new Vector3(scale.x, 0, 0), new Vector3(0, scale.y, 0), new Vector3(0, 0, scale.z));
|
||||||
|
return new Transform3D(basis * tmpBasis, origin);
|
||||||
|
}
|
||||||
|
|
||||||
private void SetLookAt(Vector3 eye, Vector3 target, Vector3 up)
|
private void SetLookAt(Vector3 eye, Vector3 target, Vector3 up)
|
||||||
{
|
{
|
||||||
// Make rotation matrix
|
// Make rotation matrix
|
||||||
|
@ -231,11 +263,21 @@ namespace Godot
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Translates the transform by the given <paramref name="offset"/>,
|
/// Translates the transform by the given <paramref name="offset"/>.
|
||||||
/// relative to the transform's basis vectors.
|
/// The operation is done in the parent/global frame, equivalent to
|
||||||
///
|
/// multiplying the matrix from the left.
|
||||||
/// Unlike <see cref="Rotated"/> and <see cref="Scaled"/>,
|
/// </summary>
|
||||||
/// this does not use matrix multiplication.
|
/// <param name="offset">The offset to translate by.</param>
|
||||||
|
/// <returns>The translated matrix.</returns>
|
||||||
|
public Transform3D Translated(Vector3 offset)
|
||||||
|
{
|
||||||
|
return new Transform3D(basis, origin + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Translates the transform by the given <paramref name="offset"/>.
|
||||||
|
/// The operation is done in the local frame, equivalent to
|
||||||
|
/// multiplying the matrix from the right.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="offset">The offset to translate by.</param>
|
/// <param name="offset">The offset to translate by.</param>
|
||||||
/// <returns>The translated matrix.</returns>
|
/// <returns>The translated matrix.</returns>
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*************************************************************************/
|
||||||
|
/* test_transform_2d.h */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TEST_TRANSFORM_2D_H
|
||||||
|
#define TEST_TRANSFORM_2D_H
|
||||||
|
|
||||||
|
#include "core/math/transform_2d.h"
|
||||||
|
|
||||||
|
#include "tests/test_macros.h"
|
||||||
|
|
||||||
|
namespace TestTransform2D {
|
||||||
|
|
||||||
|
Transform2D create_dummy_transform() {
|
||||||
|
return Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(5, 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform2D identity() {
|
||||||
|
return Transform2D();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Transform2D] translation") {
|
||||||
|
Vector2 offset = Vector2(1, 2);
|
||||||
|
|
||||||
|
// Both versions should give the same result applied to identity.
|
||||||
|
CHECK(identity().translated(offset) == identity().translated_local(offset));
|
||||||
|
|
||||||
|
// Check both versions against left and right multiplications.
|
||||||
|
Transform2D orig = create_dummy_transform();
|
||||||
|
Transform2D T = identity().translated(offset);
|
||||||
|
CHECK(orig.translated(offset) == T * orig);
|
||||||
|
CHECK(orig.translated_local(offset) == orig * T);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Transform2D] scaling") {
|
||||||
|
Vector2 scaling = Vector2(1, 2);
|
||||||
|
|
||||||
|
// Both versions should give the same result applied to identity.
|
||||||
|
CHECK(identity().scaled(scaling) == identity().scaled_local(scaling));
|
||||||
|
|
||||||
|
// Check both versions against left and right multiplications.
|
||||||
|
Transform2D orig = create_dummy_transform();
|
||||||
|
Transform2D S = identity().scaled(scaling);
|
||||||
|
CHECK(orig.scaled(scaling) == S * orig);
|
||||||
|
CHECK(orig.scaled_local(scaling) == orig * S);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Transform2D] rotation") {
|
||||||
|
real_t phi = 1.0;
|
||||||
|
|
||||||
|
// Both versions should give the same result applied to identity.
|
||||||
|
CHECK(identity().rotated(phi) == identity().rotated_local(phi));
|
||||||
|
|
||||||
|
// Check both versions against left and right multiplications.
|
||||||
|
Transform2D orig = create_dummy_transform();
|
||||||
|
Transform2D R = identity().rotated(phi);
|
||||||
|
CHECK(orig.rotated(phi) == R * orig);
|
||||||
|
CHECK(orig.rotated_local(phi) == orig * R);
|
||||||
|
}
|
||||||
|
} // namespace TestTransform2D
|
||||||
|
|
||||||
|
#endif // TEST_TRANSFORM_2D_H
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*************************************************************************/
|
||||||
|
/* test_transform_3d.h */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TEST_TRANSFORM_3D_H
|
||||||
|
#define TEST_TRANSFORM_3D_H
|
||||||
|
|
||||||
|
#include "core/math/transform_3d.h"
|
||||||
|
|
||||||
|
#include "tests/test_macros.h"
|
||||||
|
|
||||||
|
namespace TestTransform3D {
|
||||||
|
|
||||||
|
Transform3D create_dummy_transform() {
|
||||||
|
return Transform3D(Basis(Vector3(1, 2, 3), Vector3(4, 5, 6), Vector3(7, 8, 9)), Vector3(10, 11, 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform3D identity() {
|
||||||
|
return Transform3D();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Transform3D] translation") {
|
||||||
|
Vector3 offset = Vector3(1, 2, 3);
|
||||||
|
|
||||||
|
// Both versions should give the same result applied to identity.
|
||||||
|
CHECK(identity().translated(offset) == identity().translated_local(offset));
|
||||||
|
|
||||||
|
// Check both versions against left and right multiplications.
|
||||||
|
Transform3D orig = create_dummy_transform();
|
||||||
|
Transform3D T = identity().translated(offset);
|
||||||
|
CHECK(orig.translated(offset) == T * orig);
|
||||||
|
CHECK(orig.translated_local(offset) == orig * T);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Transform3D] scaling") {
|
||||||
|
Vector3 scaling = Vector3(1, 2, 3);
|
||||||
|
|
||||||
|
// Both versions should give the same result applied to identity.
|
||||||
|
CHECK(identity().scaled(scaling) == identity().scaled_local(scaling));
|
||||||
|
|
||||||
|
// Check both versions against left and right multiplications.
|
||||||
|
Transform3D orig = create_dummy_transform();
|
||||||
|
Transform3D S = identity().scaled(scaling);
|
||||||
|
CHECK(orig.scaled(scaling) == S * orig);
|
||||||
|
CHECK(orig.scaled_local(scaling) == orig * S);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Transform3D] rotation") {
|
||||||
|
Vector3 axis = Vector3(1, 2, 3).normalized();
|
||||||
|
real_t phi = 1.0;
|
||||||
|
|
||||||
|
// Both versions should give the same result applied to identity.
|
||||||
|
CHECK(identity().rotated(axis, phi) == identity().rotated_local(axis, phi));
|
||||||
|
|
||||||
|
// Check both versions against left and right multiplications.
|
||||||
|
Transform3D orig = create_dummy_transform();
|
||||||
|
Transform3D R = identity().rotated(axis, phi);
|
||||||
|
CHECK(orig.rotated(axis, phi) == R * orig);
|
||||||
|
CHECK(orig.rotated_local(axis, phi) == orig * R);
|
||||||
|
}
|
||||||
|
} // namespace TestTransform3D
|
||||||
|
|
||||||
|
#endif // TEST_TRANSFORM_3D_H
|
|
@ -49,6 +49,8 @@
|
||||||
#include "tests/core/math/test_random_number_generator.h"
|
#include "tests/core/math/test_random_number_generator.h"
|
||||||
#include "tests/core/math/test_rect2.h"
|
#include "tests/core/math/test_rect2.h"
|
||||||
#include "tests/core/math/test_rect2i.h"
|
#include "tests/core/math/test_rect2i.h"
|
||||||
|
#include "tests/core/math/test_transform_2d.h"
|
||||||
|
#include "tests/core/math/test_transform_3d.h"
|
||||||
#include "tests/core/math/test_vector2.h"
|
#include "tests/core/math/test_vector2.h"
|
||||||
#include "tests/core/math/test_vector2i.h"
|
#include "tests/core/math/test_vector2i.h"
|
||||||
#include "tests/core/math/test_vector3.h"
|
#include "tests/core/math/test_vector3.h"
|
||||||
|
|
Loading…
Reference in New Issue