# Objective
- Fixes#18081
- Enable use-cases like getting UVs or texture colors for the hit point
(which are currently not possible due to this bug).
## Solution
- Return the triangle index instead of the first vertex index of the
triangle.
## Testing
Tested successfully with my project which does a raycast to get the UV
coordinates of the hit. My code:
```rust
fn get_uv(
mesh: &Mesh,
attribute: &MeshVertexAttribute,
hit: &RayMeshHit,
_gizmos: &mut Gizmos,
) -> Result<Vec2> {
let (a, b, c) = get_indices(mesh, hit)?;
let attrs = mesh
.attribute(*attribute)
.ok_or_eyre(format!("Attribute {:?} not found", &attribute))?;
let all_uvs: &Vec<[f32; 2]> = match &attrs {
VertexAttributeValues::Float32x2(positions) => positions,
_ => bail!("Unexpected types in {:?}", Mesh::ATTRIBUTE_UV_0),
};
let bary = hit.barycentric_coords;
Ok(Vec2::from_array(all_uvs[a]) * bary.x
+ Vec2::from_array(all_uvs[b]) * bary.y
+ Vec2::from_array(all_uvs[c]) * bary.z)
}
fn get_indices(mesh: &Mesh, hit: &RayMeshHit) -> Result<(usize, usize, usize)> {
let i = hit
.triangle_index
.ok_or_eyre("Intersection Index not found")?;
Ok(mesh.indices().map_or_else(
|| (i, i + 1, i + 2),
|indices| match indices {
Indices::U16(indices) => (
indices[i * 3] as usize,
indices[i * 3 + 1] as usize,
indices[i * 3 + 2] as usize,
),
Indices::U32(indices) => (
indices[i * 3] as usize,
indices[i * 3 + 1] as usize,
indices[i * 3 + 2] as usize,
),
},
))
}
```
PS: created a new PR because the old one was coming from and targeting
the wrong branches
# Objective
- #18495
## Solution
- The code in the PR #18232 accidentally used a vertex index as a
triangle index, causing the wrong triangle to be used for normal
computation and if the triangle went out of bounds, it would skip the
ray-hit.
- Don't do that.
## Testing
- Run `cargo run --example mesh_picking`
## Objective
Reduce dependencies on `bevy_render` by preferring `bevy_mesh` imports
over `bevy_render` re-exports.
```diff
- use bevy_render::mesh::Mesh;
+ use bevy_mesh::Mesh;
```
This is intended to help with #18423 (render crate restructure). Affects
`bevy_gltf`, `bevy_animation` and `bevy_picking`.
## But Why?
As part of #18423, I'm assuming there'll be a push to make crates less
dependent on the big render crates. This PR seemed like a small and safe
step along that path - it only changes imports and makes the `bevy_mesh`
crate dependency explicit in `Cargo.toml`. Any remaining dependencies on
`bevy_render` are true dependencies.
## Testing
```
cargo run --example testbed_3d
cargo run --example mesh_picking
```
# Objective
Now that #13432 has been merged, it's important we update our reflected
types to properly opt into this feature. If we do not, then this could
cause issues for users downstream who want to make use of
reflection-based cloning.
## Solution
This PR is broken into 4 commits:
1. Add `#[reflect(Clone)]` on all types marked `#[reflect(opaque)]` that
are also `Clone`. This is mandatory as these types would otherwise cause
the cloning operation to fail for any type that contains it at any
depth.
2. Update the reflection example to suggest adding `#[reflect(Clone)]`
on opaque types.
3. Add `#[reflect(clone)]` attributes on all fields marked
`#[reflect(ignore)]` that are also `Clone`. This prevents the ignored
field from causing the cloning operation to fail.
Note that some of the types that contain these fields are also `Clone`,
and thus can be marked `#[reflect(Clone)]`. This makes the
`#[reflect(clone)]` attribute redundant. However, I think it's safer to
keep it marked in the case that the `Clone` impl/derive is ever removed.
I'm open to removing them, though, if people disagree.
4. Finally, I added `#[reflect(Clone)]` on all types that are also
`Clone`. While not strictly necessary, it enables us to reduce the
generated output since we can just call `Clone::clone` directly instead
of calling `PartialReflect::reflect_clone` on each variant/field. It
also means we benefit from any optimizations or customizations made in
the `Clone` impl, including directly dereferencing `Copy` values and
increasing reference counters.
Along with that change I also took the liberty of adding any missing
registrations that I saw could be applied to the type as well, such as
`Default`, `PartialEq`, and `Hash`. There were hundreds of these to
edit, though, so it's possible I missed quite a few.
That last commit is **_massive_**. There were nearly 700 types to
update. So it's recommended to review the first three before moving onto
that last one.
Additionally, I can break the last commit off into its own PR or into
smaller PRs, but I figured this would be the easiest way of doing it
(and in a timely manner since I unfortunately don't have as much time as
I used to for code contributions).
## Testing
You can test locally with a `cargo check`:
```
cargo check --workspace --all-features
```
_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)](https://github.com/bevyengine/bevy/pull/15800#pullrequestreview-2361694213).
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 <2771466+tbillington@users.noreply.github.com>
# Objective
- Contributes to #11478
## Solution
- Made `bevy_utils::tracing` `doc(hidden)`
- Re-exported `tracing` from `bevy_log` for end-users
- Added `tracing` directly to crates that need it.
## Testing
- CI
---
## Migration Guide
If you were importing `tracing` via `bevy::utils::tracing`, instead use
`bevy::log::tracing`. Note that many items within `tracing` are also
directly re-exported from `bevy::log` as well, so you may only need
`bevy::log` for the most common items (e.g., `warn!`, `trace!`, etc.).
This also applies to the `log_once!` family of macros.
## Notes
- While this doesn't reduce the line-count in `bevy_utils`, it further
decouples the internal crates from `bevy_utils`, making its eventual
removal more feasible in the future.
- I have just imported `tracing` as we do for all dependencies. However,
a workspace dependency may be more appropriate for version management.
# Objective
The `RayCastSettings` type is only used in the context of ray casts with
the `MeshRayCast` system parameter. The current name is somewhat
inconsistent with other existing types, like `MeshRayCast` and
`MeshPickingSettings`, but more importantly, it easily conflicts with
physics, and forces those crates to opt for some other name like
`RayCastConfig` or `RayCastOptions`.
We should rename `RayCastSettings` to `MeshRayCastSettings` to avoid
naming conflicts and improve consistency.
## Solution
Rename `RayCastSettings` to `MeshRayCastSettings`.
---
## Migration Guide
`RayCastSettings` has been renamed to `MeshRayCastSettings` to avoid
naming conflicts with other ray casting backends and types.
# Objective
The "mehses" typo introduced in a review comment
[here](https://github.com/bevyengine/bevy/pull/16657#discussion_r1870834999)
hurts my soul, it was merged right as I was about to comment about it :(
## Solution
Fix it :D
(also, why didn't the CI typo checker catch this?)
# Objective
- This fixes raycast picking with lyon
- reverse winding of 2D meshes currently results in them being rendered
but not pickable as the raycast passes through the backface and would
only hit "from below"
## Solution
- Disables backface culling for Mesh2d
## Testing
- Tested picking with bevy_prototype_lyon
- Could probably use testing with Mesh3d (should not be affected) and
SimplifiedMesh (no experience with that, could have the same issue if
used for 2D?)
---------
Co-authored-by: Aevyrie <aevyrie@gmail.com>
# Objective
- Mesh picking is noisy when a non triangle list is used
- Mesh picking runs even when users don't need it
- Resolve#16065
## Solution
- Don't add the mesh picking plugin by default
- Remove error spam
# 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`](https://github.com/aevyrie/bevy_mod_picking) (which
`bevy_picking` is based on) by @aevyrie already has a [backend for
it](74f0c3c0fb/backends/bevy_picking_raycast/src/lib.rs)
using [`bevy_mod_raycast`](https://github.com/aevyrie/bevy_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 on
`bevy_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 set
`MeshPickingBackendSettings::require_markers` to `true` and add a
`RayCastPickable` component to the desired camera and target entities.
You can also use the new `MeshRayCast` system parameter to cast rays
into the world manually:
```rust
fn ray_cast_system(mut ray_cast: MeshRayCast, foo_query: Query<(), With<Foo>>) {
let ray = Ray3d::new(Vec3::ZERO, Dir3::X);
// Only ray cast against entities with the `Foo` component.
let filter = |entity| foo_query.contains(entity);
// Never early-exit. Note that you can change behavior per-entity.
let early_exit_test = |_entity| false;
// Ignore the visibility of entities. This allows ray casting hidden entities.
let visibility = RayCastVisibility::Any;
let settings = RayCastSettings::default()
.with_filter(&filter)
.with_early_exit_test(&early_exit_test)
.with_visibility(visibility);
// Cast the ray with the settings, returning a list of intersections.
let hits = ray_cast.cast_ray(ray, &settings);
}
```
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` and `bevy_mod_picking`
- Every `Raycast` and "raycast" has been renamed to `RayCast` and "ray
cast" (similar reasoning as the "Naming" section in #15724)
- `Raycast` system param has been renamed to `MeshRayCast` to avoid
naming conflicts and to be explicit that it is not for colliders
- `RaycastBackend` has been renamed to `MeshPickingBackend`
- `RayCastVisibility` variants are now `Any`, `Visible`, and
`VisibleInView` instead of `Ignore`, `MustBeVisible`, and
`MustBeVisibleAndInView`
- `NoBackfaceCulling` has been renamed to `RayCastBackfaces`, to avoid
implying that it affects the rendering of backfaces for meshes (it
doesn't)
- `SimplifiedMesh` and `RayCastBackfaces` live near other ray casting
API types, not in their own 10 LoC module
- All intersection logic and types are in the same `intersections`
module, not split across several modules
- Some intersection types have been renamed to be clearer and more
consistent
- `IntersectionData` -> `RayMeshHit`
- `RayHit` -> `RayTriangleHit`
- General documentation and code quality improvements
### Removed / Not Ported
- Removed unused ray helpers and types, like `PrimitiveIntersection`
- Removed getters on intersection types, and made their properties
public
- There is no `2d` feature, and `Raycast::mesh_query` and
`Raycast::mesh2d_query` have been merged into `MeshRayCast::mesh_query`,
which handles both 2D and 3D
- I assume this existed previously because `Mesh2dHandle` used to be in
`bevy_sprite`. Now both the 2D and 3D mesh are in `bevy_render`.
- There is no `debug` feature or ray debug rendering
- There is no deferred API (`RaycastSource`)
- There is no `CursorRayPlugin` (the picking backend handles this)
### Note for Reviewers
In case it's helpful, the [first
commit](281638ef10)
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](74f0c3c0fb/backends/bevy_picking_raycast/src/lib.rs)
and [`bevy_mod_raycast`](https://github.com/aevyrie/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 also
~~stole~~ ported over the [ray-mesh intersection
benchmark](dbc5ef32fe/benches/ray_mesh_intersection.rs)
from `bevy_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.
https://github.com/user-attachments/assets/7742528c-8630-4c00-bacd-81576ac432bf
And below is the new `mesh_picking` example:
https://github.com/user-attachments/assets/b65c7a5a-fa3a-4c2d-8bbd-e7a2c772986e
There is also a really cool new `mesh_ray_cast` example ported over from
`bevy_mod_raycast`:
https://github.com/user-attachments/assets/3c5eb6c0-bd94-4fb0-bec6-8a85668a06c9
---------
Co-authored-by: Aevyrie <aevyrie@gmail.com>
Co-authored-by: Trent <2771466+tbillington@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>