Compare commits
5 Commits
540d471111
...
58ac8d206e
Author | SHA1 | Date |
---|---|---|
Mark Moissette | 58ac8d206e | |
kaosat.dev | ab7a0cab65 | |
kaosat.dev | 55a4deac1c | |
kaosat.dev | ce17f723b1 | |
kaosat.dev | 4865d432d9 |
11
TODO.md
11
TODO.md
|
@ -226,10 +226,13 @@ Blender side:
|
||||||
- [ ] materials_path custom property should be ignored both in the list of fixable component AND on export
|
- [ ] materials_path custom property should be ignored both in the list of fixable component AND on export
|
||||||
- [ ] if we want to add material_infos & others as normal components they should not be editable, so we need another attribute, and adapt the UI for that
|
- [ ] if we want to add material_infos & others as normal components they should not be editable, so we need another attribute, and adapt the UI for that
|
||||||
|
|
||||||
- [ ] if material library is toggled, then changes to materials should not change the blueprints that are using them => not really: as the name & co might change
|
- [x] if material library is toggled, then changes to materials should not change the blueprints that are using them => not really: as the name & co might change
|
||||||
- [ ] material assets seem to be added to list regardless of whether material exports are enabled or not
|
- [ ] material assets seem to be added to list regardless of whether material exports are enabled or not
|
||||||
- [ ] review & upgrade overall logic of material libraries, their names & output path
|
- [x] review & upgrade overall logic of material libraries, their names & output path
|
||||||
- [ ] persist exported materials path in blueprints so that it can be read from library file users
|
- [x] change materials logic to work with multiple materials per mesh
|
||||||
|
- [x] the index of the generated gltf files is reliable, and can be used both in Blender & Bevy
|
||||||
|
- [x] change MaterialInfo to MaterialInfos & turn it into a vec/list & updated logic both on Blender & Bevy side
|
||||||
|
- [ ] persist exported materials paths in blueprints so that it can be read from library file users
|
||||||
- [ ] just like "export_path" write it into each blueprint's collection
|
- [ ] just like "export_path" write it into each blueprint's collection
|
||||||
- [ ] scan for used materials per blueprint !
|
- [ ] scan for used materials per blueprint !
|
||||||
- [ ] for scenes, scan for used materials of all non instance objects (TODO: what about overrides ?)
|
- [ ] for scenes, scan for used materials of all non instance objects (TODO: what about overrides ?)
|
||||||
|
@ -323,7 +326,7 @@ Bevy Side:
|
||||||
- [x] fix "remove component" operator from the rename/fix/update components panel
|
- [x] fix "remove component" operator from the rename/fix/update components panel
|
||||||
- [ ] replace string in BlueprintInfo path with PathBuf ?
|
- [ ] replace string in BlueprintInfo path with PathBuf ?
|
||||||
|
|
||||||
- [ ] update main docs
|
- [x] update main docs
|
||||||
- [x] rename project to Blenvy
|
- [x] rename project to Blenvy
|
||||||
- [x] replace all references to the old 2 add-ons with those to Blenvy
|
- [x] replace all references to the old 2 add-ons with those to Blenvy
|
||||||
- [x] rename repo to "Blenvy"
|
- [x] rename repo to "Blenvy"
|
||||||
|
|
|
@ -2,22 +2,26 @@ use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::BlenvyConfig;
|
use crate::BlenvyConfig;
|
||||||
|
|
||||||
#[derive(Component, Reflect, Default, Debug)]
|
#[derive(Reflect, Default, Debug)]
|
||||||
#[reflect(Component)]
|
|
||||||
/// struct containing the name & path of the material to apply
|
/// struct containing the name & path of the material to apply
|
||||||
pub struct MaterialInfo {
|
pub struct MaterialInfo {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
/// component containing the full list of MaterialInfos for a given entity/object
|
||||||
|
pub struct MaterialInfos(Vec<MaterialInfo>);
|
||||||
|
|
||||||
#[derive(Component, Default, Debug)]
|
#[derive(Component, Default, Debug)]
|
||||||
pub struct MaterialProcessed;
|
pub struct MaterialProcessed;
|
||||||
|
|
||||||
/// system that injects / replaces materials from material library
|
/// system that injects / replaces materials from material library
|
||||||
pub(crate) fn inject_materials(
|
pub(crate) fn inject_materials(
|
||||||
mut blenvy_config: ResMut<BlenvyConfig>,
|
mut blenvy_config: ResMut<BlenvyConfig>,
|
||||||
material_infos: Query<
|
material_infos_query: Query<
|
||||||
(Entity, &MaterialInfo, &Children),
|
(Entity, &MaterialInfos, &Children),
|
||||||
Without<MaterialProcessed>, // (With<BlueprintReadyForPostProcess>)
|
Without<MaterialProcessed>, // (With<BlueprintReadyForPostProcess>)
|
||||||
/*(
|
/*(
|
||||||
Added<BlueprintMaterialAssetsLoaded>,
|
Added<BlueprintMaterialAssetsLoaded>,
|
||||||
|
@ -37,57 +41,64 @@ pub(crate) fn inject_materials(
|
||||||
|
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) {
|
) {
|
||||||
for (entity, material_info, children) in material_infos.iter() {
|
for (entity, material_infos, children) in material_infos_query.iter() {
|
||||||
let material_full_path = format!("{}#{}", material_info.path, material_info.name);
|
for (material_index, material_info) in material_infos.0.iter().enumerate() {
|
||||||
let mut material_found: Option<&Handle<StandardMaterial>> = None;
|
let material_full_path = format!("{}#{}", material_info.path, material_info.name);
|
||||||
|
let mut material_found: Option<&Handle<StandardMaterial>> = None;
|
||||||
if blenvy_config
|
if blenvy_config
|
||||||
.materials_cache
|
|
||||||
.contains_key(&material_full_path)
|
|
||||||
{
|
|
||||||
debug!("material is cached, retrieving");
|
|
||||||
let material = blenvy_config
|
|
||||||
.materials_cache
|
.materials_cache
|
||||||
.get(&material_full_path)
|
.contains_key(&material_full_path)
|
||||||
.expect("we should have the material available");
|
|
||||||
material_found = Some(material);
|
|
||||||
} else {
|
|
||||||
let model_handle: Handle<Gltf> = asset_server.load(material_info.path.clone()); // FIXME: kinda weird now
|
|
||||||
let mat_gltf = assets_gltf.get(model_handle.id()).unwrap_or_else(|| {
|
|
||||||
panic!(
|
|
||||||
"materials file {} should have been preloaded",
|
|
||||||
material_info.path
|
|
||||||
)
|
|
||||||
});
|
|
||||||
if mat_gltf
|
|
||||||
.named_materials
|
|
||||||
.contains_key(&material_info.name as &str)
|
|
||||||
{
|
{
|
||||||
let material = mat_gltf
|
debug!("material is cached, retrieving");
|
||||||
.named_materials
|
let material = blenvy_config
|
||||||
.get(&material_info.name as &str)
|
|
||||||
.expect("this material should have been loaded at this stage, please make sure you are correctly preloading them");
|
|
||||||
blenvy_config
|
|
||||||
.materials_cache
|
.materials_cache
|
||||||
.insert(material_full_path, material.clone());
|
.get(&material_full_path)
|
||||||
|
.expect("we should have the material available");
|
||||||
material_found = Some(material);
|
material_found = Some(material);
|
||||||
|
} else {
|
||||||
|
let model_handle: Handle<Gltf> = asset_server.load(material_info.path.clone()); // FIXME: kinda weird now
|
||||||
|
let mat_gltf = assets_gltf.get(model_handle.id()).unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"materials file {} should have been preloaded",
|
||||||
|
material_info.path
|
||||||
|
)
|
||||||
|
});
|
||||||
|
if mat_gltf
|
||||||
|
.named_materials
|
||||||
|
.contains_key(&material_info.name as &str)
|
||||||
|
{
|
||||||
|
let material = mat_gltf
|
||||||
|
.named_materials
|
||||||
|
.get(&material_info.name as &str)
|
||||||
|
.expect("this material should have been loaded at this stage, please make sure you are correctly preloading them");
|
||||||
|
blenvy_config
|
||||||
|
.materials_cache
|
||||||
|
.insert(material_full_path, material.clone());
|
||||||
|
material_found = Some(material);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
commands.entity(entity).insert(MaterialProcessed);
|
if let Some(material) = material_found {
|
||||||
|
for (child_index, child) in children.iter().enumerate() {
|
||||||
|
if child_index == material_index {
|
||||||
|
if with_materials_and_meshes.contains(*child) {
|
||||||
|
info!(
|
||||||
|
"injecting material {}, path: {:?}",
|
||||||
|
material_info.name,
|
||||||
|
material_info.path.clone()
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(material) = material_found {
|
commands.entity(*child).insert(material.clone());
|
||||||
for child in children.iter() {
|
}
|
||||||
if with_materials_and_meshes.contains(*child) {
|
}
|
||||||
info!(
|
|
||||||
"injecting material {}, path: {:?}",
|
|
||||||
material_info.name,
|
|
||||||
material_info.path.clone()
|
|
||||||
);
|
|
||||||
|
|
||||||
commands.entity(*child).insert(material.clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
commands.entity(entity).insert(MaterialProcessed);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,8 @@ impl Plugin for BlueprintsPlugin {
|
||||||
.add_event::<BlueprintEvent>()
|
.add_event::<BlueprintEvent>()
|
||||||
.register_type::<BlueprintInfo>()
|
.register_type::<BlueprintInfo>()
|
||||||
.register_type::<MaterialInfo>()
|
.register_type::<MaterialInfo>()
|
||||||
|
.register_type::<MaterialInfos>()
|
||||||
|
|
||||||
.register_type::<SpawnBlueprint>()
|
.register_type::<SpawnBlueprint>()
|
||||||
.register_type::<BlueprintInstanceDisabled>()
|
.register_type::<BlueprintInstanceDisabled>()
|
||||||
.register_type::<HideUntilReady>()
|
.register_type::<HideUntilReady>()
|
||||||
|
|
|
@ -69,14 +69,21 @@ fn components_string_to_components(
|
||||||
let mut deserializer = ron::Deserializer::from_str(ron_string.as_str())
|
let mut deserializer = ron::Deserializer::from_str(ron_string.as_str())
|
||||||
.expect("deserialzer should have been generated from string");
|
.expect("deserialzer should have been generated from string");
|
||||||
let reflect_deserializer = ReflectDeserializer::new(type_registry);
|
let reflect_deserializer = ReflectDeserializer::new(type_registry);
|
||||||
let component = reflect_deserializer
|
/*let component = reflect_deserializer
|
||||||
.deserialize(&mut deserializer)
|
.deserialize(&mut deserializer)
|
||||||
.unwrap_or_else(|_| {
|
.unwrap_or_else(|_| {
|
||||||
panic!(
|
panic!(
|
||||||
"failed to deserialize component {} with value: {:?}",
|
"failed to deserialize component {} with value: {:?}",
|
||||||
name, value
|
name, value
|
||||||
)
|
)
|
||||||
});
|
});*/
|
||||||
|
let Ok(component) = reflect_deserializer.deserialize(&mut deserializer) else {
|
||||||
|
warn!(
|
||||||
|
"failed to deserialize component {} with value: {:?}",
|
||||||
|
name, value
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
debug!("component {:?}", component);
|
debug!("component {:?}", component);
|
||||||
debug!("real type {:?}", component.get_represented_type_info());
|
debug!("real type {:?}", component.get_represented_type_info());
|
||||||
|
|
|
@ -102,7 +102,7 @@ def auto_export(changes_per_scene, changes_per_collection, changes_per_material,
|
||||||
old_selections = bpy.context.selected_objects
|
old_selections = bpy.context.selected_objects
|
||||||
|
|
||||||
# deal with materials
|
# deal with materials
|
||||||
if export_materials_library:
|
if export_materials_library and len(materials_to_export) > 0:
|
||||||
print("export MATERIALS")
|
print("export MATERIALS")
|
||||||
export_materials(materials_to_export, settings, blueprints_data)
|
export_materials(materials_to_export, settings, blueprints_data)
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ def generate_gltf_export_settings(settings):
|
||||||
if str(key) not in constant_keys:
|
if str(key) not in constant_keys:
|
||||||
gltf_export_settings[key] = standard_gltf_exporter_settings.get(key)
|
gltf_export_settings[key] = standard_gltf_exporter_settings.get(key)
|
||||||
|
|
||||||
print("GLTF EXPORT SETTINGS", gltf_export_settings)
|
#print("GLTF EXPORT SETTINGS", gltf_export_settings)
|
||||||
return gltf_export_settings
|
return gltf_export_settings
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -81,11 +81,14 @@ def generate_temporary_scene_and_export(settings, gltf_export_settings, gltf_out
|
||||||
# copies the contents of a collection into another one while replacing library instances with empties
|
# copies the contents of a collection into another one while replacing library instances with empties
|
||||||
def copy_hollowed_collection_into(source_collection, destination_collection, parent_empty=None, filter=None, blueprints_data=None, settings={}):
|
def copy_hollowed_collection_into(source_collection, destination_collection, parent_empty=None, filter=None, blueprints_data=None, settings={}):
|
||||||
collection_instances_combine_mode = getattr(settings.auto_export, "collection_instances_combine_mode")
|
collection_instances_combine_mode = getattr(settings.auto_export, "collection_instances_combine_mode")
|
||||||
|
|
||||||
for object in source_collection.objects:
|
for object in source_collection.objects:
|
||||||
if object.name.endswith("____bak"): # some objects could already have been handled, ignore them
|
if object.name.endswith("____bak"): # some objects could already have been handled, ignore them
|
||||||
continue
|
continue
|
||||||
if filter is not None and filter(object) is False:
|
if filter is not None and filter(object) is False:
|
||||||
continue
|
continue
|
||||||
|
if object.parent is not None: # if there is a parent, this object is not a direct child of the collection, and should be ignored (it will get picked up by the recursive scan inside duplicate_object)
|
||||||
|
continue
|
||||||
#check if a specific collection instance does not have an ovveride for combine_mode
|
#check if a specific collection instance does not have an ovveride for combine_mode
|
||||||
combine_mode = object['_combine'] if '_combine' in object else collection_instances_combine_mode
|
combine_mode = object['_combine'] if '_combine' in object else collection_instances_combine_mode
|
||||||
parent = parent_empty
|
parent = parent_empty
|
||||||
|
|
|
@ -8,4 +8,4 @@ custom_properties_to_filter_out = [
|
||||||
'_combine', 'template',
|
'_combine', 'template',
|
||||||
'Blenvy_scene_type', 'blenvy_scene_type',
|
'Blenvy_scene_type', 'blenvy_scene_type',
|
||||||
'materials_path', 'export_path',
|
'materials_path', 'export_path',
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import os
|
import os
|
||||||
from blenvy.blueprints.blueprint_helpers import inject_blueprints_list_into_level_scene, remove_blueprints_list_from_level_scene
|
|
||||||
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, export_gltf)
|
from ..common.export_gltf import (generate_gltf_export_settings, export_gltf)
|
||||||
|
@ -26,8 +25,8 @@ def export_level_scene(scene, settings, blueprints_data):
|
||||||
|
|
||||||
if export_blueprints :
|
if export_blueprints :
|
||||||
gltf_output_path = os.path.join(levels_path_full, scene.name)
|
gltf_output_path = os.path.join(levels_path_full, scene.name)
|
||||||
|
# we inject assets into the scene before it gets exported
|
||||||
inject_blueprints_list_into_level_scene(scene, blueprints_data, settings)
|
# TODO: this should be done in the temporary scene !
|
||||||
upsert_scene_assets(scene, blueprints_data=blueprints_data, settings=settings)
|
upsert_scene_assets(scene, blueprints_data=blueprints_data, settings=settings)
|
||||||
|
|
||||||
if export_separate_dynamic_and_static_objects:
|
if export_separate_dynamic_and_static_objects:
|
||||||
|
@ -67,8 +66,6 @@ def export_level_scene(scene, settings, blueprints_data):
|
||||||
tempScene_cleaner= lambda temp_scene, params: clear_hollow_scene(original_root_collection=scene.collection, temp_scene=temp_scene, **params)
|
tempScene_cleaner= lambda temp_scene, params: clear_hollow_scene(original_root_collection=scene.collection, temp_scene=temp_scene, **params)
|
||||||
)
|
)
|
||||||
|
|
||||||
remove_blueprints_list_from_level_scene(scene)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
gltf_output_path = os.path.join(assets_path_full, scene.name)
|
gltf_output_path = os.path.join(assets_path_full, scene.name)
|
||||||
print(" exporting gltf to", gltf_output_path, ".gltf/glb")
|
print(" exporting gltf to", gltf_output_path, ".gltf/glb")
|
||||||
|
|
|
@ -46,6 +46,13 @@ def generate_materials_scene_content(root_collection, used_material_names):
|
||||||
make_material_object("Material_"+material_name, [index * 0.2,0,0], material=material, collection=root_collection)
|
make_material_object("Material_"+material_name, [index * 0.2,0,0], material=material, collection=root_collection)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
# generates a scene for a given material
|
||||||
|
def generate_material_scene_content(root_collection, material_name):
|
||||||
|
material = bpy.data.materials[material_name]
|
||||||
|
make_material_object(f"Material_{material_name}", [0,0,0], material=material, collection=root_collection)
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def clear_materials_scene(temp_scene):
|
def clear_materials_scene(temp_scene):
|
||||||
root_collection = temp_scene.collection
|
root_collection = temp_scene.collection
|
||||||
scene_objects = [o for o in root_collection.objects]
|
scene_objects = [o for o in root_collection.objects]
|
||||||
|
@ -83,21 +90,18 @@ def export_materials(materials_to_export, settings, blueprints_data):
|
||||||
'export_apply':True
|
'export_apply':True
|
||||||
}
|
}
|
||||||
|
|
||||||
current_project_name = Path(bpy.context.blend_data.filepath).stem
|
for material in materials_to_export:
|
||||||
gltf_output_path = os.path.join(materials_path_full, current_project_name + "_materials")
|
print("exporting material", material.name)
|
||||||
|
gltf_output_path = os.path.join(materials_path_full, material.name)
|
||||||
print(" exporting Materials to", gltf_output_path, ".gltf/glb")
|
|
||||||
|
|
||||||
generate_temporary_scene_and_export(
|
|
||||||
settings=settings,
|
|
||||||
gltf_export_settings=gltf_export_settings,
|
|
||||||
temp_scene_name="__materials_scene",
|
|
||||||
gltf_output_path=gltf_output_path,
|
|
||||||
tempScene_filler= lambda temp_collection: generate_materials_scene_content(temp_collection, used_material_names),
|
|
||||||
tempScene_cleaner= lambda temp_scene, params: clear_materials_scene(temp_scene=temp_scene)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
generate_temporary_scene_and_export(
|
||||||
|
settings=settings,
|
||||||
|
gltf_export_settings=gltf_export_settings,
|
||||||
|
temp_scene_name="__materials_scene",
|
||||||
|
gltf_output_path=gltf_output_path,
|
||||||
|
tempScene_filler= lambda temp_collection: generate_material_scene_content(temp_collection, material.name),
|
||||||
|
tempScene_cleaner= lambda temp_scene, params: clear_materials_scene(temp_scene=temp_scene)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def cleanup_materials(collections, library_scenes):
|
def cleanup_materials(collections, library_scenes):
|
||||||
|
|
|
@ -8,21 +8,26 @@ def get_materials_to_export(changes_per_material, changed_export_parameters, blu
|
||||||
materials_path_full = getattr(settings,"materials_path_full", "")
|
materials_path_full = getattr(settings,"materials_path_full", "")
|
||||||
|
|
||||||
change_detection = getattr(settings.auto_export, "change_detection")
|
change_detection = getattr(settings.auto_export, "change_detection")
|
||||||
|
export_materials_library = getattr(settings.auto_export, "export_materials_library")
|
||||||
collection_instances_combine_mode = getattr(settings.auto_export, "collection_instances_combine_mode")
|
collection_instances_combine_mode = getattr(settings.auto_export, "collection_instances_combine_mode")
|
||||||
|
|
||||||
all_materials = bpy.data.materials
|
all_materials = bpy.data.materials
|
||||||
local_materials = [material for material in all_materials if material.library is None]
|
local_materials = [material for material in all_materials if material.library is None]
|
||||||
materials_to_export = []
|
materials_to_export = []
|
||||||
if change_detection and not changed_export_parameters:
|
|
||||||
changed_materials = [bpy.data.materials[material_name] for material_name in list(changes_per_material.keys())]
|
|
||||||
|
|
||||||
# first check if all materials have already been exported before (if this is the first time the exporter is run
|
if export_materials_library and change_detection:
|
||||||
# in your current Blender session for example)
|
if changed_export_parameters:
|
||||||
materials_not_on_disk = find_materials_not_on_disk(local_materials, materials_path_full, export_gltf_extension)
|
materials_to_export = [bpy.data.materials[material_name] for material_name in list(changes_per_material.keys())] # TODO: should be based on the list of materials in use
|
||||||
|
else :
|
||||||
|
changed_materials = [bpy.data.materials[material_name] for material_name in list(changes_per_material.keys())]
|
||||||
|
|
||||||
# also deal with blueprints that are always marked as "always_export"
|
# first check if all materials have already been exported before (if this is the first time the exporter is run
|
||||||
#materials_always_export = [material for material in internal_materials if is_material_always_export(material)]
|
# in your current Blender session for example)
|
||||||
materials_always_export = []
|
materials_not_on_disk = find_materials_not_on_disk(local_materials, materials_path_full, export_gltf_extension)
|
||||||
materials_to_export = list(set(changed_materials + materials_not_on_disk + materials_always_export))
|
|
||||||
|
|
||||||
|
# also deal with blueprints that are always marked as "always_export"
|
||||||
|
#materials_always_export = [material for material in internal_materials if is_material_always_export(material)]
|
||||||
|
materials_always_export = []
|
||||||
|
materials_to_export = list(set(changed_materials + materials_not_on_disk + materials_always_export))
|
||||||
|
print("materials_to_export", materials_to_export, local_materials)
|
||||||
return materials_to_export
|
return materials_to_export
|
||||||
|
|
|
@ -24,63 +24,14 @@ def assets_to_fake_ron(list_like):
|
||||||
|
|
||||||
# TODO : move to assets
|
# TODO : move to assets
|
||||||
def upsert_scene_assets(scene, blueprints_data, settings):
|
def upsert_scene_assets(scene, blueprints_data, settings):
|
||||||
"""print("level 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_level_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 = []
|
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 = posixpath.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 = posixpath.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_level_scene_assets_tree2(level_scene=scene, blueprints_data=blueprints_data, settings=settings)
|
all_assets_raw = get_level_scene_assets_tree2(level_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"] != "" ]
|
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"] != "" ]
|
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_raw", all_assets_raw)
|
||||||
print("all_assets", all_assets)
|
print("all_assets", all_assets)
|
||||||
print("local assets", local_assets + material_assets)
|
print("local assets", local_assets)
|
||||||
scene["BlueprintAssets"] = assets_to_fake_ron(local_assets + material_assets)
|
scene["BlueprintAssets"] = assets_to_fake_ron(all_assets) #local_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):
|
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_raw = get_blueprint_asset_tree(blueprint=blueprint, blueprints_data=blueprints_data, settings=settings)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import json
|
||||||
import posixpath
|
import posixpath
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
|
from ..materials.materials_helpers import get_blueprint_materials
|
||||||
from .asset_helpers import does_asset_exist, get_user_assets, get_user_assets_as_list
|
from .asset_helpers import does_asset_exist, get_user_assets, get_user_assets_as_list
|
||||||
|
|
||||||
def scan_assets(scene, blueprints_data, settings):
|
def scan_assets(scene, blueprints_data, settings):
|
||||||
|
@ -62,6 +63,7 @@ def get_userTextures():
|
||||||
print("textures", textures)
|
print("textures", textures)
|
||||||
|
|
||||||
def get_blueprint_assets_tree(blueprint, blueprints_data, parent, settings):
|
def get_blueprint_assets_tree(blueprint, blueprints_data, parent, settings):
|
||||||
|
print("blueprint", blueprint.name)
|
||||||
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")
|
||||||
assets_list = []
|
assets_list = []
|
||||||
|
@ -88,6 +90,15 @@ def get_blueprint_assets_tree(blueprint, blueprints_data, parent, settings):
|
||||||
asset["parent"] = parent
|
asset["parent"] = parent
|
||||||
asset["internal"] = blueprint.local
|
asset["internal"] = blueprint.local
|
||||||
assets_list += direct_assets
|
assets_list += direct_assets
|
||||||
|
|
||||||
|
# now get materials used by this blueprint
|
||||||
|
(blueprint_materials_names, materials_per_object) = get_blueprint_materials(blueprint=blueprint)
|
||||||
|
print("blueprint_materials", blueprint_materials_names)
|
||||||
|
for material_name in blueprint_materials_names:
|
||||||
|
materials_path = getattr(settings, "materials_path")
|
||||||
|
materials_exported_path = posixpath.join(materials_path, f"{material_name}{export_gltf_extension}")
|
||||||
|
assets_list.append({"name": material_name, "path": materials_exported_path, "type": "MATERIAL", "generated": True,"internal":blueprint.local, "parent": blueprint.name})
|
||||||
|
|
||||||
return assets_list
|
return assets_list
|
||||||
|
|
||||||
def get_level_scene_assets_tree(level_scene, blueprints_data, settings):
|
def get_level_scene_assets_tree(level_scene, blueprints_data, settings):
|
||||||
|
|
|
@ -70,11 +70,6 @@ class BLENVY_OT_assets_add(Operator):
|
||||||
context.window_manager.assets_registry.asset_type_selector = "MODEL"
|
context.window_manager.assets_registry.asset_type_selector = "MODEL"
|
||||||
context.window_manager.assets_registry.asset_path_selector = ""
|
context.window_manager.assets_registry.asset_path_selector = ""
|
||||||
|
|
||||||
"""if blueprint_assets:
|
|
||||||
bpy.data.collections[self.target_name]["assets"] = json.dumps(assets)
|
|
||||||
else:
|
|
||||||
bpy.data.scenes[self.target_name]["assets"] = json.dumps(assets)"""
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@ import bpy
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import posixpath
|
import posixpath
|
||||||
|
|
||||||
from ..core.scene_helpers import add_scene_property
|
|
||||||
|
|
||||||
def find_blueprints_not_on_disk(blueprints, folder_path, extension):
|
def find_blueprints_not_on_disk(blueprints, folder_path, extension):
|
||||||
not_found_blueprints = []
|
not_found_blueprints = []
|
||||||
for blueprint in blueprints:
|
for blueprint in blueprints:
|
||||||
|
@ -23,64 +21,9 @@ def check_if_blueprint_on_disk(scene_name, folder_path, extension):
|
||||||
return found
|
return found
|
||||||
|
|
||||||
def inject_export_path_into_internal_blueprints(internal_blueprints, blueprints_path, gltf_extension, settings):
|
def inject_export_path_into_internal_blueprints(internal_blueprints, blueprints_path, gltf_extension, settings):
|
||||||
export_materials_library = getattr(settings.auto_export, "export_materials_library")
|
|
||||||
# FIXME: duplicate of materials stuff
|
|
||||||
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
|
||||||
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 = posixpath.join(materials_path, f"{materials_library_name}{export_gltf_extension}")
|
|
||||||
|
|
||||||
for blueprint in internal_blueprints:
|
for blueprint in internal_blueprints:
|
||||||
blueprint_exported_path = posixpath.join(blueprints_path, f"{blueprint.name}{gltf_extension}")
|
blueprint_exported_path = posixpath.join(blueprints_path, f"{blueprint.name}{gltf_extension}")
|
||||||
# print("injecting blueprint path", blueprint_exported_path, "for", blueprint.name)
|
# print("injecting blueprint path", blueprint_exported_path, "for", blueprint.name)
|
||||||
blueprint.collection["export_path"] = blueprint_exported_path
|
blueprint.collection["export_path"] = blueprint_exported_path
|
||||||
if export_materials_library:
|
"""if export_materials_library:
|
||||||
blueprint.collection["materials_path"] = materials_exported_path
|
blueprint.collection["materials_path"] = materials_exported_path"""
|
||||||
|
|
||||||
|
|
||||||
def inject_blueprints_list_into_level_scene(scene, blueprints_data, settings):
|
|
||||||
project_root_path = getattr(settings, "project_root_path")
|
|
||||||
assets_path = getattr(settings,"assets_path")
|
|
||||||
levels_path = getattr(settings,"levels_path")
|
|
||||||
blueprints_path = getattr(settings, "blueprints_path")
|
|
||||||
export_gltf_extension = getattr(settings, "export_gltf_extension")
|
|
||||||
|
|
||||||
# print("injecting assets/blueprints data into scene")
|
|
||||||
assets_list_name = f"assets_list_{scene.name}_components"
|
|
||||||
assets_list_data = {}
|
|
||||||
|
|
||||||
blueprint_instance_names_for_scene = blueprints_data.blueprint_instances_per_level_scene.get(scene.name, None)
|
|
||||||
blueprint_assets_list = []
|
|
||||||
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:
|
|
||||||
#print("BLUEPRINT", blueprint)
|
|
||||||
blueprint_exported_path = None
|
|
||||||
if blueprint.local:
|
|
||||||
blueprint_exported_path = posixpath.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
|
|
||||||
#print("foo", dict(blueprint.collection))
|
|
||||||
if blueprint_exported_path is not None:
|
|
||||||
blueprint_assets_list.append({"name": blueprint.name, "path": blueprint_exported_path, "type": "MODEL", "internal": True})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assets_list_name = f"assets_{scene.name}"
|
|
||||||
scene["assets"] = json.dumps(blueprint_assets_list)
|
|
||||||
|
|
||||||
#print("blueprint assets", blueprint_assets_list)
|
|
||||||
|
|
||||||
def remove_blueprints_list_from_level_scene(scene):
|
|
||||||
assets_list = None
|
|
||||||
assets_list_name = f"assets_list_{scene.name}_components"
|
|
||||||
|
|
||||||
for object in scene.objects:
|
|
||||||
if object.name == assets_list_name:
|
|
||||||
assets_list = object
|
|
||||||
if assets_list is not None:
|
|
||||||
bpy.data.objects.remove(assets_list, do_unlink=True)
|
|
||||||
|
|
|
@ -1,28 +1,15 @@
|
||||||
import os
|
import os
|
||||||
import posixpath
|
import posixpath
|
||||||
import bpy
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from ..core.helpers_collections import (traverse_tree)
|
from ..core.helpers_collections import (traverse_tree)
|
||||||
|
|
||||||
def find_materials_not_on_disk(materials, materials_path_full, extension):
|
def find_materials_not_on_disk(materials, materials_path_full, extension):
|
||||||
not_found_materials = []
|
not_found_materials = []
|
||||||
|
|
||||||
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_full, f"{materials_library_name}{extension}")
|
|
||||||
|
|
||||||
found = os.path.exists(materials_exported_path) and os.path.isfile(materials_exported_path)
|
|
||||||
for material in materials:
|
for material in materials:
|
||||||
if not found:
|
|
||||||
not_found_materials.append(material)
|
|
||||||
|
|
||||||
"""for material in materials:
|
|
||||||
gltf_output_path = os.path.join(materials_path_full, material.name + extension)
|
gltf_output_path = os.path.join(materials_path_full, material.name + extension)
|
||||||
# print("gltf_output_path", gltf_output_path)
|
# print("gltf_output_path", gltf_output_path)
|
||||||
found = os.path.exists(gltf_output_path) and os.path.isfile(gltf_output_path)
|
found = os.path.exists(gltf_output_path) and os.path.isfile(gltf_output_path)
|
||||||
if not found:
|
if not found:
|
||||||
not_found_materials.append(material)"""
|
not_found_materials.append(material)
|
||||||
return not_found_materials
|
return not_found_materials
|
||||||
|
|
||||||
def check_if_material_on_disk(scene_name, folder_path, extension):
|
def check_if_material_on_disk(scene_name, folder_path, extension):
|
||||||
|
@ -40,7 +27,9 @@ def get_materials(object, materials_per_object):
|
||||||
# print(" slot", m, "material", material)
|
# print(" slot", m, "material", material)
|
||||||
used_materials_names.append(material.name)
|
used_materials_names.append(material.name)
|
||||||
# TODO:, also respect slots & export multiple materials if applicable !
|
# TODO:, also respect slots & export multiple materials if applicable !
|
||||||
materials_per_object[object] = material
|
if not object in materials_per_object:
|
||||||
|
materials_per_object[object] = []
|
||||||
|
materials_per_object[object].append(material)
|
||||||
return used_materials_names
|
return used_materials_names
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,22 +51,17 @@ def get_all_materials(collection_names, library_scenes):
|
||||||
def add_material_info_to_objects(materials_per_object, settings):
|
def add_material_info_to_objects(materials_per_object, settings):
|
||||||
materials_path = getattr(settings, "materials_path")
|
materials_path = getattr(settings, "materials_path")
|
||||||
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
||||||
|
|
||||||
current_project_name = Path(bpy.context.blend_data.filepath).stem
|
|
||||||
materials_library_name = f"{current_project_name}_materials"
|
|
||||||
materials_exported_path = posixpath.join(materials_path, f"{materials_library_name}{export_gltf_extension}")
|
|
||||||
#print("ADDING MAERIAL INFOS")
|
|
||||||
for object in materials_per_object.keys():
|
for object in materials_per_object.keys():
|
||||||
material = materials_per_object[object]
|
material_infos = []
|
||||||
|
for material in materials_per_object[object]:
|
||||||
|
materials_exported_path = posixpath.join(materials_path, f"{material.name}{export_gltf_extension}")
|
||||||
|
material_info = f'(name: "{material.name}", path: "{materials_exported_path}")'
|
||||||
|
material_infos.append(material_info)
|
||||||
# problem with using actual components: you NEED the type registry/component infos, so if there is none , or it is not loaded yet, it does not work
|
# problem with using actual components: you NEED the type registry/component infos, so if there is none , or it is not loaded yet, it does not work
|
||||||
# for a few components we could hardcode this
|
# for a few components we could hardcode this
|
||||||
component_value = f'(name: "{material.name}", path: "{materials_exported_path}")'
|
#bpy.ops.blenvy.component_add(target_item_name=object.name, target_item_type="OBJECT", component_type="blenvy::blueprints::materials::MaterialInfos", component_value=component_value)
|
||||||
#bpy.ops.blenvy.component_add(target_item_name=object.name, target_item_type="OBJECT", component_type="blenvy::blueprints::materials::MaterialInfo", component_value=component_value)
|
object['MaterialInfos'] = f"({material_infos})".replace("'","")
|
||||||
|
print("adding materialInfos to object", object, "material infos", material_infos)
|
||||||
materials_exported_path = posixpath.join(materials_path, f"{materials_library_name}{export_gltf_extension}")
|
|
||||||
object['MaterialInfo'] = component_value
|
|
||||||
print("adding materialInfo to object", object, "material info", component_value)
|
|
||||||
|
|
||||||
|
|
||||||
# get all the materials of all objects in a given scene
|
# get all the materials of all objects in a given scene
|
||||||
|
|
Loading…
Reference in New Issue