Skip to content
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

Picking backend for bevy 0.15 #613

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e79b691
update bevy to 0.15, commenting out bevy_egui
Vrixyz Oct 31, 2024
7c29a87
fix tests
Vrixyz Nov 5, 2024
8dc9d5f
re-enable inspector
Vrixyz Nov 7, 2024
41bc2f3
fix fmt
Vrixyz Nov 7, 2024
61d3ef2
fix warning
Vrixyz Nov 8, 2024
293d4e3
fix warning
Vrixyz Nov 27, 2024
77b7591
wip
Vrixyz Nov 27, 2024
2005e67
working example + naming polish
Vrixyz Nov 28, 2024
de8dcce
consider visibility + settings options
Vrixyz Nov 28, 2024
c8edd27
clean comments + rename some code + fix clippy + CI
Vrixyz Nov 28, 2024
9fe001a
uncomment picking feature gate
Vrixyz Dec 4, 2024
58d2bf0
Merge remote-tracking branch 'upstream' into picking_backend
Vrixyz Dec 9, 2024
7fc9907
uncomment egui code
Vrixyz Dec 9, 2024
b418dc1
reorganize folders to separate picking backend
Vrixyz Dec 9, 2024
8ec684a
add changelog line + adapt docs
Vrixyz Dec 9, 2024
d4ac95f
Merge remote-tracking branch 'upstream' into picking_backend
Vrixyz Dec 10, 2024
6592106
adapt API to split rapier context
Vrixyz Dec 10, 2024
3e9bdbb
Merge remote-tracking branch 'upstream' into picking_backend
Vrixyz Dec 27, 2024
8045cd4
picking backend feature promoted to default
Vrixyz Jan 6, 2025
76f046c
update rapier to 0.23
Vrixyz Jan 14, 2025
62d6033
fix tests + add unit tests without default features in CI
Vrixyz Jan 15, 2025
71a0533
fix cargo doc ; speed up ci doc to run without deps
Vrixyz Jan 15, 2025
acf6a50
removed --lib tests from ci because now part of #626
Vrixyz Jan 15, 2025
5210eb8
remove headless plugin in favor of adding expected plugins in finish().
Vrixyz Jan 16, 2025
d0bbbfb
fix runtime async collider test
Vrixyz Jan 21, 2025
94fce92
Merge branch 'rapier_0.23' into picking_backend
Vrixyz Jan 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
with:
prefix-key: ${{ env.RUST_CACHE_KEY }}
- name: Cargo doc
run: cargo doc
run: cargo doc --no-deps
test:
runs-on: ubuntu-latest
env:
Expand All @@ -51,9 +51,9 @@ jobs:
- name: Clippy for bevy_rapier3d
run: cargo clippy --verbose -p bevy_rapier3d
- name: Clippy for bevy_rapier2d (debug-render, simd, serde)
run: cargo clippy --verbose -p bevy_rapier2d --features debug-render-2d,simd-stable,serde-serialize
run: cargo clippy --verbose -p bevy_rapier2d --features debug-render-2d,simd-stable,serde-serialize,picking-backend
- name: Clippy for bevy_rapier3d (debug-render, simd, serde)
run: cargo clippy --verbose -p bevy_rapier3d --features debug-render-3d,simd-stable,serde-serialize
run: cargo clippy --verbose -p bevy_rapier3d --features debug-render-3d,simd-stable,serde-serialize,picking-backend
- name: Test for bevy_rapier2d
run: cargo test --verbose -p bevy_rapier2d
- name: Test for bevy_rapier3d
Expand All @@ -72,6 +72,6 @@ jobs:
with:
prefix-key: ${{ env.RUST_CACHE_KEY }}
- name: Clippy bevy_rapier2d
run: cd bevy_rapier2d && cargo clippy --verbose --features wasm-bindgen,bevy/webgl2 --target wasm32-unknown-unknown
run: cd bevy_rapier2d && cargo clippy --verbose --features bevy/webgl2 --target wasm32-unknown-unknown
- name: Clippy bevy_rapier3d
run: cd bevy_rapier3d && cargo clippy --verbose --features wasm-bindgen,bevy/webgl2 --target wasm32-unknown-unknown
run: cd bevy_rapier3d && cargo clippy --verbose --features bevy/webgl2 --target wasm32-unknown-unknown
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Unreleased

### Added

- Added optional feature `picking-backend` to support bevy_picking.
- See `picking_backend` module documentation for more details.

### Modified

