use std::marker::PhantomData;
use std::mem;
use joltc_sys::*;
use crate::{
BodyFilterImpl, BodyId, BroadPhaseLayerFilterImpl, FromJolt, IntoJolt, ObjectLayerFilterImpl,
RVec3, Vec3,
};
pub struct NarrowPhaseQuery<'physics_system> {
raw: *const JPC_NarrowPhaseQuery,
_phantom: PhantomData<&'physics_system ()>,
}
#[derive(Debug, Default, Clone, Copy)]
pub struct RRayCast {
pub origin: RVec3,
pub direction: Vec3,
}
impl RRayCast {
pub fn as_raw(&self) -> JPC_RRayCast {
JPC_RRayCast {
Origin: self.origin.into_jolt(),
Direction: self.direction.into_jolt(),
}
}
}
#[derive(Default)]
pub struct RayCastArgs {
pub ray: RRayCast,
pub broad_phase_layer_filter: Option<BroadPhaseLayerFilterImpl>,
pub object_layer_filter: Option<ObjectLayerFilterImpl>,
pub body_filter: Option<BodyFilterImpl>,
}
#[derive(Debug, Clone, Copy)]
pub struct RayCastResult {
pub body_id: BodyId,
pub fraction: f32,
pub sub_shape_id: JPC_SubShapeID,
}
impl FromJolt for RayCastResult {
type Jolt = JPC_RayCastResult;
fn from_jolt(value: Self::Jolt) -> Self {
Self {
body_id: BodyId::new(value.BodyID),
fraction: value.Fraction,
sub_shape_id: value.SubShapeID2,
}
}
}
impl<'physics_system> NarrowPhaseQuery<'physics_system> {
pub(crate) fn new(raw: *const JPC_NarrowPhaseQuery) -> Self {
Self {
raw,
_phantom: PhantomData,
}
}
pub fn cast_ray(&self, args: RayCastArgs) -> Option<RayCastResult> {
let mut raw_args = JPC_NarrowPhaseQuery_CastRayArgs {
Ray: args.ray.as_raw(),
Result: unsafe { mem::zeroed() },
BroadPhaseLayerFilter: args.broad_phase_layer_filter.as_ref().into_jolt(),
ObjectLayerFilter: args.object_layer_filter.as_ref().into_jolt(),
BodyFilter: args.body_filter.as_ref().into_jolt(),
};
let hit = unsafe { JPC_NarrowPhaseQuery_CastRay(self.raw, &mut raw_args) };
if hit {
Some(RayCastResult::from_jolt(raw_args.Result))
} else {
None
}
}
pub fn as_raw(&self) -> *const JPC_NarrowPhaseQuery {
self.raw
}
}