mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-28 08:58:07 +00:00
Getting warmer...
This commit is contained in:
+14
-5
@@ -44,9 +44,9 @@ impl Plugin for ScenePlugin {
|
||||
PostUpdate,
|
||||
(
|
||||
wasm::notify_entity_spawn_changes.pipe(error),
|
||||
wasm::save_scene_system
|
||||
.pipe(error)
|
||||
.run_if(wasm::scene_download_requested),
|
||||
wasm::save_scene_system.pipe(error).run_if(
|
||||
resource_exists::<ActiveScene>().and_then(wasm::scene_download_requested),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -62,6 +62,9 @@ struct NewScene {
|
||||
pub gltf: Option<Handle<Gltf>>,
|
||||
}
|
||||
|
||||
#[derive(Resource, Deref, DerefMut)]
|
||||
pub struct ActiveScene(pub Handle<Scene>);
|
||||
|
||||
#[derive(Component)]
|
||||
struct Inspectable;
|
||||
|
||||
@@ -161,7 +164,8 @@ fn scene_inst_ready(r_scene_mgr: Res<SceneSpawner>, q_scene_inst: Query<&SceneIn
|
||||
|
||||
fn mark_scene_objects(
|
||||
mut cmd: Commands,
|
||||
r_scene: Res<NewScene>,
|
||||
r_new_scene: Res<NewScene>,
|
||||
mut r_active_scene: Option<ResMut<ActiveScene>>,
|
||||
r_assets: Res<AssetServer>,
|
||||
ra_gltfs: Res<Assets<Gltf>>,
|
||||
ra_gltf_nodes: Res<Assets<GltfNode>>,
|
||||
@@ -212,7 +216,7 @@ fn mark_scene_objects(
|
||||
));
|
||||
});
|
||||
|
||||
if let Some(gltf) = r_scene
|
||||
if let Some(gltf) = r_new_scene
|
||||
.gltf
|
||||
.as_ref()
|
||||
.and_then(|handle| ra_gltfs.get(handle))
|
||||
@@ -273,6 +277,11 @@ fn mark_scene_objects(
|
||||
}
|
||||
}
|
||||
|
||||
// Set the new scene as the active scene
|
||||
match r_active_scene.as_mut() {
|
||||
Some(active_scene) => ***active_scene = r_new_scene.clone(),
|
||||
None => cmd.insert_resource(ActiveScene(r_new_scene.clone())),
|
||||
};
|
||||
cmd.remove_resource::<NewScene>();
|
||||
}
|
||||
|
||||
|
||||
+23
-44
@@ -1,8 +1,6 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use bevy::{
|
||||
prelude::*, reflect::serde::TypedReflectSerializer, utils::HashSet, window::PrimaryWindow,
|
||||
};
|
||||
use bevy::{prelude::*, scene::SceneInstance, utils::HashSet, window::PrimaryWindow};
|
||||
use serde::Serialize;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
@@ -22,53 +20,34 @@ pub(super) fn scene_download_requested() -> bool {
|
||||
}
|
||||
|
||||
pub(super) fn save_scene_system(world: &mut World) -> Result<(), String> {
|
||||
let mut scene = DynamicScene::from_world(world);
|
||||
let scene_inst = world
|
||||
.query::<&SceneInstance>()
|
||||
.get_single(world)
|
||||
.map_err(|err| format!("{err}"))?;
|
||||
|
||||
let scene_mgr = world.resource::<SceneSpawner>();
|
||||
|
||||
let mut builder = DynamicSceneBuilder::from_world(world);
|
||||
builder
|
||||
.allow_all()
|
||||
.allow_all_resources()
|
||||
.deny::<ComputedVisibility>()
|
||||
.deny_resource::<Time>()
|
||||
.extract_entities(scene_mgr.iter_instance_entities(**scene_inst))
|
||||
.remove_empty_entities()
|
||||
.extract_resources();
|
||||
|
||||
let scene = builder.build();
|
||||
|
||||
let type_registry = world.resource::<AppTypeRegistry>();
|
||||
|
||||
#[allow(clippy::borrowed_box)]
|
||||
let is_serializable = |reflect: &Box<dyn Reflect>| -> bool {
|
||||
TypedReflectSerializer::new(&**reflect, &type_registry.read())
|
||||
.serialize(&wasm::SERIALIZER)
|
||||
.is_ok()
|
||||
};
|
||||
|
||||
// FIXME: This includes some stuff we don't want, including (most
|
||||
// importantly) the _window_. We probably want to grab just the
|
||||
// main camera, the skybox, the glTF scene instance and its
|
||||
// children.
|
||||
scene.resources = scene
|
||||
.resources
|
||||
.into_iter()
|
||||
.filter(is_serializable)
|
||||
.collect();
|
||||
|
||||
scene.entities = scene
|
||||
.entities
|
||||
.into_iter()
|
||||
.filter_map(|mut ent| {
|
||||
ent.components = ent.components.into_iter().filter(is_serializable).collect();
|
||||
if ent.components.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(ent)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let serialized = scene
|
||||
.serialize_ron(type_registry)
|
||||
.map_err(|err| format!("{err}"))?;
|
||||
|
||||
let window = world
|
||||
.iter_entities()
|
||||
.find_map(|ent| {
|
||||
if ent.contains::<PrimaryWindow>() {
|
||||
ent.get::<Window>()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| "Failed to get Window from &mut World".to_string())?;
|
||||
.query_filtered::<&Window, With<PrimaryWindow>>()
|
||||
.get_single(world)
|
||||
.map_err(|err| format!("{err}"))?;
|
||||
|
||||
wasm::dispatch_to_js(window, "scene-download-ready", &serialized)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user