-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
Scale sprite z level by their scale #4156
Conversation
pub struct Transform2d { | ||
pub translation: Vec2, | ||
pub scale: Vec2, | ||
pub rotation: Quat, |
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.
it feels wrong to keep a Quat
for rotations, but I'm not sure if keeping only two axis of rotations would be enough here. I feel it would, which would probably make it faster?
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.
Don't we only need a single 2D rotation axis?
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.
heh 3d rotations in 2d are one of the things where I give up usually...
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 think we can use Quat::mul_vec3
with Vec3::X
, and truncate that. We then get the angle from that Vec2
, e.g. Vec2::angle_between
with Vec2::X
.
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 think we can use
Quat::mul_vec3
withVec3::X
that's exactly what local_x()
does, so it's simply
Vec2::X.angle_between(transform.local_x().truncate())
"Get the angle between the global x-axis and the local x unit-vector"
Are the numbers in the table linked above FPS? |
|
value += self.translation; | ||
value | ||
pub fn mul_vec3(&self, value: Vec3) -> Vec3 { | ||
self.rotation * self.scale * value + self.translation |
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.
self.rotation * self.scale * value + self.translation | |
self.scale * self.rotation * value + self.translation |
Let's keep the ordering consistent here.
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 sure those are commutatives. I added parentheses to make sure it happens in the right order
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.
Is this change necessary (turning the 3 lines into 1)? I would think the compiler optimises it to the same result, and the existing notation is a lot clearer about the order of operations imo.
Though mockersf is right, it definitely should be scale applied to value first, then multiplied by rotation, then lastly translation added. perhaps translation + rotation * (scale * value)
is nicer?
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 like to be clear that we're following SRT here: it's much cleaner at a glance if we're adding Translation
last.
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.
It's a matter of perspective I guess; If you were to consider Scale, Rotation, Translation as independent transformations that you compose like
translate(rotate(scale(value)))
Then it's a lot more visually similar imo, since the order of operations is
translation + (rotation * (scale * value))
It only looks inside out compared to the "SRT" acronym because the inner-most (farthest right) function is applied to the value first
crates/bevy_sprite/src/render/mod.rs
Outdated
pub rotation: Quat, | ||
} | ||
|
||
impl Transform2d { |
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.
There are a large number of convenience methods and conversions I would like for this, but IMO we should keep the scope of this PR small.
crates/bevy_sprite/src/render/mod.rs
Outdated
@@ -186,6 +187,20 @@ pub struct ExtractedSprite { | |||
pub flip_y: bool, | |||
} | |||
|
|||
#[derive(Clone, Copy)] | |||
pub struct Transform2d { |
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 feel quite strongly that this should be used in the public APIs for both UI and sprites, along with a public z-layer component. I'm not sure if this PR is the place for it though.
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 should be done in it's own PR to not go out of scope for this 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 renamed the struct to make it clear it is not to be used as a general Transform2d
So, as much as I desperately want "dedicated 2D coordinates in user-facing APIs", I don't think this PR is the place to make that change. It will require quite a bit of churn (and lots of convenience methods). I'd rather not block a serious performance win + bug fix on that; we can use the types defined here in |
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 perf changes seem good.
scale: transform.scale.truncate(), | ||
rotation: transform.rotation, | ||
}, | ||
z_layer: transform.translation.z * transform.scale.z, |
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.
z_layer: transform.translation.z * transform.scale.z, | |
z_layer: transform.translation.z, |
The sprite has 0 width, changing the depth here based on the scale doesn't make sense.
pub struct Transform2d { | ||
pub translation: Vec2, | ||
pub scale: Vec2, | ||
pub rotation: Quat, |
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 think we can use Quat::mul_vec3
with Vec3::X
, and truncate that. We then get the angle from that Vec2
, e.g. Vec2::angle_between
with Vec2::X
.
we should move to a more complete 2d Transform rather than a in between solution like this |
Objective
Solution
mul_vec2
to a single line has an impact, so I also changedmul_vec3
on transformsmany_sprites
bevymark 1300 100
bevymark 10000 100