Skip to content

Commit

Permalink
update to bevy 0.13 (#109)
Browse files Browse the repository at this point in the history
* update to bevy 0.13

* clippy

* touch up examples

* free perf lying around in a hot loop

* Bump version

* add no culling to benches

* add perf notes to changelog

* Fix CI in bevy-0.13 branch (#111)

* fix(tests): QueryFilter fixed to be in filter position

Authored-by: RobWalt <robwalter96@gmail.com>

* chore(cleanup): remove unneeded `Mesh::from`

Authored-by: RobWalt <robwalter96@gmail.com>

* chore(cleanup): use Direction3D API directly

Ok to be fair this doesn't change a lot. It saves one indirection
through the `TryFrom` trait which might even gets optimized away in the
first place. Nevertheless it is a bit more explicit which will help
newer people to understand the code and develop good habits.

Authored-by: RobWalt <robwalter96@gmail.com>

---------

Co-authored-by: Robert Walter <26892280+RobWalt@users.noreply.github.com>
  • Loading branch information
aevyrie and RobWalt authored Feb 23, 2024
1 parent e850210 commit 81f4c90
Show file tree
Hide file tree
Showing 17 changed files with 291 additions and 376 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
# 0.17.0

Raycasting is now 20-50% faster.

- Changed: updated to Bevy 0.13.
- Removed: This crate's `Ray3d` type has been replaced with Bevy's new `Ray3d` type.
- Methods on `Ray3d` have been replaced with standalone functions.
- This has resulted in a ~10% drop in performance in benchmarks.
- Changed: `Ray3d::from_transform` is now `ray_from_transform`
- Changed: `Ray3d::from_screenspace` is now `ray_from_screenspace`
- Changed: `Triangle` removed in favor of a simpler `[Vec3A; 3]`.

# 0.16.0

- Changed: updated to bevy 0.12.
- Changed: updated to Bevy 0.12.
- Changed: plugin depends on bevy sub-crates (e.g. `bevy_ecs`) instead of `bevy` to reduce
dependency count.

Expand Down
28 changes: 14 additions & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bevy_mod_raycast"
version = "0.16.0"
version = "0.17.0"
authors = ["Aevyrie <aevyrie@gmail.com>"]
edition = "2021"
license = "MIT"
Expand All @@ -11,22 +11,22 @@ categories = ["game-engines", "rendering"]
resolver = "2"

[dependencies]
bevy_app = { version = "0.12", default-features = false }
bevy_asset = { version = "0.12", default-features = false }
bevy_derive = { version = "0.12", default-features = false }
bevy_ecs = { version = "0.12", default-features = false }
bevy_gizmos = { version = "0.12", optional = true, default-features = false }
bevy_math = { version = "0.12", default-features = false }
bevy_reflect = { version = "0.12", default-features = false }
bevy_render = { version = "0.12", default-features = false }
bevy_sprite = { version = "0.12", optional = true, default-features = false }
bevy_transform = { version = "0.12", default-features = false }
bevy_utils = { version = "0.12", default-features = false }
bevy_window = { version = "0.12", default-features = false }
bevy_app = { version = "0.13", default-features = false }
bevy_asset = { version = "0.13", default-features = false }
bevy_derive = { version = "0.13", default-features = false }
bevy_ecs = { version = "0.13", default-features = false }
bevy_gizmos = { version = "0.13", optional = true, default-features = false }
bevy_math = { version = "0.13", default-features = false }
bevy_reflect = { version = "0.13", default-features = false }
bevy_render = { version = "0.13", default-features = false }
bevy_sprite = { version = "0.13", optional = true, default-features = false }
bevy_transform = { version = "0.13", default-features = false }
bevy_utils = { version = "0.13", default-features = false }
bevy_window = { version = "0.13", default-features = false }
crossbeam-channel = "0.5"

[dev-dependencies]
bevy = { version = "0.12", default-features = true, features = [
bevy = { version = "0.13", default-features = true, features = [
"default_font",
"ktx2",
"tonemapping_luts",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ I intend to track the `main` branch of Bevy. PRs supporting this are welcome!

| bevy | bevy_mod_raycast |
| ---- | ---------------- |
| 0.13 | 0.17 |
| 0.12 | 0.16 |
| 0.11 | 0.9 - 0.15 |
| 0.10 | 0.8 |
Expand Down
30 changes: 28 additions & 2 deletions benches/ray_mesh_intersection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use bevy::math::{Mat4, Vec3};
use bevy_math::Ray3d;
use bevy_mod_raycast::prelude::*;
use criterion::{black_box, criterion_group, criterion_main, Criterion};

Expand Down Expand Up @@ -54,7 +55,7 @@ fn ray_mesh_intersection(c: &mut Criterion) {
&mesh_to_world,
&mesh.positions,
Some(&mesh.normals),
&ray,
ray,
Some(&mesh.indices),
Backfaces::Cull,
));
Expand All @@ -63,6 +64,30 @@ fn ray_mesh_intersection(c: &mut Criterion) {
}
}

fn ray_mesh_intersection_no_cull(c: &mut Criterion) {
let mut group = c.benchmark_group("ray_mesh_intersection_no_cull");
group.warm_up_time(std::time::Duration::from_millis(500));

for vertices_per_side in [10_u32, 100, 1000] {
group.bench_function(format!("{}_vertices", vertices_per_side.pow(2)), |b| {
let ray = Ray3d::new(Vec3::new(0.0, 1.0, 0.0), Vec3::new(0.0, -1.0, 0.0));
let mesh_to_world = Mat4::IDENTITY;
let mesh = mesh_creation(vertices_per_side);

b.iter(|| {
black_box(bevy_mod_raycast::prelude::ray_mesh_intersection(
&mesh_to_world,
&mesh.positions,
Some(&mesh.normals),
ray,
Some(&mesh.indices),
Backfaces::Include,
));
});
});
}
}

fn ray_mesh_intersection_no_intersection(c: &mut Criterion) {
let mut group = c.benchmark_group("ray_mesh_intersection_no_intersection");
group.warm_up_time(std::time::Duration::from_millis(500));
Expand All @@ -78,7 +103,7 @@ fn ray_mesh_intersection_no_intersection(c: &mut Criterion) {
&mesh_to_world,
&mesh.positions,
Some(&mesh.normals),
&ray,
ray,
Some(&mesh.indices),
Backfaces::Cull,
));
Expand All @@ -90,6 +115,7 @@ fn ray_mesh_intersection_no_intersection(c: &mut Criterion) {
criterion_group!(
benches,
ray_mesh_intersection,
ray_mesh_intersection_no_cull,
ray_mesh_intersection_no_intersection
);
criterion_main!(benches);
12 changes: 6 additions & 6 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ fn main() {
.run();
}

const DIST: Vec3 = Vec3::new(0.0, 0.0, -7.0);
const RAY_DIST: Vec3 = Vec3::new(0.0, 0.0, -7.0);

fn raycast(mut raycast: Raycast, mut gizmos: Gizmos, time: Res<Time>) {
let t = time.elapsed_seconds();
let pos = Vec3::new(t.sin(), (t * 1.5).cos() * 2.0, t.cos()) * 1.5 + DIST;
let dir = (DIST - pos).normalize();
let pos = Vec3::new(t.sin(), (t * 1.5).cos() * 2.0, t.cos()) * 1.5 + RAY_DIST;
let dir = (RAY_DIST - pos).normalize();
// This is all that is needed to raycast into the world! You can also use the normal, non-debug
// version (raycast.cast_ray) when you don't need to visualize the ray or intersections.
raycast.debug_cast_ray(Ray3d::new(pos, dir), &default(), &mut gizmos);
Expand All @@ -32,9 +32,9 @@ fn setup(
commands.spawn(Camera3dBundle::default());
commands.spawn(PointLightBundle::default());
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::try_from(shape::Capsule::default()).unwrap()),
material: materials.add(Color::rgb(1.0, 1.0, 1.0).into()),
transform: Transform::from_translation(DIST),
mesh: meshes.add(Capsule3d::default()),
material: materials.add(Color::rgb(1.0, 1.0, 1.0)),
transform: Transform::from_translation(RAY_DIST),
..default()
});
}
14 changes: 7 additions & 7 deletions examples/minimal_deferred.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! This example demonstrates how to use the [`bevy_mod_raycast::deferred`]` API. Unlike the
//! This example demonstrates how to use the [`bevy_mod_raycast::deferred`] API. Unlike the
//! [`Raycast`] system param, this API is declarative, and does not return a result immediately.
//! Instead, behavior is defined using components, and raycasting is done once per frame.
Expand All @@ -16,7 +16,7 @@ fn main() {
.run();
}

const DIST: Vec3 = Vec3::new(0.0, 0.0, -7.0);
const RAY_DIST: Vec3 = Vec3::new(0.0, 0.0, -7.0);

#[derive(Reflect)]
struct MyRaycastSet; // Groups raycast sources with meshes, can use `()` instead.
Expand All @@ -26,8 +26,8 @@ struct MovingRaycaster;

fn move_ray(time: Res<Time>, mut query: Query<&mut Transform, With<MovingRaycaster>>) {
let t = time.elapsed_seconds();
let pos = Vec3::new(t.sin(), (t * 1.5).cos() * 2.0, t.cos()) * 1.5 + DIST;
let dir = (DIST - pos).normalize();
let pos = Vec3::new(t.sin(), (t * 1.5).cos() * 2.0, t.cos()) * 1.5 + RAY_DIST;
let dir = (RAY_DIST - pos).normalize();
*query.single_mut() = Transform::from_translation(pos).looking_to(dir, Vec3::Y);
}

Expand All @@ -47,9 +47,9 @@ fn setup(
));
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::try_from(shape::Capsule::default()).unwrap()),
material: materials.add(Color::rgb(1.0, 1.0, 1.0).into()),
transform: Transform::from_translation(DIST),
mesh: meshes.add(Capsule3d::default()),
material: materials.add(Color::rgb(1.0, 1.0, 1.0)),
transform: Transform::from_translation(RAY_DIST),
..default()
},
RaycastMesh::<MyRaycastSet>::default(), // Make this mesh ray cast-able
Expand Down
4 changes: 2 additions & 2 deletions examples/mouse_picking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ fn setup(
commands.spawn(Camera3dBundle::default());
commands.spawn(PointLightBundle::default());
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::UVSphere::default())),
material: materials.add(Color::GRAY.into()),
mesh: meshes.add(Sphere::default()),
material: materials.add(Color::GRAY),
transform: Transform::from_xyz(0.0, 0.0, -5.0),
..default()
});
Expand Down
7 changes: 5 additions & 2 deletions examples/mouse_picking_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use bevy_mod_raycast::prelude::*;

fn main() {
App::new()
.add_plugins((DefaultPlugins, DeferredRaycastingPlugin::<()>::default()))
.add_plugins((
DefaultPlugins.set(bevy_mod_raycast::low_latency_window_plugin()),
DeferredRaycastingPlugin::<()>::default(),
))
.insert_resource(RaycastPluginState::<()>::default().with_debug_cursor())
.add_systems(Startup, setup)
.add_systems(Update, print_intersections::<()>)
Expand All @@ -18,7 +21,7 @@ fn setup(
commands.spawn((Camera2dBundle::default(), RaycastSource::<()>::new_cursor()));
commands.spawn((
MaterialMesh2dBundle {
mesh: meshes.add(Mesh::from(shape::Circle::default())).into(),
mesh: meshes.add(Circle::default()).into(),
transform: Transform::default().with_scale(Vec3::splat(128.)),
material: materials.add(ColorMaterial::from(Color::PURPLE)),
..default()
Expand Down
4 changes: 2 additions & 2 deletions examples/mouse_picking_deferred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ fn setup(
commands.spawn(PointLightBundle::default());
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::UVSphere::default())),
material: materials.add(Color::GRAY.into()),
mesh: meshes.add(Sphere::default()),
material: materials.add(Color::GRAY),
transform: Transform::from_xyz(0.0, 0.0, -5.0),
..default()
},
Expand Down
24 changes: 11 additions & 13 deletions examples/reflecting_laser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use bevy_mod_raycast::prelude::*;

fn main() {
App::new()
.add_plugins((DefaultPlugins, DefaultRaycastingPlugin))
.add_plugins((
DefaultPlugins.set(bevy_mod_raycast::low_latency_window_plugin()),
DefaultRaycastingPlugin,
))
.add_systems(Startup, setup_scene)
.add_systems(Update, bouncing_raycast)
.insert_resource(ClearColor(Color::BLACK))
Expand Down Expand Up @@ -39,25 +42,20 @@ fn bouncing_raycast(
}
}

fn bounce_ray(
mut ray: Ray3d,
raycast: &mut Raycast<'_, '_>,
gizmos: &mut Gizmos<'_>,
color: Color,
) {
fn bounce_ray(mut ray: Ray3d, raycast: &mut Raycast, gizmos: &mut Gizmos, color: Color) {
let mut intersections = Vec::with_capacity(MAX_BOUNCES + 1);
intersections.push((ray.origin(), Color::rgb(30.0, 0.0, 0.0)));
intersections.push((ray.origin, Color::rgb(30.0, 0.0, 0.0)));

for i in 0..MAX_BOUNCES {
if let Some((_, hit)) = raycast.cast_ray(ray, &RaycastSettings::default()).first() {
let bright = 1.0 + 10.0 * (1.0 - i as f32 / MAX_BOUNCES as f32);
intersections.push((hit.position(), color * bright));
gizmos.sphere(hit.position(), Quat::IDENTITY, 0.005, color * bright * 2.0);
let ray_dir = ray.direction();
let ray_dir = ray.direction;
// reflect the ray
let proj = (ray_dir.dot(hit.normal()) / hit.normal().dot(hit.normal())) * hit.normal();
ray.set_direction(ray_dir - 2.0 * proj);
ray.set_origin(hit.position() + ray.direction() * 1e-6);
ray.direction = Direction3d::new(*ray_dir - 2.0 * proj).unwrap();
ray.origin = hit.position() + ray.direction * 1e-6;
} else {
break;
}
Expand Down Expand Up @@ -89,8 +87,8 @@ fn setup_scene(
));
// Make a box of planes facing inward so the laser gets trapped inside:
let plane = PbrBundle {
mesh: meshes.add(shape::Plane::default().into()),
material: materials.add(Color::GRAY.with_a(0.01).into()),
mesh: meshes.add(Plane3d::default()),
material: materials.add(Color::GRAY.with_a(0.01)),
..default()
};
let pbr_bundle = move |translation, rotation| PbrBundle {
Expand Down
16 changes: 6 additions & 10 deletions examples/simplified_mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,13 @@ fn setup_scene(
commands.spawn((
PbrBundle {
// This is a very complex mesh that will be hard to raycast on
mesh: meshes.add(Mesh::from(shape::UVSphere {
radius: 1.0,
sectors: 1000,
stacks: 1000,
})),
material: materials.add(Color::rgb(1.0, 1.0, 1.0).into()),
mesh: meshes.add(Sphere::default().mesh().uv(1000, 1000)),
material: materials.add(Color::rgb(1.0, 1.0, 1.0)),
transform: Transform::from_translation(Vec3::new(0.0, 0.0, -5.0)),
..default()
},
SimplifiedMesh {
mesh: meshes.add(Mesh::from(shape::UVSphere::default())),
mesh: meshes.add(Sphere::default()),
},
));
commands.spawn(PointLightBundle {
Expand Down Expand Up @@ -133,15 +129,15 @@ fn manage_simplified_mesh(
mut commands: Commands,
query: Query<(Entity, Option<&SimplifiedMesh>), With<Handle<Mesh>>>,
mut status_query: Query<&mut Text, With<SimplifiedStatus>>,
keyboard: Res<Input<KeyCode>>,
keyboard: Res<ButtonInput<KeyCode>>,
mut meshes: ResMut<Assets<Mesh>>,
) {
if keyboard.just_pressed(KeyCode::Space) {
if let Ok((entity, simplified_mesh)) = query.get_single() {
if let Ok(mut text) = status_query.get_single_mut() {
if simplified_mesh.is_none() {
commands.entity(entity).insert(SimplifiedMesh {
mesh: meshes.add(Mesh::from(shape::UVSphere::default())),
mesh: meshes.add(Sphere::default()),
});
text.sections[1].value = "ON".to_string();
text.sections[1].style.color = Color::GREEN;
Expand All @@ -157,7 +153,7 @@ fn manage_simplified_mesh(

fn update_fps(diagnostics: Res<DiagnosticsStore>, mut query: Query<&mut Text, With<FpsText>>) {
for mut text in &mut query {
if let Some(fps) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS) {
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
if let Some(average) = fps.average() {
// Update the value of the second section
text.sections[1].value = format!("{:.2}", average);
Expand Down
8 changes: 4 additions & 4 deletions examples/stress_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ struct FpsText;
// Insert or remove aabb components from the meshes being raycasted on.
fn update_status(
mut commands: Commands,
keyboard: Res<Input<KeyCode>>,
keyboard: Res<ButtonInput<KeyCode>>,
mut enabled: Local<Option<(bool, bool)>>,
// Bounding toggle
mut bound_status: Query<&mut Text, (With<BoundVolStatus>, Without<EarlyExitStatus>)>,
Expand All @@ -151,7 +151,7 @@ fn update_status(
}
};

if keyboard.just_pressed(KeyCode::Key1) {
if keyboard.just_pressed(KeyCode::Digit1) {
enabled.0 = !enabled.0;
for (entity, mut aabb) in &mut aabbs {
if enabled.0 {
Expand All @@ -165,7 +165,7 @@ fn update_status(
}
bool_to_text(enabled.0, bound_status.single_mut().as_mut());

if keyboard.just_pressed(KeyCode::Key2) {
if keyboard.just_pressed(KeyCode::Digit2) {
enabled.1 = !enabled.1;
for mut source in &mut sources {
source.should_early_exit = enabled.1;
Expand All @@ -176,7 +176,7 @@ fn update_status(

fn update_fps(diagnostics: Res<DiagnosticsStore>, mut query: Query<&mut Text, With<FpsText>>) {
for mut text in &mut query {
if let Some(fps) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS) {
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
if let Some(average) = fps.smoothed() {
// Update the value of the second section
text.sections[1].value = format!("{:.2}", average);
Expand Down
Loading

0 comments on commit 81f4c90

Please sign in to comment.