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 criterion::{black_box, criterion_group, criterion_main, Criterion};
use glam_det::{UnitQuat, Vec3};
use phys_collision::Shape;
use phys_geom::shape::{Capsule, Cuboid};

pub struct ContactContext<'a> {
    pub a: &'a Shape,
    pub b: &'a Shape,
    pub offset_b: &'a Vec3,
    pub orientation_a: &'a UnitQuat,
    pub orientation_b: &'a UnitQuat,
}
#[inline(never)]
pub fn transfer_parameter_by_ref_ref(p: &ContactContext) -> f32 {
    let a = *p.a;
    let b = *p.b;
    let offset_b = *p.offset_b;
    let orientation_a = *p.orientation_a;
    let orientation_b = *p.orientation_b;

    let mut v = match (a, b) {
        (Shape::Capsule(capsule), Shape::Cuboid(cuboid)) => {
            let v1 = capsule.radius() + capsule.half_height();
            let extent = cuboid.half_length();
            v1 + extent[0] + extent[1] + extent[2]
        }
        (_, _) => {
            unreachable!()
        }
    };
    v = v + offset_b.x + offset_b.y + offset_b.z;
    v = v + orientation_a.x + orientation_a.y + orientation_a.z + orientation_a.w;
    v = v + orientation_b.x + orientation_b.y + orientation_b.z + orientation_b.w;
    v
}
pub struct ContactContextValue {
    pub a: Shape,
    pub b: Shape,
    pub offset_b: Vec3,
    pub orientation_a: UnitQuat,
    pub orientation_b: UnitQuat,
}

#[inline(never)]
pub fn transfer_parameter_by_ref_value(p: &ContactContextValue) -> f32 {
    let a = p.a;
    let b = p.b;
    let offset_b = p.offset_b;
    let orientation_a = p.orientation_a;
    let orientation_b = p.orientation_b;

    let mut v = match (a, b) {
        (Shape::Capsule(capsule), Shape::Cuboid(cuboid)) => {
            let v1 = capsule.radius() + capsule.half_height();
            let extent = cuboid.half_length();
            v1 + extent[0] + extent[1] + extent[2]
        }
        (_, _) => {
            unreachable!()
        }
    };
    v = v + offset_b.x + offset_b.y + offset_b.z;
    v = v + orientation_a.x + orientation_a.y + orientation_a.z + orientation_a.w;
    v = v + orientation_b.x + orientation_b.y + orientation_b.z + orientation_b.w;
    v
}

fn parameter_bench(c: &mut Criterion) {
    let a = Shape::Capsule(Capsule::new(1.0, 1.0));
    let b = Shape::Cuboid(Cuboid::new_xyz(1.0, 1.0, 1.0));
    let offset_b: Vec3 = Default::default();
    let orientation_a: UnitQuat = Default::default();
    let orientation_b: UnitQuat = Default::default();
    let a = black_box(a);
    let b = black_box(b);
    let offset_b = black_box(offset_b);
    let orientation_a = black_box(orientation_a);
    let orientation_b = black_box(orientation_b);
    let value = ContactContextValue {
        a,
        b,
        offset_b,
        orientation_a,
        orientation_b,
    };
    c.bench_function("parameter_ref_value", |iter| {
        iter.iter(|| {
            let v = transfer_parameter_by_ref_value(&value);
            black_box(v);
        })
    });
    let value = ContactContext {
        a: &a,
        b: &b,
        offset_b: &offset_b,
        orientation_a: &orientation_a,
        orientation_b: &orientation_b,
    };
    c.bench_function("parameter_ref_ref", |iter| {
        iter.iter(|| {
            let v = transfer_parameter_by_ref_ref(&value);
            black_box(v);
        })
    });

    c.bench_function("parameter_ref_value_and_copy_value", |iter| {
        iter.iter(|| {
            let value = ContactContextValue {
                a,
                b,
                offset_b,
                orientation_a,
                orientation_b,
            };
            let v = transfer_parameter_by_ref_value(&value);
            black_box(v);
        })
    });

    c.bench_function("parameter_ref_ref_and_copy_reference", |iter| {
        iter.iter(|| {
            let value = ContactContext {
                a: &a,
                b: &b,
                offset_b: &offset_b,
                orientation_a: &orientation_a,
                orientation_b: &orientation_b,
            };
            let v = transfer_parameter_by_ref_ref(&value);
            black_box(v);
        })
    });
}

criterion_group!(benches_parameter_transfer, parameter_bench);

criterion_main!(benches_parameter_transfer);