-
-
Notifications
You must be signed in to change notification settings - Fork 133
/
Copy pathray_caster.rs
75 lines (66 loc) · 2.24 KB
/
ray_caster.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! A simple raycasting example that uses the [`RayCaster`] component.
//!
//! An alternative, more controlled approach is to use the methods of
//! the [`SpatialQuery`] system parameter.
#![allow(clippy::unnecessary_cast)]
use avian2d::{math::*, prelude::*};
use bevy::{
color::palettes::css::{GREEN, ORANGE_RED},
prelude::*,
};
use examples_common_2d::*;
fn main() {
App::new()
.add_plugins((
DefaultPlugins,
ExampleCommonPlugin,
PhysicsPlugins::default(),
))
.insert_resource(ClearColor(Color::srgb(0.05, 0.05, 0.1)))
.add_systems(Update, render_rays)
.add_systems(Startup, setup)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
commands.spawn(Camera2d);
// Spawn a perimeter of circles that the ray will be cast against
let radius = 16.0;
for x in -4..=4 {
for y in -4..=4 {
if (-3..4).contains(&x) && (-3..4).contains(&y) {
continue;
}
commands.spawn((
Mesh2d(meshes.add(Circle::new(radius))),
MeshMaterial2d(materials.add(Color::srgb(0.2, 0.7, 0.9))),
Transform::from_xyz(x as f32 * radius * 3.0, y as f32 * radius * 3.0, 0.0),
Collider::circle(radius as Scalar),
));
}
}
// Spawn a rotating kinematic body with a ray caster
commands.spawn((
RigidBody::Kinematic,
AngularVelocity(0.2),
RayCaster::new(Vector::ZERO, Dir2::X),
));
}
// Note: The `PhysicsDebugPlugin` can also render rays, hit points, and normals.
// This system is primarily for demonstration purposes.
fn render_rays(mut rays: Query<(&mut RayCaster, &mut RayHits)>, mut gizmos: Gizmos) {
for (ray, hits) in &mut rays {
// Convert to Vec3 for lines
let origin = ray.global_origin().f32();
let direction = ray.global_direction().f32();
for hit in hits.iter() {
gizmos.line_2d(origin, origin + direction * hit.distance as f32, GREEN);
}
if hits.is_empty() {
gizmos.line_2d(origin, origin + direction * 1_000_000.0, ORANGE_RED);
}
}
}