aevyrie / bevy_mod_picking

Picking and pointer events for Bevy.
https://crates.io/crates/bevy_mod_picking
Apache License 2.0
764 stars 170 forks source link

Sprite backend improvements #354

Open jnhyatt opened 1 month ago

jnhyatt commented 1 month ago

Sprite backend was not reporting world position or normal for hits. Upon further investigation I found that the backend was also not correctly hit testing sprites if they had rotation about any axis other than the Z axis. This was producing some very surprising results in some cases (i.e. reported hits weren't even close to the sprites).

This pr fixes both of these issues: sprite hits are now determined by intersecting the sprite's bounding rect with a 3d line segment extending from (cursor_x, cursor_y, near_clip) and (cursor_x, cursor_y, far_clip). This should return correct results for any arbitrary sprite transform. Hit position and normal are now being populated as well.

One question I have about the impl is whether backends are supposed to return hits in any particular order. Before, depth was being determined by sprite's Z coordinate, but since sprites now support arbitrary rotations, it's possible that a sprite with a deeper Z value could be picked in front of another. Does that mean that the hits should be sorted after hits are collected? And if so, does that mean that the sprite sorting that happens before the hit-testing can/should be removed?

aevyrie commented 1 month ago

The answers to your questions are documented here: https://docs.rs/bevy_mod_picking/latest/bevy_mod_picking/backend/struct.PointerHits.html#structfield.picks

An unordered collection of entities and their distance (depth) from the cursor.

and here: https://docs.rs/bevy_mod_picking/latest/bevy_mod_picking/backend/struct.HitData.html#structfield.depth.html

depth only needs to be self-consistent with other PointerHitss using the same RenderTarget. However, it is recommended to use the distance from the pointer to the hit, measured from the near plane of the camera, to the point, in world space.