mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-22 20:00:53 +00:00
Compare commits
2 Commits
fbcd025dc1
...
bef709a0ed
Author | SHA1 | Date | |
---|---|---|---|
|
bef709a0ed | ||
|
478be88a55 |
@ -14,7 +14,7 @@ license = "MIT OR Apache-2.0"
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.14.0-rc.3", default-features = false, features = ["bevy_asset", "bevy_scene", "bevy_gltf", "file_watcher"] }
|
||||
bevy = { version = "0.14", default-features = false, features = ["bevy_asset", "bevy_scene", "bevy_gltf", "file_watcher"] }
|
||||
serde = "1.0.188"
|
||||
ron = "0.8.1"
|
||||
serde_json = "1.0.108"
|
||||
@ -34,4 +34,4 @@ gltf = { version = "1.4.0", default-features = false, features = [
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
bevy = { version = "0.14.0-rc.3", default-features = false, features = ["dynamic_linking"] }
|
||||
bevy = { version = "0.14", default-features = false, features = ["dynamic_linking"] }
|
@ -57,7 +57,7 @@ pub(crate) fn inject_materials(
|
||||
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())
|
||||
.expect("material should have been preloaded");
|
||||
.expect(&format!("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
|
||||
|
@ -60,6 +60,12 @@ pub struct AddToGameWorld;
|
||||
pub(crate) struct OriginalChildren(pub Vec<Entity>);
|
||||
|
||||
|
||||
#[derive(Component)]
|
||||
/// You can add this component to a blueprint instance, and the instance will be hidden until it is ready
|
||||
/// You usually want to use this for worlds/level spawning , or dynamic spawning at runtime, but not when you are adding blueprint instances to an existing entity
|
||||
/// as it would first become invisible before re-appearing again
|
||||
pub struct HideUntilReady;
|
||||
|
||||
#[derive(Event, Debug)]
|
||||
pub enum BlueprintEvent {
|
||||
|
||||
@ -261,6 +267,7 @@ pub(crate) fn blueprints_assets_ready(spawn_placeholders: Query<
|
||||
Option<&Parent>,
|
||||
Option<&AddToGameWorld>,
|
||||
Option<&Name>,
|
||||
Option<&HideUntilReady>
|
||||
),
|
||||
(
|
||||
With<BlueprintAssetsLoaded>,
|
||||
@ -283,6 +290,7 @@ pub(crate) fn blueprints_assets_ready(spawn_placeholders: Query<
|
||||
original_parent,
|
||||
add_to_world,
|
||||
name,
|
||||
hide_until_ready,
|
||||
) in spawn_placeholders.iter()
|
||||
{
|
||||
/*info!(
|
||||
@ -336,8 +344,6 @@ pub(crate) fn blueprints_assets_ready(spawn_placeholders: Query<
|
||||
SceneBundle {
|
||||
scene: scene.clone(),
|
||||
transform: transforms,
|
||||
visibility: Visibility::Hidden,
|
||||
|
||||
..Default::default()
|
||||
},
|
||||
OriginalChildren(original_children),
|
||||
@ -345,15 +351,19 @@ pub(crate) fn blueprints_assets_ready(spawn_placeholders: Query<
|
||||
// these are animations specific to the inside of the blueprint
|
||||
named_animations: named_animations//gltf.named_animations.clone(),
|
||||
},
|
||||
|
||||
));
|
||||
|
||||
/* if add_to_world.is_some() {
|
||||
if hide_until_ready.is_some() {
|
||||
commands.entity(entity).insert(Visibility::Hidden); // visibility:
|
||||
}
|
||||
|
||||
// only allow automatically adding a newly spawned blueprint instance to the "world", if the entity does not have a parent
|
||||
if add_to_world.is_some() && original_parent.is_some() {
|
||||
let world = game_world
|
||||
.get_single_mut()
|
||||
.expect("there should be a game world present");
|
||||
commands.entity(world).add_child(entity);
|
||||
} */
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -382,8 +392,6 @@ pub struct BlueprintChildrenReady;
|
||||
#[reflect(Component)]
|
||||
pub struct BlueprintReadyForPostProcess;
|
||||
|
||||
|
||||
// TODO: disregard blueprints that have been spawned WAIT , we already have BlueprintSpawning
|
||||
pub(crate) fn blueprints_scenes_spawned(
|
||||
spawned_blueprint_scene_instances: Query<(Entity, Option<&Name>, Option<&Children>, Option<&SpawnTrackRoot>), (With<BlueprintSpawning>, Added<SceneInstance>)>,
|
||||
with_blueprint_infos : Query<(Entity, Option<&Name>), With<BlueprintInfo>>,
|
||||
@ -396,7 +404,6 @@ pub(crate) fn blueprints_scenes_spawned(
|
||||
mut commands: Commands,
|
||||
|
||||
all_names: Query<&Name>
|
||||
|
||||
) {
|
||||
for (entity, name, children, track_root) in spawned_blueprint_scene_instances.iter(){
|
||||
info!("Done spawning blueprint scene for entity named {:?} (track root: {:?})", name, track_root);
|
||||
@ -405,34 +412,59 @@ pub(crate) fn blueprints_scenes_spawned(
|
||||
|
||||
let mut tracker_data: HashMap<Entity, bool> = HashMap::new();
|
||||
|
||||
if track_root.is_none() {
|
||||
for parent in all_parents.iter_ancestors(entity) {
|
||||
if with_blueprint_infos.get(parent).is_ok() {
|
||||
|
||||
println!("found a parent with blueprint_info {:?} for {:?}", all_names.get(parent), all_names.get(entity));
|
||||
commands.entity(entity).insert(SpawnTrackRoot(parent));// Injecting to know which entity is the root
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if children.is_some() {
|
||||
for child in all_children.iter_descendants(entity) {
|
||||
if with_blueprint_infos.get(child).is_ok() {
|
||||
// println!("Parent blueprint instance of {:?} is {:?}", all_names.get(child), all_names.get(entity));
|
||||
|
||||
|
||||
|
||||
|
||||
for parent in all_parents.iter_ancestors(child) {
|
||||
if with_blueprint_infos.get(parent).is_ok() {
|
||||
|
||||
if parent == entity {
|
||||
//println!("yohoho");
|
||||
println!("Parent blueprint instance of {:?} is {:?}", all_names.get(child), all_names.get(parent));
|
||||
|
||||
commands.entity(child).insert(SpawnTrackRoot(entity));// Injecting to know which entity is the root
|
||||
|
||||
tracker_data.insert(child, false);
|
||||
|
||||
sub_blueprint_instances.push(child);
|
||||
if let Ok(nname) = all_names.get(child) {
|
||||
sub_blueprint_instance_names.push(nname.clone());
|
||||
}
|
||||
|
||||
tracker_data.insert(child, false);
|
||||
|
||||
if track_root.is_some() {
|
||||
/*if track_root.is_some() {
|
||||
let prev_root = track_root.unwrap().0;
|
||||
// if we already had a track root, and it is different from the current entity , change the previous track root's list of children
|
||||
if prev_root != entity {
|
||||
let mut tracker = sub_blueprint_trackers.get_mut(prev_root).expect("should have a tracker");
|
||||
tracker.1.sub_blueprint_instances.remove(&child);
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
commands.entity(child).insert(SpawnTrackRoot(entity));// Injecting to know which entity is the root
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -481,7 +513,7 @@ pub(crate) fn blueprints_transfer_components(
|
||||
) {
|
||||
|
||||
for (original, children, original_children, name, track_root) in foo.iter() {
|
||||
println!("YOOO ready !! {:?}", name);
|
||||
info!("YOOO ready !! removing empty nodes {:?}", name);
|
||||
|
||||
if children.len() == 0 {
|
||||
warn!("timing issue ! no children found, please restart your bevy app (bug being investigated)");
|
||||
@ -515,7 +547,7 @@ pub(crate) fn blueprints_transfer_components(
|
||||
}
|
||||
|
||||
commands.entity(original)
|
||||
.insert(BlueprintReadyForPostProcess); // Tag the entity so any systems dealing with post processing can now 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(original).remove::<Handle<Scene>>(); // FIXME: if we delete the handle to the scene, things get despawned ! not what we want
|
||||
//commands.entity(original).remove::<BlueprintAssetsLoadState>(); // also clear the sub assets tracker to free up handles, perhaps just freeing up the handles and leave the rest would be better ?
|
||||
//commands.entity(original).remove::<BlueprintAssetsLoaded>();
|
||||
@ -524,6 +556,7 @@ pub(crate) fn blueprints_transfer_components(
|
||||
|
||||
// now check if the current entity is a child blueprint instance of another entity
|
||||
// this should always be done last, as children should be finished before the parent can be processed correctly
|
||||
// TODO: perhaps use observers for these
|
||||
if let Some(track_root) = track_root {
|
||||
let root_name = all_names.get(track_root.0);
|
||||
println!("got some root {:?}", root_name);
|
||||
@ -555,19 +588,23 @@ pub(crate) fn blueprints_transfer_components(
|
||||
pub struct BlueprintReadyForFinalizing;
|
||||
|
||||
pub(crate) fn blueprints_finalize_instances(
|
||||
blueprint_instances: Query<(Entity, Option<&Name>, &BlueprintInfo), (With<BlueprintSpawning>, With<BlueprintReadyForFinalizing>)>,
|
||||
blueprint_instances: Query<(Entity, Option<&Name>, &BlueprintInfo, Option<&HideUntilReady>), (With<BlueprintSpawning>, With<BlueprintReadyForFinalizing>)>,
|
||||
mut blueprint_events: EventWriter<BlueprintEvent>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
for (entity, name, blueprint_info) in blueprint_instances.iter() {
|
||||
for (entity, name, blueprint_info, hide_until_ready) in blueprint_instances.iter() {
|
||||
info!("Finalizing blueprint instance {:?}", name);
|
||||
commands.entity(entity)
|
||||
.remove::<SpawnHere>()
|
||||
.remove::<BlueprintSpawning>()
|
||||
.remove::<BlueprintReadyForPostProcess>()
|
||||
.insert(BlueprintInstanceReady)
|
||||
.insert(Visibility::Visible)
|
||||
;
|
||||
if hide_until_ready.is_some() {
|
||||
println!("REVEAAAL");
|
||||
commands.entity(entity).insert(Visibility::Visible);
|
||||
}
|
||||
|
||||
|
||||
blueprint_events.send(BlueprintEvent::InstanceReady {entity: entity, blueprint_name: blueprint_info.name.clone(), blueprint_path: blueprint_info.path.clone()});
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.14.0-rc.3", features = ["dynamic_linking"] }
|
||||
bevy = { version = "0.14", features = ["dynamic_linking"] }
|
||||
blenvy = { path = "../../crates/blenvy" }
|
||||
# bevy_gltf_blueprints = { path = "../../crates/bevy_gltf_blueprints" }
|
||||
# bevy_registry_export = { path = "../../crates/bevy_registry_export" }
|
||||
|
Binary file not shown.
@ -4182,6 +4182,30 @@
|
||||
"type": "object",
|
||||
"typeInfo": "Struct"
|
||||
},
|
||||
"bevy_example::test_components::RedirectPropHitImpulse": {
|
||||
"isComponent": true,
|
||||
"isResource": false,
|
||||
"long_name": "bevy_example::test_components::RedirectPropHitImpulse",
|
||||
"oneOf": [
|
||||
{
|
||||
"items": false,
|
||||
"long_name": "Local",
|
||||
"prefixItems": [
|
||||
{
|
||||
"type": {
|
||||
"$ref": "#/$defs/glam::Vec3"
|
||||
}
|
||||
}
|
||||
],
|
||||
"short_name": "Local",
|
||||
"type": "array",
|
||||
"typeInfo": "Tuple"
|
||||
}
|
||||
],
|
||||
"short_name": "RedirectPropHitImpulse",
|
||||
"type": "object",
|
||||
"typeInfo": "Enum"
|
||||
},
|
||||
"bevy_example::test_components::TupleTest2": {
|
||||
"isComponent": true,
|
||||
"isResource": false,
|
||||
@ -8145,11 +8169,6 @@
|
||||
"$ref": "#/$defs/bevy_render::alpha::AlphaMode"
|
||||
}
|
||||
},
|
||||
"anisotropy_channel": {
|
||||
"type": {
|
||||
"$ref": "#/$defs/bevy_pbr::pbr_material::UvChannel"
|
||||
}
|
||||
},
|
||||
"anisotropy_rotation": {
|
||||
"type": {
|
||||
"$ref": "#/$defs/f32"
|
||||
@ -8160,11 +8179,6 @@
|
||||
"$ref": "#/$defs/f32"
|
||||
}
|
||||
},
|
||||
"anisotropy_texture": {
|
||||
"type": {
|
||||
"$ref": "#/$defs/core::option::Option<bevy_asset::handle::Handle<bevy_render::texture::image::Image>>"
|
||||
}
|
||||
},
|
||||
"attenuation_color": {
|
||||
"type": {
|
||||
"$ref": "#/$defs/bevy_color::color::Color"
|
||||
@ -8374,7 +8388,6 @@
|
||||
"clearcoat_perceptual_roughness",
|
||||
"anisotropy_strength",
|
||||
"anisotropy_rotation",
|
||||
"anisotropy_channel",
|
||||
"double_sided",
|
||||
"unlit",
|
||||
"fog_enabled",
|
||||
|
@ -1,5 +1,5 @@
|
||||
use bevy::prelude::*;
|
||||
use blenvy::{BluePrintBundle, BlueprintInfo, DynamicBlueprintInstance, GameWorldTag, SpawnHere};
|
||||
use blenvy::{BluePrintBundle, BlueprintInfo, DynamicBlueprintInstance, GameWorldTag, HideUntilReady, SpawnHere};
|
||||
use crate::{GameState, InAppRunning};
|
||||
|
||||
//use bevy_rapier3d::prelude::Velocity;
|
||||
@ -23,6 +23,7 @@ pub fn setup_game(
|
||||
|
||||
commands.spawn((
|
||||
BlueprintInfo{name: "World".into(), path: "levels/World.glb".into()},
|
||||
HideUntilReady,
|
||||
bevy::prelude::Name::from("world"), //FIXME: not really needed ? could be infered from blueprint's name/ path
|
||||
SpawnHere,
|
||||
GameWorldTag,
|
||||
@ -67,6 +68,7 @@ pub fn spawn_test(
|
||||
},
|
||||
DynamicBlueprintInstance,
|
||||
bevy::prelude::Name::from(format!("test{}", name_index)),
|
||||
HideUntilReady,
|
||||
// SpawnHere,
|
||||
TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)),
|
||||
/*Velocity {
|
||||
|
@ -129,11 +129,20 @@ fn exit_game(mut app_exit_events: ResMut<Events<bevy::app::AppExit>>) {
|
||||
|
||||
fn check_for_gltf_events(
|
||||
mut blueprint_events: EventReader<BlueprintEvent>,
|
||||
all_names: Query<&Name>,
|
||||
)
|
||||
{
|
||||
for event in blueprint_events.read() {
|
||||
match event {
|
||||
BlueprintEvent::InstanceReady{entity, blueprint_name, blueprint_path} => {
|
||||
info!("BLUEPRINT EVENT: {:?} for {:?}", event, all_names.get(*entity));
|
||||
|
||||
}
|
||||
_=> {
|
||||
info!("BLUEPRINT EVENT: {:?}", event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GamePlugin;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use bevy::{gltf::{GltfMaterialExtras, GltfMeshExtras, GltfSceneExtras}, prelude::*};
|
||||
use blenvy::{BlueprintAssets, BlueprintInstanceReady};
|
||||
|
||||
use crate::{BasicTest, EnumComplex};
|
||||
use crate::{BasicTest, EnumComplex, RedirectPropHitImpulse};
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct HiearchyDebugTag;
|
||||
@ -12,7 +12,7 @@ pub fn setup_hierarchy_debug(mut commands: Commands, asset_server: Res<AssetServ
|
||||
TextBundle::from_section(
|
||||
"",
|
||||
TextStyle {
|
||||
color: LinearRgba { red: 1.0, green:0.0, blue: 0.0, alpha: 1.0}.into(),
|
||||
color: LinearRgba { red: 1.0, green:1.0, blue: 1.0, alpha: 1.0}.into(),
|
||||
font_size: 15.,
|
||||
..default()
|
||||
},
|
||||
@ -30,7 +30,10 @@ pub fn setup_hierarchy_debug(mut commands: Commands, asset_server: Res<AssetServ
|
||||
|
||||
pub fn get_descendants(
|
||||
all_children: &Query<&Children>,
|
||||
all_names:&Query<&Name>, root: &Entity,
|
||||
all_names:&Query<&Name>,
|
||||
root: &Entity,
|
||||
all_transforms: &Query<&Transform>,
|
||||
all_global_transforms: &Query<&GlobalTransform>,
|
||||
nesting: usize,
|
||||
to_check: &Query<&BasicTest>//&Query<(&BlueprintInstanceReady, &BlueprintAssets)>,
|
||||
)
|
||||
@ -48,14 +51,14 @@ pub fn get_descendants(
|
||||
|
||||
let components_to_check = to_check.get(*root);
|
||||
|
||||
hierarchy_display.push( format!("{}{} ({:?})", " ".repeat(nesting), name, components_to_check) ); //
|
||||
hierarchy_display.push( format!("{}{} ({:?}) ({:?})", " ".repeat(nesting), name, all_transforms.get(*root), all_global_transforms.get(*root)) ); //components_to_check ({:?})
|
||||
|
||||
|
||||
if let Ok(children) = all_children.get(*root) {
|
||||
|
||||
for child in children.iter() {
|
||||
|
||||
let child_descendants_display = get_descendants(&all_children, &all_names, &child, nesting + 4, &to_check);
|
||||
let child_descendants_display = get_descendants(&all_children, &all_names, &child, &all_transforms, &all_global_transforms, nesting + 4, &to_check);
|
||||
hierarchy_display.push(child_descendants_display);
|
||||
}
|
||||
}
|
||||
@ -66,6 +69,8 @@ pub fn draw_hierarchy_debug(
|
||||
root: Query<(Entity, Option<&Name>, &Children), (Without<Parent>)>,
|
||||
all_children: Query<&Children>,
|
||||
all_names:Query<&Name>,
|
||||
all_transforms: Query<&Transform>,
|
||||
all_global_transforms: Query<&GlobalTransform>,
|
||||
|
||||
to_check: Query<&BasicTest>,//Query<(&BlueprintInstanceReady, &BlueprintAssets)>,
|
||||
mut display: Query<&mut Text, With<HiearchyDebugTag>>,
|
||||
@ -75,7 +80,7 @@ pub fn draw_hierarchy_debug(
|
||||
for (root_entity, name, children) in root.iter() {
|
||||
// hierarchy_display.push( format!("Hierarchy root{:?}", name) );
|
||||
|
||||
hierarchy_display.push(get_descendants(&all_children, &all_names, &root_entity, 0, &to_check));
|
||||
hierarchy_display.push(get_descendants(&all_children, &all_names, &root_entity, &all_transforms, &all_global_transforms, 0, &to_check));
|
||||
// let mut children = all_children.get(root_entity);
|
||||
/*for child in children.iter() {
|
||||
// hierarchy_display
|
||||
@ -134,13 +139,13 @@ for (id, name, scene_extras, extras, mesh_extras, material_extras) in
|
||||
}
|
||||
|
||||
fn check_for_component(
|
||||
foo: Query<(Entity, Option<&Name>, &EnumComplex)>,
|
||||
foo: Query<(Entity, Option<&Name>, &RedirectPropHitImpulse)>,
|
||||
mut display: Query<&mut Text, With<HiearchyDebugTag>>,
|
||||
|
||||
){
|
||||
let mut info_lines: Vec<String> = vec![];
|
||||
for (entiity, name , enum_complex) in foo.iter(){
|
||||
let data = format!(" We have a 'EnumComplex' component: {:?} (on {:?})", enum_complex, name);
|
||||
let data = format!(" We have a matching component: {:?} (on {:?})", enum_complex, name);
|
||||
info_lines.push(data);
|
||||
println!("yoho component");
|
||||
|
||||
@ -156,8 +161,8 @@ impl Plugin for HiearchyDebugPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app
|
||||
.add_systems(Startup, setup_hierarchy_debug)
|
||||
// .add_systems(Update, check_for_component)
|
||||
.add_systems(Update, draw_hierarchy_debug)
|
||||
//.add_systems(Update, check_for_component)
|
||||
//.add_systems(Update, draw_hierarchy_debug)
|
||||
//.add_systems(Update, check_for_gltf_extras)
|
||||
|
||||
;
|
||||
|
@ -224,6 +224,12 @@ pub struct ComponentWithFieldsOfIdenticalType{
|
||||
#[reflect(Component)]
|
||||
pub struct ComponentWithFieldsOfIdenticalType2(f32, f32, f32);
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Reflect, Component)]
|
||||
#[reflect(Component, )]
|
||||
pub enum RedirectPropHitImpulse {
|
||||
Local(Vec3),
|
||||
}
|
||||
pub struct ComponentsTestPlugin;
|
||||
impl Plugin for ComponentsTestPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
@ -279,6 +285,8 @@ impl Plugin for ComponentsTestPlugin {
|
||||
.register_type::<ComponentWithFieldsOfIdenticalType>()
|
||||
.register_type::<ComponentWithFieldsOfIdenticalType2>()
|
||||
|
||||
.register_type::<RedirectPropHitImpulse>()
|
||||
|
||||
.add_plugins(MaterialPlugin::<
|
||||
ExtendedMaterial<StandardMaterial, MyExtension>,
|
||||
>::default());
|
||||
|
@ -199,7 +199,8 @@ Blender side:
|
||||
- [ ] disabled components
|
||||
- [ ] blueprint instances as children of blueprint instances
|
||||
- [ ] blueprint instances as children of empties
|
||||
- [x] update testing files
|
||||
- [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 ?
|
||||
|
@ -21,16 +21,11 @@ def auto_export(changes_per_scene, changed_export_parameters, settings):
|
||||
# have the export parameters (not auto export, just gltf export) have changed: if yes (for example switch from glb to gltf, compression or not, animations or not etc), we need to re-export everything
|
||||
print ("changed_export_parameters", changed_export_parameters)
|
||||
try:
|
||||
# path to the current blend file
|
||||
file_path = bpy.data.filepath
|
||||
# Get the folder
|
||||
blend_file_path = os.path.dirname(file_path)
|
||||
|
||||
#should we use change detection or not
|
||||
change_detection = getattr(settings.auto_export, "change_detection")
|
||||
export_scene_settings = getattr(settings.auto_export,"export_scene_settings")
|
||||
do_export_blueprints = getattr(settings.auto_export,"export_blueprints")
|
||||
export_materials_library = getattr(settings.auto_export,"export_materials_library")
|
||||
export_scene_settings = getattr(settings.auto_export, "export_scene_settings")
|
||||
do_export_blueprints = getattr(settings.auto_export, "export_blueprints")
|
||||
export_materials_library = getattr(settings.auto_export, "export_materials_library")
|
||||
|
||||
# standard gltf export settings are stored differently
|
||||
standard_gltf_exporter_settings = get_standard_exporter_settings()
|
||||
@ -47,7 +42,10 @@ def auto_export(changes_per_scene, changed_export_parameters, settings):
|
||||
|
||||
# we inject the blueprints export path
|
||||
blueprints_path = getattr(settings,"blueprints_path")
|
||||
inject_export_path_into_internal_blueprints(internal_blueprints=blueprints_data.internal_blueprints, blueprints_path=blueprints_path, gltf_extension=gltf_extension)
|
||||
# inject the "export_path" and "material_path" properties into the internal blueprints
|
||||
inject_export_path_into_internal_blueprints(internal_blueprints=blueprints_data.internal_blueprints, blueprints_path=blueprints_path, gltf_extension=gltf_extension, settings=settings)
|
||||
|
||||
|
||||
for blueprint in blueprints_data.blueprints:
|
||||
bpy.context.window_manager.blueprints_registry.add_blueprint(blueprint)
|
||||
#bpy.context.window_manager.blueprints_registry.refresh_blueprints()
|
||||
|
@ -119,6 +119,10 @@ def duplicate_object(object, parent, combine_mode, destination_collection, bluep
|
||||
# do this both for empty replacements & normal copies
|
||||
if parent is not None:
|
||||
copy.parent = parent
|
||||
# without this, the copy"s offset from parent (if any ) will not be set correctly !
|
||||
# see here for example https://blender.stackexchange.com/questions/3763/parenting-messes-up-transforms-where-is-the-offset-stored
|
||||
copy.matrix_parent_inverse = object.matrix_parent_inverse
|
||||
|
||||
remove_unwanted_custom_properties(copy)
|
||||
copy_animation_data(object, copy)
|
||||
|
||||
|
@ -24,6 +24,7 @@ def generate_gltf_export_settings(settings):
|
||||
export_cameras=True,
|
||||
export_extras=True, # For custom exported properties.
|
||||
export_lights=True,
|
||||
export_hierarchy_full_collections=False
|
||||
|
||||
#export_texcoords=True,
|
||||
#export_normals=True,
|
||||
@ -54,6 +55,7 @@ def generate_gltf_export_settings(settings):
|
||||
|
||||
standard_gltf_exporter_settings = get_standard_exporter_settings()
|
||||
|
||||
# these essential params should NEVER be overwritten , no matter the settings of the standard exporter
|
||||
constant_keys = [
|
||||
'use_selection',
|
||||
'use_visible',
|
||||
@ -63,9 +65,10 @@ def generate_gltf_export_settings(settings):
|
||||
'export_cameras',
|
||||
'export_extras', # For custom exported properties.
|
||||
'export_lights',
|
||||
'export_hierarchy_full_collections'
|
||||
]
|
||||
|
||||
# a certain number of essential params should NEVER be overwritten , no matter the settings of the standard exporter
|
||||
#
|
||||
for key in standard_gltf_exporter_settings.keys():
|
||||
if str(key) not in constant_keys:
|
||||
gltf_export_settings[key] = standard_gltf_exporter_settings.get(key)
|
||||
|
@ -5,7 +5,7 @@ from blenvy.core.object_makers import (make_empty)
|
||||
from .duplicate_object import duplicate_object
|
||||
from .export_gltf import export_gltf
|
||||
from blenvy.core.scene_helpers import add_scene_property
|
||||
|
||||
from ..constants import custom_properties_to_filter_out
|
||||
"""
|
||||
generates a temporary scene, fills it with data, cleans up after itself
|
||||
* named using temp_scene_name
|
||||
@ -19,7 +19,7 @@ def generate_temporary_scene_and_export(settings, gltf_export_settings, gltf_out
|
||||
temp_scene = bpy.data.scenes.new(name=temp_scene_name)
|
||||
temp_root_collection = temp_scene.collection
|
||||
|
||||
properties_black_list = ['glTF2ExportSettings', 'assets', 'user_assets', 'components_meta', 'Components_meta', 'Generated_assets', 'generated_assets']
|
||||
properties_black_list = custom_properties_to_filter_out
|
||||
if additional_data is not None: # FIXME not a fan of having this here
|
||||
for entry in dict(additional_data):
|
||||
# we copy everything over except those on the black list
|
||||
@ -75,7 +75,6 @@ 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
|
||||
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")
|
||||
|
||||
for object in source_collection.objects:
|
||||
if object.name.endswith("____bak"): # some objects could already have been handled, ignore them
|
||||
continue
|
||||
|
@ -1,4 +1,11 @@
|
||||
TEMPSCENE_PREFIX = "__temp_scene"
|
||||
|
||||
#hard coded custom properties to ignore
|
||||
custom_properties_to_filter_out = ['_combine', 'template', 'components_meta']
|
||||
#hard coded custom properties to ignore on export
|
||||
custom_properties_to_filter_out = [
|
||||
'glTF2ExportSettings',
|
||||
'assets', 'user_assets', 'Generated_assets', 'generated_assets',
|
||||
'components_meta', 'Components_meta',
|
||||
'_combine', 'template',
|
||||
'Blenvy_scene_type', 'blenvy_scene_type'
|
||||
]
|
||||
#['_combine', 'template', 'components_meta', 'Components_meta', 'Blenvy_scene_type']
|
||||
|
@ -55,7 +55,7 @@ def export_main_scene(scene, settings, blueprints_data):
|
||||
auto_assets = []
|
||||
|
||||
all_assets = []
|
||||
export_gltf_extension = getattr(settings.auto_export, "export_gltf_extension", ".glb")
|
||||
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
||||
|
||||
blueprints_path = getattr(settings, "blueprints_path")
|
||||
for blueprint in blueprints_in_scene:
|
||||
@ -64,6 +64,11 @@ def export_main_scene(scene, settings, blueprints_data):
|
||||
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})
|
||||
|
||||
@ -80,7 +85,7 @@ def export_main_scene(scene, settings, blueprints_data):
|
||||
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'}])
|
||||
|
||||
|
@ -62,7 +62,7 @@ def get_userTextures():
|
||||
|
||||
def get_blueprint_assets_tree(blueprint, blueprints_data, parent, settings):
|
||||
blueprints_path = getattr(settings, "blueprints_path")
|
||||
export_gltf_extension = getattr(settings.auto_export, "export_gltf_extension", ".glb")
|
||||
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
||||
assets_list = []
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ def get_blueprint_assets_tree(blueprint, blueprints_data, parent, settings):
|
||||
|
||||
def get_main_scene_assets_tree(main_scene, blueprints_data, settings):
|
||||
blueprints_path = getattr(settings, "blueprints_path")
|
||||
export_gltf_extension = getattr(settings.auto_export, "export_gltf_extension", ".glb")
|
||||
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)
|
||||
@ -123,7 +123,7 @@ def get_main_scene_assets_tree(main_scene, blueprints_data, settings):
|
||||
|
||||
def get_blueprint_asset_tree(blueprint, blueprints_data, settings):
|
||||
blueprints_path = getattr(settings, "blueprints_path")
|
||||
export_gltf_extension = getattr(settings.auto_export, "export_gltf_extension", ".glb")
|
||||
export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb")
|
||||
|
||||
assets_list = get_user_assets_as_list(blueprint.collection)
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
import os
|
||||
import json
|
||||
import bpy
|
||||
from pathlib import Path
|
||||
|
||||
from ..core.scene_helpers import add_scene_property
|
||||
|
||||
def find_blueprints_not_on_disk(blueprints, folder_path, extension):
|
||||
@ -19,12 +21,23 @@ def check_if_blueprint_on_disk(scene_name, folder_path, extension):
|
||||
found = os.path.exists(gltf_output_path) and os.path.isfile(gltf_output_path)
|
||||
return found
|
||||
|
||||
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, 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 = os.path.join(materials_path, f"{materials_library_name}{export_gltf_extension}")
|
||||
|
||||
for blueprint in internal_blueprints:
|
||||
blueprint_exported_path = os.path.join(blueprints_path, f"{blueprint.name}{gltf_extension}")
|
||||
# print("injecting blueprint path", blueprint_exported_path, "for", blueprint.name)
|
||||
|
||||
print("blueprint_exported_path", blueprint_exported_path)
|
||||
blueprint.collection["export_path"] = blueprint_exported_path
|
||||
if export_materials_library:
|
||||
blueprint.collection["materials_path"] = materials_exported_path
|
||||
|
||||
|
||||
def inject_blueprints_list_into_main_scene(scene, blueprints_data, settings):
|
||||
project_root_path = getattr(settings, "project_root_path")
|
||||
|
@ -34,7 +34,7 @@ def get_all_materials(collection_names, library_scenes):
|
||||
|
||||
def add_material_info_to_objects(materials_per_object, settings):
|
||||
materials_path = getattr(settings, "materials_path")
|
||||
export_gltf_extension = getattr(settings.auto_export, "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"
|
||||
|
@ -122,9 +122,13 @@ def test_export_complex(setup_data):
|
||||
user_asset.path = "audio/fake.mp3"
|
||||
|
||||
# we have to cheat, since we cannot rely on the data injected when saving the library file (since we are not saving it as part of the tests)
|
||||
#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"
|
||||
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"
|
||||
|
||||
bpy.data.collections["External_blueprint"]["materials_path"] = "materials/testing_library_materials.glb"
|
||||
bpy.data.collections["External_blueprint2"]["materials_path"] = "materials/testing_library_materials.glb"
|
||||
bpy.data.collections["External_blueprint3"]["materials_path"] = "materials/testing_library_materials.glb"
|
||||
|
||||
# do the actual exporting
|
||||
prepare_and_export()
|
||||
|
@ -80,6 +80,7 @@ def test_export_complex(setup_data):
|
||||
export_props = {
|
||||
}
|
||||
gltf_settings = {
|
||||
"export_format":"GLTF_SEPARATE",
|
||||
"export_animations": True,
|
||||
"export_optimize_animation_size": False,
|
||||
"export_apply":True
|
||||
|
Loading…
Reference in New Issue
Block a user