feat(Blenvy & crates):

* added injection of assets lists to blueprints at export time
 * assets & co related tweaks & experiments
 * tweaks on the bevy side
 * all wip !
This commit is contained in:
kaosat.dev 2024-06-09 10:54:10 +02:00
parent 37f4514b31
commit 2a74dedcb8
9 changed files with 69 additions and 3 deletions

View File

@ -157,6 +157,7 @@ impl Plugin for BlueprintsPlugin {
.add_systems( .add_systems(
Update, Update,
( (
test_thingy,
( (
prepare_blueprints, prepare_blueprints,
check_for_loaded, check_for_loaded,

View File

@ -51,6 +51,35 @@ pub struct AddToGameWorld;
/// helper component, just to transfer child data /// helper component, just to transfer child data
pub(crate) struct OriginalChildren(pub Vec<Entity>); pub(crate) struct OriginalChildren(pub Vec<Entity>);
pub(crate) fn test_thingy(
spawn_placeholders: Query<
(
Entity,
&BlueprintPath,
),
(Added<BlueprintPath>, Without<Spawned>, Without<SpawnHere>),
>,
mut commands: Commands,
asset_server: Res<AssetServer>,
) {
for (entity, blueprint_path) in spawn_placeholders.iter() {
println!("added blueprint_path {:?}", blueprint_path);
commands.entity(entity).insert(
SceneBundle {
scene: asset_server.load(format!("{}#Scene0", &blueprint_path.0)), // "levels/World.glb#Scene0"),
..default()
},
);
// let model_handle: Handle<Gltf> = asset_server.load(model_path.clone());
}
}
/// spawning prepare function, /// spawning prepare function,
/// * also takes into account the already exisiting "override" components, ie "override components" > components from blueprint /// * also takes into account the already exisiting "override" components, ie "override components" > components from blueprint
pub(crate) fn prepare_blueprints( pub(crate) fn prepare_blueprints(

View File

@ -115,5 +115,7 @@ 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
- [ ] fix level asets UI
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

View File

@ -4,6 +4,12 @@ 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
def assets_to_fake_ron(list_like):
result = []
for item in list_like:
result.append(f"(name: \"{item['name']}\", path: \"{item['path']}\")")
return result#.join(", ")
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)
@ -15,7 +21,7 @@ def export_blueprints(blueprints, settings, blueprints_data):
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) 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}
# 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
@ -23,10 +29,23 @@ def export_blueprints(blueprints, settings, blueprints_data):
gltf_export_settings['export_materials'] = 'PLACEHOLDER' gltf_export_settings['export_materials'] = 'PLACEHOLDER'
collection = bpy.data.collections[blueprint.name] collection = bpy.data.collections[blueprint.name]
print("BLUEPRINT", blueprint.name)
for asset in collection.user_assets:
print(" user asset", asset.name, asset.path)
all_assets = []
auto_assets = []
collection["local_assets"] = assets_to_fake_ron([{"name": asset.name, "path": asset.path} for asset in collection.user_assets] + auto_assets)
collection["AllAssets"] = assets_to_fake_ron([{"name": asset.name, "path": asset.path} for asset in collection.user_assets]) #all_assets + [{"name": asset.name, "path": asset.path} for asset in collection.user_assets] + auto_assets)
# do the actual export # do the actual export
generate_temporary_scene_and_export( generate_temporary_scene_and_export(
settings, settings,
temp_scene_name=TEMPSCENE_PREFIX+collection.name, temp_scene_name=TEMPSCENE_PREFIX+collection.name,
additional_data = collection,
gltf_export_settings=gltf_export_settings, gltf_export_settings=gltf_export_settings,
gltf_output_path=gltf_output_path, gltf_output_path=gltf_output_path,
tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(collection, temp_collection, blueprints_data=blueprints_data, settings=settings), tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(collection, temp_collection, blueprints_data=blueprints_data, settings=settings),

View File

@ -96,6 +96,8 @@ def duplicate_object(object, parent, combine_mode, destination_collection, bluep
original_collection = object.instance_collection original_collection = object.instance_collection
original_name = object.name original_name = object.name
blueprint_name = original_collection.name blueprint_name = original_collection.name
# FIXME: blueprint path is WRONG !
print("BLUEPRINT PATH", original_collection.get('export_path', None))
blueprint_path = original_collection['export_path'] if 'export_path' in original_collection else f'./{blueprint_name}' # TODO: the default requires the currently used extension !! blueprint_path = original_collection['export_path'] if 'export_path' in original_collection else f'./{blueprint_name}' # TODO: the default requires the currently used extension !!

View File

@ -27,12 +27,16 @@ def generate_temporary_scene_and_export(settings, gltf_export_settings, gltf_out
temp_scene["local_assets"] = additional_data[entry] # this is for bevy 0.14 temp_scene["local_assets"] = additional_data[entry] # this is for bevy 0.14
temp_root_collection["local_assets"] = additional_data[entry] # for previous bevy versions, remove when migration done temp_root_collection["local_assets"] = additional_data[entry] # for previous bevy versions, remove when migration done
bla = "[(name: \"test_asset\", path: \"audio/fake.mp3\")]" bla = "[(name: \"test_asset\", path: \"audio/fake.mp3\")]"
add_scene_property(temp_scene, 'assets_components', {"LocalAssets": f"LocalAssets({additional_data[entry]})".replace("'", '')}) local_assets = additional_data.get(entry, [])
local_assets = [entry for entry in local_assets]
add_scene_property(temp_scene, 'assets_components', {"LocalAssets": f"LocalAssets({local_assets})".replace("'", '')})
if entry == entry == "AllAssets": if entry == entry == "AllAssets":
temp_scene["AllAssets"] = additional_data[entry] temp_scene["AllAssets"] = additional_data[entry]
temp_root_collection["AllAssets"] = additional_data[entry] # for previous bevy versions, remove when migration done temp_root_collection["AllAssets"] = additional_data[entry] # for previous bevy versions, remove when migration done
add_scene_property(temp_scene, 'assets_components', {"AllAssets": f"AllAssets({additional_data[entry]})".replace("'", '')}) all_assets = additional_data.get(entry, [])
all_assets = [entry for entry in all_assets]
add_scene_property(temp_scene, 'assets_components', {"AllAssets": f"AllAssets({all_assets})".replace("'", '')})
# save active scene # save active scene
original_scene = bpy.context.window.scene original_scene = bpy.context.window.scene

View File

@ -72,6 +72,7 @@ def export_main_scene(scene, settings, blueprints_data):
scene["local_assets"] = assets_to_fake_ron([{"name": asset.name, "path": asset.path} for asset in scene.user_assets] + auto_assets) scene["local_assets"] = assets_to_fake_ron([{"name": asset.name, "path": asset.path} for asset in scene.user_assets] + auto_assets)
scene["AllAssets"] = assets_to_fake_ron(all_assets + [{"name": asset.name, "path": asset.path} for asset in scene.user_assets] + auto_assets) scene["AllAssets"] = assets_to_fake_ron(all_assets + [{"name": asset.name, "path": asset.path} for asset in scene.user_assets] + auto_assets)
if export_separate_dynamic_and_static_objects: if export_separate_dynamic_and_static_objects:
#print("SPLIT STATIC AND DYNAMIC") #print("SPLIT STATIC AND DYNAMIC")
# first export static objects # first export static objects

View File

@ -23,6 +23,8 @@ def check_if_blueprint_on_disk(scene_name, folder_path, extension):
def inject_export_path_into_internal_blueprints(internal_blueprints, blueprints_path, gltf_extension): def inject_export_path_into_internal_blueprints(internal_blueprints, blueprints_path, gltf_extension):
for blueprint in internal_blueprints: for blueprint in internal_blueprints:
blueprint_exported_path = os.path.join(blueprints_path, f"{blueprint.name}{gltf_extension}") blueprint_exported_path = os.path.join(blueprints_path, f"{blueprint.name}{gltf_extension}")
print("injecting blueprint path", blueprint_exported_path, "for", blueprint.name)
blueprint.collection["export_path"] = blueprint_exported_path blueprint.collection["export_path"] = blueprint_exported_path
def inject_blueprints_list_into_main_scene(scene, blueprints_data, settings): def inject_blueprints_list_into_main_scene(scene, blueprints_data, settings):

View File

@ -120,6 +120,12 @@ def test_export_complex(setup_data):
user_asset.name = "yoho_audio" user_asset.name = "yoho_audio"
user_asset.path = "audio/fake.mp3" user_asset.path = "audio/fake.mp3"
# we have to cheat, since we cannot rely on the data injected when saving the library file
bpy.data.collections["External_blueprint"]["export_path"] = "blueprints/External_blueprint.glb"
bpy.data.collections["External_blueprint2"]["export_path"] = "blueprints/External_blueprint2.glb"
bpy.data.collections["External_blueprint3"]["export_path"] = "blueprints/External_blueprint3.glb"
prepare_and_export() prepare_and_export()
# blueprint1 => has an instance, got changed, should export # blueprint1 => has an instance, got changed, should export