use super::{Aabb, Geometry};
use crate::context::WgpuContext;
use crate::core::buffer::{IndexBuffer, VertexBuffer};
use crate::core::vertex::VertexPC;
use glam::Vec3;
pub struct BoundingBoxMesh {
vertex_buffer: VertexBuffer,
aabb: Aabb,
}
impl BoundingBoxMesh {
pub fn new(ctx: &WgpuContext, aabb: Aabb, color: [f32; 4]) -> Self {
let vertices = Self::generate_vertices(&aabb, color);
let vertex_buffer = VertexBuffer::new(ctx, &vertices, Some("bounding box"));
Self {
vertex_buffer,
aabb,
}
}
pub fn from_min_max(ctx: &WgpuContext, min: Vec3, max: Vec3, color: [f32; 4]) -> Self {
Self::new(ctx, Aabb::new(min, max), color)
}
pub fn unit_cube(ctx: &WgpuContext, color: [f32; 4]) -> Self {
Self::from_min_max(ctx, Vec3::splat(-0.5), Vec3::splat(0.5), color)
}
fn generate_vertices(aabb: &Aabb, color: [f32; 4]) -> Vec<VertexPC> {
let min = aabb.min;
let max = aabb.max;
let corners = [
Vec3::new(min.x, min.y, min.z), Vec3::new(max.x, min.y, min.z), Vec3::new(min.x, max.y, min.z), Vec3::new(max.x, max.y, min.z), Vec3::new(min.x, min.y, max.z), Vec3::new(max.x, min.y, max.z), Vec3::new(min.x, max.y, max.z), Vec3::new(max.x, max.y, max.z), ];
let edges = [
(0, 1),
(1, 3),
(3, 2),
(2, 0),
(4, 5),
(5, 7),
(7, 6),
(6, 4),
(0, 4),
(1, 5),
(2, 6),
(3, 7),
];
let mut vertices = Vec::with_capacity(24);
for (i, j) in edges {
vertices.push(VertexPC::new(corners[i].to_array(), color));
vertices.push(VertexPC::new(corners[j].to_array(), color));
}
vertices
}
pub fn vertex_layout() -> wgpu::VertexBufferLayout<'static> {
VertexPC::layout()
}
}
impl Geometry for BoundingBoxMesh {
fn vertex_buffer(&self) -> &VertexBuffer {
&self.vertex_buffer
}
fn index_buffer(&self) -> Option<&IndexBuffer> {
None
}
fn draw_count(&self) -> u32 {
24 }
fn aabb(&self) -> Aabb {
self.aabb
}
}