Compare commits
3 Commits
8602383445
...
270202d24f
Author | SHA1 | Date |
---|---|---|
kaosat.dev | 270202d24f | |
kaosat.dev | 33cddda7a5 | |
kaosat.dev | f0cca65128 |
|
@ -37,7 +37,7 @@ pub fn compute_scene_aabbs(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for entity in other_entities.iter() {
|
for entity in other_entities.iter() {
|
||||||
println!("stuff with AABB");
|
println!("already got AABB");
|
||||||
commands.entity(entity).insert(BlueprintReadyForFinalizing); // FIXME ! Yikes !!
|
commands.entity(entity).insert(BlueprintReadyForFinalizing); // FIXME ! Yikes !!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ pub struct BlueprintAsset {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// helper component, is used to store the list of sub blueprints to enable automatic loading of dependend blueprints
|
/// helper component, is used to store the list of sub blueprints to enable automatic loading of dependend blueprints
|
||||||
|
/// these are only the DIRECT dependencies of a blueprint, does not contain the indirect assets (ie assets of sub blueprints, etc)
|
||||||
#[derive(Component, Reflect, Default, Debug, Deserialize)]
|
#[derive(Component, Reflect, Default, Debug, Deserialize)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct BlueprintAssets {
|
pub struct BlueprintAssets {
|
||||||
|
@ -29,6 +30,14 @@ pub struct BlueprintAssets {
|
||||||
}
|
}
|
||||||
//(pub Vec<BlueprintAsset>);
|
//(pub Vec<BlueprintAsset>);
|
||||||
|
|
||||||
|
/// helper component, is used to store the list of sub blueprints to enable automatic loading of dependend blueprints
|
||||||
|
#[derive(Component, Reflect, Default, Debug, Deserialize)]
|
||||||
|
pub struct BlueprintAllAssets {
|
||||||
|
/// only this field should get filled in from the Blender side
|
||||||
|
pub assets: Vec<BlueprintAsset>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
///
|
///
|
||||||
/// flag component, usually added when a blueprint is loaded
|
/// flag component, usually added when a blueprint is loaded
|
||||||
|
|
|
@ -1,48 +1,58 @@
|
||||||
use crate::{BlueprintAssetsLoadState, BlueprintAssetsLoaded, BlueprintInfo, SpawnBlueprint};
|
use crate::{BlueprintAssetsLoadState, BlueprintAssetsLoaded, BlueprintChildrenReady, BlueprintInfo, BlueprintInstanceReady, BlueprintSpawning, InBlueprint, SpawnBlueprint, SubBlueprintsSpawnTracker};
|
||||||
use bevy::asset::AssetEvent;
|
use bevy::asset::{AssetEvent, UntypedAssetId};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::scene::SceneInstance;
|
use bevy::scene::SceneInstance;
|
||||||
|
use bevy::utils::hashbrown::HashMap;
|
||||||
|
|
||||||
|
|
||||||
|
/// Resource mapping asset paths (ideally untyped ids, but more complex) to a list of blueprint instance entity ids
|
||||||
|
#[derive(Debug, Clone, Resource, Default)]
|
||||||
|
pub(crate) struct AssetToBlueprintInstancesMapper{
|
||||||
|
// pub(crate) untyped_id_to_blueprint_entity_ids: HashMap<UntypedAssetId, Vec<Entity>>
|
||||||
|
pub(crate) untyped_id_to_blueprint_entity_ids: HashMap<String, Vec<Entity>>
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn react_to_asset_changes(
|
pub(crate) fn react_to_asset_changes(
|
||||||
mut gltf_events: EventReader<AssetEvent<Gltf>>,
|
mut gltf_events: EventReader<AssetEvent<Gltf>>, // FIXME: Problem: we need to react to any asset change, not just gltf files !
|
||||||
// mut untyped_events: EventReader<AssetEvent<LoadedUntypedAsset>>,
|
// mut untyped_events: EventReader<AssetEvent<LoadedUntypedAsset>>,
|
||||||
mut blueprint_assets: Query<(
|
blueprint_assets: Query<(
|
||||||
Entity,
|
Entity,
|
||||||
Option<&Name>,
|
Option<&Name>,
|
||||||
&BlueprintInfo,
|
&BlueprintInfo,
|
||||||
&mut BlueprintAssetsLoadState,
|
|
||||||
Option<&Children>,
|
Option<&Children>,
|
||||||
)>,
|
)>,
|
||||||
|
// blueprint_children_entities: Query<&InBlueprint>, => can only be used if the entites are tagged, right now that is optional...perhaps do not make it optional
|
||||||
|
assets_to_blueprint_instances: Res<AssetToBlueprintInstancesMapper>,
|
||||||
|
all_parents: Query<&Parent>,
|
||||||
|
spawning_blueprints: Query<&BlueprintSpawning>,
|
||||||
|
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
|
|
||||||
) {
|
) {
|
||||||
|
let mut respawn_candidates: Vec<&Entity> = vec![];
|
||||||
|
|
||||||
for event in gltf_events.read() {
|
for event in gltf_events.read() {
|
||||||
// LoadedUntypedAsset
|
// LoadedUntypedAsset
|
||||||
match event {
|
match event {
|
||||||
AssetEvent::Modified { id } => {
|
AssetEvent::Modified { id } => {
|
||||||
// React to the image being modified
|
// React to the gltf file 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
|
if let Some(asset_path) = asset_server.get_path(*id) {
|
||||||
blueprint_assets.iter_mut()
|
// let untyped = asset_server.get_handle_untyped(asset_path.clone());
|
||||||
{
|
// println!("matching untyped handle {:?}", untyped);
|
||||||
for tracker in assets_to_load.asset_infos.iter_mut() {
|
// let bla = untyped.unwrap().id();
|
||||||
if asset_server.get_path(*id).is_some() {
|
// asset_server.get
|
||||||
if tracker.path == asset_server.get_path(*id).unwrap().to_string() {
|
// in order to avoid respawn both a parent & a child , which would crash Bevy, we do things in two steps
|
||||||
println!("HOLY MOLY IT DETECTS !!, now respawn {:?}", entity_name);
|
if let Some(entities) = assets_to_blueprint_instances.untyped_id_to_blueprint_entity_ids.get(&asset_path.to_string()) {
|
||||||
if children.is_some() {
|
for entity in entities.iter() {
|
||||||
for child in children.unwrap().iter() {
|
println!("matching blueprint instance {}", entity);
|
||||||
commands.entity(*child).despawn_recursive();
|
// disregard entities that are already (re) spawning
|
||||||
}
|
if !respawn_candidates.contains(&entity) && blueprint_assets.get(*entity).is_ok() && spawning_blueprints.get(*entity).is_err()
|
||||||
}
|
{
|
||||||
commands
|
respawn_candidates.push(entity);
|
||||||
.entity(entity)
|
|
||||||
.remove::<BlueprintAssetsLoaded>()
|
|
||||||
.remove::<SceneInstance>()
|
|
||||||
.remove::<BlueprintAssetsLoadState>()
|
|
||||||
.insert(SpawnBlueprint);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,4 +60,48 @@ pub(crate) fn react_to_asset_changes(
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// we process all candidates here to deal with the case where multiple assets have changed in a single frame, which could cause respawn chaos
|
||||||
|
// now find hierarchy of changes and only set the uppermost parent up for respawning
|
||||||
|
// TODO: improve this, very inneficient
|
||||||
|
let mut retained_candidates: Vec<Entity> = vec![];
|
||||||
|
'outer: for entity in respawn_candidates.iter() {
|
||||||
|
for parent in all_parents.iter_ancestors(**entity){
|
||||||
|
for ent in respawn_candidates.iter() {
|
||||||
|
if **ent == parent {
|
||||||
|
if ! retained_candidates.contains(&parent) {
|
||||||
|
retained_candidates.push(parent);
|
||||||
|
}
|
||||||
|
continue 'outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ! retained_candidates.contains(&entity) {
|
||||||
|
retained_candidates.push(**entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// println!("respawn candidates {:?}", respawn_candidates);
|
||||||
|
for retained in retained_candidates.iter() {
|
||||||
|
println!("retained {}", retained);
|
||||||
|
|
||||||
|
if let Ok((entity, entity_name, _blueprint_info, children)) = blueprint_assets.get(*retained) {
|
||||||
|
println!("HOLY MOLY IT DETECTS !!, now respawn {:?}", entity_name);
|
||||||
|
|
||||||
|
// TODO: only remove those that are "in blueprint"
|
||||||
|
if children.is_some() {
|
||||||
|
for child in children.unwrap().iter() {
|
||||||
|
commands.entity(*child).despawn_recursive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commands
|
||||||
|
.entity(entity)
|
||||||
|
.remove::<BlueprintInstanceReady>()
|
||||||
|
.remove::<BlueprintAssetsLoaded>()
|
||||||
|
.remove::<SceneInstance>()
|
||||||
|
.remove::<BlueprintAssetsLoadState>()
|
||||||
|
.remove::<SubBlueprintsSpawnTracker>()
|
||||||
|
.insert(SpawnBlueprint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("done with asset updates");
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub use copy_components::*;
|
||||||
pub(crate) mod hot_reload;
|
pub(crate) mod hot_reload;
|
||||||
pub(crate) use hot_reload::*;
|
pub(crate) use hot_reload::*;
|
||||||
|
|
||||||
use bevy::{prelude::*, utils::HashMap};
|
use bevy::{prelude::*, utils::hashbrown::HashMap};
|
||||||
|
|
||||||
use crate::{BlenvyConfig, GltfComponentsSet};
|
use crate::{BlenvyConfig, GltfComponentsSet};
|
||||||
|
|
||||||
|
@ -65,7 +65,8 @@ fn aabbs_enabled(blenvy_config: Res<BlenvyConfig>) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hot_reload(watching_for_changes: Res<WatchingForChanges>) -> bool {
|
fn hot_reload(watching_for_changes: Res<WatchingForChanges>) -> bool {
|
||||||
watching_for_changes.0
|
// println!("hot reload ? {}", watching_for_changes.0);
|
||||||
|
return watching_for_changes.0
|
||||||
}
|
}
|
||||||
|
|
||||||
trait BlenvyApp {
|
trait BlenvyApp {
|
||||||
|
@ -91,6 +92,9 @@ const ASSET_ERROR: &str = ""; // TODO
|
||||||
impl Plugin for BlueprintsPlugin {
|
impl Plugin for BlueprintsPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.register_watching_for_changes()
|
app.register_watching_for_changes()
|
||||||
|
.insert_resource(AssetToBlueprintInstancesMapper {
|
||||||
|
untyped_id_to_blueprint_entity_ids: HashMap::new(),
|
||||||
|
})
|
||||||
.add_event::<BlueprintEvent>()
|
.add_event::<BlueprintEvent>()
|
||||||
.register_type::<BlueprintInfo>()
|
.register_type::<BlueprintInfo>()
|
||||||
.register_type::<MaterialInfo>()
|
.register_type::<MaterialInfo>()
|
||||||
|
|
|
@ -4,9 +4,7 @@ use bevy::{gltf::Gltf, prelude::*, scene::SceneInstance, utils::hashbrown::HashM
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AnimationInfos, AssetLoadTracker, BlenvyConfig, BlueprintAnimationPlayerLink,
|
AnimationInfos, AssetLoadTracker, AssetToBlueprintInstancesMapper, BlenvyConfig, BlueprintAnimationPlayerLink, BlueprintAnimations, BlueprintAssets, BlueprintAssetsLoadState, BlueprintAssetsLoaded, BlueprintAssetsNotLoaded, SceneAnimationPlayerLink, SceneAnimations
|
||||||
BlueprintAnimations, BlueprintAssets, BlueprintAssetsLoadState, BlueprintAssetsLoaded,
|
|
||||||
BlueprintAssetsNotLoaded, SceneAnimationPlayerLink, SceneAnimations,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// this is a flag component for our levels/game world
|
/// this is a flag component for our levels/game world
|
||||||
|
@ -39,11 +37,7 @@ impl BlueprintInfo {
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct SpawnBlueprint;
|
pub struct SpawnBlueprint;
|
||||||
|
|
||||||
#[derive(Component, Debug)]
|
|
||||||
/// flag component added when a Blueprint instance ist Ready : ie :
|
|
||||||
/// - its assets have loaded
|
|
||||||
/// - it has finished spawning
|
|
||||||
pub struct BlueprintInstanceReady;
|
|
||||||
|
|
||||||
#[derive(Component, Reflect, Default, Debug)]
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
|
@ -112,6 +106,9 @@ pub struct BlueprintSpawning;
|
||||||
|
|
||||||
use gltf::Gltf as RawGltf;
|
use gltf::Gltf as RawGltf;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Overview of the Blueprint Spawning process
|
Overview of the Blueprint Spawning process
|
||||||
- Blueprint Load Assets
|
- Blueprint Load Assets
|
||||||
|
@ -135,6 +132,10 @@ pub(crate) fn blueprints_prepare_spawn(
|
||||||
>,
|
>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
|
// for hot reload
|
||||||
|
mut assets_to_blueprint_instances: ResMut<AssetToBlueprintInstancesMapper>,
|
||||||
|
// for debug
|
||||||
|
all_names: Query<&Name>
|
||||||
) {
|
) {
|
||||||
for (entity, blueprint_info, entity_name) in blueprint_instances_to_spawn.iter() {
|
for (entity, blueprint_info, entity_name) in blueprint_instances_to_spawn.iter() {
|
||||||
info!(
|
info!(
|
||||||
|
@ -174,6 +175,7 @@ pub(crate) fn blueprints_prepare_spawn(
|
||||||
// println!("all_assets {:?}", all_assets);
|
// println!("all_assets {:?}", all_assets);
|
||||||
|
|
||||||
for asset in all_assets.assets.iter() {
|
for asset in all_assets.assets.iter() {
|
||||||
|
println!("ASSET {}",asset.path);
|
||||||
let untyped_handle = asset_server.load_untyped(&asset.path);
|
let untyped_handle = asset_server.load_untyped(&asset.path);
|
||||||
let asset_id = untyped_handle.id();
|
let asset_id = untyped_handle.id();
|
||||||
let loaded = asset_server.is_loaded_with_dependencies(asset_id);
|
let loaded = asset_server.is_loaded_with_dependencies(asset_id);
|
||||||
|
@ -186,6 +188,19 @@ pub(crate) fn blueprints_prepare_spawn(
|
||||||
handle: untyped_handle.clone(),
|
handle: untyped_handle.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: dang, too early, asset server has not yet started loading yet
|
||||||
|
// let path_id = asset_server.get_path_id(&asset.path).expect("we should have alread checked for this asset");
|
||||||
|
let path_id = asset.path.clone();
|
||||||
|
// TODO: make this dependant on if hot reload is enabled or not
|
||||||
|
if !assets_to_blueprint_instances.untyped_id_to_blueprint_entity_ids.contains_key(&path_id) {
|
||||||
|
assets_to_blueprint_instances.untyped_id_to_blueprint_entity_ids.insert(path_id.clone(), vec![]);
|
||||||
|
}
|
||||||
|
// only insert if not already present in mapping
|
||||||
|
if !assets_to_blueprint_instances.untyped_id_to_blueprint_entity_ids[&path_id].contains(&entity) {
|
||||||
|
println!("adding mapping between {} and entity {:?}", path_id, all_names.get(entity));
|
||||||
|
assets_to_blueprint_instances.untyped_id_to_blueprint_entity_ids.get_mut(&path_id).unwrap().push(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,6 +674,7 @@ pub(crate) fn blueprints_cleanup_spawned_scene(
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.entity(original)
|
.entity(original)
|
||||||
|
.remove::<BlueprintChildrenReady>() // we are done with this step, we can remove the `BlueprintChildrenReady` tag component
|
||||||
.insert(BlueprintReadyForPostProcess); // Tag the entity so any systems dealing with post processing can know it is now their "turn"
|
.insert(BlueprintReadyForPostProcess); // Tag the entity so any systems dealing with post processing can know it is now their "turn"
|
||||||
|
|
||||||
commands.entity(blueprint_root_entity).despawn_recursive(); // Remove the root entity that comes from the spawned-in scene
|
commands.entity(blueprint_root_entity).despawn_recursive(); // Remove the root entity that comes from the spawned-in scene
|
||||||
|
@ -669,6 +685,12 @@ pub(crate) fn blueprints_cleanup_spawned_scene(
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct BlueprintReadyForFinalizing;
|
pub struct BlueprintReadyForFinalizing;
|
||||||
|
|
||||||
|
#[derive(Component, Debug)]
|
||||||
|
/// flag component added when a Blueprint instance ist Ready : ie :
|
||||||
|
/// - its assets have loaded
|
||||||
|
/// - it has finished spawning
|
||||||
|
pub struct BlueprintInstanceReady;
|
||||||
|
|
||||||
pub(crate) fn blueprints_finalize_instances(
|
pub(crate) fn blueprints_finalize_instances(
|
||||||
blueprint_instances: Query<
|
blueprint_instances: Query<
|
||||||
(
|
(
|
||||||
|
@ -681,9 +703,12 @@ pub(crate) fn blueprints_finalize_instances(
|
||||||
(With<BlueprintSpawning>, With<BlueprintReadyForFinalizing>),
|
(With<BlueprintSpawning>, With<BlueprintReadyForFinalizing>),
|
||||||
>,
|
>,
|
||||||
mut sub_blueprint_trackers: Query<&mut SubBlueprintsSpawnTracker, With<BlueprintInfo>>,
|
mut sub_blueprint_trackers: Query<&mut SubBlueprintsSpawnTracker, With<BlueprintInfo>>,
|
||||||
|
spawning_blueprints: Query<&BlueprintSpawning>,
|
||||||
all_children: Query<&Children>,
|
all_children: Query<&Children>,
|
||||||
mut blueprint_events: EventWriter<BlueprintEvent>,
|
mut blueprint_events: EventWriter<BlueprintEvent>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
|
|
||||||
|
all_names: Query<&Name>
|
||||||
) {
|
) {
|
||||||
for (entity, name, blueprint_info, parent_blueprint, hide_until_ready) in
|
for (entity, name, blueprint_info, parent_blueprint, hide_until_ready) in
|
||||||
blueprint_instances.iter()
|
blueprint_instances.iter()
|
||||||
|
@ -691,6 +716,7 @@ pub(crate) fn blueprints_finalize_instances(
|
||||||
info!("Finalizing blueprint instance {:?}", name);
|
info!("Finalizing blueprint instance {:?}", name);
|
||||||
commands
|
commands
|
||||||
.entity(entity)
|
.entity(entity)
|
||||||
|
.remove::<BlueprintReadyForFinalizing>()
|
||||||
.remove::<BlueprintReadyForPostProcess>()
|
.remove::<BlueprintReadyForPostProcess>()
|
||||||
.remove::<BlueprintSpawning>()
|
.remove::<BlueprintSpawning>()
|
||||||
.remove::<SpawnBlueprint>()
|
.remove::<SpawnBlueprint>()
|
||||||
|
@ -704,24 +730,30 @@ pub(crate) fn blueprints_finalize_instances(
|
||||||
// this should always be done last, as children should be finished before the parent can be processed correctly
|
// this should always be done last, as children should be finished before the parent can be processed correctly
|
||||||
// TODO: perhaps use observers for these
|
// TODO: perhaps use observers for these
|
||||||
if let Some(track_root) = parent_blueprint {
|
if let Some(track_root) = parent_blueprint {
|
||||||
if let Ok(mut tracker) = sub_blueprint_trackers.get_mut(track_root.0) {
|
// only propagate sub_blueprint spawning if the parent blueprint instance ist actually in spawning mode
|
||||||
tracker
|
if spawning_blueprints.get(track_root.0).is_ok() {
|
||||||
.sub_blueprint_instances
|
if let Ok(mut tracker) = sub_blueprint_trackers.get_mut(track_root.0) {
|
||||||
.entry(entity)
|
tracker
|
||||||
.or_insert(true);
|
.sub_blueprint_instances
|
||||||
tracker.sub_blueprint_instances.insert(entity, true);
|
.entry(entity)
|
||||||
|
.or_insert(true);
|
||||||
|
tracker.sub_blueprint_instances.insert(entity, true);
|
||||||
|
|
||||||
|
// TODO: ugh, my limited rust knowledge, this is bad code
|
||||||
|
let mut all_spawned = true;
|
||||||
|
for val in tracker.sub_blueprint_instances.values() {
|
||||||
|
if !val {
|
||||||
|
all_spawned = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if all_spawned {
|
||||||
|
|
||||||
|
let root_name = all_names.get(track_root.0);
|
||||||
|
println!("ALLLLL SPAAAAWNED for {} named {:?}", track_root.0, root_name);
|
||||||
|
commands.entity(track_root.0).insert(BlueprintChildrenReady);
|
||||||
|
|
||||||
// TODO: ugh, my limited rust knowledge, this is bad code
|
|
||||||
let mut all_spawned = true;
|
|
||||||
for val in tracker.sub_blueprint_instances.values() {
|
|
||||||
if !val {
|
|
||||||
all_spawned = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if all_spawned {
|
|
||||||
// println!("ALLLLL SPAAAAWNED for {} named {:?}", track_root.0, root_name);
|
|
||||||
commands.entity(track_root.0).insert(BlueprintChildrenReady);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,7 +185,37 @@ Blender side:
|
||||||
|
|
||||||
- [x] BLENVY_OT_item_select is missing handling for the other types (outside of object & collection)
|
- [x] BLENVY_OT_item_select is missing handling for the other types (outside of object & collection)
|
||||||
- [x] fix selection logic
|
- [x] fix selection logic
|
||||||
|
- [x] update testing blend files
|
||||||
|
- [x] disable 'export_hierarchy_full_collections' for all cases: not reliable and redudant
|
||||||
|
- [ ] fix systematic material exports despite no changes
|
||||||
|
- [ ] investigate lack of detection of changes of adding/changing components
|
||||||
|
- [ ] change scene serialization to account for collections ...sigh
|
||||||
|
- [ ] also remove ____dummy____.bin when export format is gltf
|
||||||
|
|
||||||
|
- [ ] fix/cleanup asset information injection (also needed for hot reload)
|
||||||
|
- [ ] add back per blueprint assets
|
||||||
|
- [ ] reuse the already existing asset_scan + export thing
|
||||||
|
- thoughts:
|
||||||
|
- the "list of all assets" is actually the "fake"/generated one: nobody would write a list of assets for sub assets,
|
||||||
|
you would just add the assets to your blueprint
|
||||||
|
- in Bevy at spawning we have
|
||||||
|
blueprint => assets
|
||||||
|
for hot reload we need
|
||||||
|
asset => blueprint instances so we can despawn/respawn etc blueprint instances when one of their assets has changed
|
||||||
|
|
||||||
|
problem of untyped vs typed
|
||||||
|
perhaps have a mapping of untyped => typed id
|
||||||
|
map asset id => [entity ids]
|
||||||
|
|
||||||
|
- [ ] add option to 'split out' meshes from blueprints ?
|
||||||
|
- [ ] ie considering meshletts etc , it would make sense to keep blueprints seperate from purely mesh gltfs
|
||||||
|
- [ ] persist exported materials path in blueprints so that it can be read from library file users
|
||||||
|
- [ ] just like "export_path" write it into each blueprint's collection
|
||||||
|
- [ ] scan for used materials per blueprint !
|
||||||
|
- [ ] 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) ?
|
||||||
- [ ] hidden objects/collections only semi respected at export
|
- [ ] hidden objects/collections only semi respected at export
|
||||||
- this is because blueprints are external ?
|
- this is because blueprints are external ?
|
||||||
- [ ] verify based on gltf settings
|
- [ ] verify based on gltf settings
|
||||||
|
@ -199,20 +229,8 @@ Blender side:
|
||||||
- [ ] disabled components
|
- [ ] disabled components
|
||||||
- [ ] blueprint instances as children of blueprint instances
|
- [ ] blueprint instances as children of blueprint instances
|
||||||
- [ ] blueprint instances as children of empties
|
- [ ] blueprint instances as children of empties
|
||||||
- [x] update testing blend files
|
|
||||||
- [ ] disable 'export_hierarchy_full_collections' for all cases: not reliable and redudant
|
|
||||||
|
|
||||||
|
|
||||||
- [ ] add option to 'split out' meshes from blueprints ?
|
|
||||||
- [ ] ie considering meshletts etc , it would make sense to keep blueprints seperate from purely mesh gltfs
|
|
||||||
- [ ] persist exported materials path in blueprints so that it can be read from library file users
|
|
||||||
- [ ] just like "export_path" write it into each blueprint's collection
|
|
||||||
- [ ] scan for used materials per blueprint !
|
|
||||||
- [ ] 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:
|
Bevy Side:
|
||||||
- [x] deprecate BlueprintName & BlueprintPath & use BlueprintInfo instead
|
- [x] deprecate BlueprintName & BlueprintPath & use BlueprintInfo instead
|
||||||
- [x] make blueprint instances invisible until spawning is done to avoid "spawn flash"?
|
- [x] make blueprint instances invisible until spawning is done to avoid "spawn flash"?
|
||||||
|
@ -237,17 +255,26 @@ Bevy Side:
|
||||||
- [x] blueprint level/ collection level components are now visible in instances in Blender
|
- [x] blueprint level/ collection level components are now visible in instances in Blender
|
||||||
- [x] they do not seem to be transfered to the (instance) entity above:
|
- [x] they do not seem to be transfered to the (instance) entity above:
|
||||||
could they be on the "empty node" ?
|
could they be on the "empty node" ?
|
||||||
|
- [ ] add back & cleanup animation frame triggers
|
||||||
|
|
||||||
- [ ] simplify testing example:
|
- [ ] simplify testing example:
|
||||||
- [x] remove use of rapier physics (or even the whole common boilerplate ?)
|
- [x] remove use of rapier physics (or even the whole common boilerplate ?)
|
||||||
- [ ] remove/replace bevy editor pls with some native ui to display hierarchies
|
- [ ] remove/replace bevy editor pls with some native ui to display hierarchies
|
||||||
- [ ] a full fledged demo (including physics & co)
|
- [ ] a full fledged demo (including physics & co)
|
||||||
- [ ] other examples without interactions or physics
|
- [ ] other examples without interactions or physics
|
||||||
|
|
||||||
- [ ] add hot reloading
|
- [ ] add hot reloading
|
||||||
- [x] basics
|
- [x] basics
|
||||||
- [x] make it enabled/disabled based on general flag
|
- [x] make it enabled/disabled based on general flag
|
||||||
- [ ] make
|
- [x] account for changes impact both parent & children (ie "world" and "blueprint3") for example, which leads to a crash as there is double despawn /respawn so we need to filter things out
|
||||||
- [ ] cleanup internals
|
- [x] if there are many assets/blueprints that have changed at the same time, it causes issues similar to the above, so apply a similar fix
|
||||||
|
- [x] also ignore any entities currently spawning (better to loose some information, than cause a crash)
|
||||||
|
- [ ] something is off with blueprint level components
|
||||||
|
- [ ] add the root blueprint itself to the assets either on the blender side or on the bevy side programatically
|
||||||
|
- [x] for sub blueprint tracking: do not propagate/ deal with parent blueprints if they are not themselves Spawning (ie filter out by "BlueprintSpawning")
|
||||||
|
- [ ] invalidate despawned entity & parent entities AABB
|
||||||
|
- [x] cleanup internals
|
||||||
|
|
||||||
|
|
||||||
- [x] review & change general component insertion & spawning ordering & logic
|
- [x] review & change general component insertion & spawning ordering & logic
|
||||||
- GltfComponentsSet::Injection => GltfBlueprintsSet::Spawn => GltfBlueprintsSet::AfterSpawn
|
- GltfComponentsSet::Injection => GltfBlueprintsSet::Spawn => GltfBlueprintsSet::AfterSpawn
|
||||||
|
|
|
@ -5,41 +5,28 @@ from blenvy.assets.generate_asset_file import write_ron_assets_file
|
||||||
from ..constants import TEMPSCENE_PREFIX
|
from ..constants import TEMPSCENE_PREFIX
|
||||||
from ..common.generate_temporary_scene_and_export import generate_temporary_scene_and_export, copy_hollowed_collection_into, clear_hollow_scene
|
from ..common.generate_temporary_scene_and_export import generate_temporary_scene_and_export, copy_hollowed_collection_into, clear_hollow_scene
|
||||||
from ..common.export_gltf import generate_gltf_export_settings
|
from ..common.export_gltf import generate_gltf_export_settings
|
||||||
|
from ..utils import upsert_blueprint_assets
|
||||||
def assets_to_fake_ron(list_like):
|
|
||||||
result = []
|
|
||||||
for item in list_like:
|
|
||||||
result.append(f"(name: \"{item['name']}\", path: \"{item['path']}\")")
|
|
||||||
|
|
||||||
return f"(assets: {result})".replace("'", '')
|
|
||||||
|
|
||||||
return f"({result})".replace("'", '')
|
|
||||||
|
|
||||||
|
|
||||||
def export_blueprints(blueprints, settings, blueprints_data):
|
def export_blueprints(blueprints, settings, blueprints_data):
|
||||||
blueprints_path_full = getattr(settings, "blueprints_path_full")
|
blueprints_path_full = getattr(settings, "blueprints_path_full")
|
||||||
gltf_export_settings = generate_gltf_export_settings(settings)
|
gltf_export_settings = generate_gltf_export_settings(settings)
|
||||||
|
export_materials_library = getattr(settings.auto_export, "export_materials_library")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# save current active collection
|
# save current active collection
|
||||||
active_collection = bpy.context.view_layer.active_layer_collection
|
active_collection = bpy.context.view_layer.active_layer_collection
|
||||||
export_materials_library = getattr(settings.auto_export, "export_materials_library")
|
|
||||||
|
|
||||||
for blueprint in blueprints:
|
for blueprint in blueprints:
|
||||||
print("exporting collection", blueprint.name)
|
print("exporting collection", blueprint.name)
|
||||||
gltf_output_path = os.path.join(blueprints_path_full, blueprint.name) # TODO: reuse the export_path custom property ?
|
gltf_output_path = os.path.join(blueprints_path_full, blueprint.name) # TODO: reuse the export_path custom property ?
|
||||||
gltf_export_settings = { **gltf_export_settings, 'use_active_scene': True, 'use_active_collection': True, 'use_active_collection_with_nested':True}
|
gltf_export_settings = { **gltf_export_settings, 'use_active_scene': True, 'use_active_collection': True, 'use_active_collection_with_nested':True}
|
||||||
|
|
||||||
|
collection = bpy.data.collections[blueprint.name]
|
||||||
# if we are using the material library option, do not export materials, use placeholder instead
|
# if we are using the material library option, do not export materials, use placeholder instead
|
||||||
if export_materials_library:
|
if export_materials_library:
|
||||||
gltf_export_settings['export_materials'] = 'PLACEHOLDER'
|
gltf_export_settings['export_materials'] = 'PLACEHOLDER'
|
||||||
|
|
||||||
collection = bpy.data.collections[blueprint.name]
|
|
||||||
|
|
||||||
all_assets = []
|
|
||||||
auto_assets = []
|
|
||||||
collection["BlueprintAssets"] = assets_to_fake_ron([]) #assets_to_fake_ron([{"name": asset.name, "path": asset.path} for asset in collection.user_assets] + auto_assets) #all_assets + [{"name": asset.name, "path": asset.path} for asset in collection.user_assets] + auto_assets)
|
|
||||||
|
|
||||||
|
upsert_blueprint_assets(blueprint, blueprints_data=blueprints_data, settings=settings)
|
||||||
|
|
||||||
# do the actual export
|
# do the actual export
|
||||||
generate_temporary_scene_and_export(
|
generate_temporary_scene_and_export(
|
||||||
|
|
|
@ -10,7 +10,7 @@ from ..blueprints.get_blueprints_to_export import get_blueprints_to_export
|
||||||
from ..levels.get_levels_to_export import get_levels_to_export
|
from ..levels.get_levels_to_export import get_levels_to_export
|
||||||
from .export_gltf import get_standard_exporter_settings
|
from .export_gltf import get_standard_exporter_settings
|
||||||
|
|
||||||
from ..levels.export_main_scenes import export_main_scene
|
from ..levels.export_levels import export_main_scene
|
||||||
from ..blueprints.export_blueprints import export_blueprints
|
from ..blueprints.export_blueprints import export_blueprints
|
||||||
from .export_materials import cleanup_materials, export_materials
|
from .export_materials import cleanup_materials, export_materials
|
||||||
from ..levels.bevy_scene_components import remove_scene_components, upsert_scene_components
|
from ..levels.bevy_scene_components import remove_scene_components, upsert_scene_components
|
||||||
|
@ -56,6 +56,7 @@ def auto_export(changes_per_scene, changed_export_parameters, settings):
|
||||||
#inject/ update light shadow information
|
#inject/ update light shadow information
|
||||||
for light in bpy.data.lights:
|
for light in bpy.data.lights:
|
||||||
enabled = 'true' if light.use_shadow else 'false'
|
enabled = 'true' if light.use_shadow else 'false'
|
||||||
|
# TODO: directly set relevant components instead ?
|
||||||
light['BlenderLightShadows'] = f"(enabled: {enabled}, buffer_bias: {light.shadow_buffer_bias})"
|
light['BlenderLightShadows'] = f"(enabled: {enabled}, buffer_bias: {light.shadow_buffer_bias})"
|
||||||
|
|
||||||
# export
|
# export
|
||||||
|
@ -69,7 +70,8 @@ def auto_export(changes_per_scene, changed_export_parameters, settings):
|
||||||
|
|
||||||
# since materials export adds components we need to call this before blueprints are exported
|
# since materials export adds components we need to call this before blueprints are exported
|
||||||
# export materials & inject materials components into relevant objects
|
# export materials & inject materials components into relevant objects
|
||||||
if export_materials_library:
|
# FIXME: improve change detection, perhaps even add "material changes"
|
||||||
|
if export_materials_library and (changed_export_parameters or len(changes_per_scene.keys()) > 0 ):
|
||||||
export_materials(blueprints_data.blueprint_names, settings.library_scenes, settings)
|
export_materials(blueprints_data.blueprint_names, settings.library_scenes, settings)
|
||||||
|
|
||||||
# update the list of tracked exports
|
# update the list of tracked exports
|
||||||
|
|
|
@ -235,7 +235,9 @@ def custom_properties_hash(obj):
|
||||||
custom_properties = {}
|
custom_properties = {}
|
||||||
for property_name in obj.keys():
|
for property_name in obj.keys():
|
||||||
if property_name not in '_RNA_UI' and property_name != 'components_meta':
|
if property_name not in '_RNA_UI' and property_name != 'components_meta':
|
||||||
|
print("custom properties stuff for", obj, property_name)
|
||||||
custom_properties[property_name] = obj[property_name]
|
custom_properties[property_name] = obj[property_name]
|
||||||
|
print("custom props for hashing", custom_properties, str(h1_hash(str(custom_properties))) )
|
||||||
return str(h1_hash(str(custom_properties)))
|
return str(h1_hash(str(custom_properties)))
|
||||||
|
|
||||||
def camera_hash(obj):
|
def camera_hash(obj):
|
||||||
|
@ -316,7 +318,7 @@ def modifiers_hash(object, settings):
|
||||||
|
|
||||||
def serialize_scene(settings):
|
def serialize_scene(settings):
|
||||||
cache = {"materials":{}}
|
cache = {"materials":{}}
|
||||||
print("serializing scene")
|
print("serializing scenes")
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
|
|
||||||
|
@ -325,6 +327,7 @@ def serialize_scene(settings):
|
||||||
|
|
||||||
# TODO: only go through scenes actually in our list
|
# TODO: only go through scenes actually in our list
|
||||||
for scene in bpy.data.scenes:
|
for scene in bpy.data.scenes:
|
||||||
|
print("scene", scene.name)
|
||||||
# ignore temporary scenes
|
# ignore temporary scenes
|
||||||
if scene.name.startswith(TEMPSCENE_PREFIX):
|
if scene.name.startswith(TEMPSCENE_PREFIX):
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -9,16 +9,8 @@ from ..constants import TEMPSCENE_PREFIX
|
||||||
from ..common.generate_temporary_scene_and_export import generate_temporary_scene_and_export, copy_hollowed_collection_into, clear_hollow_scene
|
from ..common.generate_temporary_scene_and_export import generate_temporary_scene_and_export, copy_hollowed_collection_into, clear_hollow_scene
|
||||||
from ..common.export_gltf import (generate_gltf_export_settings, export_gltf)
|
from ..common.export_gltf import (generate_gltf_export_settings, export_gltf)
|
||||||
from .is_object_dynamic import is_object_dynamic, is_object_static
|
from .is_object_dynamic import is_object_dynamic, is_object_static
|
||||||
|
from ..utils import upsert_scene_assets
|
||||||
|
|
||||||
def assets_to_fake_ron(list_like):
|
|
||||||
result = []
|
|
||||||
for item in list_like:
|
|
||||||
result.append(f"(name: \"{item['name']}\", path: \"{item['path']}\")")
|
|
||||||
|
|
||||||
return f"(assets: {result})".replace("'", '')
|
|
||||||
|
|
||||||
return f"({result})".replace("'", '')
|
|
||||||
|
|
||||||
|
|
||||||
def export_main_scene(scene, settings, blueprints_data):
|
def export_main_scene(scene, settings, blueprints_data):
|
||||||
gltf_export_settings = generate_gltf_export_settings(settings)
|
gltf_export_settings = generate_gltf_export_settings(settings)
|
||||||
|
@ -41,53 +33,7 @@ def export_main_scene(scene, settings, blueprints_data):
|
||||||
gltf_output_path = os.path.join(levels_path_full, scene.name)
|
gltf_output_path = os.path.join(levels_path_full, scene.name)
|
||||||
|
|
||||||
inject_blueprints_list_into_main_scene(scene, blueprints_data, settings)
|
inject_blueprints_list_into_main_scene(scene, blueprints_data, settings)
|
||||||
"""print("main scene", scene)
|
upsert_scene_assets(scene, blueprints_data=blueprints_data, settings=settings)
|
||||||
for asset in scene.user_assets:
|
|
||||||
print(" user asset", asset.name, asset.path)
|
|
||||||
for asset in scene.generated_assets:
|
|
||||||
print(" generated asset", asset)"""
|
|
||||||
"""for blueprint in blueprints_data.blueprints_per_scenes[scene.name]:
|
|
||||||
print("BLUEPRINT", blueprint)"""
|
|
||||||
blueprint_instances_in_scene = blueprints_data.blueprint_instances_per_main_scene.get(scene.name, {}).keys()
|
|
||||||
blueprints_in_scene = [blueprints_data.blueprints_per_name[blueprint_name] for blueprint_name in blueprint_instances_in_scene]
|
|
||||||
#yala = [blueprint.collection.user_assets for blueprint in blueprints_in_scene]
|
|
||||||
#print("dsfsdf", yala)
|
|
||||||
auto_assets = []
|
|
||||||
|
|
||||||
all_assets = []
|
|
||||||
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
|
||||||
|
|
||||||
blueprints_path = getattr(settings, "blueprints_path")
|
|
||||||
for blueprint in blueprints_in_scene:
|
|
||||||
if blueprint.local:
|
|
||||||
blueprint_exported_path = os.path.join(blueprints_path, f"{blueprint.name}{export_gltf_extension}")
|
|
||||||
else:
|
|
||||||
# get the injected path of the external blueprints
|
|
||||||
blueprint_exported_path = blueprint.collection['export_path'] if 'export_path' in blueprint.collection else None
|
|
||||||
# add their material path
|
|
||||||
materials_exported_path = blueprint.collection['materials_path'] if 'materials_path' in blueprint.collection else None
|
|
||||||
auto_assets.append({"name": blueprint.name+"_material", "path": materials_exported_path})#, "generated": True, "internal":blueprint.local, "parent": None})
|
|
||||||
|
|
||||||
|
|
||||||
if blueprint_exported_path is not None: # and not does_asset_exist(assets_list, blueprint_exported_path):
|
|
||||||
auto_assets.append({"name": blueprint.name, "path": blueprint_exported_path})#, "generated": True, "internal":blueprint.local, "parent": None})
|
|
||||||
|
|
||||||
# now also add the assets of the blueprints # TODO: wait no , these should not be a part of the (scene) local assets
|
|
||||||
for asset in blueprint.collection.user_assets:
|
|
||||||
#print("adding assets of blueprint", asset.name)
|
|
||||||
all_assets.append({"name": asset.name, "path": asset.path})
|
|
||||||
|
|
||||||
"""for asset in auto_assets:
|
|
||||||
print(" generated asset", asset.name, asset.path)"""
|
|
||||||
|
|
||||||
materials_path = getattr(settings, "materials_path")
|
|
||||||
current_project_name = Path(bpy.context.blend_data.filepath).stem
|
|
||||||
materials_library_name = f"{current_project_name}_materials"
|
|
||||||
materials_exported_path = os.path.join(materials_path, f"{materials_library_name}{export_gltf_extension}")
|
|
||||||
material_assets = [{"name": materials_library_name, "path": materials_exported_path}] # we also add the material library as an asset
|
|
||||||
print("material_assets", material_assets, "extension", export_gltf_extension)
|
|
||||||
scene["BlueprintAssets"] = assets_to_fake_ron(all_assets + [{"name": asset.name, "path": asset.path} for asset in scene.user_assets] + auto_assets + material_assets)
|
|
||||||
#scene["BlueprintAssets"] = assets_to_fake_ron([{'name':'foo', 'path':'bar'}])
|
|
||||||
|
|
||||||
if export_separate_dynamic_and_static_objects:
|
if export_separate_dynamic_and_static_objects:
|
||||||
#print("SPLIT STATIC AND DYNAMIC")
|
#print("SPLIT STATIC AND DYNAMIC")
|
|
@ -0,0 +1,84 @@
|
||||||
|
import bpy
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from blenvy.assets.assets_scan import get_blueprint_asset_tree, get_main_scene_assets_tree2
|
||||||
|
|
||||||
|
def assets_to_fake_ron(list_like):
|
||||||
|
result = []
|
||||||
|
for item in list_like:
|
||||||
|
result.append(f"(name: \"{item['name']}\", path: \"{item['path']}\")")
|
||||||
|
|
||||||
|
return f"(assets: {result})".replace("'", '')
|
||||||
|
|
||||||
|
return f"({result})".replace("'", '')
|
||||||
|
|
||||||
|
|
||||||
|
# TODO : move to assets
|
||||||
|
def upsert_scene_assets(scene, blueprints_data, settings):
|
||||||
|
"""print("main scene", scene)
|
||||||
|
for asset in scene.user_assets:
|
||||||
|
print(" user asset", asset.name, asset.path)
|
||||||
|
for asset in scene.generated_assets:
|
||||||
|
print(" generated asset", asset)"""
|
||||||
|
"""for blueprint in blueprints_data.blueprints_per_scenes[scene.name]:
|
||||||
|
print("BLUEPRINT", blueprint)"""
|
||||||
|
blueprint_instances_in_scene = blueprints_data.blueprint_instances_per_main_scene.get(scene.name, {}).keys()
|
||||||
|
blueprints_in_scene = [blueprints_data.blueprints_per_name[blueprint_name] for blueprint_name in blueprint_instances_in_scene]
|
||||||
|
#yala = [blueprint.collection.user_assets for blueprint in blueprints_in_scene]
|
||||||
|
#print("dsfsdf", yala)
|
||||||
|
level_assets = []
|
||||||
|
all_assets = []
|
||||||
|
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
||||||
|
|
||||||
|
blueprints_path = getattr(settings, "blueprints_path")
|
||||||
|
for blueprint in blueprints_in_scene:
|
||||||
|
if blueprint.local:
|
||||||
|
blueprint_exported_path = os.path.join(blueprints_path, f"{blueprint.name}{export_gltf_extension}")
|
||||||
|
else:
|
||||||
|
# get the injected path of the external blueprints
|
||||||
|
blueprint_exported_path = blueprint.collection['export_path'] if 'export_path' in blueprint.collection else None
|
||||||
|
# add their material path
|
||||||
|
materials_exported_path = blueprint.collection['materials_path'] if 'materials_path' in blueprint.collection else None
|
||||||
|
level_assets.append({"name": blueprint.name+"_material", "path": materials_exported_path})#, "generated": True, "internal":blueprint.local, "parent": None})
|
||||||
|
|
||||||
|
|
||||||
|
if blueprint_exported_path is not None: # and not does_asset_exist(assets_list, blueprint_exported_path):
|
||||||
|
level_assets.append({"name": blueprint.name, "path": blueprint_exported_path})#, "generated": True, "internal":blueprint.local, "parent": None})
|
||||||
|
|
||||||
|
# now also add the assets of the blueprints # TODO: wait no , these should not be a part of the (scene) local assets
|
||||||
|
for asset in blueprint.collection.user_assets:
|
||||||
|
#print("adding assets of blueprint", asset.name)
|
||||||
|
all_assets.append({"name": asset.name, "path": asset.path})
|
||||||
|
|
||||||
|
"""for asset in level_assets:
|
||||||
|
print(" generated asset", asset.name, asset.path)"""
|
||||||
|
|
||||||
|
materials_path = getattr(settings, "materials_path")
|
||||||
|
current_project_name = Path(bpy.context.blend_data.filepath).stem
|
||||||
|
materials_library_name = f"{current_project_name}_materials"
|
||||||
|
materials_exported_path = os.path.join(materials_path, f"{materials_library_name}{export_gltf_extension}")
|
||||||
|
material_assets = [{"name": materials_library_name, "path": materials_exported_path}] # we also add the material library as an asset
|
||||||
|
print("material_assets", material_assets, "extension", export_gltf_extension)
|
||||||
|
|
||||||
|
|
||||||
|
all_assets_raw = get_main_scene_assets_tree2(main_scene=scene, blueprints_data=blueprints_data, settings=settings)
|
||||||
|
local_assets = [{"name": asset["name"], "path": asset["path"]} for asset in all_assets_raw if asset['parent'] is None and asset["path"] != "" ]
|
||||||
|
all_assets = [{"name": asset["name"], "path": asset["path"]} for asset in all_assets_raw if asset["path"] != "" ]
|
||||||
|
print("all_assets_raw", all_assets_raw)
|
||||||
|
print("all_assets", all_assets)
|
||||||
|
print("local assets", local_assets + material_assets)
|
||||||
|
scene["BlueprintAssets"] = assets_to_fake_ron(local_assets + material_assets)
|
||||||
|
|
||||||
|
|
||||||
|
#scene["BlueprintAssets"] = assets_to_fake_ron(all_assets + [{"name": asset.name, "path": asset.path} for asset in scene.user_assets] + level_assets + material_assets)
|
||||||
|
#scene["BlueprintAssets"] = assets_to_fake_ron([{'name':'foo', 'path':'bar'}])
|
||||||
|
|
||||||
|
def upsert_blueprint_assets(blueprint, blueprints_data, settings):
|
||||||
|
all_assets_raw = get_blueprint_asset_tree(blueprint=blueprint, blueprints_data=blueprints_data, settings=settings)
|
||||||
|
|
||||||
|
all_assets = []
|
||||||
|
auto_assets = []
|
||||||
|
local_assets = [{"name": asset["name"], "path": asset["path"]} for asset in all_assets_raw if asset['parent'] is None and asset["path"] != "" ]
|
||||||
|
print("all_assets_raw", all_assets_raw)
|
||||||
|
print("local assets", local_assets)
|
||||||
|
blueprint.collection["BlueprintAssets"] = assets_to_fake_ron(local_assets)
|
|
@ -121,6 +121,30 @@ def get_main_scene_assets_tree(main_scene, blueprints_data, settings):
|
||||||
added_asset.path = asset["path"]
|
added_asset.path = asset["path"]
|
||||||
return assets_list
|
return assets_list
|
||||||
|
|
||||||
|
# same as the above, withouth the clutter below : TODO: unify
|
||||||
|
def get_main_scene_assets_tree2(main_scene, blueprints_data, settings):
|
||||||
|
blueprints_path = getattr(settings, "blueprints_path")
|
||||||
|
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
||||||
|
blueprint_instance_names_for_scene = blueprints_data.blueprint_instances_per_main_scene.get(main_scene.name, None)
|
||||||
|
|
||||||
|
assets_list = get_user_assets_as_list(main_scene)
|
||||||
|
if blueprint_instance_names_for_scene:
|
||||||
|
for blueprint_name in blueprint_instance_names_for_scene:
|
||||||
|
blueprint = blueprints_data.blueprints_per_name.get(blueprint_name, None)
|
||||||
|
if blueprint is not None:
|
||||||
|
blueprint_exported_path = None
|
||||||
|
if blueprint.local:
|
||||||
|
blueprint_exported_path = os.path.join(blueprints_path, f"{blueprint.name}{export_gltf_extension}")
|
||||||
|
else:
|
||||||
|
# get the injected path of the external blueprints
|
||||||
|
blueprint_exported_path = blueprint.collection['export_path'] if 'export_path' in blueprint.collection else None
|
||||||
|
if blueprint_exported_path is not None and not does_asset_exist(assets_list, blueprint_exported_path):
|
||||||
|
assets_list.append({"name": blueprint.name, "path": blueprint_exported_path, "type": "MODEL", "generated": True, "internal":blueprint.local, "parent": None})
|
||||||
|
|
||||||
|
assets_list += get_blueprint_assets_tree(blueprint, blueprints_data, parent=blueprint.name, settings=settings)
|
||||||
|
|
||||||
|
return assets_list
|
||||||
|
|
||||||
def get_blueprint_asset_tree(blueprint, blueprints_data, settings):
|
def get_blueprint_asset_tree(blueprint, blueprints_data, settings):
|
||||||
blueprints_path = getattr(settings, "blueprints_path")
|
blueprints_path = getattr(settings, "blueprints_path")
|
||||||
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
||||||
|
|
Loading…
Reference in New Issue