-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Add mesh picking backend and MeshRayCast
system parameter
#15800
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
Conversation
Co-authored-by: Aevyrie <[email protected]>
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 is a bit of a drive-by review, but the summary of changes look great. Lots of things I haven't had the energy to clean up. :)
Thanks for your effort!
Release note candidate right there :D Seems useful too! |
Agreed, I'll add that! I've always though that example looks super cool :) (And I'll fix CI...) |
}); | ||
|
||
self.hits.retain(|(dist, _)| *dist <= nearest_blocking_hit); | ||
self.hits.sort_by_key(|(k, _)| *k); |
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 is also sort_unstable_by_key, but the docs say better performance isn't always the case 🤷 https://doc.rust-lang.org/std/vec/struct.Vec.html#method.sort_unstable_by_key
probably not worth worry about
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 familiar with the original bevy_mod_picking
, but this looks good to me. I do have some comments, but I don't think they should block this from being merged.
Reviewing this today. Have we benchmarked the changes from the "Optimize ray-AABB intersection" commit? They look reasonable but I'd like to know how much of an improvement they are before merging. |
@NthTensor Hard to get accurate traces on the overall effect, but with a simple benchmark for that function alone with 100,000 slightly randomized AABBs, I'm getting roughly a 15% improvement. (note that this bench currently includes creating the AABBs, but that's the same before and after) I did also briefly profile picking in the Caldera test scene with both the initial (roughly) one-to-one port, and the current version. Couldn't get entirely reliable results, but perf seemed to be basically identical. I think I might've slightly regressed some things (maybe removing Either way, I don't think performance is really a big concern here. In the Caldera scene, |
Looks great, that pretty much satisfies me. As a policy, I don't like merging things with the word "optimize" without some discussion of performance. |
Thank you to everyone involved with the authoring or reviewing of this PR! This work is relatively important and needs release notes! Head over to bevyengine/bevy-website#1723 if you'd like to help out. |
_Note from BD103: this PR was adopted from #16148. The majority of this PR's description is copied from the original._ # Objective Adds tests to cover various mesh picking cases and removes sources of panics. It should prevent users being able to trigger panics in `bevy_picking` code via bad mesh data such as #15891, and is a follow up to my comments in [#15800 (review)](#15800 (review)). This is motivated by #15979 ## Testing Adds 8 new tests to cover `ray_mesh_intersection` code. ## Changes from original PR I reverted the changes to the benchmarks, since that was the largest factor blocking it merging. I'll open a follow-up issue so that those benchmark changes can be implemented. --------- Co-authored-by: Trent <[email protected]>
Objective
Closes #15545.
bevy_picking
supports UI and sprite picking, but not mesh picking. Being able to pick meshes would be extremely useful for various games, tools, and our own examples, as well as scene editors and inspectors. So, we need a mesh picking backend!Luckily,
bevy_mod_picking
(whichbevy_picking
is based on) by @aevyrie already has a backend for it usingbevy_mod_raycast
. As a side product of adding mesh picking, we also get support for performing ray casts on meshes!Solution
Upstream a large chunk of the immediate-mode ray casting functionality from
bevy_mod_raycast
, and add a mesh picking backend based onbevy_mod_picking
. Huge thanks to @aevyrie who did all the hard work on these incredible crates!All meshes are pickable by default. Picking can be disabled for individual entities by adding
PickingBehavior::IGNORE
, like normal. Or, if you want mesh picking to be entirely opt-in, you can setMeshPickingBackendSettings::require_markers
totrue
and add aRayCastPickable
component to the desired camera and target entities.You can also use the new
MeshRayCast
system parameter to cast rays into the world manually:This is largely a direct port, but I did make several changes to match our APIs better, remove things we don't need or that I think are unnecessary, and do some general improvements to code quality and documentation.
Changes Relative to
bevy_mod_raycast
andbevy_mod_picking
Raycast
and "raycast" has been renamed toRayCast
and "ray cast" (similar reasoning as the "Naming" section in Ray Casting for Primitive Shapes #15724)Raycast
system param has been renamed toMeshRayCast
to avoid naming conflicts and to be explicit that it is not for collidersRaycastBackend
has been renamed toMeshPickingBackend
RayCastVisibility
variants are nowAny
,Visible
, andVisibleInView
instead ofIgnore
,MustBeVisible
, andMustBeVisibleAndInView
NoBackfaceCulling
has been renamed toRayCastBackfaces
, to avoid implying that it affects the rendering of backfaces for meshes (it doesn't)SimplifiedMesh
andRayCastBackfaces
live near other ray casting API types, not in their own 10 LoC moduleintersections
module, not split across several modulesIntersectionData
->RayMeshHit
RayHit
->RayTriangleHit
Removed / Not Ported
PrimitiveIntersection
2d
feature, andRaycast::mesh_query
andRaycast::mesh2d_query
have been merged intoMeshRayCast::mesh_query
, which handles both 2D and 3DMesh2dHandle
used to be inbevy_sprite
. Now both the 2D and 3D mesh are inbevy_render
.debug
feature or ray debug renderingRaycastSource
)CursorRayPlugin
(the picking backend handles this)Note for Reviewers
In case it's helpful, the first commit here is essentially a one-to-one port. The rest of the commits are primarily refactoring and cleaning things up in the ways listed earlier, as well as changes to the module structure.
It may also be useful to compare the original picking backend and
bevy_mod_raycast
to this PR. Feel free to mention if there are any changes that I should revert or something I should not include in this PR.Testing
I tested mesh picking and relevant components in some examples, for both 2D and 3D meshes, and added a new
mesh_picking
example. I alsostoleported over the ray-mesh intersection benchmark frombevy_mod_raycast
.Showcase
Below is a version of the
2d_shapes
example modified to demonstrate 2D mesh picking. This is not included in this PR.2024-10-09.23-17-54.mp4
And below is the new
mesh_picking
example:2024-10-09.23-56-20.mp4
There is also a really cool new
mesh_ray_cast
example ported over frombevy_mod_raycast
:2024-10-10.03-41-38.mp4