Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Bevy 0.15 #128

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 0.19.0

- Changed: updated to Bevy 0.15.
- Use `Dir3` instead of `Vec3` for normalized directions in `Ray3d::new`

# 0.18.0

- Changed: updated to Bevy 0.14.
Expand Down
30 changes: 15 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bevy_mod_raycast"
version = "0.18.0"
version = "0.19.0"
authors = ["Aevyrie <aevyrie@gmail.com>"]
edition = "2021"
license = "MIT"
Expand All @@ -11,23 +11,23 @@ categories = ["game-engines", "rendering"]
resolver = "2"

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

[dev-dependencies]
bevy = { version = "0.14.0", default-features = true, features = [
bevy = { version = "0.15.0", 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.15 | 0.19 |
| 0.14 | 0.18 |
| 0.13 | 0.17 |
| 0.12 | 0.16 |
Expand Down
251 changes: 130 additions & 121 deletions benches/ray_mesh_intersection.rs
Original file line number Diff line number Diff line change
@@ -1,121 +1,130 @@
use bevy::math::{Mat4, Vec3};
use bevy_math::Ray3d;
use bevy_mod_raycast::prelude::*;
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn ptoxznorm(p: u32, size: u32) -> (f32, f32) {
let ij = (p / (size), p % (size));
(ij.0 as f32 / size as f32, ij.1 as f32 / size as f32)
}

struct SimpleMesh {
positions: Vec<[f32; 3]>,
normals: Vec<[f32; 3]>,
indices: Vec<u32>,
}

fn mesh_creation(vertices_per_side: u32) -> SimpleMesh {
let mut positions = Vec::new();
let mut normals = Vec::new();
for p in 0..vertices_per_side.pow(2) {
let xz = ptoxznorm(p, vertices_per_side);
positions.push([xz.0 - 0.5, 0.0, xz.1 - 0.5]);
normals.push([0.0, 1.0, 0.0]);
}

let mut indices = vec![];
for p in 0..vertices_per_side.pow(2) {
if p % (vertices_per_side) != vertices_per_side - 1
&& p / (vertices_per_side) != vertices_per_side - 1
{
indices.extend_from_slice(&[p, p + 1, p + vertices_per_side]);
indices.extend_from_slice(&[p + vertices_per_side, p + 1, p + vertices_per_side + 1]);
}
}

SimpleMesh {
positions,
normals,
indices,
}
}

fn ray_mesh_intersection(c: &mut Criterion) {
let mut group = c.benchmark_group("ray_mesh_intersection");
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::Cull,
));
});
});
}
}

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));

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(1.0, 0.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::Cull,
));
});
});
}
}

criterion_group!(
benches,
ray_mesh_intersection,
ray_mesh_intersection_no_cull,
ray_mesh_intersection_no_intersection
);
criterion_main!(benches);
use bevy::math::{Mat4, Vec3};
use bevy_math::{Dir3, Ray3d};
use bevy_mod_raycast::prelude::*;
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn ptoxznorm(p: u32, size: u32) -> (f32, f32) {
let ij = (p / (size), p % (size));
(ij.0 as f32 / size as f32, ij.1 as f32 / size as f32)
}

struct SimpleMesh {
positions: Vec<[f32; 3]>,
normals: Vec<[f32; 3]>,
indices: Vec<u32>,
}

fn mesh_creation(vertices_per_side: u32) -> SimpleMesh {
let mut positions = Vec::new();
let mut normals = Vec::new();
for p in 0..vertices_per_side.pow(2) {
let xz = ptoxznorm(p, vertices_per_side);
positions.push([xz.0 - 0.5, 0.0, xz.1 - 0.5]);
normals.push([0.0, 1.0, 0.0]);
}

let mut indices = vec![];
for p in 0..vertices_per_side.pow(2) {
if p % (vertices_per_side) != vertices_per_side - 1
&& p / (vertices_per_side) != vertices_per_side - 1
{
indices.extend_from_slice(&[p, p + 1, p + vertices_per_side]);
indices.extend_from_slice(&[p + vertices_per_side, p + 1, p + vertices_per_side + 1]);
}
}

SimpleMesh {
positions,
normals,
indices,
}
}

fn ray_mesh_intersection(c: &mut Criterion) {
let mut group = c.benchmark_group("ray_mesh_intersection");
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),
Dir3::from_xyz_unchecked(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::Cull,
));
});
});
}
}

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),
Dir3::from_xyz_unchecked(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));

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),
Dir3::from_xyz_unchecked(1.0, 0.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::Cull,
));
});
});
}
}

criterion_group!(
benches,
ray_mesh_intersection,
ray_mesh_intersection_no_cull,
ray_mesh_intersection_no_intersection
);
criterion_main!(benches);
19 changes: 9 additions & 10 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ fn main() {
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 t = time.elapsed_secs();
let pos = Vec3::new(t.sin(), (t * 1.5).cos() * 2.0, t.cos()) * 1.5 + RAY_DIST;
let dir = (RAY_DIST - pos).normalize();
let dir = Dir3::new(RAY_DIST - pos).unwrap();
// 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 @@ -29,12 +29,11 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn(Camera3dBundle::default());
commands.spawn(PointLightBundle::default());
commands.spawn(PbrBundle {
mesh: meshes.add(Capsule3d::default()),
material: materials.add(Color::srgb(1.0, 1.0, 1.0)),
transform: Transform::from_translation(RAY_DIST),
..default()
});
commands.spawn(Camera3d::default());
commands.spawn(PointLight::default());
commands.spawn((
Mesh3d(meshes.add(Capsule3d::default())),
MeshMaterial3d(materials.add(Color::srgb(1.0, 1.0, 1.0))),
Transform::from_translation(RAY_DIST),
));
}
18 changes: 8 additions & 10 deletions examples/minimal_deferred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct MyRaycastSet; // Groups raycast sources with meshes, can use `()` instead
struct MovingRaycaster;

fn move_ray(time: Res<Time>, mut query: Query<&mut Transform, With<MovingRaycaster>>) {
let t = time.elapsed_seconds();
let t = time.elapsed_secs();
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 @@ -36,22 +36,20 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn(Camera3dBundle::default());
commands.spawn(PointLightBundle::default());
commands.spawn(Camera3d::default());
commands.spawn(PointLight::default());
// Unlike the immediate mode API where the raycast is built every frame in a system, instead we
// spawn an entity and mark it as a raycasting source, using its `GlobalTransform`.
commands.spawn((
MovingRaycaster,
SpatialBundle::default(),
Transform::default(),
Visibility::default(),
RaycastSource::<MyRaycastSet>::new_transform_empty(),
));
commands.spawn((
PbrBundle {
mesh: meshes.add(Capsule3d::default()),
material: materials.add(Color::srgb(1.0, 1.0, 1.0)),
transform: Transform::from_translation(RAY_DIST),
..default()
},
Mesh3d(meshes.add(Capsule3d::default())),
MeshMaterial3d(materials.add(Color::srgb(1.0, 1.0, 1.0))),
Transform::from_translation(RAY_DIST),
RaycastMesh::<MyRaycastSet>::default(), // Make this mesh ray cast-able
));
}
Loading