skullball/rust/src/net/util.rs

69 lines
1.7 KiB
Rust

use godot::{
classes::{PhysicsRayQueryParameters3D, World3D},
prelude::*,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct NetVector3 {
pub x: f32,
pub y: f32,
pub z: f32,
}
impl From<Vector3> for NetVector3 {
fn from(value: Vector3) -> Self {
NetVector3 {
x: value.x,
y: value.y,
z: value.z,
}
}
}
impl From<NetVector3> for Vector3 {
fn from(value: NetVector3) -> Self {
Vector3::new(value.x, value.y, value.z)
}
}
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(0b111);
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), Some(collider)) =
(results.get("position"), results.get("collider"))
{
Some(RaycastResult {
position: Vector3::from_variant(&position),
collider: Gd::from_variant(&collider),
})
} else {
None
}
} else {
None
}
} else {
None
}
}
pub struct RaycastResult {
pub position: Vector3,
pub collider: Gd<Object>,
}