1use nightshade::ecs::scene::commands::{save_scene_binary_to_bytes, spawn_scene, subtree_to_scene};
7use nightshade::ecs::scene::{
8 Scene, SceneError, apply_scene_settings, capture_scene_settings, embed_referenced_meshes,
9 embed_referenced_textures, load_scene_binary_from_bytes,
10};
11use nightshade::prelude::{Entity, Vec3, World, tracing};
12
13#[derive(Clone)]
16pub struct Prefab {
17 scene: Scene,
18}
19
20pub fn make_prefab(world: &mut World, root: Entity) -> Prefab {
23 let mut scene = subtree_to_scene(world, root, "prefab");
24 embed_referenced_meshes(world, &mut scene);
25 embed_referenced_textures(world, &mut scene);
26 Prefab { scene }
27}
28
29pub fn spawn_prefab(world: &mut World, prefab: &Prefab, position: Vec3) -> Vec<Entity> {
34 let settings = capture_scene_settings(world);
35 let atmosphere = world
36 .res::<nightshade::render::config::RenderSettings>()
37 .atmosphere;
38 let roots = match spawn_scene(world, &prefab.scene, None) {
39 Ok(result) => result.root_entities,
40 Err(error) => {
41 tracing::error!("Failed to spawn prefab: {error}");
42 Vec::new()
43 }
44 };
45 apply_scene_settings(world, &settings);
46 world
47 .res_mut::<nightshade::render::config::RenderSettings>()
48 .atmosphere = atmosphere;
49 for &root in &roots {
50 crate::placement::set_position(world, root, position);
51 }
52 roots
53}
54
55pub(crate) fn register_prefab_command(world: &mut World, name: &str, root: Entity) -> bool {
59 let prefab = make_prefab(world, root);
60 world
61 .res_mut::<nightshade::ecs::asset_state::AssetState>()
62 .scene_prefabs
63 .insert(name.to_string(), prefab.scene);
64 true
65}
66
67pub(crate) fn spawn_prefab_named_command(
70 world: &mut World,
71 name: &str,
72 position: Vec3,
73) -> Vec<Entity> {
74 let Some(scene) = world
75 .res::<nightshade::ecs::asset_state::AssetState>()
76 .scene_prefabs
77 .get(name)
78 .cloned()
79 else {
80 return Vec::new();
81 };
82 spawn_prefab(world, &Prefab { scene }, position)
83}
84
85pub fn save_prefab(prefab: &Prefab) -> Result<Vec<u8>, SceneError> {
87 let mut scene = prefab.scene.clone();
88 save_scene_binary_to_bytes(&mut scene)
89}
90
91pub fn load_prefab(bytes: &[u8]) -> Result<Prefab, SceneError> {
93 let scene = load_scene_binary_from_bytes(bytes)?;
94 Ok(Prefab { scene })
95}