use alloc::string::String;
use alloc::vec::Vec;
pub use concinnity_core::components::cook::{
Camera3D, EnvironmentMap, Font, Material, Mesh, VertexData,
};
use concinnity_core::components::{self, ProceduralMesh};
pub fn procedural_mesh(mesh: &ProceduralMesh) -> Result<Vec<u8>, String> {
concinnity_core::bake::payload::procedural_mesh(mesh)
}
pub fn mesh(mesh: &Mesh) -> Result<Vec<u8>, String> {
concinnity_core::bake::payload::mesh(mesh)
}
#[cfg(feature = "std")]
pub fn environment_map(map: &EnvironmentMap) -> Result<Vec<u8>, String> {
concinnity_core::bake::payload::environment_map(map, &concinnity_engine::jobs::PoolRows)
}
#[cfg(not(feature = "std"))]
pub fn environment_map(map: &EnvironmentMap) -> Result<Vec<u8>, String> {
concinnity_core::bake::payload::environment_map(
map,
&concinnity_core::bake::environment_map::Serial,
)
}
pub fn font(font: &Font) -> Result<Vec<u8>, String> {
concinnity_core::bake::payload::font(font)
}
pub fn camera(args: Camera3D) -> components::Camera3D {
components::Camera3D::bake(args)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn baked_data_reaches_a_world_that_starts() {
let mesh = ProceduralMesh {
generator: "box".into(),
half_extents: Some([0.7, 0.7, 0.7]),
..Default::default()
};
let payload = procedural_mesh(&mesh).expect("the box bakes");
let mut world = crate::World::new();
let mesh = world.add_mesh(mesh, payload);
let stone = world.add_material(Material {
roughness: 0.2,
..Default::default()
});
world.add_component(components::Prop {
mesh: Some(mesh),
material: Some(stone),
..Default::default()
});
assert_eq!((mesh.index(), stone.index()), (0, 0));
crate::test_support::assert_starts_headless(crate::App::from_world(world));
}
#[test]
fn raw_geometry_reaches_a_world_that_starts() {
let vertex = |pos: [f32; 3]| VertexData {
pos,
color: [1.0; 3],
uv: [0.0; 2],
};
let triangle = Mesh {
vertices: alloc::vec![
vertex([0.0, 0.0, 0.0]),
vertex([1.0, 0.0, 0.0]),
vertex([0.0, 1.0, 0.0]),
],
indices: alloc::vec![0, 1, 2],
..Default::default()
};
let payload = mesh(&triangle).expect("the triangle bakes");
let mut world = crate::World::new();
let handle = world.add_mesh(triangle, payload);
world.add_component(components::Prop {
mesh: Some(handle),
..Default::default()
});
assert_eq!(handle.index(), 0);
crate::test_support::assert_starts_headless(crate::App::from_world(world));
}
#[test]
fn a_file_backed_value_is_refused_toward_the_cook() {
let err = procedural_mesh(&ProceduralMesh {
generator: "heightfield".into(),
..Default::default()
})
.expect_err("an image-decoding generator");
assert!(err.contains("cook"), "{err}");
let err = font(&Font {
path: "face.ttf".into(),
..Default::default()
})
.expect_err("a file-backed face");
assert!(err.contains("cook"), "{err}");
let err = mesh(&Mesh {
source: "chair.glb".into(),
..Default::default()
})
.expect_err("a file-backed mesh");
assert!(err.contains("cook"), "{err}");
}
#[test]
fn a_baked_camera_carries_its_view() {
let baked = camera(Camera3D {
position: [0.0, 2.0, 8.0],
pitch: -0.245,
..Default::default()
});
assert_ne!(baked.view_matrix, [[0.0; 4]; 4]);
}
#[test]
fn the_sky_bakes_a_readable_environment_payload() {
let payload = environment_map(&EnvironmentMap {
generator: "sky".into(),
prefilter_face_size: 16,
irradiance_face_size: 8,
prefilter_samples: 4,
..Default::default()
})
.expect("the sky bakes");
let view = concinnity_core::bake::environment_map::deserialise(&payload)
.expect("the payload reads back");
assert_eq!(view.prefilter_face, 16);
let mut world = crate::World::new();
let handle = world.add_environment_map(payload);
assert_eq!(handle.index(), 0);
}
}