use crate::{BASE_FACING, Hex, HexLayout, InsetOptions, MeshInfo, UVOptions, face::Hexagon};
use glam::{Quat, Vec3};
use super::FaceOptions;
#[derive(Debug, Clone)]
pub struct PlaneMeshBuilder<'l> {
pub layout: &'l HexLayout,
pub pos: Hex,
pub offset: Option<Vec3>,
pub scale: Option<Vec3>,
pub rotation: Option<Quat>,
pub face_options: FaceOptions,
pub center_aligned: bool,
}
impl<'l> PlaneMeshBuilder<'l> {
#[must_use]
pub const fn new(layout: &'l HexLayout) -> Self {
Self {
layout,
pos: Hex::ZERO,
rotation: None,
offset: None,
scale: None,
face_options: FaceOptions::new(),
center_aligned: false,
}
}
#[must_use]
pub const fn at(mut self, pos: Hex) -> Self {
self.pos = pos;
self
}
#[must_use]
pub fn facing(mut self, facing: Vec3) -> Self {
self.rotation = Some(Quat::from_rotation_arc(BASE_FACING, facing.normalize()));
self
}
#[must_use]
pub const fn with_rotation(mut self, rotation: Quat) -> Self {
self.rotation = Some(rotation);
self
}
#[must_use]
pub const fn with_offset(mut self, offset: Vec3) -> Self {
self.offset = Some(offset);
self
}
#[must_use]
pub const fn with_scale(mut self, scale: Vec3) -> Self {
self.scale = Some(scale);
self
}
#[must_use]
pub const fn with_face_options(mut self, options: FaceOptions) -> Self {
self.face_options = options;
self
}
#[must_use]
pub const fn with_uv_options(mut self, uv_options: UVOptions) -> Self {
self.face_options.uv = uv_options;
self
}
#[must_use]
#[inline]
pub const fn with_inset_options(mut self, opts: InsetOptions) -> Self {
self.face_options.insetting = Some(opts);
self
}
#[must_use]
#[inline]
pub const fn center_aligned(mut self) -> Self {
self.center_aligned = true;
self
}
#[must_use]
pub fn build(self) -> MeshInfo {
let face = Hexagon::center_aligned(self.layout);
let pos = if self.center_aligned {
self.layout.hex_to_center_aligned_world_pos(self.pos)
} else {
self.layout.hex_to_world_pos(self.pos)
};
let mut offset = Vec3::new(pos.x, 0.0, pos.y);
let mut mesh = if let Some(inset) = self.face_options.insetting {
face.inset(inset.mode, inset.scale, inset.keep_inner_face)
} else {
face.into()
};
if let Some(scale) = self.scale {
mesh = mesh.with_scale(scale);
}
if let Some(rotation) = self.rotation {
mesh = mesh.rotated(rotation);
}
if let Some(custom_offset) = self.offset {
offset += custom_offset;
}
mesh = mesh.with_offset(offset);
self.face_options.uv.alter_uvs(&mut mesh.uvs);
mesh
}
}