fix(Blenvy:Bevy): Fix direct file access for gltf preload on Wasm (#199)

* Fix direct file access
* Fix dropped handles
* Remove debug messages
* Minor refactoring
* Fix access
This commit is contained in:
Jan Hohenheim 2024-07-23 23:42:25 +02:00 committed by GitHub
parent 5621b66cb3
commit b92081d06e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 64 additions and 12 deletions

View File

@ -49,8 +49,7 @@ impl Default for BluePrintBundle {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
/// Plugin for gltf blueprints /// Plugin for gltf blueprints
pub struct BlueprintsPlugin { pub struct BlueprintsPlugin {}
}
impl Default for BlueprintsPlugin { impl Default for BlueprintsPlugin {
fn default() -> Self { fn default() -> Self {
@ -58,7 +57,6 @@ impl Default for BlueprintsPlugin {
} }
} }
fn hot_reload(watching_for_changes: Res<WatchingForChanges>) -> bool { fn hot_reload(watching_for_changes: Res<WatchingForChanges>) -> bool {
// println!("hot reload ? {}", watching_for_changes.0); // println!("hot reload ? {}", watching_for_changes.0);
watching_for_changes.0 watching_for_changes.0
@ -110,6 +108,8 @@ impl Plugin for BlueprintsPlugin {
.register_type::<Vec<String>>() .register_type::<Vec<String>>()
.register_type::<BlueprintAssets>() .register_type::<BlueprintAssets>()
.register_type::<HashMap<String, Vec<String>>>() .register_type::<HashMap<String, Vec<String>>>()
.init_asset::<RawGltfAsset>()
.init_asset_loader::<RawGltfAssetLoader>()
.configure_sets( .configure_sets(
Update, Update,
(GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn) (GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn)
@ -119,6 +119,7 @@ impl Plugin for BlueprintsPlugin {
.add_systems( .add_systems(
Update, Update,
( (
load_raw_gltf,
blueprints_prepare_spawn, blueprints_prepare_spawn,
blueprints_check_assets_loading, blueprints_check_assets_loading,
blueprints_assets_loaded, blueprints_assets_loaded,
@ -132,16 +133,14 @@ impl Plugin for BlueprintsPlugin {
.chain() .chain()
.in_set(GltfBlueprintsSet::Spawn), .in_set(GltfBlueprintsSet::Spawn),
) )
// animation // animation
.add_systems( .add_systems(
Update, Update,
( (
trigger_blueprint_animation_markers_events, trigger_blueprint_animation_markers_events,
trigger_instance_animation_markers_events trigger_instance_animation_markers_events,
), ),
) )
// hot reload // hot reload
.add_systems(Update, react_to_asset_changes.run_if(hot_reload)); .add_systems(Update, react_to_asset_changes.run_if(hot_reload));
} }

View File

@ -1,6 +1,12 @@
use std::path::Path; use std::path::Path;
use bevy::{gltf::Gltf, prelude::*, scene::SceneInstance, utils::hashbrown::HashMap}; use bevy::{
asset::{io::Reader, AssetLoader, AsyncReadExt, LoadContext},
gltf::Gltf,
prelude::*,
scene::SceneInstance,
utils::hashbrown::HashMap,
};
use serde_json::Value; use serde_json::Value;
use crate::{ use crate::{
@ -115,17 +121,59 @@ Overview of the Blueprint Spawning process
=> distinguish between blueprint instances inside blueprint instances vs blueprint instances inside blueprints ?? => distinguish between blueprint instances inside blueprint instances vs blueprint instances inside blueprints ??
*/ */
pub(crate) fn blueprints_prepare_spawn( #[derive(Asset, TypePath, Debug)]
pub struct RawGltfAsset(pub RawGltf);
#[derive(Default)]
pub(super) struct RawGltfAssetLoader;
impl AssetLoader for RawGltfAssetLoader {
type Asset = RawGltfAsset;
type Settings = ();
type Error = gltf::Error;
async fn load<'a>(
&'a self,
reader: &'a mut Reader<'_>,
_settings: &'a (),
_load_context: &'a mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
let gltf = RawGltf::from_slice_without_validation(&bytes)?;
Ok(RawGltfAsset(gltf))
}
}
#[derive(Debug, Component, Deref, DerefMut)]
#[component(storage = "SparseSet")]
pub(super) struct AssociatedRawGltfHandle(Handle<RawGltfAsset>);
pub(super) fn load_raw_gltf(
blueprint_instances_to_spawn: Query<(Entity, &BlueprintInfo), Added<SpawnBlueprint>>, blueprint_instances_to_spawn: Query<(Entity, &BlueprintInfo), Added<SpawnBlueprint>>,
asset_server: Res<AssetServer>,
mut commands: Commands,
) {
for (entity, blueprint_info) in blueprint_instances_to_spawn.iter() {
let gltf_handle: Handle<RawGltfAsset> = asset_server.load(&blueprint_info.path);
commands
.entity(entity)
.insert(AssociatedRawGltfHandle(gltf_handle));
}
}
pub(super) fn blueprints_prepare_spawn(
blueprint_instances_to_spawn: Query<(Entity, &BlueprintInfo, &AssociatedRawGltfHandle)>,
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
// for hot reload // for hot reload
watching_for_changes: Res<WatchingForChanges>, watching_for_changes: Res<WatchingForChanges>,
mut assets_to_blueprint_instances: ResMut<AssetToBlueprintInstancesMapper>, mut assets_to_blueprint_instances: ResMut<AssetToBlueprintInstancesMapper>,
raw_gltf_assets: Res<Assets<RawGltfAsset>>,
// for debug // for debug
// all_names: Query<&Name> // all_names: Query<&Name>
) { ) {
for (entity, blueprint_info) in blueprint_instances_to_spawn.iter() { for (entity, blueprint_info, raw_gltf_handle) in blueprint_instances_to_spawn.iter() {
info!( info!(
"BLUEPRINT: to spawn detected: {:?} path:{:?}", "BLUEPRINT: to spawn detected: {:?} path:{:?}",
blueprint_info.name, blueprint_info.path blueprint_info.name, blueprint_info.path
@ -149,7 +197,9 @@ pub(crate) fn blueprints_prepare_spawn(
// and we also add all its assets // and we also add all its assets
/* prefetch attempt */ /* prefetch attempt */
let gltf = RawGltf::open(format!("assets/{}", blueprint_info.path)).unwrap(); let Some(RawGltfAsset(gltf)) = raw_gltf_assets.get(&raw_gltf_handle.0) else {
continue;
};
for scene in gltf.scenes() { for scene in gltf.scenes() {
if let Some(scene_extras) = scene.extras().clone() { if let Some(scene_extras) = scene.extras().clone() {
let lookup: HashMap<String, Value> = let lookup: HashMap<String, Value> =
@ -254,7 +304,10 @@ pub(crate) fn blueprints_prepare_spawn(
.entity(entity) .entity(entity)
.insert(bevy::prelude::Name::from(blueprint_info.name.clone())); .insert(bevy::prelude::Name::from(blueprint_info.name.clone()));
// add the blueprint spawning marker // add the blueprint spawning marker
commands.entity(entity).insert(BlueprintSpawning); commands
.entity(entity)
.insert(BlueprintSpawning)
.remove::<AssociatedRawGltfHandle>();
} }
} }