1use super::*;
4
5pub const MAX_MANIFOLD_POINTS: usize = 4;
7
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[derive(Copy, Clone, Debug, Default, PartialEq)]
11pub struct ManifoldPoint {
12 pub anchor_a: Vec3,
14 pub anchor_b: Vec3,
16 pub separation: f32,
18 pub base_separation: f32,
20 pub normal_impulse: f32,
22 pub total_normal_impulse: f32,
24 pub normal_velocity: f32,
26 pub feature_id: u32,
28 pub triangle_index: i32,
30 pub persisted: bool,
32}
33
34impl ManifoldPoint {
35 #[inline]
37 pub const fn from_raw(raw: ffi::b3ManifoldPoint) -> Self {
38 Self {
39 anchor_a: Vec3::from_raw(raw.anchorA),
40 anchor_b: Vec3::from_raw(raw.anchorB),
41 separation: raw.separation,
42 base_separation: raw.baseSeparation,
43 normal_impulse: raw.normalImpulse,
44 total_normal_impulse: raw.totalNormalImpulse,
45 normal_velocity: raw.normalVelocity,
46 feature_id: raw.featureId,
47 triangle_index: raw.triangleIndex,
48 persisted: raw.persisted,
49 }
50 }
51}
52
53#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
55#[derive(Copy, Clone, Debug, Default, PartialEq)]
56pub struct Manifold {
57 pub points: [ManifoldPoint; MAX_MANIFOLD_POINTS],
59 pub normal: Vec3,
61 pub twist_impulse: f32,
63 pub friction_impulse: Vec3,
65 pub rolling_impulse: Vec3,
67 pub point_count: i32,
69}
70
71impl Manifold {
72 #[inline]
74 pub fn points(&self) -> &[ManifoldPoint] {
75 let count = self.point_count.clamp(0, MAX_MANIFOLD_POINTS as i32) as usize;
76 &self.points[..count]
77 }
78
79 #[inline]
81 pub fn from_raw(raw: ffi::b3Manifold) -> Self {
82 Self {
83 points: raw.points.map(ManifoldPoint::from_raw),
84 normal: Vec3::from_raw(raw.normal),
85 twist_impulse: raw.twistImpulse,
86 friction_impulse: Vec3::from_raw(raw.frictionImpulse),
87 rolling_impulse: Vec3::from_raw(raw.rollingImpulse),
88 point_count: raw.pointCount.clamp(0, MAX_MANIFOLD_POINTS as i32),
89 }
90 }
91}
92
93#[derive(Clone, Debug, PartialEq)]
95pub struct ContactData {
96 pub contact_id: ContactId,
98 pub shape_id_a: ShapeId,
100 pub shape_id_b: ShapeId,
102 pub manifolds: Vec<Manifold>,
104}
105
106impl ContactData {
107 #[inline]
114 pub(crate) unsafe fn from_raw_parts(
115 raw: ffi::b3ContactData,
116 contact_id: ContactId,
117 shape_id_a: ShapeId,
118 shape_id_b: ShapeId,
119 ) -> Self {
120 let manifolds = if raw.manifolds.is_null() || raw.manifoldCount <= 0 {
121 Vec::new()
122 } else {
123 unsafe { std::slice::from_raw_parts(raw.manifolds, raw.manifoldCount as usize) }
124 .iter()
125 .copied()
126 .map(Manifold::from_raw)
127 .collect()
128 };
129
130 Self {
131 contact_id,
132 shape_id_a,
133 shape_id_b,
134 manifolds,
135 }
136 }
137}