phys-collision 2.0.1-beta.0

Provides collision detection ability
// Copyright (C) 2020-2025 phys-collision authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use approx_det::assert_relative_eq;
use glam_det::Point3;
use wasm_bindgen_test::*;

use crate::collision_tasks::tests::common::{
    convex1contact_manifold_wide_to_convex1contact_manifold, get_input_wide,
    Convex1ContactManifold, Mvec3, TestInput,
};
use crate::collision_tasks::ShapeWideTester;
use crate::shapes::{ConvexHullWide, SphereWide};
use crate::traits::PairWideTest;
use crate::{ConvexHull, ConvexHullId, ShapeContainer, Sphere};

wasm_bindgen_test_configure!(run_in_browser);

#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
struct ConvexHullInput {
    pub vertices: Vec<Point3>,
}

type InputTypeData = TestInput<Sphere, ConvexHullInput>;
type InputType = TestInput<Sphere, ConvexHullId>;

#[test]
#[wasm_bindgen_test]
fn test_sphere_convex_hull_tester() {
    let _ = env_logger::builder().is_test(true).try_init();

    let file_input = include_bytes!("resource/sphere_convex_hull/contact.json");
    let input0: InputTypeData =
        serde_json::from_slice(file_input).expect("file should be proper JSON");
    let convex_hull = ConvexHull::new_unchecked(&input0.b.vertices[..]);
    let mut container = ShapeContainer::default();
    let id = container.add(convex_hull);
    let input0 = InputType {
        a: input0.a,
        b: id,
        speculative_margin: input0.speculative_margin,
        offset_b: input0.offset_b,
        orientation_a: input0.orientation_a,
        orientation_b: input0.orientation_b,
    };
    let mut output0 = Convex1ContactManifold {
        offset_a: Mvec3 {
            x: 0.0,
            y: 0.0,
            z: 0.0,
        },
        normal: Mvec3 {
            x: 0.0,
            y: -1_f32,
            z: 0.0,
        },
        depth: 1_f32,
        feature_id: 0,
        contact_exists: true,
    };
    output0.offset_a -= output0.normal * output0.depth;
    let array = [input0];
    let outputs = [output0];
    let pair_count = array.len();
    TestWide!(
        SphereWide,
        ConvexHullWide,
        array,
        pair_count,
        outputs,
        convex1contact_manifold_wide_to_convex1contact_manifold,
        Some(&container)
    );
}

#[test]
#[wasm_bindgen_test]
fn test_sphere_convex_hull_tester2() {
    let _ = env_logger::builder().is_test(true).try_init();

    let file_input = include_bytes!("resource/sphere_convex_hull/contact2.json");
    let input0: InputTypeData =
        serde_json::from_slice(file_input).expect("file should be proper JSON");
    let convex_hull = ConvexHull::new_unchecked(&input0.b.vertices[..]);
    let mut container = ShapeContainer::default();
    let id = container.add(convex_hull);
    let input0 = InputType {
        a: input0.a,
        b: id,
        speculative_margin: input0.speculative_margin,
        offset_b: input0.offset_b,
        orientation_a: input0.orientation_a,
        orientation_b: input0.orientation_b,
    };
    let mut output0 = Convex1ContactManifold {
        offset_a: Mvec3 {
            x: 0.0,
            y: 0.58578646,
            z: -1.192_092_9E-7,
        },
        normal: Mvec3 {
            x: 0.0,
            y: -1_f32,
            z: 0.0,
        },
        depth: 0.414_213_6_f32,
        feature_id: 0,
        contact_exists: true,
    };
    output0.offset_a -= output0.normal * output0.depth;
    let array = [input0];
    let outputs = [output0];
    let pair_count = array.len();
    TestWide!(
        SphereWide,
        ConvexHullWide,
        array,
        pair_count,
        outputs,
        convex1contact_manifold_wide_to_convex1contact_manifold,
        Some(&container),
        epsilon = 1e-3f32
    );
}

//qhull has no "shift to center" param
#[cfg(not(feature = "qhull"))]
mod shift {
    use glam::{UnitQuat, Vec3};
    use phys_geom::shape::Sphere;

    use crate::collision_tasks::tests::common::{
        build_displaced_convexhull_test, CollisionTestShape,
    };

    #[test]
    fn test_sphere_convex_shift() {
        let shape_a = Sphere::new(2.);
        let convexhull_cuboid_length = Vec3::new(4., 5., 6.);
        let convexhull_displacement_vec = Vec3::new(1e0, 1e4, 1e2);
        let desired_offset_b = Vec3::new(0., 4.1, 0.);
        let rotation_a = UnitQuat::from_euler_default(-1., -2., -3.);
        let rotation_b = UnitQuat::from_euler_default(1., 2., 3.);

        build_displaced_convexhull_test(
            &CollisionTestShape::Sphere(shape_a),
            convexhull_cuboid_length,
            convexhull_displacement_vec,
            desired_offset_b,
            rotation_a,
            rotation_b,
        );
    }
}