1mod error;
11pub use error::*;
12
13pub mod types;
14pub use types::{
15 CollisionEvent, CollisionFilter, CollisionPair, Contact, ContactManifold, FeatureId,
16 MAX_CONTACTS, PhysicsMaterial, RichContact, RichContactManifold,
17};
18
19pub mod broadphase;
20pub use broadphase::{BroadPhase, BruteForceBroadPhase, BvhBroadphase, SweepAndPrune};
21
22pub mod dbvt;
23pub use dbvt::{BvhAabb, DynamicBvh};
24
25pub mod narrowphase;
26pub use narrowphase::{
27 BatchNarrowPhase, ContactFilter, NarrowPhaseContact, ShapeKind, shape_shape_contact,
28};
29pub use narrowphase::{Epa, Gjk, NarrowPhaseDispatcher};
30
31pub mod ccd;
32pub use ccd::{
33 CcdBodyEntry, CcdPair, CcdPipeline, CcdPipelineConfig, ConservativeAdvancement, RigidBodyState,
34 ToiResult, advance_body_to, integrate_angular, integrate_linear, quat_mul, quat_normalize,
35 quat_rotate, slerp_quat, time_of_impact,
36};
37
38pub mod sweep;
39pub use sweep::{
40 RayHit, SweepResult, aabb_aabb_overlap, point_aabb_dist_sq, ray_aabb, ray_sphere, ray_triangle,
41 sphere_aabb_overlap, swept_aabb_aabb, swept_sphere_aabb, swept_sphere_sphere,
42};
43
44pub mod sap;
45
46pub mod query;
47
48pub mod gjk_epa;
49pub use gjk_epa::{
50 ConvexShape, EpaFace, EpaResult, GjkBox, GjkCapsule, GjkSphere, Simplex, add3, cross3,
51 do_simplex, dot3, epa, gjk_distance, gjk_epa_contact, gjk_intersect, len3, minkowski_support,
52 normalize3, scale3, sub3,
53};
54
55pub mod contact_graph;
56pub use contact_graph::{
57 ContactCache, ContactGraph, ContactKey, PersistedContact, SpeculativeContact,
58 speculative_contact, speculative_impulse,
59};
60
61pub mod manifold_cache;
63pub use manifold_cache::{
64 CachingStrategy, ContactIsland, ContactManifoldCache, ContactPointId, ManifoldCompressor,
65 ManifoldLifetimeManager, ManifoldMetrics, ManifoldPointMatcher, ManifoldReduction,
66 PersistentManifold, age_cache_warm_start, age_manifold_warm_start, age_warm_start,
67 apply_position_corrections, baumgarte_correction, baumgarte_correction_slop,
68 build_contact_islands, compute_manifold_metrics, find_match_with_strategy,
69};
70
71pub mod sat_collision;
73pub use sat_collision::{
74 Capsule as SatCapsule, ContactFeature, ContactManifoldBuilder, ConvexPolyhedraSat,
75 ConvexPolyhedron, ConvexPolytope, Obb, ObbBvh, ObbBvhNode, ObbCapsuleCollision, ObbCollision,
76 ObbTree, ObbTriangleCollision, PolyhedraContact, PolytopeCollision, SatAxisCache, SatContact,
77 SatContactPointGenerator, closest_points_on_segments, edge_edge_contact, obb_bvh_pair_query,
78 obb_overlap_on_axis, obb_project,
79};
80
81#[cfg(test)]
82mod prop_tests {
83
84 use oxiphysics_core::Transform;
85 use oxiphysics_core::math::Vec3;
86 use oxiphysics_geometry::Sphere;
87 use proptest::prelude::*;
88
89 use crate::broadphase::{BroadPhase, BruteForceBroadPhase};
90 use crate::narrowphase::{Gjk, sphere_sphere};
91 use oxiphysics_core::Aabb;
92
93 fn positive_f64() -> impl Strategy<Value = f64> {
94 0.01_f64..20.0_f64
95 }
96
97 fn coord_f64() -> impl Strategy<Value = f64> {
98 -50.0_f64..50.0_f64
99 }
100
101 fn aabb_strategy() -> impl Strategy<Value = Aabb> {
102 (
103 coord_f64(),
104 coord_f64(),
105 coord_f64(),
106 positive_f64(),
107 positive_f64(),
108 positive_f64(),
109 )
110 .prop_map(|(x, y, z, ex, ey, ez)| {
111 Aabb::new(Vec3::new(x, y, z), Vec3::new(x + ex, y + ey, z + ez))
112 })
113 }
114
115 proptest! {
116 #[test]
117 fn prop_gjk_separated_spheres_no_intersection(
118 r1 in positive_f64(),
119 r2 in positive_f64(),
120 extra_sep in 0.01_f64..10.0_f64,
122 ) {
123 let s1 = Sphere::new(r1);
124 let s2 = Sphere::new(r2);
125 let t1 = Transform::from_position(Vec3::zeros());
126 let sep = r1 + r2 + extra_sep;
127 let t2 = Transform::from_position(Vec3::new(sep, 0.0, 0.0));
128 let intersects = Gjk::intersect(&s1, &t1, &s2, &t2);
129 prop_assert!(!intersects, "separated spheres (r1={}, r2={}, sep={}) reported intersecting", r1, r2, sep);
130 }
131
132 #[test]
133 fn prop_gjk_overlapping_spheres_intersect(
134 r1 in positive_f64(),
135 r2 in positive_f64(),
136 dist_frac in 0.0_f64..0.99_f64,
138 ) {
139 let s1 = Sphere::new(r1);
140 let s2 = Sphere::new(r2);
141 let t1 = Transform::from_position(Vec3::zeros());
142 let dist = (r1 + r2) * dist_frac;
143 let t2 = Transform::from_position(Vec3::new(dist, 0.0, 0.0));
144 let intersects = Gjk::intersect(&s1, &t1, &s2, &t2);
145 prop_assert!(intersects, "overlapping spheres (r1={}, r2={}, dist={}) not reported intersecting", r1, r2, dist);
146 }
147
148 #[test]
149 fn prop_broadphase_pairs_have_overlapping_aabbs(
150 aabbs in proptest::collection::vec(aabb_strategy(), 1..8),
151 ) {
152 let pairs = BruteForceBroadPhase.find_pairs(&aabbs);
153 for pair in &pairs {
154 let a = &aabbs[pair.a];
155 let b = &aabbs[pair.b];
156 prop_assert!(
157 a.intersects(b),
158 "pair ({},{}) reported but AABBs don't overlap", pair.a, pair.b
159 );
160 }
161 }
162
163 #[test]
164 fn prop_contact_normal_unit_length(
165 r1 in positive_f64(),
166 r2 in positive_f64(),
167 dist_frac in 0.01_f64..0.99_f64,
168 ) {
169 let s1 = Sphere::new(r1);
170 let s2 = Sphere::new(r2);
171 let t1 = Transform::from_position(Vec3::zeros());
172 let dist = (r1 + r2) * dist_frac;
173 let t2 = Transform::from_position(Vec3::new(dist, 0.0, 0.0));
174 if let Some(contact) = sphere_sphere(&s1, &t1, &s2, &t2) {
175 let nlen = contact.normal.norm();
176 prop_assert!((nlen - 1.0).abs() < 1e-6, "contact normal length={}", nlen);
177 }
178 }
179
180 #[test]
181 fn prop_contact_depth_non_negative(
182 r1 in positive_f64(),
183 r2 in positive_f64(),
184 dist_frac in 0.01_f64..0.99_f64,
185 ) {
186 let s1 = Sphere::new(r1);
187 let s2 = Sphere::new(r2);
188 let t1 = Transform::from_position(Vec3::zeros());
189 let dist = (r1 + r2) * dist_frac;
190 let t2 = Transform::from_position(Vec3::new(dist, 0.0, 0.0));
191 if let Some(contact) = sphere_sphere(&s1, &t1, &s2, &t2) {
192 prop_assert!(contact.depth >= 0.0, "contact depth={} is negative", contact.depth);
193 }
194 }
195 }
196}
197pub mod recast;
198pub use recast::{RecastBuilder, RecastConfig, RecastError};
199
200pub mod compound_shapes;
201pub mod contact_generation;
202pub mod contact_manifold;
203pub mod deformable_collision;
204pub mod fluid_collision;
205pub mod gjk_enhanced;
206pub mod gjk_extended;
207pub mod joint_collision;
208pub mod kdtree_collision;
209pub mod mesh_collision;
210pub mod parallel_collision;
211pub mod proximity;
212pub mod proximity_query;
213pub mod ray_casting;
214pub mod shape_cast;
215pub mod soft_body_collision;
216pub mod softbody_collision;
217pub mod spatial_queries;
218pub mod terrain_collision;
219pub mod voxel_collision;