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 std::time::Instant;

use criterion::*;
use glam_det::{Isometry3, Isometry3x4, Point3x4};
use glamdet_na_conv::ConvTo;
use phys_collision::volume::aabb3wide::Aabb3Wide;
use phys_collision::Aabb3;
use phys_geom::math::Point3Ext;

fn bench_transform_aabb(c: &mut Criterion) {
    let mut group = c.benchmark_group("transform_aabb");

    for body_cnt in [1000, 5000, 10000] {
        let mut body_aabb = vec![Aabb3::default(); body_cnt];
        let mut body_aabb_result = vec![Aabb3::default(); body_cnt];
        let mut body_transform = vec![Isometry3::IDENTITY; body_cnt];
        for i in 0..body_cnt {
            body_aabb[i] = Aabb3::new([-1.0f32, -1.0f32, -1.0f32], [1f32, 1f32, 1f32]);
            body_transform[i] = Isometry3::from_rotation_x(i as f32);
        }
        let id = BenchmarkId::new("sequence-simd", format!("{body_cnt}"));
        group.bench_function(id, |b| {
            b.iter_custom(|iters| {
                let start = Instant::now();
                for _ in 0..iters {
                    for i in (0..body_cnt).step_by(4) {
                        let aabb3wide = Aabb3Wide::new(
                            Point3x4::compose_soa(&[
                                body_aabb[i].min().to_array().into(),
                                body_aabb[i + 1].min().to_array().into(),
                                body_aabb[i + 2].min().to_array().into(),
                                body_aabb[i + 3].min().to_array().into(),
                            ]),
                            Point3x4::compose_soa(&[
                                body_aabb[i].max().to_array().into(),
                                body_aabb[i + 1].max().to_array().into(),
                                body_aabb[i + 2].max().to_array().into(),
                                body_aabb[i + 3].max().to_array().into(),
                            ]),
                        );
                        let transform = Isometry3x4::compose_soa(&[
                            body_transform[i],
                            body_transform[i + 1],
                            body_transform[i + 2],
                            body_transform[i + 3],
                        ]);
                        let aabb3wide_result = aabb3wide.transform(transform);
                        body_aabb_result[i] = aabb3wide_result.extract(0);
                        body_aabb_result[i + 1] = aabb3wide_result.extract(1);
                        body_aabb_result[i + 2] = aabb3wide_result.extract(2);
                        body_aabb_result[i + 3] = aabb3wide_result.extract(3);
                    }
                }
                start.elapsed()
            });
        });

        let id = BenchmarkId::new("sequence", format!("{body_cnt}"));
        group.bench_function(id, |b| {
            b.iter_custom(|iters| {
                let start = Instant::now();
                for _ in 0..iters {
                    for i in 0..body_cnt {
                        body_aabb_result[i] = body_aabb[i].transform(body_transform[i].conv_to());
                    }
                }
                start.elapsed()
            });
        });
    }
}

criterion_group!(compute_aabb, bench_transform_aabb,);
criterion_main!(compute_aabb);