use super::group::collate_refs;
use crate::mesh::{InstanceMeta, Mesh};
use nalgebra::Matrix4;
const IDENTITY16: [f64; 16] = [
1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, ];
pub(super) fn compose_world(meta: &InstanceMeta) -> Matrix4<f64> {
let t = Matrix4::from_row_slice(&meta.transform);
let l = Matrix4::from_row_slice(meta.local_transform.as_ref().unwrap_or(&IDENTITY16));
let c = Matrix4::from_row_slice(meta.canonical_transform.as_ref().unwrap_or(&IDENTITY16));
t * l * c
}
pub(super) fn mat4_to_row_major_f32(m: &Matrix4<f64>) -> [f32; 16] {
let mut out = [0.0f32; 16];
for r in 0..4 {
for c in 0..4 {
out[r * 4 + c] = m[(r, c)] as f32;
}
}
out
}
#[derive(Debug, Clone)]
pub struct InstanceOccurrence {
pub mesh_index: usize,
pub transform: [f32; 16],
}
#[derive(Debug, Clone)]
pub struct InstanceTemplate {
pub rep_identity: u128,
pub template_index: usize,
pub occurrences: Vec<InstanceOccurrence>,
}
#[derive(Debug, Clone, Default)]
pub struct Collated {
pub templates: Vec<InstanceTemplate>,
pub flat_indices: Vec<usize>,
pub dropped_placeholders: usize,
pub verification_rejections: usize,
}
impl Collated {
pub fn unique_geometry_count(&self) -> usize {
self.templates.len() + self.flat_indices.len()
}
pub fn instanced_occurrence_count(&self) -> usize {
self.templates.iter().map(|t| t.occurrences.len()).sum()
}
}
pub struct InstanceMeshRef<'a> {
pub positions: &'a [f32],
pub normals: &'a [f32],
pub indices: &'a [u32],
pub origin: [f64; 3],
pub instance_meta: Option<&'a InstanceMeta>,
pub entity_id: u32,
pub color: [f32; 4],
pub item_id: Option<u32>,
}
impl<'a> InstanceMeshRef<'a> {
pub fn from_mesh(m: &'a Mesh) -> Self {
InstanceMeshRef {
positions: &m.positions,
normals: &m.normals,
indices: &m.indices,
origin: m.origin,
instance_meta: m.instance_meta.as_ref(),
entity_id: 0,
color: [0.0; 4],
item_id: None,
}
}
}
pub(super) fn to_post_rtc(mut m: Matrix4<f64>, rtc: [f64; 3]) -> Matrix4<f64> {
m[(0, 3)] -= rtc[0];
m[(1, 3)] -= rtc[1];
m[(2, 3)] -= rtc[2];
m
}
pub use super::dont_bake::{
bake_source_at_world, compose_instance_world_row_major, instance_rel_row_major_f32,
};
pub fn collate_instances(meshes: &[Mesh], min_group: usize, rtc: [f64; 3]) -> Collated {
let refs: Vec<InstanceMeshRef> = meshes.iter().map(InstanceMeshRef::from_mesh).collect();
collate_refs(&refs, min_group, rtc)
}
pub use super::verify::verify_recomposition;