diff --git a/Cargo.toml b/Cargo.toml index 1b313cb..ad3f9cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ members = [ "examples/bevy_gltf_save_load/basic/", "examples/bevy_registry_export/basic", - "testing/bevy_registry_export/basic" + "testing/bevy_example" ] resolver = "2" @@ -34,9 +34,6 @@ semicolon_if_nothing_returned = "warn" [profile.dev.package."*"] opt-level = 3 -[profile.dev.package.bevy] -features = ["dynamic"] - #### --------------------Production/ release------------------------------- [profile.release] strip = "debuginfo" diff --git a/crates/bevy_gltf_blueprints/Cargo.toml b/crates/bevy_gltf_blueprints/Cargo.toml index b70b40e..d6d1d16 100644 --- a/crates/bevy_gltf_blueprints/Cargo.toml +++ b/crates/bevy_gltf_blueprints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_gltf_blueprints" -version = "0.8.0" +version = "0.9.0" authors = ["Mark 'kaosat-dev' Moissette"] description = "Adds the ability to define Blueprints/Prefabs for [Bevy](https://bevyengine.org/) inside gltf files and spawn them in Bevy." homepage = "https://github.com/kaosat-dev/Blender_bevy_components_workflow" diff --git a/crates/bevy_gltf_blueprints/README.md b/crates/bevy_gltf_blueprints/README.md index fe5baa9..6cad9a1 100644 --- a/crates/bevy_gltf_blueprints/README.md +++ b/crates/bevy_gltf_blueprints/README.md @@ -25,8 +25,8 @@ Here's a minimal usage example: ```toml # Cargo.toml [dependencies] -bevy="0.12" -bevy_gltf_blueprints = { version = "0.8"} +bevy="0.13" +bevy_gltf_blueprints = { version = "0.9"} ``` @@ -64,7 +64,7 @@ fn spawn_blueprint( Add the following to your `[dependencies]` section in `Cargo.toml`: ```toml -bevy_gltf_blueprints = "0.8" +bevy_gltf_blueprints = "0.9" ``` Or use `cargo add`: @@ -346,8 +346,8 @@ The main branch is compatible with the latest Bevy release, while the branch `be Compatibility of `bevy_gltf_blueprints` versions: | `bevy_gltf_blueprints` | `bevy` | | :-- | :-- | -| `0.8` | `0.13` | -| `0.3 - 0.7` | `0.12` | +| `0.9` | `0.13` | +| `0.3 - 0.8` | `0.12` | | `0.1 - 0.2` | `0.11` | | branch `main` | `0.13` | | branch `bevy_main` | `main` | diff --git a/crates/bevy_gltf_components/Cargo.toml b/crates/bevy_gltf_components/Cargo.toml index 33c73d9..6e23e47 100644 --- a/crates/bevy_gltf_components/Cargo.toml +++ b/crates/bevy_gltf_components/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_gltf_components" -version = "0.4.0" +version = "0.5.0" authors = ["Mark 'kaosat-dev' Moissette"] description = "Allows you to define [Bevy](https://bevyengine.org/) components direclty inside gltf files and instanciate the components on the Bevy side." homepage = "https://github.com/kaosat-dev/Blender_bevy_components_workflow" diff --git a/crates/bevy_gltf_components/README.md b/crates/bevy_gltf_components/README.md index 01c8c75..a5308d5 100644 --- a/crates/bevy_gltf_components/README.md +++ b/crates/bevy_gltf_components/README.md @@ -24,7 +24,7 @@ Here's a minimal usage example: # Cargo.toml [dependencies] bevy="0.13" -bevy_gltf_components = { version = "0.4"} +bevy_gltf_components = { version = "0.5"} ``` @@ -60,7 +60,7 @@ bevy_gltf_components = { version = "0.4"} Add the following to your `[dependencies]` section in `Cargo.toml`: ```toml -bevy_gltf_components = "0.4" +bevy_gltf_components = "0.5" ``` Or use `cargo add`: @@ -71,7 +71,7 @@ cargo add bevy_gltf_components ## Configuration -starting with version 0.4, this plugin is configurable +starting with version 0.3, this plugin is configurable Use the default configuration: ```rust no_run @@ -117,8 +117,8 @@ The main branch is compatible with the latest Bevy release, while the branch `be Compatibility of `bevy_gltf_components` versions: | `bevy_gltf_components` | `bevy` | | :-- | :-- | -| `0.4` | `0.13` | -| `0.2 - 0.3` | `0.12` | +| `0.5` | `0.13` | +| `0.2 - 0.4` | `0.12` | | `0.1` | `0.11` | | branch `main` | `0.13` | | branch `bevy_main` | `main` | diff --git a/crates/bevy_gltf_components/src/lib.rs b/crates/bevy_gltf_components/src/lib.rs index 3cd2b1c..d91f6dc 100644 --- a/crates/bevy_gltf_components/src/lib.rs +++ b/crates/bevy_gltf_components/src/lib.rs @@ -8,7 +8,13 @@ pub mod process_gltfs; pub use process_gltfs::*; use bevy::{ +<<<<<<< HEAD ecs::{component::Component, reflect::ReflectComponent, system::Resource}, +======= + app::Startup, + ecs::system::{Res, Resource}, + log::warn, +>>>>>>> 9cb9dda5d35c635d367fa81ca1a6c752cda9bc02 prelude::{App, IntoSystemConfigs, Plugin, SystemSet, Update}, reflect::Reflect, }; @@ -72,12 +78,19 @@ impl Default for ComponentsFromGltfPlugin { } } +fn check_for_legacy_mode(gltf_components_config: Res) { + if gltf_components_config.legacy_mode { + warn!("using simplified component definitions is deprecated since 0.3, prefer defining components with real ron values (use the bevy_components tool for Blender for simplicity) "); + } +} + impl Plugin for ComponentsFromGltfPlugin { fn build(&self, app: &mut App) { app.register_type::() .insert_resource(GltfComponentsConfig { legacy_mode: self.legacy_mode, }) + .add_systems(Startup, check_for_legacy_mode) .add_systems( Update, (add_components_from_gltf_extras).in_set(GltfComponentsSet::Injection), diff --git a/crates/bevy_gltf_components/src/ronstring_to_reflect_component.rs b/crates/bevy_gltf_components/src/ronstring_to_reflect_component.rs index 096ec79..dc095f5 100644 --- a/crates/bevy_gltf_components/src/ronstring_to_reflect_component.rs +++ b/crates/bevy_gltf_components/src/ronstring_to_reflect_component.rs @@ -91,14 +91,11 @@ pub fn ronstring_to_reflect_component( parsed_value = format!("({formated})"); } } - } - // FIXME: waaait this should be part of the legacy mode as it modifies the ron data ??? - // so it means the values generated by the Blende add-on are incomplete (trivial to fix, but still) - if parsed_value.is_empty() { - parsed_value = "()".to_string(); + if parsed_value.is_empty() { + parsed_value = "()".to_string(); + } } - let ron_string = format!( "{{ \"{}\":{} }}", type_registration.type_info().type_path(), @@ -106,7 +103,7 @@ pub fn ronstring_to_reflect_component( ); // usefull to determine what an entity looks like Serialized - /*let test_struct = VecOfColors(vec![Color::Rgba { red: 0., green: 0.0, blue: 0.0, alpha: 0.0 }]);//TuppleTestColor(Color::Rgba { red: 0., green: 0.0, blue: 0.0, alpha: 0.0 }); + /*let test_struct = CameraRenderGraph::new("name"); let serializer = ReflectSerializer::new(&test_struct, &type_registry); let serialized = ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap(); diff --git a/crates/bevy_gltf_save_load/Cargo.toml b/crates/bevy_gltf_save_load/Cargo.toml index 06d9ff8..062fc03 100644 --- a/crates/bevy_gltf_save_load/Cargo.toml +++ b/crates/bevy_gltf_save_load/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_gltf_save_load" -version = "0.3.0" +version = "0.4.0" authors = ["Mark 'kaosat-dev' Moissette"] description = "Save & load your bevy games" homepage = "https://github.com/kaosat-dev/Blender_bevy_components_workflow" @@ -18,5 +18,5 @@ bevy = { version = "0.13", default-features = false, features = ["bevy_asset", " [dependencies] bevy = { version = "0.13", default-features = false, features = ["bevy_asset", "bevy_scene", "bevy_gltf"] } -#bevy_gltf_blueprints = "0.7" +#bevy_gltf_blueprints = "0.9" bevy_gltf_blueprints = { path = "../bevy_gltf_blueprints" } diff --git a/crates/bevy_gltf_save_load/README.md b/crates/bevy_gltf_save_load/README.md index d7aa20e..1141132 100644 --- a/crates/bevy_gltf_save_load/README.md +++ b/crates/bevy_gltf_save_load/README.md @@ -35,8 +35,8 @@ Here's a minimal usage example: # Cargo.toml [dependencies] bevy="0.13" -bevy_gltf_save_load = "0.3" -bevy_gltf_blueprints = "0.6" // also needed +bevy_gltf_save_load = "0.4" +bevy_gltf_blueprints = "0.9" // also needed ``` ```rust no_run @@ -142,7 +142,11 @@ Add the following to your `[dependencies]` section in `Cargo.toml`: ```toml bevy_gltf_save_load = "0.3" +<<<<<<< HEAD bevy_gltf_blueprints = "0.8" // also needed, as bevy_gltf_save_load does not re-export it at this time +======= +bevy_gltf_blueprints = "0.6" // also needed, as bevy_gltf_save_load does not re-export it at this time +>>>>>>> 9cb9dda5d35c635d367fa81ca1a6c752cda9bc02 ``` @@ -299,9 +303,9 @@ The main branch is compatible with the latest Bevy release, while the branch `be Compatibility of `bevy_gltf_save_load` versions: | `bevy_gltf_save_load` | `bevy` | | :-- | :-- | -| `0.3 ` | `0.13` | -| `0.1 - 0.2` | `0.12` | -| branch `main` | `0.13` | +| `0.4 ` | `0.13` | +| `0.1 -0.3` | `0.12` | +| branch `main` | `0.12` | | branch `bevy_main` | `main` | diff --git a/crates/bevy_registry_export/Cargo.toml b/crates/bevy_registry_export/Cargo.toml index 2ffe820..aa6f674 100644 --- a/crates/bevy_registry_export/Cargo.toml +++ b/crates/bevy_registry_export/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_registry_export" -version = "0.2.0" +version = "0.3.0" authors = ["Mark 'kaosat-dev' Moissette", "Pascal 'Killercup' Hertleif"] description = "Allows you to define [Bevy](https://bevyengine.org/) components direclty inside gltf files and instanciate the components on the Bevy side." homepage = "https://github.com/kaosat-dev/Blender_bevy_components_workflow" diff --git a/crates/bevy_registry_export/README.md b/crates/bevy_registry_export/README.md index 0052701..6fe601b 100644 --- a/crates/bevy_registry_export/README.md +++ b/crates/bevy_registry_export/README.md @@ -18,7 +18,7 @@ Here's a minimal usage example: # Cargo.toml [dependencies] bevy="0.13" -bevy_registry_export = "0.2" +bevy_registry_export = "0.3" ``` ```rust no_run @@ -44,7 +44,7 @@ take a look at the [example]('https://github.com/kaosat-dev/Blender_bevy_compone Add the following to your `[dependencies]` section in `Cargo.toml`: ```toml -bevy_registry_export = "0.2" +bevy_registry_export = "0.3" ``` @@ -112,9 +112,10 @@ The main branch is compatible with the latest Bevy release, while the branch `be Compatibility of `bevy_registry_export` versions: | `bevy_registry_export` | `bevy` | `bevy_components (Blender add-on)` | | :-- | :-- |:-- | -| `0.1 ` | `0.13` | `0.1 - 0.2` | -| `0.1 ` | `0.12` | `0.1 - 0.2` | -| branch `main` | `0.13` | `0.1.0` | +| `0.3 ` | `0.13` | `0.3` | +| `0.2 ` | `0.12` | `0.3` | +| `0.1 ` | `0.12` | `0.1 -0.2` | +| branch `main` | `0.12` | `0.1` | | branch `bevy_main` | `main` | `n/a` | diff --git a/examples/bevy_registry_export/basic/assets/basic.blend b/examples/bevy_registry_export/basic/assets/basic.blend index b38fad3..cdb6b22 100644 Binary files a/examples/bevy_registry_export/basic/assets/basic.blend and b/examples/bevy_registry_export/basic/assets/basic.blend differ diff --git a/examples/bevy_registry_export/basic/assets/models/World.glb b/examples/bevy_registry_export/basic/assets/models/World.glb index 04d2c2a..b7bc2b5 100644 Binary files a/examples/bevy_registry_export/basic/assets/models/World.glb and b/examples/bevy_registry_export/basic/assets/models/World.glb differ diff --git a/examples/bevy_registry_export/basic/assets/models/library/Container.glb b/examples/bevy_registry_export/basic/assets/models/library/Container.glb index 630a6c0..21cf8ab 100644 Binary files a/examples/bevy_registry_export/basic/assets/models/library/Container.glb and b/examples/bevy_registry_export/basic/assets/models/library/Container.glb differ diff --git a/examples/bevy_registry_export/basic/assets/models/library/Health_Pickup.glb b/examples/bevy_registry_export/basic/assets/models/library/Health_Pickup.glb index 6454202..0361392 100644 Binary files a/examples/bevy_registry_export/basic/assets/models/library/Health_Pickup.glb and b/examples/bevy_registry_export/basic/assets/models/library/Health_Pickup.glb differ diff --git a/examples/bevy_registry_export/basic/assets/models/library/MagicTeapot.glb b/examples/bevy_registry_export/basic/assets/models/library/MagicTeapot.glb index a66129d..35b4638 100644 Binary files a/examples/bevy_registry_export/basic/assets/models/library/MagicTeapot.glb and b/examples/bevy_registry_export/basic/assets/models/library/MagicTeapot.glb differ diff --git a/examples/bevy_registry_export/basic/assets/models/library/Pillar.glb b/examples/bevy_registry_export/basic/assets/models/library/Pillar.glb index 08371d4..ca08896 100644 Binary files a/examples/bevy_registry_export/basic/assets/models/library/Pillar.glb and b/examples/bevy_registry_export/basic/assets/models/library/Pillar.glb differ diff --git a/examples/bevy_registry_export/basic/assets/models/library/Player.glb b/examples/bevy_registry_export/basic/assets/models/library/Player.glb index 81a30b8..e91658d 100644 Binary files a/examples/bevy_registry_export/basic/assets/models/library/Player.glb and b/examples/bevy_registry_export/basic/assets/models/library/Player.glb differ diff --git a/examples/bevy_registry_export/basic/assets/models/library/Unused_in_level_test.glb b/examples/bevy_registry_export/basic/assets/models/library/Unused_in_level_test.glb index c80b966..18b9054 100644 Binary files a/examples/bevy_registry_export/basic/assets/models/library/Unused_in_level_test.glb and b/examples/bevy_registry_export/basic/assets/models/library/Unused_in_level_test.glb differ diff --git a/testing/bevy_registry_export/basic/Cargo.toml b/testing/bevy_example/Cargo.toml similarity index 56% rename from testing/bevy_registry_export/basic/Cargo.toml rename to testing/bevy_example/Cargo.toml index da6df7f..9b8d995 100644 --- a/testing/bevy_registry_export/basic/Cargo.toml +++ b/testing/bevy_example/Cargo.toml @@ -1,14 +1,14 @@ [package] -name = "bevy_bevy_registry_export_basic_testing" +name = "bevy_example" version = "0.3.0" edition = "2021" license = "MIT OR Apache-2.0" [dependencies] bevy="0.12" -bevy_gltf_blueprints = { path = "../../../crates/bevy_gltf_blueprints" } -bevy_registry_export = { path = "../../../crates/bevy_registry_export" } -bevy_gltf_worlflow_examples_common = { path = "../../../examples/common" } +bevy_gltf_blueprints = { path = "../../crates/bevy_gltf_blueprints" } +bevy_registry_export = { path = "../../crates/bevy_registry_export" } +bevy_gltf_worlflow_examples_common = { path = "../../examples/common" } bevy_rapier3d = { version = "0.23.0", features = [ "serde-serialize", "debug-render-3d", "enhanced-determinism"] } bevy_asset_loader = { version = "0.18", features = ["standard_dynamic_assets" ]} diff --git a/testing/bevy_registry_export/basic/README.md b/testing/bevy_example/README.md similarity index 100% rename from testing/bevy_registry_export/basic/README.md rename to testing/bevy_example/README.md diff --git a/testing/bevy_registry_export/basic/assets/assets_core.assets.ron b/testing/bevy_example/assets/assets_core.assets.ron similarity index 100% rename from testing/bevy_registry_export/basic/assets/assets_core.assets.ron rename to testing/bevy_example/assets/assets_core.assets.ron diff --git a/testing/bevy_registry_export/basic/assets/assets_game.assets.ron b/testing/bevy_example/assets/assets_game.assets.ron similarity index 100% rename from testing/bevy_registry_export/basic/assets/assets_game.assets.ron rename to testing/bevy_example/assets/assets_game.assets.ron diff --git a/testing/bevy_registry_export/basic/assets/registry.json b/testing/bevy_example/assets/registry.json similarity index 97% rename from testing/bevy_registry_export/basic/assets/registry.json rename to testing/bevy_example/assets/registry.json index 86a81b7..e104314 100644 --- a/testing/bevy_registry_export/basic/assets/registry.json +++ b/testing/bevy_example/assets/registry.json @@ -71,19 +71,6 @@ "type": "array", "typeInfo": "List" }, - "alloc::vec::Vec": { - "isComponent": false, - "isResource": false, - "items": { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::TupleVec3" - } - }, - "short_name": "Vec", - "title": "alloc::vec::Vec", - "type": "array", - "typeInfo": "List" - }, "alloc::vec::Vec": { "isComponent": false, "isResource": false, @@ -97,6 +84,19 @@ "type": "array", "typeInfo": "List" }, + "alloc::vec::Vec": { + "isComponent": false, + "isResource": false, + "items": { + "type": { + "$ref": "#/$defs/bevy_example::test_components::TupleVec3" + } + }, + "short_name": "Vec", + "title": "alloc::vec::Vec", + "type": "array", + "typeInfo": "List" + }, "alloc::vec::Vec": { "isComponent": false, "isResource": false, @@ -648,7 +648,7 @@ "type": "object", "typeInfo": "Enum" }, - "bevy_asset::handle::Handle>": { + "bevy_asset::handle::Handle>": { "isComponent": true, "isResource": false, "oneOf": [ @@ -671,7 +671,7 @@ "prefixItems": [ { "type": { - "$ref": "#/$defs/bevy_asset::id::AssetId>" + "$ref": "#/$defs/bevy_asset::id::AssetId>" } } ], @@ -682,7 +682,7 @@ } ], "short_name": "Handle>", - "title": "bevy_asset::handle::Handle>", + "title": "bevy_asset::handle::Handle>", "type": "object", "typeInfo": "Enum" }, @@ -1656,7 +1656,7 @@ "type": "object", "typeInfo": "Enum" }, - "bevy_asset::id::AssetId>": { + "bevy_asset::id::AssetId>": { "isComponent": false, "isResource": false, "oneOf": [ @@ -1698,7 +1698,7 @@ } ], "short_name": "AssetId>", - "title": "bevy_asset::id::AssetId>", + "title": "bevy_asset::id::AssetId>", "type": "object", "typeInfo": "Enum" }, @@ -2208,489 +2208,6 @@ "type": "object", "typeInfo": "Enum" }, - "bevy_bevy_registry_export_basic_testing::test_components::AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut": { - "additionalProperties": false, - "isComponent": true, - "isResource": false, - "properties": {}, - "required": [], - "short_name": "AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut", - "title": "bevy_bevy_registry_export_basic_testing::test_components::AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut", - "type": "object", - "typeInfo": "Struct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::BasicTest": { - "additionalProperties": false, - "isComponent": true, - "isResource": false, - "properties": { - "a": { - "type": { - "$ref": "#/$defs/f32" - } - }, - "b": { - "type": { - "$ref": "#/$defs/u64" - } - }, - "c": { - "type": { - "$ref": "#/$defs/alloc::string::String" - } - } - }, - "required": [ - "a", - "b", - "c" - ], - "short_name": "BasicTest", - "title": "bevy_bevy_registry_export_basic_testing::test_components::BasicTest", - "type": "object", - "typeInfo": "Struct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::EnumComplex": { - "isComponent": true, - "isResource": false, - "oneOf": [ - { - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/f32" - } - } - ], - "short_name": "Float", - "title": "Float", - "type": "array", - "typeInfo": "Tuple" - }, - { - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/alloc::string::String" - } - } - ], - "short_name": "Wood", - "title": "Wood", - "type": "array", - "typeInfo": "Tuple" - }, - { - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::BasicTest" - } - } - ], - "short_name": "Vec", - "title": "Vec", - "type": "array", - "typeInfo": "Tuple" - }, - { - "title": "SomeThing" - }, - { - "additionalProperties": false, - "properties": { - "a": { - "title": "a", - "type": { - "$ref": "#/$defs/f32" - } - }, - "b": { - "title": "b", - "type": { - "$ref": "#/$defs/u32" - } - }, - "c": { - "title": "c", - "type": { - "$ref": "#/$defs/alloc::string::String" - } - } - }, - "required": [ - "a", - "b", - "c" - ], - "short_name": "StructLike", - "title": "StructLike", - "type": "object", - "typeInfo": "Struct" - }, - { - "title": "None" - } - ], - "short_name": "EnumComplex", - "title": "bevy_bevy_registry_export_basic_testing::test_components::EnumComplex", - "type": "object", - "typeInfo": "Enum" - }, - "bevy_bevy_registry_export_basic_testing::test_components::EnumTest": { - "isComponent": true, - "isResource": false, - "oneOf": [ - "Metal", - "Wood", - "Rock", - "Cloth", - "Squishy", - "None" - ], - "short_name": "EnumTest", - "title": "bevy_bevy_registry_export_basic_testing::test_components::EnumTest", - "type": "string", - "typeInfo": "Enum" - }, - "bevy_bevy_registry_export_basic_testing::test_components::NestedTupleStuff": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/f32" - } - }, - { - "type": { - "$ref": "#/$defs/u64" - } - }, - { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::NestingTestLevel2" - } - } - ], - "short_name": "NestedTupleStuff", - "title": "bevy_bevy_registry_export_basic_testing::test_components::NestedTupleStuff", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::NestingTestLevel2": { - "additionalProperties": false, - "isComponent": true, - "isResource": false, - "properties": { - "basic": { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::BasicTest" - } - }, - "color": { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::TupleTestColor" - } - }, - "colors_list": { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::VecOfColors" - } - }, - "enable": { - "type": { - "$ref": "#/$defs/bool" - } - }, - "enum_inner": { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::EnumTest" - } - }, - "nested": { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::NestingTestLevel3" - } - }, - "text": { - "type": { - "$ref": "#/$defs/alloc::string::String" - } - }, - "toggle": { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::TupleTestBool" - } - } - }, - "required": [ - "text", - "enable", - "enum_inner", - "color", - "toggle", - "basic", - "nested", - "colors_list" - ], - "short_name": "NestingTestLevel2", - "title": "bevy_bevy_registry_export_basic_testing::test_components::NestingTestLevel2", - "type": "object", - "typeInfo": "Struct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::NestingTestLevel3": { - "additionalProperties": false, - "isComponent": true, - "isResource": false, - "properties": { - "vec": { - "type": { - "$ref": "#/$defs/bevy_bevy_registry_export_basic_testing::test_components::TupleVec3" - } - } - }, - "required": [ - "vec" - ], - "short_name": "NestingTestLevel3", - "title": "bevy_bevy_registry_export_basic_testing::test_components::NestingTestLevel3", - "type": "object", - "typeInfo": "Struct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleTest2": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/f32" - } - }, - { - "type": { - "$ref": "#/$defs/u64" - } - }, - { - "type": { - "$ref": "#/$defs/alloc::string::String" - } - } - ], - "short_name": "TupleTest2", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleTest2", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleTestBool": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/bool" - } - } - ], - "short_name": "TupleTestBool", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleTestBool", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleTestColor": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/bevy_render::color::Color" - } - } - ], - "short_name": "TupleTestColor", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleTestColor", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleTestF32": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/f32" - } - } - ], - "short_name": "TupleTestF32", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleTestF32", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleTestStr": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/alloc::string::String" - } - } - ], - "short_name": "TupleTestStr", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleTestStr", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleTestU64": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/u64" - } - } - ], - "short_name": "TupleTestU64", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleTestU64", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleVec": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/alloc::vec::Vec" - } - } - ], - "short_name": "TupleVec", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleVec", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleVec2": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/glam::Vec2" - } - } - ], - "short_name": "TupleVec2", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleVec2", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleVec3": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/glam::Vec3" - } - } - ], - "short_name": "TupleVec3", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleVec3", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::TupleVecF32F32": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/alloc::vec::Vec<(f32, f32)>" - } - } - ], - "short_name": "TupleVecF32F32", - "title": "bevy_bevy_registry_export_basic_testing::test_components::TupleVecF32F32", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::UnitTest": { - "additionalProperties": false, - "isComponent": true, - "isResource": false, - "properties": {}, - "required": [], - "short_name": "UnitTest", - "title": "bevy_bevy_registry_export_basic_testing::test_components::UnitTest", - "type": "object", - "typeInfo": "Struct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::VecOfColors": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/alloc::vec::Vec" - } - } - ], - "short_name": "VecOfColors", - "title": "bevy_bevy_registry_export_basic_testing::test_components::VecOfColors", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::VecOfF32s": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/alloc::vec::Vec" - } - } - ], - "short_name": "VecOfF32s", - "title": "bevy_bevy_registry_export_basic_testing::test_components::VecOfF32s", - "type": "array", - "typeInfo": "TupleStruct" - }, - "bevy_bevy_registry_export_basic_testing::test_components::VecOfVec3s2": { - "isComponent": true, - "isResource": false, - "items": false, - "prefixItems": [ - { - "type": { - "$ref": "#/$defs/alloc::vec::Vec" - } - } - ], - "short_name": "VecOfVec3s2", - "title": "bevy_bevy_registry_export_basic_testing::test_components::VecOfVec3s2", - "type": "array", - "typeInfo": "TupleStruct" - }, "bevy_core::name::Name": { "additionalProperties": false, "isComponent": true, @@ -3083,6 +2600,489 @@ "type": "object", "typeInfo": "Struct" }, + "bevy_example::test_components::AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut": { + "additionalProperties": false, + "isComponent": true, + "isResource": false, + "properties": {}, + "required": [], + "short_name": "AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut", + "title": "bevy_example::test_components::AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut", + "type": "object", + "typeInfo": "Struct" + }, + "bevy_example::test_components::BasicTest": { + "additionalProperties": false, + "isComponent": true, + "isResource": false, + "properties": { + "a": { + "type": { + "$ref": "#/$defs/f32" + } + }, + "b": { + "type": { + "$ref": "#/$defs/u64" + } + }, + "c": { + "type": { + "$ref": "#/$defs/alloc::string::String" + } + } + }, + "required": [ + "a", + "b", + "c" + ], + "short_name": "BasicTest", + "title": "bevy_example::test_components::BasicTest", + "type": "object", + "typeInfo": "Struct" + }, + "bevy_example::test_components::EnumComplex": { + "isComponent": true, + "isResource": false, + "oneOf": [ + { + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/f32" + } + } + ], + "short_name": "Float", + "title": "Float", + "type": "array", + "typeInfo": "Tuple" + }, + { + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/alloc::string::String" + } + } + ], + "short_name": "Wood", + "title": "Wood", + "type": "array", + "typeInfo": "Tuple" + }, + { + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/bevy_example::test_components::BasicTest" + } + } + ], + "short_name": "Vec", + "title": "Vec", + "type": "array", + "typeInfo": "Tuple" + }, + { + "title": "SomeThing" + }, + { + "additionalProperties": false, + "properties": { + "a": { + "title": "a", + "type": { + "$ref": "#/$defs/f32" + } + }, + "b": { + "title": "b", + "type": { + "$ref": "#/$defs/u32" + } + }, + "c": { + "title": "c", + "type": { + "$ref": "#/$defs/alloc::string::String" + } + } + }, + "required": [ + "a", + "b", + "c" + ], + "short_name": "StructLike", + "title": "StructLike", + "type": "object", + "typeInfo": "Struct" + }, + { + "title": "None" + } + ], + "short_name": "EnumComplex", + "title": "bevy_example::test_components::EnumComplex", + "type": "object", + "typeInfo": "Enum" + }, + "bevy_example::test_components::EnumTest": { + "isComponent": true, + "isResource": false, + "oneOf": [ + "Metal", + "Wood", + "Rock", + "Cloth", + "Squishy", + "None" + ], + "short_name": "EnumTest", + "title": "bevy_example::test_components::EnumTest", + "type": "string", + "typeInfo": "Enum" + }, + "bevy_example::test_components::NestedTupleStuff": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/f32" + } + }, + { + "type": { + "$ref": "#/$defs/u64" + } + }, + { + "type": { + "$ref": "#/$defs/bevy_example::test_components::NestingTestLevel2" + } + } + ], + "short_name": "NestedTupleStuff", + "title": "bevy_example::test_components::NestedTupleStuff", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::NestingTestLevel2": { + "additionalProperties": false, + "isComponent": true, + "isResource": false, + "properties": { + "basic": { + "type": { + "$ref": "#/$defs/bevy_example::test_components::BasicTest" + } + }, + "color": { + "type": { + "$ref": "#/$defs/bevy_example::test_components::TupleTestColor" + } + }, + "colors_list": { + "type": { + "$ref": "#/$defs/bevy_example::test_components::VecOfColors" + } + }, + "enable": { + "type": { + "$ref": "#/$defs/bool" + } + }, + "enum_inner": { + "type": { + "$ref": "#/$defs/bevy_example::test_components::EnumTest" + } + }, + "nested": { + "type": { + "$ref": "#/$defs/bevy_example::test_components::NestingTestLevel3" + } + }, + "text": { + "type": { + "$ref": "#/$defs/alloc::string::String" + } + }, + "toggle": { + "type": { + "$ref": "#/$defs/bevy_example::test_components::TupleTestBool" + } + } + }, + "required": [ + "text", + "enable", + "enum_inner", + "color", + "toggle", + "basic", + "nested", + "colors_list" + ], + "short_name": "NestingTestLevel2", + "title": "bevy_example::test_components::NestingTestLevel2", + "type": "object", + "typeInfo": "Struct" + }, + "bevy_example::test_components::NestingTestLevel3": { + "additionalProperties": false, + "isComponent": true, + "isResource": false, + "properties": { + "vec": { + "type": { + "$ref": "#/$defs/bevy_example::test_components::TupleVec3" + } + } + }, + "required": [ + "vec" + ], + "short_name": "NestingTestLevel3", + "title": "bevy_example::test_components::NestingTestLevel3", + "type": "object", + "typeInfo": "Struct" + }, + "bevy_example::test_components::TupleTest2": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/f32" + } + }, + { + "type": { + "$ref": "#/$defs/u64" + } + }, + { + "type": { + "$ref": "#/$defs/alloc::string::String" + } + } + ], + "short_name": "TupleTest2", + "title": "bevy_example::test_components::TupleTest2", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::TupleTestBool": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/bool" + } + } + ], + "short_name": "TupleTestBool", + "title": "bevy_example::test_components::TupleTestBool", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::TupleTestColor": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/bevy_render::color::Color" + } + } + ], + "short_name": "TupleTestColor", + "title": "bevy_example::test_components::TupleTestColor", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::TupleTestF32": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/f32" + } + } + ], + "short_name": "TupleTestF32", + "title": "bevy_example::test_components::TupleTestF32", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::TupleTestStr": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/alloc::string::String" + } + } + ], + "short_name": "TupleTestStr", + "title": "bevy_example::test_components::TupleTestStr", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::TupleTestU64": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/u64" + } + } + ], + "short_name": "TupleTestU64", + "title": "bevy_example::test_components::TupleTestU64", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::TupleVec": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/alloc::vec::Vec" + } + } + ], + "short_name": "TupleVec", + "title": "bevy_example::test_components::TupleVec", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::TupleVec2": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/glam::Vec2" + } + } + ], + "short_name": "TupleVec2", + "title": "bevy_example::test_components::TupleVec2", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::TupleVec3": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/glam::Vec3" + } + } + ], + "short_name": "TupleVec3", + "title": "bevy_example::test_components::TupleVec3", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::TupleVecF32F32": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/alloc::vec::Vec<(f32, f32)>" + } + } + ], + "short_name": "TupleVecF32F32", + "title": "bevy_example::test_components::TupleVecF32F32", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::UnitTest": { + "additionalProperties": false, + "isComponent": true, + "isResource": false, + "properties": {}, + "required": [], + "short_name": "UnitTest", + "title": "bevy_example::test_components::UnitTest", + "type": "object", + "typeInfo": "Struct" + }, + "bevy_example::test_components::VecOfColors": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/alloc::vec::Vec" + } + } + ], + "short_name": "VecOfColors", + "title": "bevy_example::test_components::VecOfColors", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::VecOfF32s": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/alloc::vec::Vec" + } + } + ], + "short_name": "VecOfF32s", + "title": "bevy_example::test_components::VecOfF32s", + "type": "array", + "typeInfo": "TupleStruct" + }, + "bevy_example::test_components::VecOfVec3s2": { + "isComponent": true, + "isResource": false, + "items": false, + "prefixItems": [ + { + "type": { + "$ref": "#/$defs/alloc::vec::Vec" + } + } + ], + "short_name": "VecOfVec3s2", + "title": "bevy_example::test_components::VecOfVec3s2", + "type": "array", + "typeInfo": "TupleStruct" + }, "bevy_gltf::GltfExtras": { "additionalProperties": false, "isComponent": true, diff --git a/testing/bevy_example/assets/testing.blend b/testing/bevy_example/assets/testing.blend new file mode 100644 index 0000000..4b2fdbf Binary files /dev/null and b/testing/bevy_example/assets/testing.blend differ diff --git a/testing/bevy_example/expected_screenshot.png b/testing/bevy_example/expected_screenshot.png new file mode 100644 index 0000000..f0e0e70 Binary files /dev/null and b/testing/bevy_example/expected_screenshot.png differ diff --git a/testing/bevy_registry_export/basic/src/core/mod.rs b/testing/bevy_example/src/core/mod.rs similarity index 100% rename from testing/bevy_registry_export/basic/src/core/mod.rs rename to testing/bevy_example/src/core/mod.rs diff --git a/testing/bevy_registry_export/basic/src/game/in_game.rs b/testing/bevy_example/src/game/in_game.rs similarity index 100% rename from testing/bevy_registry_export/basic/src/game/in_game.rs rename to testing/bevy_example/src/game/in_game.rs diff --git a/testing/bevy_example/src/game/mod.rs b/testing/bevy_example/src/game/mod.rs new file mode 100644 index 0000000..38145f0 --- /dev/null +++ b/testing/bevy_example/src/game/mod.rs @@ -0,0 +1,109 @@ +pub mod in_game; +use std::{ + fs::{self}, + time::Duration, +}; + +use bevy_gltf_blueprints::{AnimationPlayerLink, BlueprintName}; +pub use in_game::*; + +use bevy::{ + prelude::*, render::view::screenshot::ScreenshotManager, time::common_conditions::on_timer, + window::PrimaryWindow, +}; +use bevy_gltf_worlflow_examples_common::{AppState, GameState}; + +use crate::{TupleTestF32, UnitTest}; + +fn start_game(mut next_app_state: ResMut>) { + next_app_state.set(AppState::AppLoading); +} + +// if the export from Blender worked correctly, we should have animations (simplified here by using AnimationPlayerLink) +// if the export from Blender worked correctly, we should have an Entity called "Cylinder" that has two components: UnitTest, TupleTestF32 +// if the export from Blender worked correctly, we should have an Entity called "Blueprint4_nested" that has a child called "Blueprint3" that has a "BlueprintName" component with value Blueprint3 + +fn validate_export( + parents: Query<&Parent>, + children: Query<&Children>, + names: Query<&Name>, + blueprints: Query<(Entity, &Name, &BlueprintName)>, + animation_player_links: Query<(Entity, &AnimationPlayerLink)>, + exported_cylinder: Query<(Entity, &Name, &UnitTest, &TupleTestF32)>, + empties_candidates: Query<(Entity, &Name, &GlobalTransform)>, +) { + let animations_found = !animation_player_links.is_empty(); + + let mut cylinder_found = false; + if let Ok(nested_cylinder) = exported_cylinder.get_single() { + let parent_name = names + .get(parents.get(nested_cylinder.0).unwrap().get()) + .unwrap(); + cylinder_found = parent_name.to_string() == *"Cube.001" + && nested_cylinder.1.to_string() == *"Cylinder" + && nested_cylinder.3 .0 == 75.1; + } + + let mut nested_blueprint_found = false; + for (entity, name, blueprint_name) in blueprints.iter() { + if name.to_string() == *"Blueprint4_nested" && blueprint_name.0 == *"Blueprint4_nested" { + if let Ok(cur_children) = children.get(entity) { + for child in cur_children.iter() { + if let Ok((_, child_name, child_blueprint_name)) = blueprints.get(*child) { + if child_name.to_string() == *"Blueprint3" + && child_blueprint_name.0 == *"Blueprint3" + { + nested_blueprint_found = true; + } + } + } + } + } + } + + let mut empty_found = false; + for (_, name, _) in empties_candidates.iter() { + if name.to_string() == *"Empty" { + empty_found = true; + break; + } + } + + fs::write( + "bevy_diagnostics.json", + format!( + "{{ \"animations\": {}, \"cylinder_found\": {} , \"nested_blueprint_found\": {}, \"empty_found\": {} }}", + animations_found, cylinder_found, nested_blueprint_found, empty_found + ), + ) + .expect("Unable to write file"); +} + +fn generate_screenshot( + main_window: Query>, + mut screenshot_manager: ResMut, +) { + screenshot_manager + .save_screenshot_to_disk(main_window.single(), "screenshot.png") + .unwrap(); +} + +fn exit_game(mut app_exit_events: ResMut>) { + app_exit_events.send(bevy::app::AppExit); +} + +pub struct GamePlugin; +impl Plugin for GamePlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, (spawn_test).run_if(in_state(GameState::InGame))) + .add_systems(Update, validate_export) + .add_systems(Update, generate_screenshot.run_if(on_timer(Duration::from_secs_f32(0.2)))) // TODO: run once + .add_systems(OnEnter(AppState::MenuRunning), start_game) + .add_systems(OnEnter(AppState::AppRunning), setup_game) + .add_systems( + Update, + exit_game.run_if(on_timer(Duration::from_secs_f32(0.5))), + ) // shut down the app after this time + ; + } +} diff --git a/testing/bevy_registry_export/basic/src/main.rs b/testing/bevy_example/src/main.rs similarity index 100% rename from testing/bevy_registry_export/basic/src/main.rs rename to testing/bevy_example/src/main.rs diff --git a/testing/bevy_registry_export/basic/src/test_components.rs b/testing/bevy_example/src/test_components.rs similarity index 98% rename from testing/bevy_registry_export/basic/src/test_components.rs rename to testing/bevy_example/src/test_components.rs index 58a19c2..8c340e1 100644 --- a/testing/bevy_registry_export/basic/src/test_components.rs +++ b/testing/bevy_example/src/test_components.rs @@ -7,11 +7,11 @@ use std::ops::Range; #[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] -struct UnitTest; +pub struct UnitTest; #[derive(Component, Reflect, Default, Debug, Deref, DerefMut)] #[reflect(Component)] -struct TupleTestF32(f32); +pub struct TupleTestF32(pub f32); #[derive(Component, Reflect, Default, Debug, Deref, DerefMut)] #[reflect(Component)] diff --git a/testing/bevy_registry_export/basic/assets/basic.blend b/testing/bevy_registry_export/basic/assets/basic.blend deleted file mode 100644 index 532628b..0000000 Binary files a/testing/bevy_registry_export/basic/assets/basic.blend and /dev/null differ diff --git a/testing/bevy_registry_export/basic/assets/models/World.glb b/testing/bevy_registry_export/basic/assets/models/World.glb deleted file mode 100644 index 81caa9d..0000000 Binary files a/testing/bevy_registry_export/basic/assets/models/World.glb and /dev/null differ diff --git a/testing/bevy_registry_export/basic/assets/models/library/Container.glb b/testing/bevy_registry_export/basic/assets/models/library/Container.glb deleted file mode 100644 index 5818d2c..0000000 Binary files a/testing/bevy_registry_export/basic/assets/models/library/Container.glb and /dev/null differ diff --git a/testing/bevy_registry_export/basic/assets/models/library/Health_Pickup.glb b/testing/bevy_registry_export/basic/assets/models/library/Health_Pickup.glb deleted file mode 100644 index f5d97cb..0000000 Binary files a/testing/bevy_registry_export/basic/assets/models/library/Health_Pickup.glb and /dev/null differ diff --git a/testing/bevy_registry_export/basic/assets/models/library/MagicTeapot.glb b/testing/bevy_registry_export/basic/assets/models/library/MagicTeapot.glb deleted file mode 100644 index 47c37cd..0000000 Binary files a/testing/bevy_registry_export/basic/assets/models/library/MagicTeapot.glb and /dev/null differ diff --git a/testing/bevy_registry_export/basic/assets/models/library/Pillar.glb b/testing/bevy_registry_export/basic/assets/models/library/Pillar.glb deleted file mode 100644 index 9a6f3e0..0000000 Binary files a/testing/bevy_registry_export/basic/assets/models/library/Pillar.glb and /dev/null differ diff --git a/testing/bevy_registry_export/basic/assets/models/library/Player.glb b/testing/bevy_registry_export/basic/assets/models/library/Player.glb deleted file mode 100644 index 2d749b2..0000000 Binary files a/testing/bevy_registry_export/basic/assets/models/library/Player.glb and /dev/null differ diff --git a/testing/bevy_registry_export/basic/assets/models/library/Unused_in_level_test.glb b/testing/bevy_registry_export/basic/assets/models/library/Unused_in_level_test.glb deleted file mode 100644 index c80b966..0000000 Binary files a/testing/bevy_registry_export/basic/assets/models/library/Unused_in_level_test.glb and /dev/null differ diff --git a/testing/bevy_registry_export/basic/src/game/in_main_menu.rs b/testing/bevy_registry_export/basic/src/game/in_main_menu.rs deleted file mode 100644 index 32142cd..0000000 --- a/testing/bevy_registry_export/basic/src/game/in_main_menu.rs +++ /dev/null @@ -1,98 +0,0 @@ -use bevy::prelude::*; -use bevy_gltf_worlflow_examples_common::{AppState, InMainMenu}; - -pub fn setup_main_menu(mut commands: Commands) { - commands.spawn((Camera2dBundle::default(), InMainMenu)); - - commands.spawn(( - TextBundle::from_section( - "SOME GAME TITLE !!", - TextStyle { - //font: asset_server.load("fonts/FiraMono-Medium.ttf"), - font_size: 18.0, - color: Color::WHITE, - ..Default::default() - }, - ) - .with_style(Style { - position_type: PositionType::Absolute, - top: Val::Px(100.0), - left: Val::Px(200.0), - ..default() - }), - InMainMenu, - )); - - commands.spawn(( - TextBundle::from_section( - "New Game (press Enter to start, press T once the game is started for demo spawning)", - TextStyle { - //font: asset_server.load("fonts/FiraMono-Medium.ttf"), - font_size: 18.0, - color: Color::WHITE, - ..Default::default() - }, - ) - .with_style(Style { - position_type: PositionType::Absolute, - top: Val::Px(200.0), - left: Val::Px(200.0), - ..default() - }), - InMainMenu, - )); - - /* - commands.spawn(( - TextBundle::from_section( - "Load Game", - TextStyle { - //font: asset_server.load("fonts/FiraMono-Medium.ttf"), - font_size: 18.0, - color: Color::WHITE, - ..Default::default() - }, - ) - .with_style(Style { - position_type: PositionType::Absolute, - top: Val::Px(250.0), - left: Val::Px(200.0), - ..default() - }), - InMainMenu - )); - - commands.spawn(( - TextBundle::from_section( - "Exit Game", - TextStyle { - //font: asset_server.load("fonts/FiraMono-Medium.ttf"), - font_size: 18.0, - color: Color::WHITE, - ..Default::default() - }, - ) - .with_style(Style { - position_type: PositionType::Absolute, - top: Val::Px(300.0), - left: Val::Px(200.0), - ..default() - }), - InMainMenu - ));*/ -} - -pub fn teardown_main_menu(bla: Query>, mut commands: Commands) { - for bli in bla.iter() { - commands.entity(bli).despawn_recursive(); - } -} - -pub fn main_menu( - keycode: Res>, - mut next_app_state: ResMut>, -) { - if keycode.just_pressed(KeyCode::Enter) { - next_app_state.set(AppState::AppLoading); - } -} diff --git a/testing/bevy_registry_export/basic/src/game/mod.rs b/testing/bevy_registry_export/basic/src/game/mod.rs deleted file mode 100644 index b236141..0000000 --- a/testing/bevy_registry_export/basic/src/game/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -pub mod in_game; -pub use in_game::*; - -pub mod in_main_menu; -pub use in_main_menu::*; - -use bevy::prelude::*; -use bevy_gltf_worlflow_examples_common::{AppState, GameState}; - -pub struct GamePlugin; -impl Plugin for GamePlugin { - fn build(&self, app: &mut App) { - app.add_systems( - Update, - (spawn_test, spawn_test_unregisted_components).run_if(in_state(GameState::InGame)), - ) - .add_systems(OnEnter(AppState::MenuRunning), setup_main_menu) - .add_systems(OnExit(AppState::MenuRunning), teardown_main_menu) - .add_systems(Update, main_menu.run_if(in_state(AppState::MenuRunning))) - .add_systems(OnEnter(AppState::AppRunning), setup_game); - } -} diff --git a/tools/bevy_components/README.md b/tools/bevy_components/README.md index 2c385d3..d871271 100644 --- a/tools/bevy_components/README.md +++ b/tools/bevy_components/README.md @@ -18,6 +18,8 @@ of your Bevy components you get a nicely packed custom_property to use with ... > IMPORTANT !! if you have previously used v0.1 , v0.2 had a breaking change, please see [this](#regenerate-ui-values) section on how to upgrade your data to v0.2.\ This problem should not be present going forward +> IMPORTANT !! if you have previously used v0.2 , v0.3 had a breaking change, please see [this](#regenerate-custom-property-values) section on how to upgrade your data to v0.3. + ## Installation: * grab the latest release zip file from the releases tab (choose the bevy_components releases !) @@ -206,6 +208,9 @@ It will add the component to the select object ![update custom properties for all](./docs/other_options2.png) + > IMPORTANT !! use this if you have previously used v0.1 or v0.2 , as v0.3 had a breaking change, that makes it **necessary** to use this **once** to upgrade components data + You should also re-export your gltf files , otherwise you might run into issues + ### regenerate UI values diff --git a/tools/bevy_components/TODO.md b/tools/bevy_components/TODO.md index a18dd11..0fa7f88 100644 --- a/tools/bevy_components/TODO.md +++ b/tools/bevy_components/TODO.md @@ -192,7 +192,7 @@ UI: - [x] fix enums (see Clusterconfig) - [x] need an example with one tupple one struct - [x] projection - - [ ] additionalmassproperties + - [x] additionalmassproperties - [x] fix tupleStructs (see TupleVecF32F32) => always the same problem of having us pre-parse data without knowing what we have inside - find a way to only split by level 0 (highest level) nesting "," seperators, ignoring any level of nesting until we dig one level deeper - solve nesting level use issues diff --git a/tools/bevy_components/__init__.py b/tools/bevy_components/__init__.py index 74637f0..6088927 100644 --- a/tools/bevy_components/__init__.py +++ b/tools/bevy_components/__init__.py @@ -1,7 +1,7 @@ bl_info = { "name": "bevy_components", "author": "kaosigh", - "version": (0, 2, 0), + "version": (0, 3, 0), "blender": (3, 4, 0), "location": "VIEW_3D", "description": "UI to help create Bevy blueprints and components", diff --git a/tools/bevy_components/propGroups/conversions_from_prop_group.py b/tools/bevy_components/propGroups/conversions_from_prop_group.py index c1d5c61..6fadb30 100644 --- a/tools/bevy_components/propGroups/conversions_from_prop_group.py +++ b/tools/bevy_components/propGroups/conversions_from_prop_group.py @@ -6,6 +6,7 @@ conversion_tables = { "char": lambda value: '"'+value+'"', "str": lambda value: '"'+value+'"', "alloc::string::String": lambda value: '"'+value+'"', + "alloc::borrow::Cow": lambda value: '"'+value+'"', "glam::Vec2": lambda value: "Vec2(x:"+str(value[0])+ ", y:"+str(value[1])+")", "glam::DVec2": lambda value: "DVec2(x:"+str(value[0])+ ", y:"+str(value[1])+")", @@ -39,7 +40,7 @@ def property_group_value_to_custom_property_value(property_group, definition, re elif type_info == "Struct": values = {} if len(property_group.field_names) ==0: - value = '' + value = '()' else: for index, field_name in enumerate(property_group.field_names): item_type_name = definition["properties"][field_name]["type"]["$ref"].replace("#/$defs/", "") @@ -137,7 +138,6 @@ def property_group_value_to_custom_property_value(property_group, definition, re value = conversion_tables[type_name](value) if is_value_type else value value = '""' if isinstance(value, PropertyGroup) else value - #print("generating custom property value", value, type(value)) if isinstance(value, str): value = value.replace("'", "") diff --git a/tools/bevy_components/propGroups/conversions_to_prop_group.py b/tools/bevy_components/propGroups/conversions_to_prop_group.py index 1bbfde2..d34c2a2 100644 --- a/tools/bevy_components/propGroups/conversions_to_prop_group.py +++ b/tools/bevy_components/propGroups/conversions_to_prop_group.py @@ -161,6 +161,8 @@ type_mappings = { "glam::Quat": lambda value: parse_vec4(value, float, "Quat"), 'alloc::string::String': lambda value: str(value.replace('"', "")), + 'alloc::borrow::Cow': lambda value: str(value.replace('"', "")), + 'bevy_render::color::Color': lambda value: parse_color(value, float, "Rgba"), 'bevy_ecs::Entity': lambda value: int(value), } diff --git a/tools/bevy_components/registry/registry.py b/tools/bevy_components/registry/registry.py index 9312cbf..abc1970 100644 --- a/tools/bevy_components/registry/registry.py +++ b/tools/bevy_components/registry/registry.py @@ -31,7 +31,7 @@ def toggle_watcher(self, context): def watch_schema(): self = bpy.context.window_manager.components_registry - print("watching schema file for changes") + # print("watching schema file for changes") try: stamp = os.stat(self.schemaFullPath).st_mtime stamp = str(stamp) diff --git a/tools/bevy_components/tests/expected_component_values.py b/tools/bevy_components/tests/expected_component_values.py index 533a6d8..de5cedf 100644 --- a/tools/bevy_components/tests/expected_component_values.py +++ b/tools/bevy_components/tests/expected_component_values.py @@ -1,6 +1,6 @@ -expected_custom_property_values = {'AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut': '', +expected_custom_property_values = {'AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut': '()', 'Aabb': '(center: Vec3A(x:0.0, y:0.0, z:0.0), half_extents: Vec3A(x:0.0, y:0.0, z:0.0))', 'AdditionalMassProperties': 'Mass(0.0)', 'AmbientLightSettings': '(brightness: 0.0, color: Rgba(red:1.0, green:1.0, blue:0.0, alpha:1.0))', @@ -14,20 +14,20 @@ expected_custom_property_values = {'AComponentWithAnExtremlyExageratedOrMaybeNot '0.0))', 'BlueprintName': '(" ")', 'BorderColor': '(Rgba(red:1.0, green:1.0, blue:0.0, alpha:1.0))', - 'Button': '', + 'Button': '()', 'CalculatedClip': '(clip: (max: Vec2(x:0.0, y:0.0), min: Vec2(x:0.0, y:0.0)))', 'Camera': '(hdr: true, is_active: true, msaa_writeback: true, order: 0, viewport: None)', 'Camera2d': '(clear_color: Default)', 'Camera3d': '(clear_color: Default, depth_load_op: Clear(0.0), depth_texture_usages: "", ' 'screen_space_specular_transmission_quality: "", screen_space_specular_transmission_steps: 0)', - 'CameraRenderGraph': '( )', - 'CameraTrackable': '', + 'CameraRenderGraph': '(" ")', + 'CameraTrackable': '()', 'CameraTracking': '(offset: Vec3(x:0.0, y:0.0, z:0.0))', 'CameraTrackingOffset': '(Vec3(x:0.0, y:0.0, z:0.0))', 'CascadeShadowConfig': '(bounds: [], minimum_distance: 0.0, overlap_proportion: 0.0)', 'Cascades': '(cascades: "")', - 'CascadesFrusta': '', - 'CascadesVisibleEntities': '', + 'CascadesFrusta': '()', + 'CascadesVisibleEntities': '()', 'Ccd': '(enabled: true)', 'Children': '([])', 'ClusterConfig': 'None', @@ -36,10 +36,10 @@ expected_custom_property_values = {'AComponentWithAnExtremlyExageratedOrMaybeNot 'CollisionGroups': '(filters: (0), memberships: (0))', 'ColorGrading': '(exposure: 0.0, gamma: 0.0, post_saturation: 0.0, pre_saturation: 0.0)', 'ContactForceEventThreshold': '(0.0)', - 'ContentSize': '', + 'ContentSize': '()', 'ContrastAdaptiveSharpeningSettings': '(denoise: true, enabled: true, sharpening_strength: 0.0)', - 'CubemapFrusta': '', - 'CubemapVisibleEntities': '', + 'CubemapFrusta': '()', + 'CubemapVisibleEntities': '()', 'Damping': '(angular_damping: 0.0, linear_damping: 0.0)', 'DebandDither': 'Disabled', 'DirectionalLight': '(color: Rgba(red:1.0, green:1.0, blue:0.0, alpha:1.0), illuminance: 0.0, shadow_depth_bias: 0.0, ' @@ -53,7 +53,7 @@ expected_custom_property_values = {'AComponentWithAnExtremlyExageratedOrMaybeNot 'FogSettings': '(color: Rgba(red:1.0, green:1.0, blue:0.0, alpha:1.0), directional_light_color: Rgba(red:1.0, ' 'green:1.0, blue:0.0, alpha:1.0), directional_light_exponent: 0.0, falloff: "")', 'Friction': '(coefficient: 0.0, combine_rule: "")', - 'Frustum': '', + 'Frustum': '()', 'Fxaa': '(edge_threshold: "", edge_threshold_min: "", enabled: true)', 'GlobalTransform': '((matrix3: (x_axis: Vec3A(x:0.0, y:0.0, z:0.0), y_axis: Vec3A(x:0.0, y:0.0, z:0.0), z_axis: ' 'Vec3A(x:0.0, y:0.0, z:0.0)), translation: Vec3A(x:0.0, y:0.0, z:0.0)))', @@ -86,13 +86,13 @@ expected_custom_property_values = {'AComponentWithAnExtremlyExageratedOrMaybeNot 'Handle': 'Strong("")', 'InheritedVisibility': '(true)', 'Interaction': 'Pressed', - 'Label': '', + 'Label': '()', 'LockedAxes': '(0)', 'MaterialInfo': '(name: " ", source: " ")', 'Mesh2dHandle': '(Strong(""))', 'MeshMorphWeights': '(weights: [])', 'MorphWeights': '(first_mesh: "", weights: [])', - 'Name': '(hash: 0, name: )', + 'Name': '(hash: 0, name: " ")', 'NestedTupleStuff': '(0.0, 0, (basic: (a: 0.0, b: 0, c: " "), color: (Rgba(red:1.0, green:1.0, blue:0.0, alpha:1.0)), ' 'colors_list: ([]), enable: true, enum_inner: Metal, nested: (vec: (Vec3(x:0.0, y:0.0, z:0.0))), ' 'text: " ", toggle: (true)))', @@ -100,37 +100,37 @@ expected_custom_property_values = {'AComponentWithAnExtremlyExageratedOrMaybeNot 'colors_list: ([]), enable: true, enum_inner: Metal, nested: (vec: (Vec3(x:0.0, y:0.0, z:0.0))), ' 'text: " ", toggle: (true))', 'NestingTestLevel3': '(vec: (Vec3(x:0.0, y:0.0, z:0.0)))', - 'NoFrustumCulling': '', - 'NoWireframe': '', + 'NoFrustumCulling': '()', + 'NoWireframe': '()', 'Node': '(calculated_size: Vec2(x:0.0, y:0.0), outline_offset: 0.0, outline_width: 0.0, stack_index: 0, ' 'unrounded_size: Vec2(x:0.0, y:0.0))', - 'NotShadowCaster': '', - 'NotShadowReceiver': '', + 'NotShadowCaster': '()', + 'NotShadowReceiver': '()', 'OrthographicProjection': '(area: (max: Vec2(x:0.0, y:0.0), min: Vec2(x:0.0, y:0.0)), far: 0.0, near: 0.0, scale: ' '0.0, scaling_mode: Fixed(height: 0.0, width: 0.0), viewport_origin: Vec2(x:0.0, y:0.0))', 'Outline': '(color: Rgba(red:1.0, green:1.0, blue:0.0, alpha:1.0), offset: Auto, width: Auto)', 'Parent': '(0)', 'PerspectiveProjection': '(aspect_ratio: 0.0, far: 0.0, fov: 0.0, near: 0.0)', - 'Pickable': '', - 'Player': '', + 'Pickable': '()', + 'Player': '()', 'PointLight': '(color: Rgba(red:1.0, green:1.0, blue:0.0, alpha:1.0), intensity: 0.0, radius: 0.0, range: 0.0, ' 'shadow_depth_bias: 0.0, shadow_normal_bias: 0.0, shadows_enabled: true)', - 'PrimaryWindow': '', + 'PrimaryWindow': '()', 'Projection': 'Perspective((aspect_ratio: 0.0, far: 0.0, fov: 0.0, near: 0.0))', 'RelativeCursorPosition': '(normalized: "", normalized_visible_node_rect: (max: Vec2(x:0.0, y:0.0), min: Vec2(x:0.0, ' 'y:0.0)))', 'RenderLayers': '(0)', 'Restitution': '(coefficient: 0.0, combine_rule: "")', 'RigidBody': 'Dynamic', - 'SSAOSettings': '', + 'SSAOSettings': '()', 'ScreenSpaceAmbientOcclusionSettings': '(quality_level: "")', - 'Sensor': '', + 'Sensor': '()', 'ShadowFilteringMethod': 'Hardware2x2', 'ShadowmapSettings': '(size: 0)', 'SkinnedMesh': '(inverse_bindposes: Strong(""), joints: [])', 'Sleeping': '(angular_threshold: 0.0, linear_threshold: 0.0, sleeping: true)', 'SolverGroups': '(filters: (0), memberships: (0))', - 'SpawnHere': '', + 'SpawnHere': '()', 'SpotLight': '(color: Rgba(red:1.0, green:1.0, blue:0.0, alpha:1.0), inner_angle: 0.0, intensity: 0.0, outer_angle: ' '0.0, radius: 0.0, range: 0.0, shadow_depth_bias: 0.0, shadow_normal_bias: 0.0, shadows_enabled: true)', 'Sprite': '(anchor: Center, color: Rgba(red:1.0, green:1.0, blue:0.0, alpha:1.0), custom_size: "", flip_x: true, ' @@ -167,14 +167,14 @@ expected_custom_property_values = {'AComponentWithAnExtremlyExageratedOrMaybeNot 'UiImage': '(flip_x: true, flip_y: true, texture: Strong(""))', 'UiImageSize': '(size: Vec2(x:0.0, y:0.0))', 'UiTextureAtlasImage': '(flip_x: true, flip_y: true, index: 0)', - 'UnitTest': '', + 'UnitTest': '()', 'VecOfColors': '([])', 'VecOfF32s': '([])', 'VecOfVec3s2': '([])', 'Velocity': '(angvel: Vec3(x:0.0, y:0.0, z:0.0), linvel: Vec3(x:0.0, y:0.0, z:0.0))', 'ViewVisibility': '(true)', 'Visibility': 'Inherited', - 'VisibleEntities': '', + 'VisibleEntities': '()', 'Window': '(canvas: None, composite_alpha_mode: Auto, cursor: (grab_mode: None, hit_test: true, icon: Default, ' 'visible: true), decorations: true, enabled_buttons: (close: true, maximize: true, minimize: true), ' 'fit_canvas_to_parent: true, focused: true, ime_enabled: true, ime_position: Vec2(x:0.0, y:0.0), internal: ' @@ -183,12 +183,13 @@ expected_custom_property_values = {'AComponentWithAnExtremlyExageratedOrMaybeNot 'resize_constraints: (max_height: 0.0, max_width: 0.0, min_height: 0.0, min_width: 0.0), resolution: ' '(physical_height: 0, physical_width: 0, scale_factor: 0.0, scale_factor_override: None), title: " ", ' 'transparent: true, visible: true, window_level: AlwaysOnBottom, window_theme: "")', - 'Wireframe': '', + 'Wireframe': '()', 'ZIndex': 'Local(0)'} -expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut': '', + +expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut': '()', 'Aabb': '(center: Vec3A(x:0.5714026093482971, y:0.42888906598091125, z:0.5780913233757019), half_extents: ' 'Vec3A(x:0.20609822869300842, y:0.8133212327957153, z:0.8235888481140137))', 'AdditionalMassProperties': 'Mass(0.42888906598091125)', @@ -207,22 +208,22 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate 'BlueprintName': '("sbnpsago")', 'BorderColor': '(Rgba(red:0.5714026093482971, green:0.42888906598091125, blue:0.5780913233757019, ' 'alpha:0.20609822869300842))', - 'Button': '', + 'Button': '()', 'CalculatedClip': '(clip: (max: Vec2(x:0.5714026093482971, y:0.42888906598091125), min: Vec2(x:0.5780913233757019, ' 'y:0.20609822869300842)))', 'Camera': '(hdr: true, is_active: false, msaa_writeback: false, order: 61, viewport: None)', 'Camera2d': '(clear_color: None)', 'Camera3d': '(clear_color: None, depth_load_op: Clear(0.42888906598091125), depth_texture_usages: "", ' 'screen_space_specular_transmission_quality: "", screen_space_specular_transmission_steps: 73)', - 'CameraRenderGraph': '(sbnpsago)', - 'CameraTrackable': '', + 'CameraRenderGraph': '("sbnpsago")', + 'CameraTrackable': '()', 'CameraTracking': '(offset: Vec3(x:0.5714026093482971, y:0.42888906598091125, z:0.5780913233757019))', 'CameraTrackingOffset': '(Vec3(x:0.5714026093482971, y:0.42888906598091125, z:0.5780913233757019))', 'CascadeShadowConfig': '(bounds: [0.42888906598091125], minimum_distance: 0.5780913233757019, overlap_proportion: ' '0.20609822869300842)', 'Cascades': '(cascades: "")', - 'CascadesFrusta': '', - 'CascadesVisibleEntities': '', + 'CascadesFrusta': '()', + 'CascadesVisibleEntities': '()', 'Ccd': '(enabled: true)', 'Children': '([0])', 'ClusterConfig': 'None', @@ -232,10 +233,10 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate 'ColorGrading': '(exposure: 0.5714026093482971, gamma: 0.42888906598091125, post_saturation: 0.5780913233757019, ' 'pre_saturation: 0.20609822869300842)', 'ContactForceEventThreshold': '(0.5714026093482971)', - 'ContentSize': '', + 'ContentSize': '()', 'ContrastAdaptiveSharpeningSettings': '(denoise: true, enabled: false, sharpening_strength: 0.42888906598091125)', - 'CubemapFrusta': '', - 'CubemapVisibleEntities': '', + 'CubemapFrusta': '()', + 'CubemapVisibleEntities': '()', 'Damping': '(angular_damping: 0.5714026093482971, linear_damping: 0.42888906598091125)', 'DebandDither': 'Disabled', 'DirectionalLight': '(color: Rgba(red:0.5714026093482971, green:0.42888906598091125, blue:0.5780913233757019, ' @@ -254,7 +255,7 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate 'green:0.8235888481140137, blue:0.6534725427627563, alpha:0.16022956371307373), ' 'directional_light_exponent: 0.5206693410873413, falloff: "")', 'Friction': '(coefficient: 0.5714026093482971, combine_rule: "")', - 'Frustum': '', + 'Frustum': '()', 'Fxaa': '(edge_threshold: "", edge_threshold_min: "", enabled: true)', 'GlobalTransform': '((matrix3: (x_axis: Vec3A(x:0.5714026093482971, y:0.42888906598091125, z:0.5780913233757019), ' 'y_axis: Vec3A(x:0.20609822869300842, y:0.8133212327957153, z:0.8235888481140137), z_axis: ' @@ -289,13 +290,13 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate 'Handle': 'Strong("")', 'InheritedVisibility': '(true)', 'Interaction': 'None', - 'Label': '', + 'Label': '()', 'LockedAxes': '(73)', 'MaterialInfo': '(name: "sbnpsago", source: "piuzfbqp")', 'Mesh2dHandle': '(Strong(""))', 'MeshMorphWeights': '(weights: [0.42888906598091125])', 'MorphWeights': '(first_mesh: "", weights: [0.42888906598091125])', - 'Name': '(hash: 73, name: bnpsagop)', + 'Name': '(hash: 73, name: "bnpsagop")', 'NestedTupleStuff': '(0.5714026093482971, 54, (basic: (a: 0.4825616776943207, b: 1, c: "gopiuzfb"), color: ' '(Rgba(red:0.5206693410873413, green:0.3277728259563446, blue:0.24999667704105377, ' 'alpha:0.952816903591156)), colors_list: ([Rgba(red:0.0445563830435276, green:0.8601610660552979, ' @@ -311,13 +312,13 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate '(vec: (Vec3(x:0.1329781413078308, y:0.7678378224372864, z:0.9824132323265076))), text: ' '"otmbsahe", toggle: (false))', 'NestingTestLevel3': '(vec: (Vec3(x:0.5714026093482971, y:0.42888906598091125, z:0.5780913233757019)))', - 'NoFrustumCulling': '', - 'NoWireframe': '', + 'NoFrustumCulling': '()', + 'NoWireframe': '()', 'Node': '(calculated_size: Vec2(x:0.5714026093482971, y:0.42888906598091125), outline_offset: 0.5780913233757019, ' 'outline_width: 0.20609822869300842, stack_index: 62, unrounded_size: Vec2(x:0.8235888481140137, ' 'y:0.6534725427627563))', - 'NotShadowCaster': '', - 'NotShadowReceiver': '', + 'NotShadowCaster': '()', + 'NotShadowReceiver': '()', 'OrthographicProjection': '(area: (max: Vec2(x:0.5714026093482971, y:0.42888906598091125), min: ' 'Vec2(x:0.5780913233757019, y:0.20609822869300842)), far: 0.8133212327957153, near: ' '0.8235888481140137, scale: 0.6534725427627563, scaling_mode: ' @@ -328,13 +329,13 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate 'Parent': '(0)', 'PerspectiveProjection': '(aspect_ratio: 0.5714026093482971, far: 0.42888906598091125, fov: 0.5780913233757019, near: ' '0.20609822869300842)', - 'Pickable': '', - 'Player': '', + 'Pickable': '()', + 'Player': '()', 'PointLight': '(color: Rgba(red:0.5714026093482971, green:0.42888906598091125, blue:0.5780913233757019, ' 'alpha:0.20609822869300842), intensity: 0.8133212327957153, radius: 0.8235888481140137, range: ' '0.6534725427627563, shadow_depth_bias: 0.16022956371307373, shadow_normal_bias: 0.5206693410873413, ' 'shadows_enabled: false)', - 'PrimaryWindow': '', + 'PrimaryWindow': '()', 'Projection': 'Perspective((aspect_ratio: 0.42888906598091125, far: 0.5780913233757019, fov: 0.20609822869300842, ' 'near: 0.8133212327957153))', 'RelativeCursorPosition': '(normalized: "", normalized_visible_node_rect: (max: Vec2(x:0.5714026093482971, ' @@ -342,15 +343,15 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate 'RenderLayers': '(73)', 'Restitution': '(coefficient: 0.5714026093482971, combine_rule: "")', 'RigidBody': 'Dynamic', - 'SSAOSettings': '', + 'SSAOSettings': '()', 'ScreenSpaceAmbientOcclusionSettings': '(quality_level: "")', - 'Sensor': '', + 'Sensor': '()', 'ShadowFilteringMethod': 'Jimenez14', 'ShadowmapSettings': '(size: 73)', 'SkinnedMesh': '(inverse_bindposes: Strong(""), joints: [0, 0])', 'Sleeping': '(angular_threshold: 0.5714026093482971, linear_threshold: 0.42888906598091125, sleeping: true)', 'SolverGroups': '(filters: (73), memberships: (4))', - 'SpawnHere': '', + 'SpawnHere': '()', 'SpotLight': '(color: Rgba(red:0.5714026093482971, green:0.42888906598091125, blue:0.5780913233757019, ' 'alpha:0.20609822869300842), inner_angle: 0.8133212327957153, intensity: 0.8235888481140137, ' 'outer_angle: 0.6534725427627563, radius: 0.16022956371307373, range: 0.5206693410873413, ' @@ -402,7 +403,7 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate 'UiImage': '(flip_x: true, flip_y: false, texture: Weak(Uuid(uuid: "73b3b118-7d01-4778-8bcc-4e79055f5d22")))', 'UiImageSize': '(size: Vec2(x:0.5714026093482971, y:0.42888906598091125))', 'UiTextureAtlasImage': '(flip_x: true, flip_y: false, index: 54)', - 'UnitTest': '', + 'UnitTest': '()', 'VecOfColors': '([Rgba(red:0.42888906598091125, green:0.5780913233757019, blue:0.20609822869300842, ' 'alpha:0.8133212327957153)])', 'VecOfF32s': '([0.42888906598091125])', @@ -411,7 +412,7 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate 'Vec3(x:0.20609822869300842, y:0.8133212327957153, z:0.8235888481140137))', 'ViewVisibility': '(true)', 'Visibility': 'Visible', - 'VisibleEntities': '', + 'VisibleEntities': '()', 'Window': '(canvas: None, composite_alpha_mode: PostMultiplied, cursor: (grab_mode: Confined, hit_test: true, icon: ' 'Default, visible: false), decorations: false, enabled_buttons: (close: true, maximize: false, minimize: ' 'true), fit_canvas_to_parent: false, focused: true, ime_enabled: true, ime_position: ' @@ -423,5 +424,6 @@ expected_custom_property_values_randomized = {'AComponentWithAnExtremlyExagerate '0.36258742213249207), resolution: (physical_height: 58, physical_width: 98, scale_factor: ' '0.8600491285324097, scale_factor_override: None), title: "otmbsahe", transparent: false, visible: true, ' 'window_level: Normal, window_theme: "")', - 'Wireframe': '', + 'Wireframe': '()', 'ZIndex': 'Local(54)'} + diff --git a/tools/bevy_components/tests/setup_data.py b/tools/bevy_components/tests/setup_data.py new file mode 100644 index 0000000..32c6b30 --- /dev/null +++ b/tools/bevy_components/tests/setup_data.py @@ -0,0 +1,31 @@ +import bpy +import pytest + +@pytest.fixture +def setup_data(request): + print("\nSetting up resources...") + + schemaPath = "../../testing/bevy_example/assets/registry.json" + + yield {"schema_path": schemaPath} + + def finalizer(): + print("\nPerforming teardown...") + registry = bpy.context.window_manager.components_registry + + type_infos = registry.type_infos + object = bpy.context.object + remove_component_operator = bpy.ops.object.remove_bevy_component + + for type_name in type_infos: + definition = type_infos[type_name] + component_name = definition["short_name"] + if component_name in object: + try: + remove_component_operator(component_name=component_name) + except Exception as error: + pass + + request.addfinalizer(finalizer) + + return None \ No newline at end of file diff --git a/tools/bevy_components/tests/test_components.py b/tools/bevy_components/tests/test_components.py index 49487ef..ecda556 100644 --- a/tools/bevy_components/tests/test_components.py +++ b/tools/bevy_components/tests/test_components.py @@ -1,5 +1,4 @@ import bpy -import pytest import pprint from ..propGroups.conversions_to_prop_group import property_group_value_from_custom_property_value @@ -7,37 +6,11 @@ from ..propGroups.conversions_from_prop_group import property_group_value_to_cus from .component_values_shuffler import component_values_shuffler from .expected_component_values import (expected_custom_property_values, expected_custom_property_values_randomized) -@pytest.fixture -def setup_data(request): - print("\nSetting up resources...") - - def finalizer(): - print("\nPerforming teardown...") - registry = bpy.context.window_manager.components_registry - #registry.schemaPath = "../../testing/bevy_registry_export/basic/assets/registry.json" - #bpy.ops.object.reload_registry() - - type_infos = registry.type_infos - object = bpy.context.object - remove_component_operator = bpy.ops.object.remove_bevy_component - - for type_name in type_infos: - definition = type_infos[type_name] - component_name = definition["short_name"] - if component_name in object: - try: - remove_component_operator(component_name=component_name) - except Exception as error: - pass - - request.addfinalizer(finalizer) - - return None - +from .setup_data import setup_data def test_components_should_generate_correct_custom_properties(setup_data): registry = bpy.context.window_manager.components_registry - registry.schemaPath = "../../testing/bevy_registry_export/basic/assets/registry.json" + registry.schemaPath = setup_data["schema_path"] bpy.ops.object.reload_registry() type_infos = registry.type_infos @@ -83,9 +56,9 @@ def test_components_should_generate_correct_custom_properties(setup_data): assert len(added_components) == 152 -def test_components_should_generate_correct_custom_properties_with_randomozied_values(setup_data): +def test_components_should_generate_correct_custom_properties_with_randomized_values(setup_data): registry = bpy.context.window_manager.components_registry - registry.schemaPath = "../../testing/bevy_registry_export/basic/assets/registry.json" + registry.schemaPath = setup_data["schema_path"] bpy.ops.object.reload_registry() type_infos = registry.type_infos @@ -136,7 +109,7 @@ def test_components_should_generate_correct_custom_properties_with_randomozied_v def test_components_should_generate_correct_propertyGroup_values_from_custom_properties(setup_data): registry = bpy.context.window_manager.components_registry - registry.schemaPath = "../../testing/bevy_registry_export/basic/assets/registry.json" + registry.schemaPath = setup_data["schema_path"] bpy.ops.object.reload_registry() type_infos = registry.type_infos @@ -195,7 +168,7 @@ def test_components_should_generate_correct_propertyGroup_values_from_custom_pro def test_remove_components(setup_data): registry = bpy.context.window_manager.components_registry - registry.schemaPath = "../../testing/bevy_registry_export/basic/assets/registry.json" + registry.schemaPath = setup_data["schema_path"] bpy.ops.object.reload_registry() type_infos = registry.type_infos @@ -244,10 +217,9 @@ def test_remove_components(setup_data): def test_copy_paste_components(setup_data): context = bpy.context registry = context.window_manager.components_registry - registry.schemaPath = "../../testing/bevy_registry_export/basic/assets/registry.json" + registry.schemaPath = setup_data["schema_path"] bpy.ops.object.reload_registry() - #component_type = "bevy_bevy_registry_export_basic_example::test_components::BasicTest" short_name = "BasicTest" component_type = registry.short_names_to_long_names[short_name] @@ -294,4 +266,3 @@ def test_copy_paste_components(setup_data): a_fieldValue = getattr(propertyGroup, propertyGroup.field_names[0]) assert a_fieldValue == 25.0 - diff --git a/tools/bevy_components/tests/test_registry.py b/tools/bevy_components/tests/test_registry.py index 8322212..e13bb10 100644 --- a/tools/bevy_components/tests/test_registry.py +++ b/tools/bevy_components/tests/test_registry.py @@ -1,11 +1,10 @@ import bpy +from .setup_data import setup_data - -def test_blend(): +def test_blend(setup_data): registry = bpy.context.window_manager.components_registry - registry.schemaPath = "../../testing/bevy_registry_export/basic/assets/registry.json" + registry.schemaPath = setup_data["schema_path"] bpy.ops.object.reload_registry() - #print("registry type infos", registry.type_infos) short_name = "BasicTest" component_type = registry.short_names_to_long_names[short_name] @@ -19,11 +18,6 @@ def test_blend(): target_components_metadata = object.components_meta.components component_meta = next(filter(lambda component: component["name"] == short_name, target_components_metadata), None) propertyGroup = getattr(component_meta, property_group_name, None) - print("propertyGroup", propertyGroup, propertyGroup.field_names) - - - """copy_component_operator = bpy.ops.object.copy_bevy_component - copy_component_operator()""" assert propertyGroup.field_names == ['a', 'b', 'c'] \ No newline at end of file diff --git a/tools/bevy_components/tests/test_shuffler.py b/tools/bevy_components/tests/test_shuffler.py index 8d5aad6..078e561 100644 --- a/tools/bevy_components/tests/test_shuffler.py +++ b/tools/bevy_components/tests/test_shuffler.py @@ -1,9 +1,10 @@ import bpy from .component_values_shuffler import component_values_shuffler +from .setup_data import setup_data -def test_shuffler(): +def test_shuffler(setup_data): registry = bpy.context.window_manager.components_registry - registry.schemaPath = "../../testing/bevy_registry_export/basic/assets/registry.json" + registry.schemaPath = setup_data["schema_path"] bpy.ops.object.reload_registry() type_infos = registry.type_infos diff --git a/tools/gltf_auto_export/__init__.py b/tools/gltf_auto_export/__init__.py index 79895e9..4e2dcc4 100644 --- a/tools/gltf_auto_export/__init__.py +++ b/tools/gltf_auto_export/__init__.py @@ -1,7 +1,7 @@ bl_info = { "name": "gltf_auto_export", "author": "kaosigh", - "version": (0, 12, 1), + "version": (0, 14, 0), "blender": (3, 4, 0), "location": "File > Import-Export", "description": "glTF/glb auto-export", diff --git a/tools/gltf_auto_export/auto_export/auto_export.py b/tools/gltf_auto_export/auto_export/auto_export.py index dcef1cf..a9cd0f4 100644 --- a/tools/gltf_auto_export/auto_export/auto_export.py +++ b/tools/gltf_auto_export/auto_export/auto_export.py @@ -21,6 +21,9 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): folder_path = os.path.dirname(file_path) # get the preferences for our addon + #should we use change detection or not + export_change_detection = getattr(addon_prefs, "export_change_detection") + export_blueprints = getattr(addon_prefs,"export_blueprints") export_output_folder = getattr(addon_prefs,"export_output_folder") @@ -75,7 +78,7 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): if matching_collection is not None: changed_collections.append(matching_collection) - collections_to_export = list(set(changed_collections + collections_not_on_disk)) + collections_to_export = list(set(changed_collections + collections_not_on_disk)) if export_change_detection else collections # we need to re_export everything if the export parameters have been changed collections_to_export = collections if changed_export_parameters else collections_to_export @@ -110,14 +113,14 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): print("export MAIN scenes") for scene_name in main_scene_names: # we have more relaxed rules to determine if the main scenes have changed : any change is ok, (allows easier handling of changes, render settings etc) - do_export_main_scene = changed_export_parameters or scene_name in changes_per_scene.keys() or not check_if_blueprint_on_disk(scene_name, export_levels_path, gltf_extension) + do_export_main_scene = not export_change_detection or changed_export_parameters or scene_name in changes_per_scene.keys() or not check_if_blueprint_on_disk(scene_name, export_levels_path, gltf_extension) if do_export_main_scene: print(" exporting scene:", scene_name) export_main_scene(bpy.data.scenes[scene_name], folder_path, addon_prefs, library_collections) # now deal with blueprints/collections - do_export_library_scene = changed_export_parameters or len(collections_to_export) > 0 # export_library_scene_name in changes_per_scene.keys() + do_export_library_scene = not export_change_detection or changed_export_parameters or len(collections_to_export) > 0 # export_library_scene_name in changes_per_scene.keys() print("export LIBRARY") if do_export_library_scene: # we only want to go through the library scenes where our collections to export are present diff --git a/tools/gltf_auto_export/auto_export/export_gltf.py b/tools/gltf_auto_export/auto_export/export_gltf.py index bc76f28..11fb4da 100644 --- a/tools/gltf_auto_export/auto_export/export_gltf.py +++ b/tools/gltf_auto_export/auto_export/export_gltf.py @@ -33,7 +33,8 @@ def generate_gltf_export_preferences(addon_prefs): export_skins=True, export_morph=False, export_apply=False, - export_animations=False + export_animations=False, + export_optimize_animation_size=False ) for key in addon_prefs.__annotations__.keys(): diff --git a/tools/gltf_auto_export/auto_export/operators.py b/tools/gltf_auto_export/auto_export/operators.py index 2c6048d..d252bea 100644 --- a/tools/gltf_auto_export/auto_export/operators.py +++ b/tools/gltf_auto_export/auto_export/operators.py @@ -9,7 +9,8 @@ from ..helpers.helpers_collections import (get_exportable_collections) from .auto_export import auto_export class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper): - """test""" + """auto export gltf""" + #bl_idname = "object.xxx" bl_idname = "export_scenes.auto_gltf" bl_label = "Apply settings" bl_options = {'PRESET', 'UNDO'} @@ -21,7 +22,7 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper): 'export_main_scene_name', 'export_output_folder', 'export_library_scene_name', - + 'export_change_detection', 'export_blueprints', 'export_blueprints_path', @@ -79,7 +80,17 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper): # we inject all that we need, the above is not sufficient for (k, v) in self.properties.items(): if k in self.white_list or k not in AutoExportGltfPreferenceNames: - export_props[k] = v + value = v + # FIXME: really weird having to do this + if k == "collection_instances_combine_mode": + value = self.collection_instances_combine_mode + if k == "export_format": + value = self.export_format + if k == "export_image_format": + value = self.export_image_format + if k == "export_materials": + value = self.export_materials + export_props[k] = value # we add main & library scene names to our preferences export_props['main_scene_names'] = list(map(lambda scene_data: scene_data.name, getattr(self,"main_scenes"))) @@ -93,7 +104,7 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper): #print("saving settings", bpy.data.texts[".gltf_auto_export_settings"].as_string(), "raw", json.dumps(export_props)) def load_settings(self, context): - #print("loading settings") + # print("loading settings") settings = None try: settings = bpy.data.texts[".gltf_auto_export_settings"].as_string() @@ -102,10 +113,10 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper): self.will_save_settings = False if settings: - #print("loading settings in invoke AutoExportGLTF", settings) + print("loading settings in invoke AutoExportGLTF", settings) try: for (k, v) in settings.items(): - #print("loading setting", k, v) + print("loading setting", k, v) setattr(self, k, v) self.will_save_settings = True @@ -128,7 +139,8 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper): item = library_scenes.add() item.name = item_name - except (AttributeError, TypeError): + except Exception as error: + print("error", error) self.report({"ERROR"}, "Loading export settings failed. Removed corrupted settings") bpy.data.texts.remove(bpy.data.texts[".gltf_auto_export_settings"]) diff --git a/tools/gltf_auto_export/auto_export/preferences.py b/tools/gltf_auto_export/auto_export/preferences.py index 2172cf0..e2467b1 100644 --- a/tools/gltf_auto_export/auto_export/preferences.py +++ b/tools/gltf_auto_export/auto_export/preferences.py @@ -15,6 +15,7 @@ AutoExportGltfPreferenceNames = [ 'export_main_scene_name', 'export_output_folder', 'export_library_scene_name', + 'export_change_detection', 'export_blueprints', 'export_blueprints_path', @@ -39,7 +40,7 @@ AutoExportGltfPreferenceNames = [ 'library_scene_names', 'previous_export_settings', 'filter_glob', - 'will_save_settings' + 'will_save_settings', ] class AutoExportGltfAddonPreferences(AddonPreferences): @@ -86,6 +87,11 @@ class AutoExportGltfAddonPreferences(AddonPreferences): description='The name of the library scene to auto export', default='Library' ) + export_change_detection: BoolProperty( + name='Change detection', + description='Use change detection to determine what/if should be exported', + default=True + ) # scene components export_scene_settings: BoolProperty( name='Export scene settings', diff --git a/tools/gltf_auto_export/helpers/helpers_scenes.py b/tools/gltf_auto_export/helpers/helpers_scenes.py index 32b196c..e5b4dfb 100644 --- a/tools/gltf_auto_export/helpers/helpers_scenes.py +++ b/tools/gltf_auto_export/helpers/helpers_scenes.py @@ -2,18 +2,60 @@ import bpy from .helpers_collections import (set_active_collection) from .object_makers import (make_empty) + +# these are mostly for when using this add-on together with the bevy_components add-on +custom_properties_to_filter_out = ['_combine', 'template', 'components_meta'] + +def is_component_valid(object, component_name): + if "components_meta" in object: + target_components_metadata = object.components_meta.components + component_meta = next(filter(lambda component: component["name"] == component_name, target_components_metadata), None) + if component_meta != None: + return component_meta.enabled and not component_meta.invalid + return True + +def remove_unwanted_custom_properties(object): + to_remove = [] + for component_name in object.keys(): + if not is_component_valid(object, component_name): + to_remove.append(component_name) + + for cp in custom_properties_to_filter_out + to_remove: + if cp in object: + del object[cp] + +def duplicate_object(object): + obj_copy = object.copy() + if object.data: + data = object.data.copy() + obj_copy.data = data + if object.animation_data and object.animation_data.action: + obj_copy.animation_data.action = object.animation_data.action.copy() + return obj_copy + +#also removes unwanted custom_properties for all objects in hiearchy +def duplicate_object_recursive(object, parent, collection): + original_name = object.name + object.name = original_name + "____bak" + copy = duplicate_object(object) + copy.name = original_name + collection.objects.link(copy) + + remove_unwanted_custom_properties(copy) + + if parent: + copy.parent = parent + + for child in object.children: + duplicate_object_recursive(child, copy, collection) + return copy + + # 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, library_collections=[], addon_prefs={}): collection_instances_combine_mode = getattr(addon_prefs, "collection_instances_combine_mode") legacy_mode = getattr(addon_prefs, "export_legacy_mode") - - root_objects = [] - special_properties= { # to be able to reset any special property afterwards - "combine": [], - } - collection_instances_combine_mode= collection_instances_combine_mode - for object in source_collection.objects: if filter is not None and filter(object) is False: continue @@ -29,25 +71,22 @@ def copy_hollowed_collection_into(source_collection, destination_collection, par empty_obj = make_empty(original_name, object.location, object.rotation_euler, object.scale, destination_collection) """we inject the collection/blueprint name, as a component called 'BlueprintName', but we only do this in the empty, not the original object""" empty_obj['BlueprintName'] = '"'+collection_name+'"' if legacy_mode else '("'+collection_name+'")' - empty_obj['SpawnHere'] = '' + empty_obj['SpawnHere'] = '()' - for k, v in object.items(): - if k != 'template' or k != '_combine': # do not copy these properties - empty_obj[k] = v + # we copy custom properties over from our original object to our empty + for component_name, component_value in object.items(): + if component_name not in custom_properties_to_filter_out and is_component_valid(object, component_name): #copy only valid properties + empty_obj[component_name] = component_value if parent_empty is not None: empty_obj.parent = parent_empty - else: - # we backup special properties that we do not want to export, and remove them - if '_combine' in object: - special_properties["combine"].append((object, object['_combine'])) - del object['_combine'] + else: + + # we create a copy of our object and its children, to leave the original one as it is + if object.parent == None: + copy = duplicate_object_recursive(object, None, destination_collection) - if parent_empty is not None: - object.parent = parent_empty - destination_collection.objects.link(object) - else: - root_objects.append(object) - destination_collection.objects.link(object) + if parent_empty is not None: + copy.parent = parent_empty # for every sub-collection of the source, copy its content into a new sub-collection of the destination for collection in source_collection.children: @@ -58,7 +97,7 @@ def copy_hollowed_collection_into(source_collection, destination_collection, par if parent_empty is not None: collection_placeholder.parent = parent_empty - nested_results = copy_hollowed_collection_into( + copy_hollowed_collection_into( source_collection = collection, destination_collection = destination_collection, parent_empty = collection_placeholder, @@ -66,19 +105,11 @@ def copy_hollowed_collection_into(source_collection, destination_collection, par library_collections = library_collections, addon_prefs=addon_prefs ) - sub_root_objects = nested_results["root_objects"] - sub_special_properties = nested_results["special_properties"] - - root_objects.extend(sub_root_objects) - for s in sub_special_properties.keys(): - if not s in special_properties.keys(): - special_properties[s] = [] - special_properties[s].extend(sub_special_properties[s]) - - return {"root_objects": root_objects, "special_properties": special_properties} + + return {} # clear & remove "hollow scene" -def clear_hollow_scene(temp_scene, original_root_collection, root_objects, special_properties): +def clear_hollow_scene(temp_scene, original_root_collection): def restore_original_names(collection): if collection.name.endswith("____bak"): collection.name = collection.name.replace("____bak", "") @@ -86,6 +117,9 @@ def clear_hollow_scene(temp_scene, original_root_collection, root_objects, speci if object.instance_type == 'COLLECTION': if object.name.endswith("____bak"): object.name = object.name.replace("____bak", "") + else: + if object.name.endswith("____bak"): + object.name = object.name.replace("____bak", "") for child_collection in collection.children: restore_original_names(child_collection) @@ -96,37 +130,15 @@ def clear_hollow_scene(temp_scene, original_root_collection, root_objects, speci temp_root_collection = temp_scene.collection temp_scene_objects = [o for o in temp_root_collection.objects] for object in temp_scene_objects: - if object.type == 'EMPTY': - if hasattr(object, "SpawnHere"): - bpy.data.objects.remove(object, do_unlink=True) - else: - try: - temp_root_collection.objects.unlink(object) - except: - print("failed to unlink", object) - if object in root_objects: - pass - else: - bpy.data.objects.remove(object, do_unlink=True) - else: - temp_root_collection.objects.unlink(object) - - # remove temporary collections - """for collection in temporary_collections: - bpy.data.collections.remove(collection)""" - - # put back special properties - for (object, value) in special_properties["combine"]: - object['_combine'] = value - + bpy.data.objects.remove(object, do_unlink=True) # remove the temporary scene bpy.data.scenes.remove(temp_scene) # convenience utility to get lists of scenes def get_scenes(addon_prefs): - level_scene_names= list(map(lambda scene: scene.name, getattr(addon_prefs,"main_scenes"))) - library_scene_names = list(map(lambda scene: scene.name, getattr(addon_prefs,"library_scenes"))) + level_scene_names= list(map(lambda scene: scene.name, getattr(addon_prefs,"main_scenes"))) # getattr(addon_prefs, "main_scene_names_compact").split(',')# + library_scene_names = list(map(lambda scene: scene.name, getattr(addon_prefs,"library_scenes"))) #getattr(addon_prefs, "main_scene_names_compact").split(',')# level_scene_names = list(filter(lambda name: name in bpy.data.scenes, level_scene_names)) library_scene_names = list(filter(lambda name: name in bpy.data.scenes, library_scene_names)) diff --git a/tools/gltf_auto_export/helpers/to_remove_later.py b/tools/gltf_auto_export/helpers/to_remove_later.py index cdeba37..595bc93 100644 --- a/tools/gltf_auto_export/helpers/to_remove_later.py +++ b/tools/gltf_auto_export/helpers/to_remove_later.py @@ -219,4 +219,24 @@ def did_export_parameters_change(current_params, previous_params): print("copying ", key,"to", components_holder) if not key in components_holder: components_holder[key] = components[key] - """ \ No newline at end of file + """ + +# potentially useful alternative +def duplicate_object2(object, original_name): + print("copy object", object) + + with bpy.context.temp_override(object=object, active_object = object): + bpy.ops.object.duplicate(linked=False) + new_obj = bpy.context.active_object + + print("new obj", new_obj, "bpy.context.view_layer", bpy.context.view_layer.objects) + for obj in bpy.context.view_layer.objects: + print("obj", obj) + bpy.context.view_layer.update() + new_obj.name = original_name + + if object.animation_data: + print("OJECT ANIMATION") + new_obj.animation_data.action = object.animation_data.action.copy() + + return new_obj \ No newline at end of file diff --git a/tools/gltf_auto_export/pytest.ini b/tools/gltf_auto_export/pytest.ini new file mode 100644 index 0000000..33c0e52 --- /dev/null +++ b/tools/gltf_auto_export/pytest.ini @@ -0,0 +1,9 @@ +[pytest] +blender-template = ../../testing/bevy_example/assets/testing.blend +addopts = -svv +testpaths = + tests + +# dependencies: +# pytest_blender +# pixelmatch \ No newline at end of file diff --git a/tools/gltf_auto_export/tests/__init__.py b/tools/gltf_auto_export/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/gltf_auto_export/tests/test_basic.py b/tools/gltf_auto_export/tests/test_basic.py new file mode 100644 index 0000000..0ebe949 --- /dev/null +++ b/tools/gltf_auto_export/tests/test_basic.py @@ -0,0 +1,212 @@ +import bpy +import os +import subprocess +import json +import pytest +import shutil + + +@pytest.fixture +def setup_data(request): + print("\nSetting up resources...") + root_path = "../../testing/bevy_example" + assets_root_path = os.path.join(root_path, "assets") + + models_path = os.path.join(assets_root_path, "models") + materials_path = os.path.join(assets_root_path, "materials") + other_materials_path = os.path.join(assets_root_path, "other_materials") + yield {"root_path": root_path, "assets_root_path": assets_root_path, "models_path": models_path, "materials_path": materials_path, "other_materials_path": other_materials_path} + + def finalizer(): + print("\nPerforming teardown...") + if os.path.exists(models_path): + shutil.rmtree(models_path) + + if os.path.exists(materials_path): + shutil.rmtree(materials_path) + + if os.path.exists(other_materials_path): + shutil.rmtree(other_materials_path) + + + request.addfinalizer(finalizer) + + return None + +def test_export_do_not_export_blueprints(setup_data): + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'] + } + stored_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_settings.clear() + stored_settings.write(json.dumps(export_props)) + + auto_export_operator( + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=False, + ) + assert os.path.exists(os.path.join(setup_data["models_path"], "World.glb")) == True + assert os.path.exists(os.path.join(setup_data["models_path"], "library", "Blueprint1.glb")) == False + +def test_export_custom_blueprints_path(setup_data): + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'] + } + stored_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_settings.clear() + stored_settings.write(json.dumps(export_props)) + + auto_export_operator( + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_blueprints_path = "another_library_path" + ) + assert os.path.exists(os.path.join(setup_data["models_path"], "World.glb")) == True + assert os.path.exists(os.path.join(setup_data["models_path"], "another_library_path", "Blueprint1.glb")) == True + +def test_export_materials_library(setup_data): + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'] + } + stored_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_settings.clear() + stored_settings.write(json.dumps(export_props)) + + auto_export_operator( + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_materials_library = True + ) + + assert os.path.exists(os.path.join(setup_data["models_path"], "library", "Blueprint1.glb")) == True + assert os.path.exists(os.path.join(setup_data["materials_path"], "testing_materials_library.glb")) == True + + +def test_export_materials_library_custom_path(setup_data): + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'] + } + stored_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_settings.clear() + stored_settings.write(json.dumps(export_props)) + + auto_export_operator( + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_materials_library = True, + export_materials_path="other_materials" + ) + + assert os.path.exists(os.path.join(setup_data["models_path"], "library", "Blueprint1.glb")) == True + assert os.path.exists(os.path.join(setup_data["materials_path"], "testing_materials_library.glb")) == False + assert os.path.exists(os.path.join(setup_data["other_materials_path"], "testing_materials_library.glb")) == True + +def test_export_collection_instances_combine_mode(setup_data): # TODO: change & check this + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'] + } + stored_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_settings.clear() + stored_settings.write(json.dumps(export_props)) + + + bpy.data.objects["Cube"]["dynamic"] = True + + auto_export_operator( + direct_mode=True, + export_output_folder="./models", + export_blueprints=True, + collection_instances_combine_mode = 'Embed' + ) + + assert os.path.exists(os.path.join(setup_data["models_path"], "World.glb")) == True + assert os.path.exists(os.path.join(setup_data["models_path"], "World_dynamic.glb")) == False + + +def test_export_do_not_export_marked_assets(setup_data): + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'] + } + stored_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_settings.clear() + stored_settings.write(json.dumps(export_props)) + + auto_export_operator( + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_marked_assets = False + ) + assert os.path.exists(os.path.join(setup_data["models_path"], "World.glb")) == True + assert os.path.exists(os.path.join(setup_data["models_path"], "library", "Blueprint1.glb")) == True + assert os.path.exists(os.path.join(setup_data["models_path"], "library", "Blueprint2.glb")) == False + assert os.path.exists(os.path.join(setup_data["models_path"], "library", "Blueprint3.glb")) == True + assert os.path.exists(os.path.join(setup_data["models_path"], "library", "Blueprint4_nested.glb")) == True + assert os.path.exists(os.path.join(setup_data["models_path"], "library", "Blueprint5.glb")) == False + + +def test_export_separate_dynamic_and_static_objects(setup_data): + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'] + } + stored_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_settings.clear() + stored_settings.write(json.dumps(export_props)) + + + bpy.data.objects["Cube"]["dynamic"] = True + + auto_export_operator( + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_separate_dynamic_and_static_objects = True + ) + + assert os.path.exists(os.path.join(setup_data["models_path"], "World.glb")) == True + assert os.path.exists(os.path.join(setup_data["models_path"], "World_dynamic.glb")) == True diff --git a/tools/gltf_auto_export/tests/test_bevy_integration.py b/tools/gltf_auto_export/tests/test_bevy_integration.py new file mode 100644 index 0000000..70ba140 --- /dev/null +++ b/tools/gltf_auto_export/tests/test_bevy_integration.py @@ -0,0 +1,125 @@ +import bpy +import os +import subprocess +import json +import pytest +import shutil + +from PIL import Image +from pixelmatch.contrib.PIL import pixelmatch + +@pytest.fixture +def setup_data(request): + print("\nSetting up resources...") + + def finalizer(): + root_path = "../../testing/bevy_example" + assets_root_path = os.path.join(root_path, "assets") + models_path = os.path.join(assets_root_path, "models") + #materials_path = os.path.join("../../testing", "materials") + #other_materials_path = os.path.join("../../testing", "other_materials") + + print("\nPerforming teardown...") + if os.path.exists(models_path): + shutil.rmtree(models_path) + + """if os.path.exists(materials_path): + shutil.rmtree(materials_path) + + if os.path.exists(other_materials_path): + shutil.rmtree(other_materials_path)""" + diagnostics_file_path = os.path.join(root_path, "bevy_diagnostics.json") + if os.path.exists(diagnostics_file_path): + os.remove(diagnostics_file_path) + + screenshot_observed_path = os.path.join(root_path, "screenshot.png") + if os.path.exists(screenshot_observed_path): + os.remove(screenshot_observed_path) + + request.addfinalizer(finalizer) + + return None + + +""" +- removes existing gltf files if needed +- calls exporter on the testing scene +- launches bevy app & checks for output +- if all worked => test is a-ok +""" +def test_export_complex(setup_data): + root_path = "../../testing/bevy_example" + assets_root_path = os.path.join(root_path, "assets") + models_path = os.path.join(assets_root_path, "models") + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # with change detection + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'] + } + stored_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_settings.clear() + stored_settings.write(json.dumps(export_props)) + + # move the main cube + bpy.data.objects["Cube"].location = [1, 0, 0] + # move the cube in the library + bpy.data.objects["Blueprint1_mesh"].location = [1, 2, 1] + + auto_export_operator( + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_legacy_mode=False, + export_animations=True + ) + # blueprint1 => has an instance, got changed, should export + # blueprint2 => has NO instance, but marked as asset, should export + # blueprint3 => has NO instance, not marked as asset, used inside blueprint 4: should export + # blueprint4 => has an instance, with nested blueprint3, should export + # blueprint5 => has NO instance, not marked as asset, should NOT export + + assert os.path.exists(os.path.join(models_path, "World.glb")) == True + + assert os.path.exists(os.path.join(models_path, "library", "Blueprint1.glb")) == True + assert os.path.exists(os.path.join(models_path, "library", "Blueprint2.glb")) == True + assert os.path.exists(os.path.join(models_path, "library", "Blueprint3.glb")) == True + assert os.path.exists(os.path.join(models_path, "library", "Blueprint4_nested.glb")) == True + assert os.path.exists(os.path.join(models_path, "library", "Blueprint5.glb")) == False + assert os.path.exists(os.path.join(models_path, "library", "Blueprint6_animated.glb")) == True + assert os.path.exists(os.path.join(models_path, "library", "Blueprint7_hierarchy.glb")) == True + + # now run bevy + bla = "cargo run --features bevy/dynamic_linking" + # assert getattr(propertyGroup, 'a') == 0.5714026093482971 + FNULL = open(os.devnull, 'w') #use this if you want to suppress output to stdout from the subprocess + filename = "my_file.dat" + args = bla + #subprocess.call(args, stdout=FNULL, stderr=FNULL, shell=False, cwd=bevy_run_exec_path) + return_code = subprocess.call(["cargo", "run", "--features", "bevy/dynamic_linking"], cwd=root_path) + print("RETURN CODE OF BEVY APP", return_code) + assert return_code == 0 + + with open(os.path.join(root_path, "bevy_diagnostics.json")) as diagnostics_file: + diagnostics = json.load(diagnostics_file) + print("diagnostics", diagnostics) + assert diagnostics["animations"] == True + assert diagnostics["cylinder_found"] == True + assert diagnostics["empty_found"] == True + + # last but not least, do a visual compare + screenshot_expected_path = os.path.join(root_path, "expected_screenshot.png") + screenshot_observed_path = os.path.join(root_path, "screenshot.png") + img_a = Image.open(screenshot_expected_path) + img_b = Image.open(screenshot_observed_path) + img_diff = Image.new("RGBA", img_a.size) + mismatch = pixelmatch(img_a, img_b, img_diff, includeAA=True) + print("image mismatch", mismatch) + assert mismatch < 50 + + + diff --git a/tools/gltf_auto_export/ui/main.py b/tools/gltf_auto_export/ui/main.py index 828cf57..0e7edb9 100644 --- a/tools/gltf_auto_export/ui/main.py +++ b/tools/gltf_auto_export/ui/main.py @@ -37,7 +37,6 @@ class GLTF_PT_auto_export_main(bpy.types.Panel): sfile = context.space_data - class GLTF_PT_auto_export_root(bpy.types.Panel): bl_space_type = 'FILE_BROWSER' bl_region_type = 'TOOL_PROPS' @@ -66,6 +65,7 @@ class GLTF_PT_auto_export_root(bpy.types.Panel): layout.active = operator.auto_export layout.prop(operator, 'will_save_settings') + layout.prop(operator, "export_change_detection") layout.prop(operator, "export_output_folder") layout.prop(operator, "export_scene_settings") layout.prop(operator, "export_legacy_mode") @@ -124,8 +124,6 @@ class GLTF_PT_auto_export_root(bpy.types.Panel): remove_operator.action = 'REMOVE' remove_operator.scene_type = 'library' col.separator() - - class GLTF_PT_auto_export_blueprints(bpy.types.Panel): bl_space_type = 'FILE_BROWSER'