use std::io;
use draco_core::mesh::Mesh;
use crate::traits::{Reader, Writer};
#[derive(Debug, Clone)]
pub struct Transform {
pub matrix: [[f32; 4]; 4],
}
#[derive(Debug, Clone)]
pub struct MeshInstance {
pub name: Option<String>,
pub mesh: Mesh,
pub transform: Option<Transform>,
}
#[derive(Debug, Clone)]
pub struct SceneNode {
pub name: Option<String>,
pub transform: Option<Transform>,
pub mesh_instances: Vec<MeshInstance>,
pub children: Vec<SceneNode>,
}
impl SceneNode {
pub fn new(name: Option<String>) -> Self {
Self {
name,
transform: None,
mesh_instances: Vec::new(),
children: Vec::new(),
}
}
pub fn with_mesh_instances(name: Option<String>, mesh_instances: Vec<MeshInstance>) -> Self {
Self {
name,
transform: None,
mesh_instances,
children: Vec::new(),
}
}
}
#[derive(Debug, Clone)]
pub struct Scene {
pub name: Option<String>,
pub root_nodes: Vec<SceneNode>,
}
impl Scene {
pub fn new(name: Option<String>) -> Self {
Self {
name,
root_nodes: Vec::new(),
}
}
pub fn from_mesh_instances(name: Option<String>, mesh_instances: Vec<MeshInstance>) -> Self {
Self {
root_nodes: vec![SceneNode::with_mesh_instances(name.clone(), mesh_instances)],
name,
}
}
}
pub trait SceneReader: Reader {
fn read_scene(&mut self) -> io::Result<Scene>;
fn read_scenes(&mut self) -> io::Result<Vec<Scene>> {
Ok(vec![self.read_scene()?])
}
}
pub trait SceneWriter: Writer {
fn add_scene(&mut self, scene: &Scene) -> io::Result<()>;
fn add_scenes(&mut self, scenes: &[Scene]) -> io::Result<()> {
for scene in scenes {
self.add_scene(scene)?;
}
Ok(())
}
}
pub fn flatten_to_scene<R: Reader>(reader: &mut R, name: Option<String>) -> io::Result<Scene> {
let meshes = reader.read_meshes()?;
let mesh_instances = meshes
.into_iter()
.map(|mesh| MeshInstance {
name: None,
mesh,
transform: None,
})
.collect();
Ok(Scene::from_mesh_instances(name, mesh_instances))
}