- `RapierContext` has been split in multiple `Component`s:
Expand Down
13 changes: 9 additions & 4 deletions bevy_rapier2d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ rust.unexpected_cfgs = { level = "warn", check-cfg = [
clippy = { needless_lifetimes = "allow" }

[features]
default = ["dim2", "async-collider", "debug-render-2d"]
default = ["dim2", "async-collider", "debug-render-2d", "picking-backend"]
dim2 = []
debug-render-2d = [
"bevy/bevy_core_pipeline",
Expand All @@ -45,16 +45,21 @@ rapier-debug-render = ["rapier2d/debug-render"]
parallel = ["rapier2d/parallel"]
simd-stable = ["rapier2d/simd-stable"]
simd-nightly = ["rapier2d/simd-nightly"]
wasm-bindgen = ["rapier2d/wasm-bindgen"]
serde-serialize = ["rapier2d/serde-serialize", "bevy/serialize", "serde"]
enhanced-determinism = ["rapier2d/enhanced-determinism"]
headless = []
async-collider = ["bevy/bevy_asset", "bevy/bevy_scene", "bevy/bevy_render"]
picking-backend = ["bevy/bevy_picking"]
async-collider = [
"bevy/bevy_asset",
"bevy/bevy_scene",
"bevy/bevy_render",
"bevy/bevy_image",
]

[dependencies]
bevy = { version = "0.15", default-features = false }
nalgebra = { version = "0.33", features = ["convert-glam029"] }
rapier2d = "0.22"
rapier2d = "0.23"
bitflags = "2.4"
log = "0.4"
serde = { version = "1", features = ["derive"], optional = true }
Expand Down
25 changes: 20 additions & 5 deletions bevy_rapier3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ rust.unexpected_cfgs = { level = "warn", check-cfg = [
clippy = { needless_lifetimes = "allow" }

[features]
default = ["dim3", "async-collider", "debug-render-3d"]
default = ["dim3", "async-collider", "debug-render-3d", "picking-backend"]
dim3 = []
debug-render = ["debug-render-3d"]
debug-render-2d = [
Expand All @@ -46,16 +46,21 @@ rapier-debug-render = ["rapier3d/debug-render"]
parallel = ["rapier3d/parallel"]
simd-stable = ["rapier3d/simd-stable"]
simd-nightly = ["rapier3d/simd-nightly"]
wasm-bindgen = ["rapier3d/wasm-bindgen"]
serde-serialize = ["rapier3d/serde-serialize", "bevy/serialize", "serde"]
enhanced-determinism = ["rapier3d/enhanced-determinism"]
headless = []
async-collider = ["bevy/bevy_asset", "bevy/bevy_scene", "bevy/bevy_render"]
picking-backend = ["bevy/bevy_picking"]
async-collider = [
"bevy/bevy_asset",
"bevy/bevy_scene",
"bevy/bevy_render",
"bevy/bevy_image",
]

[dependencies]
bevy = { version = "0.15", default-features = false }
nalgebra = { version = "0.33", features = ["convert-glam029"] }
rapier3d = "0.22"
rapier3d = "0.23"
bitflags = "2.4"
log = "0.4"
serde = { version = "1", features = ["derive"], optional = true }
Expand All @@ -67,6 +72,9 @@ bevy = { version = "0.15", default-features = false, features = [
"tonemapping_luts",
"bevy_state",
"bevy_debug_stepping",
"bevy_text",
"bevy_ui",
"default_font",
] }
approx = "0.5.1"
glam = { version = "0.29", features = ["approx"] }
Expand All @@ -75,4 +83,11 @@ bevy_egui = "0.31"

[package.metadata.docs.rs]
# Enable all the features when building the docs on docs.rs
features = ["debug-render-3d", "serde-serialize"]

[[example]]
name = "picking3"
required-features = ["picking-backend"]

[[example]]
name = "testbed3"
required-features = ["picking-backend"]
100 changes: 100 additions & 0 deletions bevy_rapier3d/examples/picking3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//! A simple scene to demonstrate picking events for rapier [`Collider`] entities.

use bevy::prelude::*;
use bevy_rapier3d::prelude::*;

fn main() {
App::new()
.add_plugins((
DefaultPlugins,
RapierPhysicsPlugin::<NoUserData>::default(),
RapierDebugRenderPlugin::default(),
RapierPickingPlugin::default(),
))
.insert_resource(RapierPickingSettings {
// Optional: only needed when you want fine-grained control
// over which cameras and entities should be used with the rapier picking backend.
// This is disabled by default, and no marker components are required on cameras or colliders.
// This resource is inserted by default,
// you only need to add it if you want to override the default settings.
require_markers: true,
..Default::default()
})
.add_systems(Startup, (setup_graphics, setup_physics))
.run();
}

pub fn setup_graphics(mut commands: Commands) {
// Camera
commands.spawn((
Camera3d::default(),
Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
RapierPickable,
));
}

pub fn setup_physics(mut commands: Commands) {
commands
.spawn((
Text::new("Click Me to get a box\nDrag cubes to rotate"),
Node {
position_type: PositionType::Absolute,
top: Val::Percent(12.0),
left: Val::Percent(12.0),
..default()
},
))
.observe(on_click_spawn_cube)
.observe(
|out: Trigger<Pointer<Out>>, mut texts: Query<&mut TextColor>| {
let mut text_color = texts.get_mut(out.entity()).unwrap();
text_color.0 = Color::WHITE;
},
)
.observe(
|over: Trigger<Pointer<Over>>, mut texts: Query<&mut TextColor>| {
let mut color = texts.get_mut(over.entity()).unwrap();
color.0 = bevy::color::palettes::tailwind::CYAN_400.into();
},
);
// Base
let ground_size = 3.1;
let ground_height = 0.1;
commands.spawn((
Transform::from_xyz(0.0, -ground_height / 2.0, 0.0),
Collider::cuboid(ground_size, ground_height, ground_size),
ColliderDebugColor(Hsla::BLACK),
));
}

fn on_click_spawn_cube(
_click: Trigger<Pointer<Click>>,
mut commands: Commands,
mut num: Local<usize>,
) {
let rad = 0.25;
let colors = [
Hsla::hsl(220.0, 1.0, 0.3),
Hsla::hsl(180.0, 1.0, 0.3),
Hsla::hsl(260.0, 1.0, 0.7),
];
commands
.spawn((
Transform::from_xyz(0.0, 0.25 + 0.55 * *num as f32, 0.0),
Visibility::default(),
RigidBody::Dynamic,
Collider::cuboid(rad, rad, rad),
ColliderDebugColor(colors[*num % 3]),
RapierPickable,
))
// With the RapierPickingPlugin added, you can add pointer event observers to colliders:
.observe(on_drag_rotate);
*num += 1;
}

fn on_drag_rotate(drag: Trigger<Pointer<Drag>>, mut transforms: Query<&mut Transform>) {
if let Ok(mut transform) = transforms.get_mut(drag.entity()) {
transform.rotate_y(drag.delta.x * 0.02);
transform.rotate_x(drag.delta.y * 0.02);
}
}
4 changes: 2 additions & 2 deletions bevy_rapier3d/examples/static_trimesh3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub fn setup_physics(mut commands: Commands, mut ball_state: ResMut<BallState>)
indices.push([2 * i + 2, 2 * i + 1, 2 * i + 3]);
}

commands.spawn(Collider::trimesh(vertices, indices));
commands.spawn(Collider::trimesh(vertices, indices).unwrap());

// Create a bowl with a cosine cross-section,
// so that we can join the end of the ramp smoothly
Expand Down Expand Up @@ -97,7 +97,7 @@ pub fn setup_physics(mut commands: Commands, mut ball_state: ResMut<BallState>)
-bowl_size.y / 2.0,
bowl_size.z / 2.0 - ramp_size.z / 2.0,
),
Collider::trimesh(vertices, indices),
Collider::trimesh(vertices, indices).unwrap(),
));
}

Expand Down
11 changes: 11 additions & 0 deletions bevy_rapier3d/examples/testbed3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod joints3;
mod joints_despawn3;
mod locked_rotations3;
mod multiple_colliders3;
mod picking3;
mod ray_casting3;
mod static_trimesh3;

Expand All @@ -28,6 +29,7 @@ pub enum Examples {
JointsDespawn3,
LockedRotations3,
MultipleColliders3,
Picking3,
Raycasting3,
StaticTrimesh3,
}
Expand Down Expand Up @@ -64,6 +66,7 @@ fn main() {
RapierPhysicsPlugin::<NoUserData>::default(),
RapierDebugRenderPlugin::default(),
WorldInspectorPlugin::new(),
RapierPickingPlugin::default(),
))
.register_type::<Examples>()
.register_type::<ExamplesRes>()
Expand All @@ -78,6 +81,7 @@ fn main() {
(Examples::JointsDespawn3, "JointsDespawn3").into(),
(Examples::LockedRotations3, "LockedRotations3").into(),
(Examples::MultipleColliders3, "MultipleColliders3").into(),
(Examples::Picking3, "Picking3").into(),
(Examples::Raycasting3, "Raycasting3").into(),
(Examples::StaticTrimesh3, "StaticTrimesh3").into(),
]))
Expand Down Expand Up @@ -173,6 +177,13 @@ fn main() {
)
.add_systems(OnExit(Examples::MultipleColliders3), cleanup)
//
// picking
.add_systems(
OnEnter(Examples::Picking3),
(picking3::setup_graphics, picking3::setup_physics),
)
.add_systems(OnExit(Examples::Picking3), cleanup)
//
// raycasting
.add_systems(
OnEnter(Examples::Raycasting3),
Expand Down
2 changes: 1 addition & 1 deletion bevy_rapier_benches3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rapier3d = { features = ["profiler"], version = "0.22" }
rapier3d = { features = ["profiler"], version = "0.23" }
bevy_rapier3d = { version = "0.28", path = "../bevy_rapier3d" }
bevy = { version = "0.15", default-features = false }

Expand Down
12 changes: 8 additions & 4 deletions bevy_rapier_benches3d/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,25 @@ pub fn custom_bencher(steps: usize, setup: impl Fn(&mut App)) {
timer_full_update.start();
app.update();
timer_full_update.pause();
let elapsed_time = timer_full_update.time() as f32;
let elapsed_time = timer_full_update.time().as_millis();
let rc = app
.world_mut()
.query::<&RapierContextSimulation>()
.single(app.world());
rapier_step_times.push(rc.pipeline.counters.step_time.time() as f32);
rapier_step_times.push(rc.pipeline.counters.step_time.time().as_millis() as f32);
total_update_times.push(elapsed_time);
}
timer_total.pause();
let average_total = total_update_times.iter().sum::<f32>() / total_update_times.len() as f32;
let average_total = total_update_times
.iter()
.map(|time| *time as f32)
.sum::<f32>()
/ total_update_times.len() as f32;
println!("average total time: {} ms", average_total);
let average_rapier_step =
rapier_step_times.iter().sum::<f32>() / rapier_step_times.len() as f32;
println!("average rapier step time: {} ms", average_rapier_step);
let average_rapier_overhead = average_total - average_rapier_step;
println!("average bevy overhead: {} ms", average_rapier_overhead);
println!("total time: {} ms", timer_total.time());
println!("total time: {} ms", timer_total.time().as_millis());
}
19 changes: 12 additions & 7 deletions src/geometry/collider_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,12 @@ impl Collider {
}

