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#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
95#[derive(Clone, Debug, Default, PartialEq)]
96pub struct ContactData {
97 pub contact_id: ContactId,
99 pub shape_id_a: ShapeId,
101 pub shape_id_b: ShapeId,
103 pub manifolds: Vec<Manifold>,
105}
106
107impl ContactData {
108 #[inline]
115 pub unsafe fn from_raw(raw: ffi::b3ContactData) -> Self {
116 let manifolds = if raw.manifolds.is_null() || raw.manifoldCount <= 0 {
117 Vec::new()
118 } else {
119 unsafe { std::slice::from_raw_parts(raw.manifolds, raw.manifoldCount as usize) }
120 .iter()
121 .copied()
122 .map(Manifold::from_raw)
123 .collect()
124 };
125
126 Self {
127 contact_id: ContactId::from_raw(raw.contactId),
128 shape_id_a: ShapeId::from_raw(raw.shapeIdA),
129 shape_id_b: ShapeId::from_raw(raw.shapeIdB),
130 manifolds,
131 }
132 }
133}