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::nums::{i32x4, Num};
use glam_det::Point3;
use wasm_bindgen_test::*;

use crate::ConvexHull as MotphysConvexHull;
wasm_bindgen_test_configure!(run_in_browser);

#[test]
#[wasm_bindgen_test]
fn test_convex_hull_create() {
    let _ = env_logger::builder().is_test(true).try_init();
    let file_input = include_bytes!("resource/convex_hull_create/points.json");
    let input0: Vec<Point3> =
        serde_json::from_slice(file_input).expect("file should be proper JSON");
    let _convex_hull = MotphysConvexHull::new_unchecked(&input0);
}
#[cfg(feature = "qhull")]
fn are_circular_equal<T: PartialEq + Clone>(arr1: &[T], arr2: &[T]) -> bool {
    if arr1.len() != arr2.len() {
        return false;
    }

    let doubled_arr1: Vec<T> = arr1.iter().chain(arr1.iter()).cloned().collect();

    is_subarray(&doubled_arr1, arr2)
}
#[cfg(feature = "qhull")]
fn is_subarray<T: PartialEq>(arr1: &[T], arr2: &[T]) -> bool {
    for i in 0..=arr1.len() - arr2.len() {
        if &arr1[i..i + arr2.len()] == arr2 {
            return true;
        }
    }
    false
}

#[test]
#[wasm_bindgen_test]
fn tail_bounding_plane() {
    let file_input = include_bytes!("resource/convex_hull_create/convex_hull_diamond.json");
    let input0: Vec<Point3> =
        serde_json::from_slice(file_input).expect("file should be proper JSON");
    let convex_hull = MotphysConvexHull::new_unchecked(&input0);
    let face_count = convex_hull.get_face_count();
    let bounding_plane_wide_count = convex_hull.get_bounding_plane_wide_count();
    let lane_count = i32x4::lanes();
    let bounding_plane_count = bounding_plane_wide_count * lane_count;
    assert!(bounding_plane_count >= face_count);
    for i in face_count..bounding_plane_count {
        let tail_offset = convex_hull.get_bounding_plane_offset(i);
        assert_relative_eq!(tail_offset, f32::MIN);
    }
}

#[test]
#[wasm_bindgen_test]
#[cfg(feature = "qhull")]
fn tail_qhull() {
    let input0: Vec<Point3> = vec![
        //cube points
        Point3::new(0.0, 0.0, 0.0),
        Point3::new(1.0, 0.0, 0.0),
        Point3::new(1.0, 1.0, 0.0),
        Point3::new(0.0, 1.0, 0.0),
        Point3::new(0.0, 0.0, 1.0),
        Point3::new(1.0, 0.0, 1.0),
        Point3::new(1.0, 1.0, 1.0),
        Point3::new(0.0, 1.0, 1.0),
    ];

    let convex_hull = MotphysConvexHull::new_unchecked(&input0);
    let face_count = convex_hull.get_face_count();
    assert_eq!(face_count, 6);
    let expected_results = [
        vec![5, 4, 0, 1],
        vec![3, 2, 1, 0],
        vec![6, 2, 3, 7],
        vec![5, 6, 7, 4],
        vec![3, 0, 4, 7],
        vec![5, 1, 2, 6],
    ];
    #[allow(clippy::needless_range_loop)]
    for i in 0..face_count {
        let vertices = convex_hull.get_vertex_indices(i);
        let vertices = vertices.iter().map(|v| v.index()).collect::<Vec<_>>();
        are_circular_equal(&vertices, &expected_results[i]);
        println!("vertices {vertices:?}");
    }
}

#[test]
#[wasm_bindgen_test]
fn test_convex_hull2() {
    let _ = env_logger::builder().is_test(true).try_init();
    let points: Vec<Point3> =
        serde_json::from_slice(include_bytes!("resource/convex_hull_create/points2.json")).unwrap();
    let _convex_hull = MotphysConvexHull::new_unchecked(&points);
}

#[test]
#[wasm_bindgen_test]
fn test_convex_hull3() {
    let _ = env_logger::builder().is_test(true).try_init();
    let points: Vec<Point3> =
        serde_json::from_slice(include_bytes!("resource/convex_hull_create/points3.json")).unwrap();
    let _convex_hull = MotphysConvexHull::new_unchecked(&points);
}

#[test]
#[wasm_bindgen_test]
#[cfg(feature = "qhull")]
fn test_convex_hull_4() {
    let _ = env_logger::builder().is_test(true).try_init();
    let points: Vec<Point3> = serde_json::from_slice(include_bytes!(
        "resource/convex_hull_create/l_leg_ankle_link_points.json"
    ))
    .unwrap();
    let convex_hull = MotphysConvexHull::new_unchecked(&points);
    let face_count = convex_hull.get_face_count();
    assert_eq!(face_count, 2811);
}