feat(Blenvy): basic working loading of levels & assets
* removed/ obsoleted blueprintsList * now using AllAssets (meh naming) * modified example & internals to enable loading levels as Blueprints as well * internals quite messy for now, needs a big cleanup still * disabled materials library for now, needs to be overhauled to make use of asset logic as well * added more mock assets for testing * related changes to blender & bevy side
This commit is contained in:
parent
2a74dedcb8
commit
1fdb45bab6
|
@ -1,6 +1,6 @@
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use bevy::{gltf::Gltf, prelude::*, utils::HashMap};
|
use bevy::{asset::LoadedUntypedAsset, gltf::Gltf, prelude::*, utils::HashMap};
|
||||||
|
|
||||||
use crate::{BluePrintsConfig, BlueprintAnimations};
|
use crate::{BluePrintsConfig, BlueprintAnimations};
|
||||||
|
|
||||||
|
@ -24,30 +24,35 @@ pub struct AllAssets(pub Vec<MyAsset>);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// helper component, is used to store the list of sub blueprints to enable automatic loading of dependend blueprints
|
////////////////////////
|
||||||
#[derive(Component, Reflect, Default, Debug)]
|
///
|
||||||
#[reflect(Component)]
|
/// flag component, usually added when a blueprint is loaded
|
||||||
pub struct BlueprintsList(pub HashMap<String, Vec<String>>);
|
#[derive(Component)]
|
||||||
|
pub(crate) struct BlueprintAssetsLoaded;
|
||||||
|
/// flag component
|
||||||
|
#[derive(Component)]
|
||||||
|
pub(crate) struct BlueprintAssetsNotLoaded;
|
||||||
|
|
||||||
/// helper component, for tracking loaded assets's loading state, id , handle etc
|
/// helper component, for tracking loaded assets's loading state, id , handle etc
|
||||||
#[derive(Default, Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct AssetLoadTracker<T: bevy::prelude::Asset> {
|
pub(crate) struct AssetLoadTracker {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub id: AssetId<T>,
|
pub id: AssetId<LoadedUntypedAsset>,
|
||||||
pub loaded: bool,
|
pub loaded: bool,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub handle: Handle<T>,
|
pub handle: Handle<LoadedUntypedAsset>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// helper component, for tracking loaded assets
|
/// helper component, for tracking loaded assets
|
||||||
#[derive(Component, Debug)]
|
#[derive(Component, Debug)]
|
||||||
pub(crate) struct AssetsToLoad<T: bevy::prelude::Asset> {
|
pub(crate) struct AssetsToLoad {
|
||||||
pub all_loaded: bool,
|
pub all_loaded: bool,
|
||||||
pub asset_infos: Vec<AssetLoadTracker<T>>,
|
pub asset_infos: Vec<AssetLoadTracker>,
|
||||||
pub progress: f32,
|
pub progress: f32,
|
||||||
}
|
}
|
||||||
impl<T: bevy::prelude::Asset> Default for AssetsToLoad<T> {
|
impl Default for AssetsToLoad {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
all_loaded: Default::default(),
|
all_loaded: Default::default(),
|
||||||
|
@ -56,10 +61,3 @@ impl<T: bevy::prelude::Asset> Default for AssetsToLoad<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// flag component, usually added when a blueprint is loaded
|
|
||||||
#[derive(Component)]
|
|
||||||
pub(crate) struct BlueprintAssetsLoaded;
|
|
||||||
/// flag component
|
|
||||||
#[derive(Component)]
|
|
||||||
pub(crate) struct BlueprintAssetsNotLoaded;
|
|
||||||
|
|
|
@ -129,13 +129,13 @@ impl Plugin for BlueprintsPlugin {
|
||||||
.register_type::<HashMap<u32, Vec<String>>>()
|
.register_type::<HashMap<u32, Vec<String>>>()
|
||||||
.register_type::<HashMap<String, HashMap<u32, Vec<String>>>>()
|
.register_type::<HashMap<String, HashMap<u32, Vec<String>>>>()
|
||||||
.add_event::<AnimationMarkerReached>()
|
.add_event::<AnimationMarkerReached>()
|
||||||
.register_type::<BlueprintsList>()
|
|
||||||
.register_type::<MyAsset>()
|
.register_type::<MyAsset>()
|
||||||
.register_type::<Vec<MyAsset>>()
|
.register_type::<Vec<MyAsset>>()
|
||||||
.register_type::<Vec<String>>()
|
.register_type::<Vec<String>>()
|
||||||
.register_type::<LocalAssets>()
|
.register_type::<LocalAssets>()
|
||||||
.register_type::<AllAssets>()
|
.register_type::<AllAssets>()
|
||||||
|
|
||||||
|
|
||||||
.register_type::<HashMap<String, Vec<String>>>()
|
.register_type::<HashMap<String, Vec<String>>>()
|
||||||
.insert_resource(BluePrintsConfig {
|
.insert_resource(BluePrintsConfig {
|
||||||
format: self.format,
|
format: self.format,
|
||||||
|
@ -158,20 +158,23 @@ impl Plugin for BlueprintsPlugin {
|
||||||
Update,
|
Update,
|
||||||
(
|
(
|
||||||
test_thingy,
|
test_thingy,
|
||||||
(
|
check_for_loaded2,
|
||||||
|
spawn_from_blueprints2,
|
||||||
|
|
||||||
|
/*(
|
||||||
prepare_blueprints,
|
prepare_blueprints,
|
||||||
check_for_loaded,
|
check_for_loaded,
|
||||||
spawn_from_blueprints,
|
spawn_from_blueprints,
|
||||||
apply_deferred,
|
apply_deferred,
|
||||||
)
|
)
|
||||||
.chain(),
|
.chain(),*/
|
||||||
(compute_scene_aabbs, apply_deferred)
|
(compute_scene_aabbs, apply_deferred)
|
||||||
.chain()
|
.chain()
|
||||||
.run_if(aabbs_enabled),
|
.run_if(aabbs_enabled),
|
||||||
apply_deferred,
|
apply_deferred,
|
||||||
(
|
(
|
||||||
materials_inject,
|
materials_inject,
|
||||||
check_for_material_loaded,
|
// check_for_material_loaded,
|
||||||
materials_inject2,
|
materials_inject2,
|
||||||
)
|
)
|
||||||
.chain()
|
.chain()
|
||||||
|
|
|
@ -66,7 +66,9 @@ pub(crate) fn materials_inject(
|
||||||
} else {
|
} else {
|
||||||
let material_file_handle: Handle<Gltf> = asset_server.load(materials_path.clone());
|
let material_file_handle: Handle<Gltf> = asset_server.load(materials_path.clone());
|
||||||
let material_file_id = material_file_handle.id();
|
let material_file_id = material_file_handle.id();
|
||||||
let asset_infos: Vec<AssetLoadTracker<Gltf>> = vec![AssetLoadTracker {
|
|
||||||
|
// FIXME: fix this stuff
|
||||||
|
/*let asset_infos: Vec<AssetLoadTracker> = vec![AssetLoadTracker {
|
||||||
name: material_full_path,
|
name: material_full_path,
|
||||||
id: material_file_id,
|
id: material_file_id,
|
||||||
loaded: false,
|
loaded: false,
|
||||||
|
@ -81,12 +83,14 @@ pub(crate) fn materials_inject(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.insert(BlueprintMaterialAssetsNotLoaded);
|
.insert(BlueprintMaterialAssetsNotLoaded);
|
||||||
/**/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO, merge with check_for_loaded, make generic ?
|
// TODO, merge with check_for_loaded, make generic ?
|
||||||
|
// FIXME: fix this:
|
||||||
|
/*
|
||||||
pub(crate) fn check_for_material_loaded(
|
pub(crate) fn check_for_material_loaded(
|
||||||
mut blueprint_assets_to_load: Query<
|
mut blueprint_assets_to_load: Query<
|
||||||
(Entity, &mut AssetsToLoad<Gltf>),
|
(Entity, &mut AssetsToLoad<Gltf>),
|
||||||
|
@ -121,7 +125,7 @@ pub(crate) fn check_for_material_loaded(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/// system that injects / replaces materials from material library
|
/// system that injects / replaces materials from material library
|
||||||
pub(crate) fn materials_inject2(
|
pub(crate) fn materials_inject2(
|
||||||
mut blueprints_config: ResMut<BluePrintsConfig>,
|
mut blueprints_config: ResMut<BluePrintsConfig>,
|
||||||
|
|
|
@ -0,0 +1,248 @@
|
||||||
|
|
||||||
|
|
||||||
|
/// helper component, for tracking loaded assets's loading state, id , handle etc
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub(crate) struct AssetLoadTracker<T: bevy::prelude::Asset> {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub name: String,
|
||||||
|
pub id: AssetId<T>,
|
||||||
|
pub loaded: bool,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub handle: Handle<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// helper component, for tracking loaded assets
|
||||||
|
#[derive(Component, Debug)]
|
||||||
|
pub(crate) struct AssetsToLoad<T: bevy::prelude::Asset> {
|
||||||
|
pub all_loaded: bool,
|
||||||
|
pub asset_infos: Vec<AssetLoadTracker<T>>,
|
||||||
|
pub progress: f32,
|
||||||
|
}
|
||||||
|
impl<T: bevy::prelude::Asset> Default for AssetsToLoad<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
all_loaded: Default::default(),
|
||||||
|
asset_infos: Default::default(),
|
||||||
|
progress: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// flag component, usually added when a blueprint is loaded
|
||||||
|
#[derive(Component)]
|
||||||
|
pub(crate) struct BlueprintAssetsLoaded;
|
||||||
|
/// flag component
|
||||||
|
#[derive(Component)]
|
||||||
|
pub(crate) struct BlueprintAssetsNotLoaded;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// spawning prepare function,
|
||||||
|
/// * also takes into account the already exisiting "override" components, ie "override components" > components from blueprint
|
||||||
|
pub(crate) fn prepare_blueprints(
|
||||||
|
spawn_placeholders: Query<
|
||||||
|
(
|
||||||
|
Entity,
|
||||||
|
&BlueprintName,
|
||||||
|
Option<&Parent>,
|
||||||
|
Option<&Library>,
|
||||||
|
Option<&Name>,
|
||||||
|
Option<&BlueprintsList>,
|
||||||
|
),
|
||||||
|
(Added<BlueprintName>, Added<SpawnHere>, Without<Spawned>),
|
||||||
|
>,
|
||||||
|
|
||||||
|
mut commands: Commands,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
blueprints_config: Res<BluePrintsConfig>,
|
||||||
|
) {
|
||||||
|
for (entity, blupeprint_name, original_parent, library_override, name, blueprints_list) in
|
||||||
|
spawn_placeholders.iter()
|
||||||
|
{
|
||||||
|
debug!(
|
||||||
|
"requesting to spawn {:?} for entity {:?}, id: {:?}, parent:{:?}",
|
||||||
|
blupeprint_name.0, name, entity, original_parent
|
||||||
|
);
|
||||||
|
|
||||||
|
// println!("main model path {:?}", model_path);
|
||||||
|
if blueprints_list.is_some() {
|
||||||
|
let blueprints_list = blueprints_list.unwrap();
|
||||||
|
// println!("blueprints list {:?}", blueprints_list.0.keys());
|
||||||
|
let mut asset_infos: Vec<AssetLoadTracker<Gltf>> = vec![];
|
||||||
|
let library_path =
|
||||||
|
library_override.map_or_else(|| &blueprints_config.library_folder, |l| &l.0);
|
||||||
|
for (blueprint_name, _) in blueprints_list.0.iter() {
|
||||||
|
let model_file_name = format!("{}.{}", &blueprint_name, &blueprints_config.format);
|
||||||
|
let model_path = Path::new(&library_path).join(Path::new(model_file_name.as_str()));
|
||||||
|
|
||||||
|
let model_handle: Handle<Gltf> = asset_server.load(model_path.clone());
|
||||||
|
let model_id = model_handle.id();
|
||||||
|
let loaded = asset_server.is_loaded_with_dependencies(model_id);
|
||||||
|
if !loaded {
|
||||||
|
asset_infos.push(AssetLoadTracker {
|
||||||
|
name: model_path.to_string_lossy().into(),
|
||||||
|
id: model_id,
|
||||||
|
loaded: false,
|
||||||
|
handle: model_handle.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if not all assets are already loaded, inject a component to signal that we need them to be loaded
|
||||||
|
if !asset_infos.is_empty() {
|
||||||
|
commands
|
||||||
|
.entity(entity)
|
||||||
|
.insert(AssetsToLoad {
|
||||||
|
all_loaded: false,
|
||||||
|
asset_infos,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.insert(BlueprintAssetsNotLoaded);
|
||||||
|
} else {
|
||||||
|
commands.entity(entity).insert(BlueprintAssetsLoaded);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// in case there are no blueprintsList, we revert back to the old behaviour
|
||||||
|
commands.entity(entity).insert(BlueprintAssetsLoaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn check_for_loaded(
|
||||||
|
mut blueprint_assets_to_load: Query<
|
||||||
|
(Entity, &mut AssetsToLoad<Gltf>),
|
||||||
|
With<BlueprintAssetsNotLoaded>,
|
||||||
|
>,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
for (entity, mut assets_to_load) in blueprint_assets_to_load.iter_mut() {
|
||||||
|
let mut all_loaded = true;
|
||||||
|
let mut loaded_amount = 0;
|
||||||
|
let total = assets_to_load.asset_infos.len();
|
||||||
|
for tracker in assets_to_load.asset_infos.iter_mut() {
|
||||||
|
let asset_id = tracker.id;
|
||||||
|
let loaded = asset_server.is_loaded_with_dependencies(asset_id);
|
||||||
|
tracker.loaded = loaded;
|
||||||
|
if loaded {
|
||||||
|
loaded_amount += 1;
|
||||||
|
} else {
|
||||||
|
all_loaded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let progress: f32 = loaded_amount as f32 / total as f32;
|
||||||
|
// println!("progress: {}",progress);
|
||||||
|
assets_to_load.progress = progress;
|
||||||
|
|
||||||
|
if all_loaded {
|
||||||
|
assets_to_load.all_loaded = true;
|
||||||
|
commands
|
||||||
|
.entity(entity)
|
||||||
|
.insert(BlueprintAssetsLoaded)
|
||||||
|
.remove::<BlueprintAssetsNotLoaded>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn spawn_from_blueprints(
|
||||||
|
spawn_placeholders: Query<
|
||||||
|
(
|
||||||
|
Entity,
|
||||||
|
&BlueprintName,
|
||||||
|
Option<&Transform>,
|
||||||
|
Option<&Parent>,
|
||||||
|
Option<&Library>,
|
||||||
|
Option<&AddToGameWorld>,
|
||||||
|
Option<&Name>,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
With<BlueprintAssetsLoaded>,
|
||||||
|
Added<BlueprintAssetsLoaded>,
|
||||||
|
Without<BlueprintAssetsNotLoaded>,
|
||||||
|
),
|
||||||
|
>,
|
||||||
|
|
||||||
|
mut commands: Commands,
|
||||||
|
mut game_world: Query<Entity, With<GameWorldTag>>,
|
||||||
|
|
||||||
|
assets_gltf: Res<Assets<Gltf>>,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
blueprints_config: Res<BluePrintsConfig>,
|
||||||
|
|
||||||
|
children: Query<&Children>,
|
||||||
|
) {
|
||||||
|
for (
|
||||||
|
entity,
|
||||||
|
blupeprint_name,
|
||||||
|
transform,
|
||||||
|
original_parent,
|
||||||
|
library_override,
|
||||||
|
add_to_world,
|
||||||
|
name,
|
||||||
|
) in spawn_placeholders.iter()
|
||||||
|
{
|
||||||
|
debug!(
|
||||||
|
"attempting to spawn {:?} for entity {:?}, id: {:?}, parent:{:?}",
|
||||||
|
blupeprint_name.0, name, entity, original_parent
|
||||||
|
);
|
||||||
|
|
||||||
|
let what = &blupeprint_name.0;
|
||||||
|
let model_file_name = format!("{}.{}", &what, &blueprints_config.format);
|
||||||
|
|
||||||
|
// library path is either defined at the plugin level or overriden by optional Library components
|
||||||
|
let library_path =
|
||||||
|
library_override.map_or_else(|| &blueprints_config.library_folder, |l| &l.0);
|
||||||
|
let model_path = Path::new(&library_path).join(Path::new(model_file_name.as_str()));
|
||||||
|
|
||||||
|
// info!("attempting to spawn {:?}", model_path);
|
||||||
|
let model_handle: Handle<Gltf> = asset_server.load(model_path.clone()); // FIXME: kinda weird now
|
||||||
|
|
||||||
|
let gltf = assets_gltf.get(&model_handle).unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"gltf file {:?} should have been loaded",
|
||||||
|
model_path.to_str()
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// WARNING we work under the assumtion that there is ONLY ONE named scene, and that the first one is the right one
|
||||||
|
let main_scene_name = gltf
|
||||||
|
.named_scenes
|
||||||
|
.keys()
|
||||||
|
.next()
|
||||||
|
.expect("there should be at least one named scene in the gltf file to spawn");
|
||||||
|
|
||||||
|
let scene = &gltf.named_scenes[main_scene_name];
|
||||||
|
|
||||||
|
// transforms are optional, but still deal with them correctly
|
||||||
|
let mut transforms: Transform = Transform::default();
|
||||||
|
if transform.is_some() {
|
||||||
|
transforms = *transform.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut original_children: Vec<Entity> = vec![];
|
||||||
|
if let Ok(c) = children.get(entity) {
|
||||||
|
for child in c.iter() {
|
||||||
|
original_children.push(*child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commands.entity(entity).insert((
|
||||||
|
SceneBundle {
|
||||||
|
scene: scene.clone(),
|
||||||
|
transform: transforms,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
Spawned,
|
||||||
|
OriginalChildren(original_children),
|
||||||
|
BlueprintAnimations {
|
||||||
|
// these are animations specific to the inside of the blueprint
|
||||||
|
named_animations: gltf.named_animations.clone(),
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
if add_to_world.is_some() {
|
||||||
|
let world = game_world
|
||||||
|
.get_single_mut()
|
||||||
|
.expect("there should be a game world present");
|
||||||
|
commands.entity(world).add_child(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use bevy::{gltf::Gltf, prelude::*, utils::HashMap};
|
use bevy::{gltf::Gltf, prelude::*, utils::HashMap};
|
||||||
|
|
||||||
use crate::{BluePrintsConfig, BlueprintAnimations, BlueprintsList, AssetLoadTracker, AssetsToLoad, BlueprintAssetsNotLoaded, BlueprintAssetsLoaded};
|
use crate::{AllAssets, AssetsToLoad, AssetLoadTracker, BluePrintsConfig, BlueprintAnimations, BlueprintAssetsLoaded, BlueprintAssetsNotLoaded};
|
||||||
|
|
||||||
/// this is a flag component for our levels/game world
|
/// this is a flag component for our levels/game world
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
|
@ -59,81 +59,103 @@ pub(crate) fn test_thingy(
|
||||||
Entity,
|
Entity,
|
||||||
&BlueprintPath,
|
&BlueprintPath,
|
||||||
),
|
),
|
||||||
(Added<BlueprintPath>, Without<Spawned>, Without<SpawnHere>),
|
(Added<BlueprintPath>, Without<Spawned>, Without<SpawnHere>)>,
|
||||||
>,
|
|
||||||
|
// before 0.14 we have to use a seperate query, after migrating we can query at the root level
|
||||||
|
entities_with_assets: Query<
|
||||||
|
(
|
||||||
|
Entity,
|
||||||
|
/*&BlueprintName,
|
||||||
|
&BlueprintPath,
|
||||||
|
Option<&Parent>,*/
|
||||||
|
Option<&Name>,
|
||||||
|
Option<&AllAssets>,
|
||||||
|
),
|
||||||
|
(Added<AllAssets>), // Added<AllAssets>
|
||||||
|
>,
|
||||||
|
|
||||||
|
|
||||||
|
bla_bla : Query<
|
||||||
|
(Entity,
|
||||||
|
&BlueprintName,
|
||||||
|
&BlueprintPath,
|
||||||
|
Option<&Parent>,),(Added<BlueprintPath>)
|
||||||
|
>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
|
|
||||||
|
|
||||||
) {
|
) {
|
||||||
for (entity, blueprint_path) in spawn_placeholders.iter() {
|
for (entity, blueprint_path) in spawn_placeholders.iter() {
|
||||||
println!("added blueprint_path {:?}", blueprint_path);
|
//println!("added blueprint_path {:?}", blueprint_path);
|
||||||
commands.entity(entity).insert(
|
/*commands.entity(entity).insert(
|
||||||
SceneBundle {
|
SceneBundle {
|
||||||
scene: asset_server.load(format!("{}#Scene0", &blueprint_path.0)), // "levels/World.glb#Scene0"),
|
scene: asset_server.load(format!("{}#Scene0", &blueprint_path.0)), // "levels/World.glb#Scene0"),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
);
|
);*/
|
||||||
// let model_handle: Handle<Gltf> = asset_server.load(model_path.clone());
|
// let model_handle: Handle<Gltf> = asset_server.load(model_path.clone());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
for (entity, blueprint_name, blueprint_path, parent) in bla_bla.iter() {
|
||||||
|
println!("added blueprint to spawn {:?} {:?}", blueprint_name, blueprint_path);
|
||||||
|
let untyped_handle = asset_server.load_untyped(&blueprint_path.0);
|
||||||
|
let asset_id = untyped_handle.id();
|
||||||
|
let loaded = asset_server.is_loaded_with_dependencies(asset_id);
|
||||||
|
|
||||||
/// spawning prepare function,
|
let mut asset_infos: Vec<AssetLoadTracker> = vec![];
|
||||||
/// * also takes into account the already exisiting "override" components, ie "override components" > components from blueprint
|
if !loaded {
|
||||||
pub(crate) fn prepare_blueprints(
|
asset_infos.push(AssetLoadTracker {
|
||||||
spawn_placeholders: Query<
|
name: blueprint_name.0.clone(),
|
||||||
(
|
id: asset_id,
|
||||||
Entity,
|
loaded: false,
|
||||||
&BlueprintName,
|
handle: untyped_handle.clone(),
|
||||||
Option<&Parent>,
|
});
|
||||||
Option<&Library>,
|
}
|
||||||
Option<&Name>,
|
|
||||||
Option<&BlueprintsList>,
|
|
||||||
),
|
|
||||||
(Added<BlueprintName>, Added<SpawnHere>, Without<Spawned>),
|
|
||||||
>,
|
|
||||||
|
|
||||||
mut commands: Commands,
|
// now insert load tracker
|
||||||
asset_server: Res<AssetServer>,
|
if !asset_infos.is_empty() {
|
||||||
blueprints_config: Res<BluePrintsConfig>,
|
commands
|
||||||
) {
|
.entity(entity)
|
||||||
for (entity, blupeprint_name, original_parent, library_override, name, blueprints_list) in
|
.insert(AssetsToLoad {
|
||||||
spawn_placeholders.iter()
|
all_loaded: false,
|
||||||
{
|
asset_infos,
|
||||||
debug!(
|
..Default::default()
|
||||||
"requesting to spawn {:?} for entity {:?}, id: {:?}, parent:{:?}",
|
})
|
||||||
blupeprint_name.0, name, entity, original_parent
|
.insert(BlueprintAssetsNotLoaded);
|
||||||
);
|
} else {
|
||||||
|
commands.entity(entity).insert(BlueprintAssetsLoaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// println!("main model path {:?}", model_path);
|
for (child_entity, child_entity_name, all_assets) in entities_with_assets.iter(){
|
||||||
if blueprints_list.is_some() {
|
println!("added assets {:?} to {:?}", all_assets, child_entity_name);
|
||||||
let blueprints_list = blueprints_list.unwrap();
|
if all_assets.is_some() {
|
||||||
// println!("blueprints list {:?}", blueprints_list.0.keys());
|
let mut asset_infos: Vec<AssetLoadTracker> = vec![];
|
||||||
let mut asset_infos: Vec<AssetLoadTracker<Gltf>> = vec![];
|
|
||||||
let library_path =
|
|
||||||
library_override.map_or_else(|| &blueprints_config.library_folder, |l| &l.0);
|
|
||||||
for (blueprint_name, _) in blueprints_list.0.iter() {
|
|
||||||
let model_file_name = format!("{}.{}", &blueprint_name, &blueprints_config.format);
|
|
||||||
let model_path = Path::new(&library_path).join(Path::new(model_file_name.as_str()));
|
|
||||||
|
|
||||||
let model_handle: Handle<Gltf> = asset_server.load(model_path.clone());
|
for asset in all_assets.unwrap().0.iter() {
|
||||||
let model_id = model_handle.id();
|
let untyped_handle = asset_server.load_untyped(&asset.path);
|
||||||
let loaded = asset_server.is_loaded_with_dependencies(model_id);
|
//println!("untyped handle {:?}", untyped_handle);
|
||||||
|
//asset_server.load(asset.path);
|
||||||
|
|
||||||
|
let asset_id = untyped_handle.id();
|
||||||
|
//println!("ID {:?}", asset_id);
|
||||||
|
let loaded = asset_server.is_loaded_with_dependencies(asset_id);
|
||||||
|
//println!("Loaded ? {:?}", loaded);
|
||||||
if !loaded {
|
if !loaded {
|
||||||
asset_infos.push(AssetLoadTracker {
|
asset_infos.push(AssetLoadTracker {
|
||||||
name: model_path.to_string_lossy().into(),
|
name: asset.name.clone(),
|
||||||
id: model_id,
|
id: asset_id,
|
||||||
loaded: false,
|
loaded: false,
|
||||||
handle: model_handle.clone(),
|
handle: untyped_handle.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if not all assets are already loaded, inject a component to signal that we need them to be loaded
|
|
||||||
|
// now insert load tracker
|
||||||
if !asset_infos.is_empty() {
|
if !asset_infos.is_empty() {
|
||||||
commands
|
commands
|
||||||
.entity(entity)
|
.entity(child_entity)
|
||||||
.insert(AssetsToLoad {
|
.insert(AssetsToLoad {
|
||||||
all_loaded: false,
|
all_loaded: false,
|
||||||
asset_infos,
|
asset_infos,
|
||||||
|
@ -141,59 +163,66 @@ pub(crate) fn prepare_blueprints(
|
||||||
})
|
})
|
||||||
.insert(BlueprintAssetsNotLoaded);
|
.insert(BlueprintAssetsNotLoaded);
|
||||||
} else {
|
} else {
|
||||||
commands.entity(entity).insert(BlueprintAssetsLoaded);
|
commands.entity(child_entity).insert(BlueprintAssetsLoaded);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// in case there are no blueprintsList, we revert back to the old behaviour
|
|
||||||
commands.entity(entity).insert(BlueprintAssetsLoaded);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn check_for_loaded(
|
pub(crate) fn check_for_loaded2(
|
||||||
mut blueprint_assets_to_load: Query<
|
mut blueprint_assets_to_load: Query<
|
||||||
(Entity, &mut AssetsToLoad<Gltf>),
|
(Entity, Option<&Name>, &mut AssetsToLoad),
|
||||||
With<BlueprintAssetsNotLoaded>,
|
With<BlueprintAssetsNotLoaded>,
|
||||||
>,
|
>,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) {
|
) {
|
||||||
for (entity, mut assets_to_load) in blueprint_assets_to_load.iter_mut() {
|
for (entity,entity_name, mut assets_to_load) in blueprint_assets_to_load.iter_mut() {
|
||||||
let mut all_loaded = true;
|
let mut all_loaded = true;
|
||||||
let mut loaded_amount = 0;
|
let mut loaded_amount = 0;
|
||||||
let total = assets_to_load.asset_infos.len();
|
let total = assets_to_load.asset_infos.len();
|
||||||
for tracker in assets_to_load.asset_infos.iter_mut() {
|
for tracker in assets_to_load.asset_infos.iter_mut() {
|
||||||
let asset_id = tracker.id;
|
let asset_id = tracker.id;
|
||||||
let loaded = asset_server.is_loaded_with_dependencies(asset_id);
|
let loaded = asset_server.is_loaded_with_dependencies(asset_id);
|
||||||
tracker.loaded = loaded;
|
println!("loading {}: // load state: {:?}", tracker.name, asset_server.load_state(asset_id));
|
||||||
if loaded {
|
|
||||||
|
// FIXME: hack for now
|
||||||
|
let failed = asset_server.load_state(asset_id) == bevy::asset::LoadState::Failed;
|
||||||
|
|
||||||
|
tracker.loaded = loaded || failed;
|
||||||
|
if loaded || failed {
|
||||||
loaded_amount += 1;
|
loaded_amount += 1;
|
||||||
} else {
|
} else {
|
||||||
all_loaded = false;
|
all_loaded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let progress: f32 = loaded_amount as f32 / total as f32;
|
let progress: f32 = loaded_amount as f32 / total as f32;
|
||||||
// println!("progress: {}",progress);
|
println!("progress: {}",progress);
|
||||||
assets_to_load.progress = progress;
|
assets_to_load.progress = progress;
|
||||||
|
|
||||||
if all_loaded {
|
if all_loaded {
|
||||||
assets_to_load.all_loaded = true;
|
assets_to_load.all_loaded = true;
|
||||||
|
println!("done with loading {:?}, inserting components", entity_name);
|
||||||
commands
|
commands
|
||||||
.entity(entity)
|
.entity(entity)
|
||||||
.insert(BlueprintAssetsLoaded)
|
.insert(BlueprintAssetsLoaded)
|
||||||
.remove::<BlueprintAssetsNotLoaded>();
|
.remove::<BlueprintAssetsNotLoaded>()
|
||||||
|
.remove::<AssetsToLoad>()
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn spawn_from_blueprints(
|
|
||||||
|
|
||||||
|
pub(crate) fn spawn_from_blueprints2(
|
||||||
spawn_placeholders: Query<
|
spawn_placeholders: Query<
|
||||||
(
|
(
|
||||||
Entity,
|
Entity,
|
||||||
&BlueprintName,
|
&BlueprintName,
|
||||||
|
&BlueprintPath,
|
||||||
Option<&Transform>,
|
Option<&Transform>,
|
||||||
Option<&Parent>,
|
Option<&Parent>,
|
||||||
Option<&Library>,
|
|
||||||
Option<&AddToGameWorld>,
|
Option<&AddToGameWorld>,
|
||||||
Option<&Name>,
|
Option<&Name>,
|
||||||
),
|
),
|
||||||
|
@ -216,33 +245,28 @@ pub(crate) fn spawn_from_blueprints(
|
||||||
for (
|
for (
|
||||||
entity,
|
entity,
|
||||||
blupeprint_name,
|
blupeprint_name,
|
||||||
|
blueprint_path,
|
||||||
transform,
|
transform,
|
||||||
original_parent,
|
original_parent,
|
||||||
library_override,
|
|
||||||
add_to_world,
|
add_to_world,
|
||||||
name,
|
name,
|
||||||
) in spawn_placeholders.iter()
|
) in spawn_placeholders.iter()
|
||||||
{
|
{
|
||||||
debug!(
|
info!(
|
||||||
"attempting to spawn {:?} for entity {:?}, id: {:?}, parent:{:?}",
|
"attempting to spawn blueprint {:?} for entity {:?}, id: {:?}, parent:{:?}",
|
||||||
blupeprint_name.0, name, entity, original_parent
|
blupeprint_name.0, name, entity, original_parent
|
||||||
);
|
);
|
||||||
|
|
||||||
let what = &blupeprint_name.0;
|
let what = &blupeprint_name.0;
|
||||||
let model_file_name = format!("{}.{}", &what, &blueprints_config.format);
|
let model_file_name = format!("{}.{}", &what, &blueprints_config.format);
|
||||||
|
|
||||||
// library path is either defined at the plugin level or overriden by optional Library components
|
|
||||||
let library_path =
|
|
||||||
library_override.map_or_else(|| &blueprints_config.library_folder, |l| &l.0);
|
|
||||||
let model_path = Path::new(&library_path).join(Path::new(model_file_name.as_str()));
|
|
||||||
|
|
||||||
// info!("attempting to spawn {:?}", model_path);
|
// info!("attempting to spawn {:?}", model_path);
|
||||||
let model_handle: Handle<Gltf> = asset_server.load(model_path.clone()); // FIXME: kinda weird now
|
let model_handle: Handle<Gltf> = asset_server.load(blueprint_path.0.clone()); // FIXME: kinda weird now
|
||||||
|
|
||||||
let gltf = assets_gltf.get(&model_handle).unwrap_or_else(|| {
|
let gltf = assets_gltf.get(&model_handle).unwrap_or_else(|| {
|
||||||
panic!(
|
panic!(
|
||||||
"gltf file {:?} should have been loaded",
|
"gltf file {:?} should have been loaded",
|
||||||
model_path.to_str()
|
&blueprint_path.0
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -289,3 +313,8 @@ pub(crate) fn spawn_from_blueprints(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -95,8 +95,8 @@ pub(crate) fn spawned_blueprint_post_process(
|
||||||
commands.entity(original).remove::<SpawnHere>();
|
commands.entity(original).remove::<SpawnHere>();
|
||||||
commands.entity(original).remove::<Spawned>();
|
commands.entity(original).remove::<Spawned>();
|
||||||
commands.entity(original).remove::<Handle<Scene>>();
|
commands.entity(original).remove::<Handle<Scene>>();
|
||||||
commands.entity(original).remove::<AssetsToLoad<Gltf>>(); // 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::<AssetsToLoad>(); // 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(original).remove::<BlueprintAssetsLoaded>();
|
||||||
commands.entity(root_entity).despawn_recursive();
|
commands.entity(root_entity).despawn_recursive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
some text
|
|
@ -1,5 +1,5 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_gltf_blueprints::{BluePrintBundle, BlueprintName, GameWorldTag};
|
use bevy_gltf_blueprints::{BluePrintBundle, BlueprintName, BlueprintPath, GameWorldTag};
|
||||||
use bevy_gltf_worlflow_examples_common_rapier::{GameState, InAppRunning};
|
use bevy_gltf_worlflow_examples_common_rapier::{GameState, InAppRunning};
|
||||||
|
|
||||||
use bevy_rapier3d::prelude::Velocity;
|
use bevy_rapier3d::prelude::Velocity;
|
||||||
|
@ -11,7 +11,7 @@ pub fn setup_game(
|
||||||
mut next_game_state: ResMut<NextState<GameState>>,
|
mut next_game_state: ResMut<NextState<GameState>>,
|
||||||
) {
|
) {
|
||||||
// here we actually spawn our game world/level
|
// here we actually spawn our game world/level
|
||||||
commands.spawn((
|
/*commands.spawn((
|
||||||
SceneBundle {
|
SceneBundle {
|
||||||
scene: asset_server.load("levels/World.glb#Scene0"),
|
scene: asset_server.load("levels/World.glb#Scene0"),
|
||||||
..default()
|
..default()
|
||||||
|
@ -19,7 +19,16 @@ pub fn setup_game(
|
||||||
bevy::prelude::Name::from("world"),
|
bevy::prelude::Name::from("world"),
|
||||||
GameWorldTag,
|
GameWorldTag,
|
||||||
InAppRunning,
|
InAppRunning,
|
||||||
|
));*/
|
||||||
|
|
||||||
|
commands.spawn((
|
||||||
|
BlueprintName("World".into()),
|
||||||
|
BlueprintPath("levels/World.glb".into()),
|
||||||
|
bevy::prelude::Name::from("world"),
|
||||||
|
GameWorldTag,
|
||||||
|
InAppRunning,
|
||||||
));
|
));
|
||||||
|
|
||||||
next_game_state.set(GameState::InGame)
|
next_game_state.set(GameState::InGame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ pub use in_game::*;
|
||||||
use std::{collections::HashMap, fs, time::Duration};
|
use std::{collections::HashMap, fs, time::Duration};
|
||||||
|
|
||||||
use bevy_gltf_blueprints::{
|
use bevy_gltf_blueprints::{
|
||||||
BlueprintAnimationPlayerLink, BlueprintName, BlueprintsList, GltfBlueprintsSet, SceneAnimations,
|
AllAssets, BlueprintAnimationPlayerLink, BlueprintName, GltfBlueprintsSet, SceneAnimations
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
|
@ -23,7 +23,7 @@ fn start_game(mut next_app_state: ResMut<NextState<AppState>>) {
|
||||||
|
|
||||||
// if the export from Blender worked correctly, we should have animations (simplified here by using AnimationPlayerLink)
|
// if the export from Blender worked correctly, we should have animations (simplified here by using AnimationPlayerLink)
|
||||||
// if the export from Blender worked correctly, we should have an Entity called "Blueprint4_nested" that has a child called "Blueprint3" that has a "BlueprintName" component with value Blueprint3
|
// if the export from Blender worked correctly, we should have an Entity called "Blueprint4_nested" that has a child called "Blueprint3" that has a "BlueprintName" component with value Blueprint3
|
||||||
// if the export from Blender worked correctly, we should have a blueprints_list
|
// if the export from Blender worked correctly, we should have an assets_list
|
||||||
// if the export from Blender worked correctly, we should have the correct tree of entities
|
// if the export from Blender worked correctly, we should have the correct tree of entities
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
|
@ -36,7 +36,7 @@ fn validate_export(
|
||||||
scene_animations: Query<(Entity, &SceneAnimations)>,
|
scene_animations: Query<(Entity, &SceneAnimations)>,
|
||||||
empties_candidates: Query<(Entity, &Name, &GlobalTransform)>,
|
empties_candidates: Query<(Entity, &Name, &GlobalTransform)>,
|
||||||
|
|
||||||
blueprints_list: Query<(Entity, &BlueprintsList)>,
|
assets_list: Query<(Entity, &AllAssets)>,
|
||||||
root: Query<(Entity, &Name, &Children), (Without<Parent>, With<Children>)>,
|
root: Query<(Entity, &Name, &Children), (Without<Parent>, With<Children>)>,
|
||||||
) {
|
) {
|
||||||
let animations_found =
|
let animations_found =
|
||||||
|
@ -66,8 +66,8 @@ fn validate_export(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check if there are blueprints_list components
|
// check if there are assets_list components
|
||||||
let blueprints_list_found = !blueprints_list.is_empty();
|
let assets_list_found = !assets_list.is_empty();
|
||||||
|
|
||||||
// there should be no entity named xxx____bak as it means an error in the Blender side export process
|
// there should be no entity named xxx____bak as it means an error in the Blender side export process
|
||||||
let mut exported_names_correct = true;
|
let mut exported_names_correct = true;
|
||||||
|
@ -104,8 +104,8 @@ fn validate_export(
|
||||||
fs::write(
|
fs::write(
|
||||||
"bevy_diagnostics.json",
|
"bevy_diagnostics.json",
|
||||||
format!(
|
format!(
|
||||||
"{{ \"animations\": {}, \"nested_blueprint_found\": {}, \"empty_found\": {}, \"blueprints_list_found\": {}, \"exported_names_correct\": {} }}",
|
"{{ \"animations\": {}, \"nested_blueprint_found\": {}, \"empty_found\": {}, \"assets_list_found\": {}, \"exported_names_correct\": {} }}",
|
||||||
animations_found, nested_blueprint_found, empty_found, blueprints_list_found, exported_names_correct
|
animations_found, nested_blueprint_found, empty_found, assets_list_found, exported_names_correct
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.expect("Unable to write file");
|
.expect("Unable to write file");
|
||||||
|
|
|
@ -116,6 +116,8 @@ General issues:
|
||||||
- [ ] remove 'export_marked_assets' it should be a default setting
|
- [ ] remove 'export_marked_assets' it should be a default setting
|
||||||
- [x] disable/ hide asset editing ui for external assets
|
- [x] disable/ hide asset editing ui for external assets
|
||||||
- [ ] inject_export_path_into_internal_blueprints should be called on every asset/blueprint scan !! Not just on export
|
- [ ] inject_export_path_into_internal_blueprints should be called on every asset/blueprint scan !! Not just on export
|
||||||
- [ ] fix level asets UI
|
- [x] fix level asets UI
|
||||||
|
|
||||||
|
- [x] remove BlueprintsList & replace is with assets list
|
||||||
|
|
||||||
clear && pytest -svv --blender-template ../../testing/bevy_example/art/testing_library.blend --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration_prepare.py && pytest -svv --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration.py
|
clear && pytest -svv --blender-template ../../testing/bevy_example/art/testing_library.blend --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration_prepare.py && pytest -svv --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration.py
|
|
@ -109,13 +109,6 @@ def duplicate_object(object, parent, combine_mode, destination_collection, bluep
|
||||||
empty_obj["BlueprintPath"] = f'("{blueprint_path}")'
|
empty_obj["BlueprintPath"] = f'("{blueprint_path}")'
|
||||||
empty_obj['SpawnHere'] = '()'
|
empty_obj['SpawnHere'] = '()'
|
||||||
|
|
||||||
# we also inject a list of all sub blueprints, so that the bevy side can preload them
|
|
||||||
children_per_blueprint = {}
|
|
||||||
blueprint = blueprints_data.blueprints_per_name.get(blueprint_name, None)
|
|
||||||
if blueprint:
|
|
||||||
children_per_blueprint[blueprint_name] = blueprint.nested_blueprints
|
|
||||||
empty_obj["BlueprintsList"] = f"({json.dumps(dict(children_per_blueprint))})"
|
|
||||||
|
|
||||||
# we copy custom properties over from our original object to our empty
|
# we copy custom properties over from our original object to our empty
|
||||||
for component_name, component_value in object.items():
|
for component_name, component_value in object.items():
|
||||||
if component_name not in custom_properties_to_filter_out and is_component_valid_and_enabled(object, component_name): #copy only valid properties
|
if component_name not in custom_properties_to_filter_out and is_component_valid_and_enabled(object, component_name): #copy only valid properties
|
||||||
|
|
|
@ -8,6 +8,12 @@ from blenvy.materials.materials_helpers import get_all_materials
|
||||||
from .generate_temporary_scene_and_export import generate_temporary_scene_and_export
|
from .generate_temporary_scene_and_export import generate_temporary_scene_and_export
|
||||||
from .export_gltf import (generate_gltf_export_settings)
|
from .export_gltf import (generate_gltf_export_settings)
|
||||||
|
|
||||||
|
# material library logic
|
||||||
|
# To avoid redundant materials (can be very costly, mostly when using high res textures)
|
||||||
|
# - we explore a gltf file containing all materials from a blend file
|
||||||
|
# - we add materialInfo component to each object that uses one of the materials, so that "what material is used by which object" is preserved
|
||||||
|
#
|
||||||
|
|
||||||
def clear_material_info(collection_names, library_scenes):
|
def clear_material_info(collection_names, library_scenes):
|
||||||
for scene in library_scenes:
|
for scene in library_scenes:
|
||||||
root_collection = scene.collection
|
root_collection = scene.collection
|
||||||
|
|
|
@ -9,7 +9,7 @@ def draw_assets(layout, name, title, asset_registry, target_type, target_name, e
|
||||||
number_of_generated_assets = len(generated_assets)
|
number_of_generated_assets = len(generated_assets)
|
||||||
|
|
||||||
header, panel = layout.panel(f"assets{name}", default_closed=True)
|
header, panel = layout.panel(f"assets{name}", default_closed=True)
|
||||||
header.label(text=title + f"({number_of_user_assets + number_of_generated_assets})", icon="ASSET_MANAGER")
|
header.label(text=title + f"({number_of_user_assets})", icon="ASSET_MANAGER")
|
||||||
|
|
||||||
|
|
||||||
blueprint_assets = target_type == 'BLUEPRINT'
|
blueprint_assets = target_type == 'BLUEPRINT'
|
||||||
|
@ -42,8 +42,9 @@ def draw_assets(layout, name, title, asset_registry, target_type, target_name, e
|
||||||
if editable:
|
if editable:
|
||||||
row = panel.row()
|
row = panel.row()
|
||||||
#panel.separator()
|
#panel.separator()
|
||||||
|
print("here", user_assets)
|
||||||
for asset in user_assets:
|
for asset in user_assets:
|
||||||
|
print("asset", asset)
|
||||||
row = panel.row()
|
row = panel.row()
|
||||||
split = row.split(factor=nesting_indent)
|
split = row.split(factor=nesting_indent)
|
||||||
col = split.column()
|
col = split.column()
|
||||||
|
|
|
@ -59,7 +59,7 @@ def setup_data(request):
|
||||||
if os.path.exists(screenshot_observed_path):
|
if os.path.exists(screenshot_observed_path):
|
||||||
os.remove(screenshot_observed_path)
|
os.remove(screenshot_observed_path)
|
||||||
|
|
||||||
request.addfinalizer(finalizer)
|
#request.addfinalizer(finalizer)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ def test_export_complex(setup_data):
|
||||||
blenvy.auto_export.auto_export = True
|
blenvy.auto_export.auto_export = True
|
||||||
blenvy.auto_export.export_scene_settings = True
|
blenvy.auto_export.export_scene_settings = True
|
||||||
blenvy.auto_export.export_blueprints = True
|
blenvy.auto_export.export_blueprints = True
|
||||||
blenvy.auto_export.export_materials_library = True
|
blenvy.auto_export.export_materials_library = False # TODO: switch back
|
||||||
|
|
||||||
bpy.data.scenes['World'].blenvy_scene_type = 'Level' # set scene as main/level scene
|
bpy.data.scenes['World'].blenvy_scene_type = 'Level' # set scene as main/level scene
|
||||||
bpy.data.scenes['Library'].blenvy_scene_type = 'Library' # set scene as Library scene
|
bpy.data.scenes['Library'].blenvy_scene_type = 'Library' # set scene as Library scene
|
||||||
|
|
|
@ -53,7 +53,7 @@ def test_export_external_blueprints(setup_data):
|
||||||
blenvy.auto_export.auto_export = True
|
blenvy.auto_export.auto_export = True
|
||||||
blenvy.auto_export.export_scene_settings = True
|
blenvy.auto_export.export_scene_settings = True
|
||||||
blenvy.auto_export.export_blueprints = True
|
blenvy.auto_export.export_blueprints = True
|
||||||
blenvy.auto_export.export_materials_library = True
|
blenvy.auto_export.export_materials_library = False # TODO switch back
|
||||||
|
|
||||||
print("SCENES", bpy.data.scenes)
|
print("SCENES", bpy.data.scenes)
|
||||||
for scene in bpy.data.scenes:
|
for scene in bpy.data.scenes:
|
||||||
|
|
Loading…
Reference in New Issue