82 lines
2.2 KiB
Rust
82 lines
2.2 KiB
Rust
use godot::{
|
|
classes::{PhysicsRayQueryParameters3D, World3D},
|
|
prelude::*,
|
|
};
|
|
|
|
pub fn cast_ray(
|
|
from: Vector3,
|
|
to: Vector3,
|
|
world: &Option<Gd<World3D>>,
|
|
exclude: &Array<Rid>,
|
|
) -> Option<RaycastResult> {
|
|
let ray = PhysicsRayQueryParameters3D::create(from, to);
|
|
if let Some(mut ray) = ray {
|
|
ray.set_collision_mask(0b1111);
|
|
ray.set_hit_back_faces(false);
|
|
ray.set_hit_from_inside(false);
|
|
ray.set_collide_with_bodies(true);
|
|
ray.set_exclude(&exclude);
|
|
if let Some(world) = world
|
|
&& let Some(mut space) = world.get_direct_space_state()
|
|
{
|
|
let results = space.intersect_ray(&ray);
|
|
if let Some(position) = results.get("position")
|
|
&& let Some(collider) = results.get("collider")
|
|
&& let Some(normal) = results.get("normal")
|
|
{
|
|
Some(RaycastResult {
|
|
position: Vector3::from_variant(&position),
|
|
normal: Vector3::from_variant(&normal),
|
|
collider: Gd::from_variant(&collider),
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
} else {
|
|
None
|
|
}
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn shotgun_ray(
|
|
from: Vector3,
|
|
to: Vector3,
|
|
up: Vector3,
|
|
world: &Option<Gd<World3D>>,
|
|
exclude: &Array<Rid>,
|
|
density: u8,
|
|
angle: f32,
|
|
distance: f32,
|
|
) -> Vec<RaycastResult> {
|
|
let mut results = Vec::new();
|
|
|
|
let original_dir = (to - from).normalized();
|
|
let step = angle / density as f32;
|
|
|
|
let up = up.normalized();
|
|
let right = original_dir.cross(up).normalized();
|
|
|
|
for y in 0..density {
|
|
let y_rot = -(angle / 2.) + step * y as f32;
|
|
for x in 0..density {
|
|
let x_rot = -(angle / 2.) + step * x as f32;
|
|
let dir = original_dir.rotated(up, x_rot).rotated(right, y_rot);
|
|
let to = from + dir * distance;
|
|
if let Some(res) = cast_ray(from, to, world, exclude) {
|
|
results.push(res);
|
|
}
|
|
}
|
|
}
|
|
|
|
results
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct RaycastResult {
|
|
pub position: Vector3,
|
|
pub normal: Vector3,
|
|
pub collider: Gd<Object>,
|
|
}
|