mod axes;
mod bounds;
mod instanced;
mod lines;
mod mesh;
pub use axes::Axes;
pub use bounds::BoundingBoxMesh;
pub use instanced::InstancedMesh;
pub use lines::{LineStrip, Lines};
pub use mesh::Mesh;
use crate::core::buffer::{IndexBuffer, VertexBuffer};
use glam::Vec3;
#[derive(Debug, Clone, Copy)]
pub struct Aabb {
pub min: Vec3,
pub max: Vec3,
}
impl Aabb {
pub fn new(min: Vec3, max: Vec3) -> Self {
Self { min, max }
}
pub fn from_points(points: impl IntoIterator<Item = Vec3>) -> Self {
let mut min = Vec3::splat(f32::MAX);
let mut max = Vec3::splat(f32::MIN);
for p in points {
min = min.min(p);
max = max.max(p);
}
Self { min, max }
}
pub fn center(&self) -> Vec3 {
(self.min + self.max) * 0.5
}
pub fn size(&self) -> Vec3 {
self.max - self.min
}
pub fn corners(&self) -> [Vec3; 8] {
[
Vec3::new(self.min.x, self.min.y, self.min.z),
Vec3::new(self.max.x, self.min.y, self.min.z),
Vec3::new(self.min.x, self.max.y, self.min.z),
Vec3::new(self.min.x, self.min.y, self.max.z),
Vec3::new(self.max.x, self.max.y, self.min.z),
Vec3::new(self.max.x, self.min.y, self.max.z),
Vec3::new(self.min.x, self.max.y, self.max.z),
Vec3::new(self.max.x, self.max.y, self.max.z),
]
}
pub fn contains(&self, point: Vec3) -> bool {
point.x >= self.min.x
&& point.x <= self.max.x
&& point.y >= self.min.y
&& point.y <= self.max.y
&& point.z >= self.min.z
&& point.z <= self.max.z
}
pub fn merge(&self, other: &Aabb) -> Self {
Self {
min: self.min.min(other.min),
max: self.max.max(other.max),
}
}
}
impl Default for Aabb {
fn default() -> Self {
Self {
min: Vec3::ZERO,
max: Vec3::ZERO,
}
}
}
pub trait Geometry {
fn vertex_buffer(&self) -> &VertexBuffer;
fn index_buffer(&self) -> Option<&IndexBuffer>;
fn draw_count(&self) -> u32;
fn aabb(&self) -> Aabb;
fn draw<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) {
render_pass.set_vertex_buffer(0, self.vertex_buffer().slice());
if let Some(index_buffer) = self.index_buffer() {
render_pass.set_index_buffer(index_buffer.slice(), wgpu::IndexFormat::Uint32);
render_pass.draw_indexed(0..self.draw_count(), 0, 0..1);
} else {
render_pass.draw(0..self.draw_count(), 0..1);
}
}
}