rolt/
narrow_phase.rs

1use std::marker::PhantomData;
2use std::mem;
3
4use joltc_sys::*;
5
6use crate::{
7    BodyFilterImpl, BodyId, BroadPhaseLayerFilterImpl, FromJolt, IntoJolt, ObjectLayerFilterImpl,
8    RVec3, Vec3,
9};
10
11/// See also: Jolt's [`NarrowPhaseQuery`](https://jrouwe.github.io/JoltPhysicsDocs/5.0.0/class_narrow_phase_query.html) class.
12pub struct NarrowPhaseQuery<'physics_system> {
13    raw: *const JPC_NarrowPhaseQuery,
14    _phantom: PhantomData<&'physics_system ()>,
15}
16
17/// See also: Jolt's [`RRayCast`](https://jrouwe.github.io/JoltPhysicsDocs/5.0.0/struct_r_ray_cast.html) class.
18#[derive(Debug, Default, Clone, Copy)]
19pub struct RRayCast {
20    /// Origin of the ray.
21    pub origin: RVec3,
22
23    /// Direction and length of the ray. Anything beyond this length will not be
24    /// reported as a hit.
25    pub direction: Vec3,
26}
27
28impl RRayCast {
29    pub fn as_raw(&self) -> JPC_RRayCast {
30        JPC_RRayCast {
31            Origin: self.origin.into_jolt(),
32            Direction: self.direction.into_jolt(),
33        }
34    }
35}
36
37/// Arguments for [`NarrowPhaseQuery::cast_ray`].
38#[derive(Default)]
39pub struct RayCastArgs {
40    pub ray: RRayCast,
41    pub broad_phase_layer_filter: Option<BroadPhaseLayerFilterImpl>,
42    pub object_layer_filter: Option<ObjectLayerFilterImpl>,
43    pub body_filter: Option<BodyFilterImpl>,
44}
45
46/// The result of calling [`NarrowPhaseQuery::cast_ray`].
47#[derive(Debug, Clone, Copy)]
48pub struct RayCastResult {
49    pub body_id: BodyId,
50    pub fraction: f32,
51    pub sub_shape_id: JPC_SubShapeID,
52}
53
54impl FromJolt for RayCastResult {
55    type Jolt = JPC_RayCastResult;
56
57    fn from_jolt(value: Self::Jolt) -> Self {
58        Self {
59            body_id: BodyId::new(value.BodyID),
60            fraction: value.Fraction,
61            sub_shape_id: value.SubShapeID2,
62        }
63    }
64}
65
66impl<'physics_system> NarrowPhaseQuery<'physics_system> {
67    pub(crate) fn new(raw: *const JPC_NarrowPhaseQuery) -> Self {
68        Self {
69            raw,
70            _phantom: PhantomData,
71        }
72    }
73
74    pub fn cast_ray(&self, args: RayCastArgs) -> Option<RayCastResult> {
75        let mut raw_args = JPC_NarrowPhaseQuery_CastRayArgs {
76            Ray: args.ray.as_raw(),
77            Result: unsafe { mem::zeroed() },
78            BroadPhaseLayerFilter: args.broad_phase_layer_filter.as_ref().into_jolt(),
79            ObjectLayerFilter: args.object_layer_filter.as_ref().into_jolt(),
80            BodyFilter: args.body_filter.as_ref().into_jolt(),
81        };
82
83        let hit = unsafe { JPC_NarrowPhaseQuery_CastRay(self.raw, &mut raw_args) };
84
85        if hit {
86            Some(RayCastResult::from_jolt(raw_args.Result))
87        } else {
88            None
89        }
90    }
91
92    pub fn as_raw(&self) -> *const JPC_NarrowPhaseQuery {
93        self.raw
94    }
95}