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);