use crate::scene::{NodeId, Scene3D};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct AppendOffsets {
pub nodes: u32,
pub meshes: u32,
pub materials: u32,
pub textures: u32,
pub skeletons: u32,
pub skins: u32,
pub animations: u32,
pub cameras: u32,
pub lights: u32,
pub audio_sources: u32,
pub audio_emitters: u32,
}
impl Scene3D {
pub fn append(&mut self, other: &Scene3D) -> AppendOffsets {
let off = AppendOffsets {
nodes: self.nodes.len() as u32,
meshes: self.meshes.len() as u32,
materials: self.materials.len() as u32,
textures: self.textures.len() as u32,
skeletons: self.skeletons.len() as u32,
skins: self.skins.len() as u32,
animations: self.animations.len() as u32,
cameras: self.cameras.len() as u32,
lights: self.lights.len() as u32,
audio_sources: self.audio_sources.len() as u32,
audio_emitters: self.audio_emitters.len() as u32,
};
for node in &other.nodes {
let mut n = node.clone();
for c in &mut n.children {
c.0 += off.nodes;
}
if let Some(m) = &mut n.mesh {
m.0 += off.meshes;
}
if let Some(c) = &mut n.camera {
c.0 += off.cameras;
}
if let Some(l) = &mut n.light {
l.0 += off.lights;
}
if let Some(s) = &mut n.skin {
s.0 += off.skins;
}
if let Some(e) = &mut n.audio_emitter {
e.0 += off.audio_emitters;
}
self.nodes.push(n);
}
let variant_map: Vec<u32> = other
.material_variants
.iter()
.map(|name| self.find_or_add_material_variant(name).0)
.collect();
let dangling_base = self.material_variants.len() as u32;
for mesh in &other.meshes {
let mut m = mesh.clone();
for prim in &mut m.primitives {
if let Some(mat) = &mut prim.material {
mat.0 += off.materials;
}
for mapping in &mut prim.variant_mappings {
mapping.material.0 += off.materials;
for v in &mut mapping.variants {
match variant_map.get(v.0 as usize) {
Some(&mapped) => v.0 = mapped,
None => v.0 = v.0.saturating_add(dangling_base),
}
}
}
}
self.meshes.push(m);
}
let tex_off = off.textures;
for material in &other.materials {
let mut mat = material.clone();
mat.map_texture_ids(|mut t| {
t.0 += tex_off;
t
});
self.materials.push(mat);
}
self.textures.extend(other.textures.iter().cloned());
for skel in &other.skeletons {
let mut s = skel.clone();
for j in &mut s.joints {
j.0 += off.nodes;
}
self.skeletons.push(s);
}
for skin in &other.skins {
let mut s = *skin;
s.skeleton.0 += off.skeletons;
if let Some(r) = &mut s.root_node {
r.0 += off.nodes;
}
self.skins.push(s);
}
for anim in &other.animations {
let mut a = anim.clone();
for ch in &mut a.channels {
ch.target.node.0 += off.nodes;
}
self.animations.push(a);
}
self.cameras.extend(other.cameras.iter().cloned());
self.lights.extend(other.lights.iter().cloned());
self.audio_sources
.extend(other.audio_sources.iter().cloned());
for em in &other.audio_emitters {
let mut e = em.clone();
e.source.0 += off.audio_sources;
self.audio_emitters.push(e);
}
for r in &other.roots {
self.roots.push(NodeId(r.0 + off.nodes));
}
off
}
}