fix(bevy components): fix handling of unit/empty structs (#151)

* closes #133 
* fix(gltf_auto_export): corrected ron value for "spawnHere" components
* fix(bevy_components): fixed handling of empty/ unit structs
   * updated to/from prop_groups
   * updated tests/ expected files
   * bumped version
   * removed verbose "watching schema file for changes"
* fix(bevy_gltf_components): fixed issue of incorect handling of empty component values in non legacy mode:
   * aka: replacing empty component values (ron strings) with '()' should ONLY happen in legacy mode
   * even more aka: ron strings for component values should not be altered when not in legacy mode (provided ron
  strings should be valid)
* tests():
   * changed bevy_component tests to use testing/bevy_example as source for registry data
   * removed testing/bevy_registry_export, as it is redudant
   * related tweaks & cleanups
* chore(crates): bumped up versions because of breaking change
* chore(examples): updated registry export example to use up-to-date / fixed components data
* chore(bevy_gltf_components): added back warning about legacy mode, in a less spammy way
* docs(bevy_components): added notes about v0.3 breaking changes
This commit is contained in:
Mark Moissette 2024-03-04 08:20:00 +01:00 committed by GitHub
parent b40ab4983f
commit 9cb9dda5d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
51 changed files with 145 additions and 11404 deletions

View File

@ -16,9 +16,7 @@ members = [
"examples/bevy_gltf_save_load/basic/",
"examples/bevy_registry_export/basic",
"testing/bevy_registry_export/basic",
"testing/bevy_example"
]
resolver = "2"

View File

@ -1,6 +1,6 @@
[package]
name = "bevy_gltf_blueprints"
version = "0.7.3"
version = "0.8.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"
@ -17,6 +17,6 @@ workspace = true
bevy = { version = "0.12", default-features = false, features = ["bevy_asset", "bevy_scene", "bevy_gltf", "bevy_animation", "animation"] }
[dependencies]
bevy_gltf_components = "0.3"
bevy_gltf_components = "0.4"
#bevy_gltf_components = { path = "../bevy_gltf_components" }
bevy = { version = "0.12", default-features = false, features = ["bevy_asset", "bevy_scene", "bevy_gltf", "bevy_animation", "animation"] }

View File

@ -26,7 +26,7 @@ Here's a minimal usage example:
# Cargo.toml
[dependencies]
bevy="0.12"
bevy_gltf_blueprints = { version = "0.7"}
bevy_gltf_blueprints = { version = "0.8"}
```
@ -64,7 +64,7 @@ fn spawn_blueprint(
Add the following to your `[dependencies]` section in `Cargo.toml`:
```toml
bevy_gltf_blueprints = "0.7"
bevy_gltf_blueprints = "0.8"
```
Or use `cargo add`:
@ -346,7 +346,7 @@ 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.3 - 0.7` | `0.12` |
| `0.3 - 0.8` | `0.12` |
| `0.1 - 0.2` | `0.11` |
| branch `main` | `0.12` |
| branch `bevy_main` | `main` |

View File

@ -1,6 +1,6 @@
[package]
name = "bevy_gltf_components"
version = "0.3.2"
version = "0.4.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"

View File

@ -24,7 +24,7 @@ Here's a minimal usage example:
# Cargo.toml
[dependencies]
bevy="0.12"
bevy_gltf_components = { version = "0.3"}
bevy_gltf_components = { version = "0.4"}
```
@ -60,7 +60,7 @@ bevy_gltf_components = { version = "0.3"}
Add the following to your `[dependencies]` section in `Cargo.toml`:
```toml
bevy_gltf_components = "0.3"
bevy_gltf_components = "0.4"
```
Or use `cargo add`:
@ -117,7 +117,7 @@ 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.2 - 0.3` | `0.12` |
| `0.2 - 0.4` | `0.12` |
| `0.1` | `0.11` |
| branch `main` | `0.12` |
| branch `bevy_main` | `main` |

View File

@ -8,7 +8,9 @@ pub mod process_gltfs;
pub use process_gltfs::*;
use bevy::{
ecs::system::Resource,
app::Startup,
ecs::system::{Res, Resource},
log::warn,
prelude::{App, IntoSystemConfigs, Plugin, SystemSet, Update},
};
@ -66,11 +68,18 @@ impl Default for ComponentsFromGltfPlugin {
}
}
fn check_for_legacy_mode(gltf_components_config: Res<GltfComponentsConfig>) {
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.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),

View File

@ -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();

View File

