use glam_det::nums::*;
use glam_det::{BVec3x4, Mat3x4, UnitQuat, UnitQuatx4, Vec3, Vec3x4};
use crate::collision_tasks::{ShapeTester, ShapeWideTester};
use crate::convex_contact_manifold::{Convex4ContactManifoldWide, ConvexContactManifold};
use crate::shapes::{Cuboid, CuboidWide, Sphere, SphereWide};
use crate::traits::{ContactContext, ContactManifoldWide, CreateShapeWide, PairTest, PairWideTest};
use crate::ShapeContainer;
impl PairWideTest<SphereWide, CuboidWide> for ShapeWideTester {
#[inline]
fn should_reset_manifold_before_test() -> bool {
false
}
#[inline]
fn test(
a: &SphereWide,
b: &CuboidWide,
contact_context: &ContactContext,
manifold: &mut Convex4ContactManifoldWide,
) {
let orientation_b = Mat3x4::from_quat(*contact_context.orientation_b);
let local_offset_b = orientation_b.transpose() * contact_context.offset_b;
let clamped_local_offset = local_offset_b.clamp(-b.half_length, b.half_length);
let mut outside_normal = clamped_local_offset - local_offset_b;
let distance = outside_normal.length();
let inverse_distance = distance.recip();
outside_normal *= inverse_distance;
let outside_depth = a.radius - distance;
let depth_x = b.half_length.x - local_offset_b.x.absf();
let depth_y = b.half_length.y - local_offset_b.y.absf();
let depth_z = b.half_length.z - local_offset_b.z.absf();
let mut inside_depth = depth_x.min(depth_y).min(depth_z);
let is_x_min = inside_depth.eq(depth_x);
let is_y_min = inside_depth.eq(depth_y) & !is_x_min;
let is_z_min = !(is_x_min | is_y_min);
let mut inside_normal = Vec3x4::select(
local_offset_b.cmplt(Vec3x4::ZERO),
Vec3x4::ONE,
Vec3x4::NEG_ONE,
);
inside_normal = Vec3x4::select(
BVec3x4::new(is_x_min, is_y_min, is_z_min),
inside_normal,
Vec3x4::ZERO,
);
inside_depth += a.radius;
let use_inside = distance.eq(f32x4::ZERO);
let local_normal = Vec3x4::lane_select(use_inside, inside_normal, outside_normal);
manifold.normal = (orientation_b * local_normal).as_unit_vec3x4_unchecked();
manifold.depth[0] = inside_depth.select(use_inside, outside_depth);
manifold.feature_id[0] = u32x4::ZERO;
manifold.offset_a[0] = manifold.normal * (-a.radius);
manifold.contact_exists[0] = manifold.depth[0].gt(-contact_context.speculative_margin);
}
}
impl_pair_narrowphase!(Sphere, Cuboid, SphereWide, CuboidWide, 1);