-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add scale_around_center
method to BoundingVolume
trait
#12142
Conversation
Welcome, new contributor! Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨ |
Nice docs and tests :) Thanks! |
This looks good implementation-wise, but we might need to think more about what the scaling should actually do. This scales bounding volumes in each direction relative to their centers, right? So the center remains the same, but just the size changes. The Parry collision detection library actually scales the min and max of AABBs directly, which also affects the center (this is consistent with how rotation for bounding volumes works, see #11681). I believe one reason for doing scaling like that is that you can e.g. scale entire Bounding Volume Hierarchies without having to separately scale the AABB sizes and center coordinates. BVHs can even be used to accelerate colliders like polylines and trimeshes, and scaling them requires scaling the BVH, which in turn requires scaling the center coordinates of the bounding volumes. The kind of scaling in this PR isn't generally as useful in my opinion; if you want to expand AABBs for e.g. speculative contacts or CCD, you'd typically want to expand them by a specific amount, and we have |
Jolt also scales min and max separately: https://github.com/jrouwe/JoltPhysics/blob/17d727a8d02b5e82ab8cc89b7cd0967f4a9fe61d/Jolt/Geometry/AABox.h#L214 |
The meaning of "scale" is controversial. |
For scaling with respect to the center, you can also just do this: I haven't seen any libraries with scaling wrt the center yet, but if we do want a separate method for it, some naming ideas:
|
|
I agree the naming isn't precise. Renaming fn scale(&self, scale: Self::HalfSize, point: Self::Position) {
let b = Self {
min: (self.min - point) * scale + point,
max: (self.max - point) * scale + point,
};
debug_assert!(b.min.x <= b.max.x && b.min.y <= b.max.y);
b
} would work. In this way, we could also have the component-wise scaling mentioned by @Jondolf, by choosing to scale around zero. My only issue is that I'm not really sure this makes sense for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few suggestions, otherwise everything looks good in terms of code.
Personally, "scaling around X" sounds kind of weird to me, since "around" often implies some kind of rotational or orbiting motion like in the case of Transform::translate_around
and Transform::rotate_around
. This is why I'm not 100% sold on the name scale_around_center
. But I don't have a clear favorite in terms of naming, so I probably wouldn't block over it
Self { | ||
center: self.center, | ||
sphere: Sphere { | ||
radius: self.radius() * scale, | ||
}, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be cleaner and what the BoundingCircle
version already does
Self { | |
center: self.center, | |
sphere: Sphere { | |
radius: self.radius() * scale, | |
}, | |
} | |
Self::new(self.center, self.radius() * scale) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I think I missed this since grow
and shrink
don't use Self::new
.
crates/bevy_math/src/bounding/mod.rs
Outdated
@@ -43,6 +43,9 @@ pub trait BoundingVolume { | |||
|
|||
/// Decrease the size of the bounding volume in each direction by the given amount | |||
fn shrink(&self, amount: Self::HalfSize) -> Self; | |||
|
|||
/// Scale the size of the bounding volume around the center by the given amount |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"the center" could be confused with the global origin, i.e. (0, 0, 0). It should explicitly refer to the center of the bounding volume.
/// Scale the size of the bounding volume around the center by the given amount | |
/// Scale the size of the bounding volume around its center by the given amount |
assert!((scaled.min - Vec2::new(-2., -2.)).length() < std::f32::EPSILON); | ||
assert!((scaled.max - Vec2::new(2., 2.)).length() < std::f32::EPSILON); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a matter of preference, but you can use splat
when every element is the same
assert!((scaled.min - Vec2::new(-2., -2.)).length() < std::f32::EPSILON); | |
assert!((scaled.max - Vec2::new(2., 2.)).length() < std::f32::EPSILON); | |
assert!((scaled.min - Vec2::splat(-2.)).length() < std::f32::EPSILON); | |
assert!((scaled.max - Vec2::splat(2.)).length() < std::f32::EPSILON); |
same for 3D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I followed the style choices for the above tests here, since they choose to not use splat
. There's a mix of both though overall, and I think I also prefer splat
.
min: Vec2::new(-1., -1.), | ||
max: Vec2::new(1., 1.), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly to the previous comment, there are constants for this:
min: Vec2::new(-1., -1.), | |
max: Vec2::new(1., 1.), | |
min: Vec2::NEG_ONE, | |
max: Vec2::ONE, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not fully sold on the name scale_around_center
(see my comment #12142 (review)), but I don't have a clearly better suggestion right now and the code looks good, so I'm content with this. We can always rename later if a better name pops up.
Note: You should probably update the PR title and description to match the new name :)
scale
method to BoundingVolume
traitscale_around_center
method to BoundingVolume
trait
Code looks good but I'd like to understand the motivation before I approve. What's the use-case for this? |
@NthTensor In my use case, I need to scale the y-direction of a 2D bullet asset's
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I think this is worth adding.scale_around_center
name seems pretty clear. Nice tests!
@chompaa once you've resolved merge conflicts I'll merge this in :) |
@alice-i-cecile All should be good now :) |
Awesome thanks. I tried doing this on the web client and git was very confused about the |
Objective
Add a
scale_around_center
method to theBoundingVolume
trait, as per #12130.Solution
Added
scale_around_center
to theBoundingVolume
trait, implemented inAabb2d
,Aabb3d
,BoundingCircle
, andBoundingSphere
(with tests).