Skip to content

Commit f043159

Browse files
bors[bot]rand0m-cloudBromeon
authored
Merge #930
930: Deprecate Transform2D::from_rotation_translation_scale and add from_scale_rotation_origin r=Bromeon a=rand0m-cloud This should close #915. This PR fixes a bug in the Transform2D constructor where the position was rotated around the origin. Co-authored-by: Abby Bryant <[email protected]> Co-authored-by: Jan Haller <[email protected]>
2 parents d0b59e5 + fa72097 commit f043159

File tree

1 file changed

+54
-2
lines changed

1 file changed

+54
-2
lines changed

gdnative-core/src/core_types/geom/transform2d.rs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ impl Transform2D {
7676
}
7777

7878
/// Constructs the transform from a given angle (in radians), translation, and scale.
79+
///
80+
/// # Deprecation
81+
/// This constructor has been deprecated due to the order of transformations applied deviate from one's expectations.
82+
/// Using a non-zero rotation will affect the resulting transform's origin.
83+
///
84+
/// Consider using [`Transform2D::from_scale_rotation_origin`] or applying transformations manually.
85+
#[deprecated = "Misleading behavior (see description); consider `from_scale_rotation_origin` or manual transformations."]
7986
#[inline]
8087
pub fn from_rotation_translation_scale(
8188
translation: Vector2,
@@ -88,6 +95,29 @@ impl Transform2D {
8895
.scaled(scale)
8996
}
9097

98+
/// Constructs the transform from a given scale, angle (in radians), and origin.
99+
///
100+
/// This is **NOT** equivalent to either of these two lines:
101+
/// ```ignore
102+
/// Transform2D::IDENTITY.scaled(scale).rotated(rotation).translated(origin)
103+
/// Transform2D::IDENTITY.translated(origin).rotated(rotation).scaled(scale)
104+
/// ```
105+
///
106+
/// Those transformations do not preserve the given origin; see documentation for [`rotated`], [`scaled`], and [`translated`].
107+
///
108+
/// [`rotated`]: Self::rotated
109+
/// [`scaled`]: Self::scaled
110+
/// [`translated`]: Self::translated
111+
#[inline]
112+
pub fn from_scale_rotation_origin(scale: Vector2, rotation: f32, origin: Vector2) -> Self {
113+
let mut tr = Self::IDENTITY;
114+
tr.set_scale(scale);
115+
tr.set_rotation(rotation);
116+
tr.origin = origin;
117+
118+
tr
119+
}
120+
91121
/// Returns the inverse of the transform, under the assumption that the transformation is composed of rotation, scaling and translation.
92122
#[inline]
93123
pub fn affine_inverse(&self) -> Self {
@@ -164,7 +194,7 @@ impl Transform2D {
164194
self.set_scale(scale);
165195
}
166196

167-
/// Rotates the transform by the given angle (in radians), using matrix multiplication.
197+
/// Rotates the transform by the given angle (in radians), using matrix multiplication. This will modify the transform's origin.
168198
#[inline]
169199
pub fn rotated(&self, rotation: f32) -> Self {
170200
let mut tr = Self::IDENTITY;
@@ -186,7 +216,7 @@ impl Transform2D {
186216
self.b = self.b.normalized() * scale.y;
187217
}
188218

189-
/// Scales the transform by the given scale factor, using matrix multiplication.
219+
/// Scales the transform by the given scale factor, using matrix multiplication. This will modify the transform's origin.
190220
#[inline]
191221
pub fn scaled(&self, scale: Vector2) -> Self {
192222
let mut new = *self;
@@ -445,3 +475,25 @@ godot_test!(
445475
test_transform2d_behavior_impl()
446476
}
447477
);
478+
479+
#[test]
480+
fn test_transform2d_constructor() {
481+
use std::f32::consts::PI;
482+
483+
let scale = Vector2::new(2.0, 0.5);
484+
let rotation = PI / 4.0;
485+
let origin = Vector2::new(250.0, 150.0);
486+
487+
let tr = Transform2D::from_scale_rotation_origin(scale, rotation, origin);
488+
489+
assert_eq!(tr.origin, origin);
490+
491+
let actual_local_right = tr.basis_xform(Vector2::RIGHT);
492+
let expected_local_right = Vector2::RIGHT.rotated(-rotation) * scale;
493+
assert!(
494+
actual_local_right.is_equal_approx(expected_local_right),
495+
"{:?} != {:?}",
496+
actual_local_right,
497+
expected_local_right
498+
);
499+
}

0 commit comments

Comments
 (0)