qchull 2.0.1-beta.0

Provides quick convex hull algorithm
// Copyright (C) 2020-2025 qchull 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 glam_det::{Point3, UnitVec3, Vec3};

pub struct ConvexHull {
    pub points: Vec<Point3>,
    pub bounding_planes: Vec<HalfPlane>,
    pub face_indices_start: Vec<u32>,
    pub face_vertex_indices: Vec<u32>,
    pub center: Vec3,
    pub volume: f32,
    /// The offset vector applied to all points if align-to-center is enabled.
    ///
    /// - If `None`, align-to-center is disabled, and points remain at their original positions.
    /// - If `Some(Vec3)`, align-to-center is enabled, and points are shifted by the given vector,
    ///   meaning the original positions are at `pos + shift_center`.
    pub shift_center: Option<Vec3>,
}

/// n⋅x≤d
/// n is the normal of the plane
/// d is the offset of the plane
/// x is the point on the plane
/// so the normal of the plane is toward the outside of the convex hull
pub struct HalfPlane {
    pub center: Point3,
    pub normal: UnitVec3,
    pub offset: f32,
}

impl HalfPlane {
    #[inline]
    pub(crate) fn new(center: Point3, normal: UnitVec3, offset: f32) -> Self {
        Self {
            center,
            normal,
            offset,
        }
    }
}

impl ConvexHull {
    #[inline]
    pub(crate) fn with_points(points: Vec<Point3>) -> Self {
        Self {
            points,
            bounding_planes: vec![],
            face_indices_start: vec![],
            face_vertex_indices: vec![],
            center: Vec3::default(),
            volume: 1.0,
            shift_center: None,
        }
    }
}