You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Create new trait `XformInv<...>`.
- Implement `XformInv<Rect2/Vector2>` for `Transform2D` and `Transform2D::basis_xform_inv`.
- Implement `XformInv<Aabb/Plane/Vector3>` for `Transform3D` and `XformInv<Vector3>` for `Basis`.
- Document transform/basis operations.
@@ -629,6 +629,24 @@ impl Mul<Vector3> for Basis {
629
629
}
630
630
}
631
631
632
+
implXformInv<Vector3>forBasis{
633
+
/// Inversely transforms given [`Vector3`] by this basis,
634
+
/// under the assumption that the basis is orthonormal (i.e. rotation/reflection is fine, scaling/skew is not).
635
+
///
636
+
/// `basis.xform_inv(vector)` is equivalent to `basis.transposed() * vector`. See [`Basis::transposed()`].
637
+
///
638
+
/// For transforming by inverse of a non-orthonormal basis (e.g. with scaling) `basis.inverse() * vector` can be used instead. See [`Basis::inverse()`].
639
+
///
640
+
/// _Godot equivalent: `vector * basis`_
641
+
fnxform_inv(&self,rhs:Vector3) -> Vector3{
642
+
Vector3::new(
643
+
self.col_a().dot(rhs),
644
+
self.col_b().dot(rhs),
645
+
self.col_c().dot(rhs),
646
+
)
647
+
}
648
+
}
649
+
632
650
// SAFETY:
633
651
// This type is represented as `Self` in Godot, so `*mut Self` is sound.
@@ -349,6 +358,19 @@ impl Mul<Vector2> for Transform2D {
349
358
}
350
359
}
351
360
361
+
implXformInv<Vector2>forTransform2D{
362
+
/// Inversely transforms (multiplies) the given [`Vector2`] by this transformation matrix,
363
+
/// under the assumption that the transformation basis is orthonormal (i.e. rotation/reflection is fine, scaling/skew is not).
364
+
///
365
+
/// For transforming by inverse of an affine transformation (e.g. with scaling) `transform.affine_inverse() * vector` can be used instead. See: [`Transform2D::affine_inverse()`].
366
+
///
367
+
/// _Godot equivalent: `vector * transform` or `transform.inverse() * vector`_
368
+
fnxform_inv(&self,rhs:Vector2) -> Vector2{
369
+
let v = rhs - self.origin;
370
+
self.basis_xform_inv(v)
371
+
}
372
+
}
373
+
352
374
implMul<real>forTransform2D{
353
375
typeOutput = Self;
354
376
@@ -370,9 +392,41 @@ impl Mul<Rect2> for Transform2D {
370
392
let ya = self.b* rhs.position.y;
371
393
let yb = self.b* rhs.end().y;
372
394
373
-
let position = Vector2::coord_min(xa, xb) + Vector2::coord_min(ya, yb) + self.origin;
374
-
let end = Vector2::coord_max(xa, xb) + Vector2::coord_max(ya, yb) + self.origin;
375
-
Rect2::new(position, end - position)
395
+
let position = Vector2::coord_min(xa, xb) + Vector2::coord_min(ya, yb);
396
+
let end = Vector2::coord_max(xa, xb) + Vector2::coord_max(ya, yb);
397
+
Rect2::new(position + self.origin, end - position)
398
+
}
399
+
}
400
+
401
+
implXformInv<Rect2>forTransform2D{
402
+
/// Inversely transforms (multiplies) the given [`Rect2`] by this [`Transform2D`] transformation matrix, under the assumption that the transformation basis is orthonormal (i.e. rotation/reflection is fine, scaling/skew is not).
403
+
///
404
+
/// For transforming by inverse of an affine transformation (e.g. with scaling) `transform.affine_inverse() * vector` can be used instead. See: [`Transform2D::affine_inverse()`].
405
+
///
406
+
/// _Godot equivalent: `rect2 * transform` or `transform.inverse() * rect2`_
@@ -303,6 +312,19 @@ impl Mul<Vector3> for Transform3D {
303
312
}
304
313
}
305
314
315
+
implXformInv<Vector3>forTransform3D{
316
+
/// Inversely transforms given [`Vector3`] by this transformation matrix,
317
+
/// under the assumption that the transformation basis is orthonormal (i.e. rotation/reflection is fine, scaling/skew is not).
318
+
///
319
+
/// For transforming by inverse of an affine transformation (e.g. with scaling) `transform.affine_inverse() * vector` can be used instead. See [`Transform3D::affine_inverse()`].
320
+
///
321
+
/// _Godot equivalent: `aabb * transform`_
322
+
fnxform_inv(&self,rhs:Vector3) -> Vector3{
323
+
let v = rhs - self.origin;
324
+
self.basis.xform_inv(v)
325
+
}
326
+
}
327
+
306
328
implMul<real>forTransform3D{
307
329
typeOutput = Self;
308
330
@@ -342,6 +364,55 @@ impl Mul<Aabb> for Transform3D {
342
364
}
343
365
}
344
366
367
+
implXformInv<Aabb>forTransform3D{
368
+
/// Inversely transforms each vertex in given [`Aabb`] individually by this transformation matrix,
369
+
/// under the assumption that the transformation basis is orthonormal (i.e. rotation/reflection is fine, scaling/skew is not),
370
+
/// and then creates an `Aabb` encompassing all of them.
371
+
///
372
+
/// For transforming by inverse of an affine transformation (e.g. with scaling) `transform.affine_inverse() * aabb` can be used instead. See [`Transform3D::affine_inverse()`].
373
+
///
374
+
/// _Godot equivalent: `aabb * transform`_
375
+
fnxform_inv(&self,rhs:Aabb) -> Aabb{
376
+
// Same as Godot's `Transform3D::xform_inv` but omits unnecessary `Aabb::expand_to`.
377
+
// There is probably some more clever way to do that.
378
+
379
+
// Use the first vertex initialize our min/max.
380
+
let end = self.xform_inv(rhs.end());
381
+
// `min` is the "lowest" vertex of our Aabb, `max` is the farthest vertex.
0 commit comments