mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-22 11:50:53 +00:00
feat(Blenvy:Bevy):
* cleaned up hot reload code a bit * renamed a few things for clarity * experimented with hiding entity while spawning & showing it again after spawn to try and remove "flashes" happening when spawning blueprints with lights * for testing example, fixed dynamic spawner test
This commit is contained in:
parent
fb54b0c913
commit
6cbb144746
@ -58,12 +58,12 @@ pub(crate) struct AssetLoadTracker {
|
||||
|
||||
/// helper component, for tracking loaded assets
|
||||
#[derive(Component, Debug)]
|
||||
pub(crate) struct BlenvyAssetsLoadState {
|
||||
pub(crate) struct BlueprintAssetsLoadState {
|
||||
pub all_loaded: bool,
|
||||
pub asset_infos: Vec<AssetLoadTracker>,
|
||||
pub progress: f32,
|
||||
}
|
||||
impl Default for BlenvyAssetsLoadState {
|
||||
impl Default for BlueprintAssetsLoadState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
all_loaded: Default::default(),
|
||||
|
@ -17,7 +17,7 @@ use bevy::{
|
||||
render::mesh::Mesh,
|
||||
};
|
||||
|
||||
use crate::{AssetLoadTracker, BlenvyAssetsLoadState, BlenvyConfig, BlueprintInstanceReady};
|
||||
use crate::{AssetLoadTracker, BlueprintAssetsLoadState, BlenvyConfig, BlueprintInstanceReady};
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
@ -72,7 +72,7 @@ pub(crate) fn materials_inject(
|
||||
|
||||
commands
|
||||
.entity(entity)
|
||||
.insert(BlenvyAssetsLoadState {
|
||||
.insert(BlueprintAssetsLoadState {
|
||||
all_loaded: false,
|
||||
asset_infos,
|
||||
..Default::default()
|
||||
@ -86,7 +86,7 @@ pub(crate) fn materials_inject(
|
||||
// TODO, merge with blueprints_check_assets_loading, make generic ?
|
||||
pub(crate) fn check_for_material_loaded(
|
||||
mut blueprint_assets_to_load: Query<
|
||||
(Entity, &mut BlenvyAssetsLoadState),
|
||||
(Entity, &mut BlueprintAssetsLoadState),
|
||||
With<BlueprintMaterialAssetsNotLoaded>,
|
||||
>,
|
||||
asset_server: Res<AssetServer>,
|
||||
|
@ -1,9 +1,9 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use bevy::{asset::LoadedUntypedAsset, gltf::Gltf, prelude::*, scene::SceneInstance, transform::commands, utils::hashbrown::HashMap};
|
||||
use bevy::{asset::LoadedUntypedAsset, gltf::Gltf, prelude::*, render::view::visibility, scene::SceneInstance, transform::commands, utils::hashbrown::HashMap};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::{BlueprintAssets, BlenvyAssetsLoadState, AssetLoadTracker, BlenvyConfig, BlueprintAnimations, BlueprintAssetsLoaded, BlueprintAssetsNotLoaded};
|
||||
use crate::{BlueprintAssets, BlueprintAssetsLoadState, AssetLoadTracker, BlenvyConfig, BlueprintAnimations, BlueprintAssetsLoaded, BlueprintAssetsNotLoaded};
|
||||
|
||||
/// this is a flag component for our levels/game world
|
||||
#[derive(Component)]
|
||||
@ -164,12 +164,13 @@ asset_server: Res<AssetServer>,
|
||||
if !asset_infos.is_empty() {
|
||||
commands
|
||||
.entity(entity)
|
||||
.insert(BlenvyAssetsLoadState {
|
||||
.insert(BlueprintAssetsLoadState {
|
||||
all_loaded: false,
|
||||
asset_infos,
|
||||
..Default::default()
|
||||
})
|
||||
.insert(BlueprintAssetsNotLoaded);
|
||||
.insert(BlueprintAssetsNotLoaded)
|
||||
;
|
||||
} else {
|
||||
commands.entity(entity).insert(BlueprintAssetsLoaded);
|
||||
}
|
||||
@ -178,7 +179,7 @@ asset_server: Res<AssetServer>,
|
||||
|
||||
pub(crate) fn blueprints_check_assets_loading(
|
||||
mut blueprint_assets_to_load: Query<
|
||||
(Entity, Option<&Name>, &BlueprintInfo, &mut BlenvyAssetsLoadState),
|
||||
(Entity, Option<&Name>, &BlueprintInfo, &mut BlueprintAssetsLoadState),
|
||||
With<BlueprintAssetsNotLoaded>,
|
||||
>,
|
||||
asset_server: Res<AssetServer>,
|
||||
@ -222,7 +223,7 @@ pub(crate) fn blueprints_check_assets_loading(
|
||||
.entity(entity)
|
||||
.insert(BlueprintAssetsLoaded)
|
||||
.remove::<BlueprintAssetsNotLoaded>()
|
||||
//.remove::<BlenvyAssetsLoadState>() //REMOVE it in release mode/ when hot reload is off, keep it for dev/hot reload
|
||||
//.remove::<BlueprintAssetsLoadState>() //REMOVE it in release mode/ when hot reload is off, keep it for dev/hot reload
|
||||
;
|
||||
}else {
|
||||
println!("LOADING: done for ALL assets of {:?} (instance of {}): {} ",entity_name, blueprint_info.path, progress * 100.0);
|
||||
@ -233,7 +234,7 @@ pub(crate) fn blueprints_check_assets_loading(
|
||||
/*
|
||||
pub(crate) fn hot_reload_asset_check(
|
||||
mut blueprint_assets: Query<
|
||||
(Entity, Option<&Name>, &BlueprintInfo, &mut BlenvyAssetsLoadState)>,
|
||||
(Entity, Option<&Name>, &BlueprintInfo, &mut BlueprintAssetsLoadState)>,
|
||||
asset_server: Res<AssetServer>,
|
||||
mut commands: Commands,
|
||||
){
|
||||
@ -260,109 +261,42 @@ use bevy::asset::AssetEvent;
|
||||
pub(crate) fn react_to_asset_changes(
|
||||
mut gltf_events: EventReader<AssetEvent<Gltf>>,
|
||||
mut untyped_events: EventReader<AssetEvent<LoadedUntypedAsset>>,
|
||||
mut blueprint_assets: Query<(Entity, Option<&Name>, &BlueprintInfo, &mut BlenvyAssetsLoadState, Option<&Children>)>,
|
||||
mut blueprint_assets: Query<(Entity, Option<&Name>, &BlueprintInfo, &mut BlueprintAssetsLoadState, Option<&Children>)>,
|
||||
asset_server: Res<AssetServer>,
|
||||
mut commands: Commands,
|
||||
|
||||
) {
|
||||
|
||||
for event in untyped_events.read() {
|
||||
for (entity, entity_name, blueprint_info, mut assets_to_load, c) in blueprint_assets.iter_mut() {
|
||||
for tracker in assets_to_load.asset_infos.iter_mut() {
|
||||
let asset_id = tracker.id;
|
||||
|
||||
println!("changed {:?} (blueprint {}) {}", entity_name, blueprint_info.path, event.is_modified(asset_id));
|
||||
}
|
||||
}
|
||||
|
||||
match event {
|
||||
AssetEvent::Added { id } => {
|
||||
// React to the image being created
|
||||
println!("Added untyped {:?}", asset_server.get_path(*id))
|
||||
}
|
||||
AssetEvent::LoadedWithDependencies { id } => {
|
||||
// React to the image being loaded
|
||||
// after all dependencies
|
||||
println!("Loaded with deps untyped {:?}", asset_server.get_path(*id))
|
||||
}
|
||||
AssetEvent::Modified { id } => {
|
||||
// React to the image being modified
|
||||
println!("Modified untyped {:?}", asset_server.get_path(*id))
|
||||
}
|
||||
AssetEvent::Removed { id } => {
|
||||
// React to the image being removed
|
||||
println!("Removed untyped {:?}", asset_server.get_path(*id))
|
||||
},
|
||||
AssetEvent::Unused { id } => {
|
||||
// React to the last strong handle for the asset being dropped
|
||||
println!("unused untyped {:?}", asset_server.get_path(*id))
|
||||
}
|
||||
}
|
||||
}
|
||||
for event in gltf_events.read() {
|
||||
// LoadedUntypedAsset
|
||||
|
||||
/*for (entity, entity_name, blueprint_info, mut assets_to_load) in blueprint_assets.iter_mut() {
|
||||
for tracker in assets_to_load.asset_infos.iter_mut() {
|
||||
let asset_id = tracker.id;
|
||||
if blueprint_info.path.ends_with("glb") || blueprint_info.path.ends_with("gltf") {
|
||||
// let typed_asset_id = asset_server.get_handle(blueprint_info.path);
|
||||
let foo: Handle<Gltf> = asset_server.load(blueprint_info.path.clone());
|
||||
//println!("changed {:?} (blueprint {}) {}", entity_name, blueprint_info.path, event.is_modified(foo.id()));
|
||||
println!("changed {:?} (blueprint {}) {}", entity_name, blueprint_info.path, event.is_modified(foo.id()));
|
||||
println!("added {:?} (blueprint {}) {}", entity_name, blueprint_info.path, event.is_added(foo.id()));
|
||||
println!("removed {:?} (blueprint {}) {}", entity_name, blueprint_info.path, event.is_removed(foo.id()));
|
||||
println!("loaded with deps {:?} (blueprint {}) {}", entity_name, blueprint_info.path, event.is_loaded_with_dependencies(foo.id()));
|
||||
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
match event {
|
||||
AssetEvent::Added { id } => {
|
||||
// React to the image being created
|
||||
println!("Added gltf, path {:?}", asset_server.get_path(*id));
|
||||
|
||||
}
|
||||
AssetEvent::LoadedWithDependencies { id } => {
|
||||
// React to the image being loaded
|
||||
// after all dependencies
|
||||
println!("Loaded gltf with deps{:?}", asset_server.get_path(*id))
|
||||
}
|
||||
AssetEvent::Modified { id } => {
|
||||
// React to the image being modified
|
||||
println!("Modified gltf {:?}", asset_server.get_path(*id));
|
||||
|
||||
// println!("Modified gltf {:?}", asset_server.get_path(*id));
|
||||
for (entity, entity_name, blueprint_info, mut assets_to_load, children) in blueprint_assets.iter_mut() {
|
||||
for tracker in assets_to_load.asset_infos.iter_mut() {
|
||||
if asset_server.get_path(*id).is_some() {
|
||||
if tracker.path == asset_server.get_path(*id).unwrap().to_string() {
|
||||
println!("HOLY MOLY IT DETECTS !!, now respawn {:?}", entity_name);
|
||||
if children.is_some() {
|
||||
for child in children.unwrap().iter(){
|
||||
commands.entity(*child).despawn_recursive();
|
||||
|
||||
}
|
||||
}
|
||||
commands.entity(entity)
|
||||
.remove::<BlueprintAssetsLoaded>()
|
||||
.remove::<SceneInstance>()
|
||||
.remove::<BlenvyAssetsLoadState>()
|
||||
.remove::<BlueprintAssetsLoadState>()
|
||||
.insert(SpawnHere);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
AssetEvent::Removed { id } => {
|
||||
// React to the image being removed
|
||||
println!("Removed gltf {:?}", asset_server.get_path(*id))
|
||||
},
|
||||
AssetEvent::Unused { id } => {
|
||||
// React to the last strong handle for the asset being dropped
|
||||
println!("unused gltf {:?}", asset_server.get_path(*id))
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,6 +381,8 @@ pub(crate) fn blueprints_spawn(
|
||||
SceneBundle {
|
||||
scene: scene.clone(),
|
||||
transform: transforms,
|
||||
visibility: Visibility::Hidden,
|
||||
|
||||
..Default::default()
|
||||
},
|
||||
Spawned,
|
||||
|
@ -99,10 +99,11 @@ pub(crate) fn spawned_blueprint_post_process(
|
||||
commands.entity(original).remove::<SpawnHere>();
|
||||
commands.entity(original).remove::<Spawned>();
|
||||
// commands.entity(original).remove::<Handle<Scene>>(); // FIXME: if we delete the handle to the scene, things get despawned ! not what we want
|
||||
//commands.entity(original).remove::<BlenvyAssetsLoadState>(); // also clear the sub assets tracker to free up handles, perhaps just freeing up the handles and leave the rest would be better ?
|
||||
//commands.entity(original).remove::<BlueprintAssetsLoadState>(); // also clear the sub assets tracker to free up handles, perhaps just freeing up the handles and leave the rest would be better ?
|
||||
//commands.entity(original).remove::<BlueprintAssetsLoaded>();
|
||||
commands.entity(root_entity).despawn_recursive();
|
||||
|
||||
commands.entity(original).insert( Visibility::Visible
|
||||
);
|
||||
blueprint_events.send(BlueprintEvent::Spawned {blueprint_name: blueprint_info.name.clone(), blueprint_path: blueprint_info.path.clone() });
|
||||
|
||||
debug!("DONE WITH POST PROCESS");
|
||||
|
@ -62,7 +62,7 @@ pub fn spawn_test(
|
||||
let new_entity = commands
|
||||
.spawn((
|
||||
BluePrintBundle {
|
||||
blueprint: BlueprintInfo{name: "Health_Pickup".into() , path:"foo/bar.glb".into()}, // FIXME
|
||||
blueprint: BlueprintInfo{name: "Blueprint1".into() , path:"blueprints/Blueprint1.glb".into()}, // FIXME
|
||||
..Default::default()
|
||||
},
|
||||
bevy::prelude::Name::from(format!("test{}", name_index)),
|
||||
|
@ -210,6 +210,7 @@ Blender side:
|
||||
- [ ] for scenes, scan for used materials of all non instance objects (TODO: what about overrides ?)
|
||||
|
||||
- [ ] add a way of visualizing per blueprint instances ?
|
||||
- [ ] display export path of blueprints (mostly external) ?
|
||||
|
||||
Bevy Side:
|
||||
- [x] deprecate BlueprintName & BlueprintPath & use BlueprintInfo instead
|
||||
@ -220,7 +221,15 @@ Bevy Side:
|
||||
- [ ] remove/replace bevy editor pls with some native ui to display hierarchies
|
||||
- [ ] a full fledged demo (including physics & co)
|
||||
- [ ] other examples without interactions or physics
|
||||
- [x] try out hot reloading
|
||||
- [ ] add hot reloading
|
||||
- [x] basics
|
||||
- [ ] make it enabled/disabled based on general flag
|
||||
- [ ] cleanup internals
|
||||
- [ ] review & change general component insertion & spawning ordering & logic
|
||||
- GltfComponentsSet::Injection => GltfBlueprintsSet::Spawn => GltfBlueprintsSet::AfterSpawn
|
||||
Injection => inject lights & co => spawn => afterSpawn
|
||||
=> Injection => inject lights & co
|
||||
|
||||
- [ ] add a way of overriding assets for collection instances => doubt this is possible
|
||||
- [ ] cleanup all the spurious debug messages
|
||||
- [ ] fix animation handling
|
||||
|
Loading…
Reference in New Issue
Block a user