/// Initializes a collider with a triangle mesh shape defined by its vertex and index buffers.
pub fn trimesh(vertices: Vec<Vect>, indices: Vec<[u32; 3]>) -> Self {
pub fn trimesh(
vertices: Vec<Vect>,
indices: Vec<[u32; 3]>,
) -> Result<Self, crate::rapier::prelude::TriMeshBuilderError> {
let vertices = vertices.into_iter().map(|v| v.into()).collect();
SharedShape::trimesh(vertices, indices).into()
Ok(SharedShape::trimesh(vertices, indices)?.into())
}

/// Initializes a collider with a triangle mesh shape defined by its vertex and index buffers, and flags
Expand All @@ -162,9 +165,9 @@ impl Collider {
vertices: Vec<Vect>,
indices: Vec<[u32; 3]>,
flags: TriMeshFlags,
) -> Self {
) -> Result<Self, crate::rapier::prelude::TriMeshBuilderError> {
let vertices = vertices.into_iter().map(|v| v.into()).collect();
SharedShape::trimesh_with_flags(vertices, indices, flags).into()
Ok(SharedShape::trimesh_with_flags(vertices, indices, flags)?.into())
}

/// Initializes a collider with a Bevy Mesh.
Expand All @@ -175,9 +178,11 @@ impl Collider {
let (vtx, idx) = extract_mesh_vertices_indices(mesh)?;

match collider_shape {
ComputedColliderShape::TriMesh(flags) => {
Some(SharedShape::trimesh_with_flags(vtx, idx, *flags).into())
}
ComputedColliderShape::TriMesh(flags) => Some(
SharedShape::trimesh_with_flags(vtx, idx, *flags)
.ok()?
.into(),
),
ComputedColliderShape::ConvexHull => {
SharedShape::convex_hull(&vtx).map(|shape| shape.into())
}
Expand Down
Loading
Loading