@ -1,6 +1,6 @@
[package]
name = "bevy_gltf_save_load"
version = "0.2.1"
version = "0.3.0"
authors = ["Mark 'kaosat-dev' Moissette"]
description = "Save & load your bevy games"
homepage = "https://github.com/kaosat-dev/Blender_bevy_components_workflow"
@ -18,4 +18,5 @@ bevy = { version = "0.12", default-features = false, features = ["bevy_asset", "
[dependencies]
bevy = { version = "0.12", default-features = false, features = ["bevy_asset", "bevy_scene", "bevy_gltf"] }
bevy_gltf_blueprints = "0.7"
bevy_gltf_blueprints = "0.8"
#bevy_gltf_blueprints = { path = "../bevy_gltf_blueprints" }

View File

@ -35,7 +35,7 @@ Here's a minimal usage example:
# Cargo.toml
[dependencies]
bevy="0.12"
bevy_gltf_save_load = "0.1"
bevy_gltf_save_load = "0.3"
bevy_gltf_blueprints = "0.6" // also needed
```
@ -141,7 +141,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_gltf_save_load = "0.1"
bevy_gltf_save_load = "0.3"
bevy_gltf_blueprints = "0.6" // also needed, as bevy_gltf_save_load does not re-export it at this time
```
@ -299,7 +299,7 @@ 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.1 ` | `0.12` |
| `0.1 -0.3` | `0.12` |
| branch `main` | `0.12` |
| branch `bevy_main` | `main` |

View File

@ -1,6 +1,6 @@
[package]
name = "bevy_registry_export"
version = "0.1.1"
version = "0.2.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"

View File

@ -18,7 +18,7 @@ Here's a minimal usage example:
# Cargo.toml
[dependencies]
bevy="0.12"
bevy_registry_export = "0.1"
bevy_registry_export = "0.2"
```
```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.1"
bevy_registry_export = "0.2"
```
@ -112,8 +112,9 @@ 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.12` | `0.1.0` |
| branch `main` | `0.12` | `0.1.0` |
| `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` |

View File

@ -1,16 +0,0 @@
[package]
name = "bevy_bevy_registry_export_basic_testing"
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_rapier3d = { version = "0.23.0", features = [ "serde-serialize", "debug-render-3d", "enhanced-determinism"] }
bevy_asset_loader = { version = "0.18", features = ["standard_dynamic_assets" ]}
bevy_editor_pls = { version = "0.6" }
rand = "0.8.5"

View File

@ -1,15 +0,0 @@
# Bevy registry export example/demo
This example showcases
* the use of the bevy_registry_export crate to extract all components & types information into a json file.
* That file is then used by the [Blender addon](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/tools/bevy_components) to create Uis for each component,
to be able to add & edit Bevy components easilly in Blender !
## Running this example
```
cargo run --features bevy/dynamic_linking
```
Running the example also regenerates the registry.json file.

View File

@ -1,6 +0,0 @@
({
"world":File (path: "models/World.glb"),
"models": Folder (
path: "models/library",
),
})

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +0,0 @@
use bevy::prelude::*;
use bevy_gltf_blueprints::*;
use bevy_registry_export::*;
pub struct CorePlugin;
impl Plugin for CorePlugin {
fn build(&self, app: &mut App) {
app.add_plugins((
ExportRegistryPlugin {
save_path: "assets/registry.json".into(),
..Default::default()
},
BlueprintsPlugin {
legacy_mode: false,
library_folder: "models/library".into(),
format: GltfFormat::GLB,
aabbs: true,
..Default::default()
},
));
}
}

View File

@ -1,128 +0,0 @@
use bevy::prelude::*;
use bevy_gltf_blueprints::{BluePrintBundle, BlueprintName, GameWorldTag};
use bevy_gltf_worlflow_examples_common::{assets::GameAssets, GameState, InAppRunning};
use bevy_rapier3d::prelude::Velocity;
use rand::Rng;
pub fn setup_game(
mut commands: Commands,
game_assets: Res<GameAssets>,
models: Res<Assets<bevy::gltf::Gltf>>,
mut next_game_state: ResMut<NextState<GameState>>,
) {
println!("setting up all stuff");
commands.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 0.2,
});
// here we actually spawn our game world/level
commands.spawn((
SceneBundle {
// note: because of this issue https://github.com/bevyengine/bevy/issues/10436, "world" is now a gltf file instead of a scene
scene: models
.get(game_assets.world.id())
.expect("main level should have been loaded")
.scenes[0]
.clone(),
..default()
},
bevy::prelude::Name::from("world"),
GameWorldTag,
InAppRunning,
));
next_game_state.set(GameState::InGame)
}
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct UnregisteredComponent;
pub fn spawn_test(
keycode: Res<Input<KeyCode>>,
mut commands: Commands,
mut game_world: Query<(Entity, &Children), With<GameWorldTag>>,
) {
if keycode.just_pressed(KeyCode::T) {
let world = game_world.single_mut();
let world = world.1[0];
let mut rng = rand::thread_rng();
let range = 5.5;
let x: f32 = rng.gen_range(-range..range);
let y: f32 = rng.gen_range(-range..range);
let mut rng = rand::thread_rng();
let range = 0.8;
let vel_x: f32 = rng.gen_range(-range..range);
let vel_y: f32 = rng.gen_range(2.0..2.5);
let vel_z: f32 = rng.gen_range(-range..range);
let name_index: u64 = rng.gen();
let new_entity = commands
.spawn((
BluePrintBundle {
blueprint: BlueprintName("Health_Pickup".to_string()),
..Default::default()
},
bevy::prelude::Name::from(format!("test{}", name_index)),
// BlueprintName("Health_Pickup".to_string()),
// SpawnHere,
TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)),
Velocity {
linvel: Vec3::new(vel_x, vel_y, vel_z),
angvel: Vec3::new(0.0, 0.0, 0.0),
},
))
.id();
commands.entity(world).add_child(new_entity);
}
}
pub fn spawn_test_unregisted_components(
keycode: Res<Input<KeyCode>>,
mut commands: Commands,
mut game_world: Query<(Entity, &Children), With<GameWorldTag>>,
) {
if keycode.just_pressed(KeyCode::U) {
let world = game_world.single_mut();
let world = world.1[0];
let mut rng = rand::thread_rng();
let range = 5.5;
let x: f32 = rng.gen_range(-range..range);
let y: f32 = rng.gen_range(-range..range);
let mut rng = rand::thread_rng();
let range = 0.8;
let vel_x: f32 = rng.gen_range(-range..range);
let vel_y: f32 = rng.gen_range(2.0..2.5);
let vel_z: f32 = rng.gen_range(-range..range);
let name_index: u64 = rng.gen();
let new_entity = commands
.spawn((
BluePrintBundle {
blueprint: BlueprintName("Health_Pickup".to_string()),
..Default::default()
},
bevy::prelude::Name::from(format!("test{}", name_index)),
// BlueprintName("Health_Pickup".to_string()),
// SpawnHere,
TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)),
Velocity {
linvel: Vec3::new(vel_x, vel_y, vel_z),
angvel: Vec3::new(0.0, 0.0, 0.0),
},
UnregisteredComponent,
))
.id();
commands.entity(world).add_child(new_entity);
}
}

View File

@ -1,112 +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<Entity, With<InMainMenu>>, mut commands: Commands) {
for bli in bla.iter() {
commands.entity(bli).despawn_recursive();
}
}
pub fn main_menu(
keycode: Res<Input<KeyCode>>,
mut next_app_state: ResMut<NextState<AppState>>,
// mut next_game_state: ResMut<NextState<GameState>>,
// mut save_requested_events: EventWriter<SaveRequest>,
// mut load_requested_events: EventWriter<LoadRequest>,
) {
if keycode.just_pressed(KeyCode::Return) {
next_app_state.set(AppState::AppLoading);
// next_game_state.set(GameState::None);
}
if keycode.just_pressed(KeyCode::L) {
next_app_state.set(AppState::AppLoading);
// load_requested_events.send(LoadRequest { path: "toto".into() })
}
if keycode.just_pressed(KeyCode::S) {
// save_requested_events.send(SaveRequest { path: "toto".into() })
}
}

View File

@ -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);
}
}

View File

@ -1,27 +0,0 @@
use bevy::prelude::*;
use bevy_editor_pls::prelude::*;
use bevy_gltf_worlflow_examples_common::CommonPlugin;
mod core;
use crate::core::*;
mod game;
use game::*;
mod test_components;
use test_components::*;
fn main() {
App::new()
.add_plugins((
DefaultPlugins.set(AssetPlugin::default()),
// editor
EditorPlugin::default(),
// our custom plugins
CommonPlugin,
CorePlugin, // reusable plugins
GamePlugin, // specific to our game
ComponentsTestPlugin, // Showcases different type of components /structs
))
.run();
}

View File

@ -1,190 +0,0 @@
use bevy::{
pbr::{ExtendedMaterial, MaterialExtension},
prelude::*,
render::render_resource::*,
};
use std::ops::Range;
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct UnitTest;
#[derive(Component, Reflect, Default, Debug, Deref, DerefMut)]
#[reflect(Component)]
struct TupleTestF32(f32);
#[derive(Component, Reflect, Default, Debug, Deref, DerefMut)]
#[reflect(Component)]
struct TupleTestU64(u64);
#[derive(Component, Reflect, Default, Debug, Deref, DerefMut)]
#[reflect(Component)]
pub struct TupleTestStr(String);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct TupleTest2(f32, u64, String);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct TupleTestBool(bool);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct TupleVec2(Vec2);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct TupleVec3(Vec3);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct TupleVec(Vec<String>);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct TupleVecF32F32(Vec<(f32, f32)>);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct TupleTestColor(Color);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct BasicTest {
a: f32,
b: u64,
c: String,
}
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub enum EnumTest {
Metal,
Wood,
Rock,
Cloth,
Squishy,
#[default]
None,
}
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct NestingTestLevel2 {
text: String,
enable: bool,
enum_inner: EnumTest,
color: TupleTestColor,
toggle: TupleTestBool,
basic: BasicTest,
pub nested: NestingTestLevel3,
colors_list: VecOfColors,
}
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct NestingTestLevel3 {
vec: TupleVec3,
}
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct NestedTupleStuff(f32, u64, NestingTestLevel2);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub enum EnumComplex {
Float(f32),
Wood(String),
Vec(BasicTest),
SomeThing,
StructLike {
a: f32,
b: u32,
c: String,
},
#[default]
None,
}
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct VecOfVec3s2(Vec<TupleVec3>);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct VecOfColors(Vec<Color>);
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct AAAAddedCOMPONENT;
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut;
/* fn toto(){
let bla:core::ops::Range<f32> = Range { start: 0.1, end: 5.0};
} */
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct VecOfF32s(Vec<f32>);
// test for extended materials
#[derive(Asset, AsBindGroup, Reflect, Debug, Clone)]
struct MyExtension {
// We need to ensure that the bindings of the base material and the extension do not conflict,
// so we start from binding slot 100, leaving slots 0-99 for the base material.
#[uniform(100)]
quantize_steps: u32,
}
impl MaterialExtension for MyExtension {
fn fragment_shader() -> ShaderRef {
"shaders/extended_material.wgsl".into()
}
fn deferred_fragment_shader() -> ShaderRef {
"shaders/extended_material.wgsl".into()
}
}
pub struct ComponentsTestPlugin;
impl Plugin for ComponentsTestPlugin {
fn build(&self, app: &mut App) {
app.register_type::<BasicTest>()
.register_type::<UnitTest>()
.register_type::<TupleTestF32>()
.register_type::<TupleTestU64>()
.register_type::<TupleTestStr>()
.register_type::<TupleTestBool>()
.register_type::<TupleTest2>()
.register_type::<TupleVec2>()
.register_type::<TupleVec3>()
.register_type::<EnumTest>()
.register_type::<TupleTestColor>()
.register_type::<TupleVec>()
.register_type::<Vec<String>>()
.register_type::<NestingTestLevel2>()
.register_type::<NestingTestLevel3>()
.register_type::<NestedTupleStuff>()
.register_type::<EnumComplex>()
.register_type::<VecOfVec3s2>()
.register_type::<TupleVecF32F32>()
.register_type::<(f32, f32)>()
.register_type::<Vec<(f32, f32)>>()
.register_type::<Vec<TupleVec3>>()
.register_type::<Vec<Color>>()
.register_type::<VecOfColors>()
.register_type::<Range<f32>>()
.register_type::<VecOfF32s>()
.register_type::<Vec<f32>>()
// .register_type::<AAAAddedCOMPONENT>()
.register_type::<AComponentWithAnExtremlyExageratedOrMaybeNotButCouldBeNameOrWut>()
.add_plugins(MaterialPlugin::<
ExtendedMaterial<StandardMaterial, MyExtension>,
>::default());
}
}

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -6,6 +6,7 @@ conversion_tables = {
"char": lambda value: '"'+value+'"',
"str": lambda value: '"'+value+'"',
"alloc::string::String": lambda value: '"'+value+'"',
"alloc::borrow::Cow<str>": 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("'", "")

View File

@ -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<str>': lambda value: str(value.replace('"', "")),
'bevy_render::color::Color': lambda value: parse_color(value, float, "Rgba"),
'bevy_ecs::Entity': lambda value: int(value),
}

View File

@ -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)

View File

@ -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<WireframeMaterial>': '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<WireframeMaterial>': '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)'}

View File

@ -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

View File

@ -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

View File

@ -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']

View File

@ -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

View File

@ -1,7 +1,7 @@
bl_info = {
"name": "gltf_auto_export",
"author": "kaosigh",
"version": (0, 13, 1),
"version": (0, 14, 0),
"blender": (3, 4, 0),
"location": "File > Import-Export",
"description": "glTF/glb auto-export",

View File

@ -71,7 +71,7 @@ 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'] = '()'
# we copy custom properties over from our original object to our empty
for component_name, component_value in object.items():