mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-26 13:32:32 +00:00
chore(Blenvy): more general cleanups & doc updates
* also more work done on example upgrades
This commit is contained in:
parent
30b052d4d2
commit
b756819088
@ -1,7 +1,6 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"crates/*",
|
"crates/*",
|
||||||
"examples/common*",
|
|
||||||
"examples/blenvy/*",
|
"examples/blenvy/*",
|
||||||
"testing/bevy_example/",
|
"testing/bevy_example/",
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Blender add-ons
|
# Blender add-ons
|
||||||
|
|
||||||
- gltf_auto_export and bevy_components have been replaced with a single add-on for simplicity
|
- gltf_auto_export and bevy_components have been replaced with a single Blenvy add-on for simplicity
|
||||||
|
|
||||||
## Components:
|
## Components:
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ Blenvy will take care of loading all needed blueprints & other assets for you
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## BlueprintDisabled
|
## BlueprintInstanceDisabled
|
||||||
|
|
||||||
you can now query for this component
|
you can now query for this component
|
||||||
|
|
||||||
|
13
TODO.md
13
TODO.md
@ -58,7 +58,7 @@ Components:
|
|||||||
- [x] BLENVY_OT_component_rename_component
|
- [x] BLENVY_OT_component_rename_component
|
||||||
- [x] BLENVY_OT_component_fix
|
- [x] BLENVY_OT_component_fix
|
||||||
- [x] add handling for core::ops::Range<f32> & other ranges
|
- [x] add handling for core::ops::Range<f32> & other ranges
|
||||||
- [x] fix is_component_valid that is used in gltf_auto_export
|
- [x] fix is_component_valid that is used in blenvy
|
||||||
- [x] Hashmap Support
|
- [x] Hashmap Support
|
||||||
- [x] fix parsing of keys's type either on Bevy side (prefered) or on the Blender side
|
- [x] fix parsing of keys's type either on Bevy side (prefered) or on the Blender side
|
||||||
- [x] fix weird issue with missing "0" property when adding new entry in empty hashmap => happens only if the values for the "setter" have never been set
|
- [x] fix weird issue with missing "0" property when adding new entry in empty hashmap => happens only if the values for the "setter" have never been set
|
||||||
@ -286,7 +286,7 @@ Bevy Side:
|
|||||||
- [ ] invalidate despawned entity & parent entities AABB
|
- [ ] invalidate despawned entity & parent entities AABB
|
||||||
- [ ] add unloading/cache removal of materials
|
- [ ] add unloading/cache removal of materials
|
||||||
|
|
||||||
|
- [ ] add back and upgrade save-load
|
||||||
|
|
||||||
- [x] review & change general component insertion & spawning ordering & logic
|
- [x] review & change general component insertion & spawning ordering & logic
|
||||||
- GltfComponentsSet::Injection => GltfBlueprintsSet::Spawn => GltfBlueprintsSet::AfterSpawn
|
- GltfComponentsSet::Injection => GltfBlueprintsSet::Spawn => GltfBlueprintsSet::AfterSpawn
|
||||||
@ -299,8 +299,13 @@ Bevy Side:
|
|||||||
- [x] how to deal with animation graphs ?
|
- [x] how to deal with animation graphs ?
|
||||||
|
|
||||||
|
|
||||||
- [ ] remove "Library" component & co
|
- [x] remove "Library" component & co
|
||||||
- [ ] BlueprintDisabled => BlueprintInstanceDisabled
|
- [x] make "InBlueprint" non optional,
|
||||||
|
- [ ] and perhaps rename it to "FromBlueprint(BlueprintInfo)"
|
||||||
|
|
||||||
|
- [x] BlueprintInstanceDisabled => BlueprintInstanceDisabled
|
||||||
|
- [x] fix "remove component" operator from the rename/fix/update components panel
|
||||||
|
- [ ] replace string in BlueprintInfo path with PathBuf ?
|
||||||
|
|
||||||
- [ ] update main docs
|
- [ ] update main docs
|
||||||
- [ ] rename project to Blenvy
|
- [ ] rename project to Blenvy
|
||||||
|
@ -33,7 +33,7 @@ Its main use case is as a backbone for the [```blenvy``` Blender add-on](https:/
|
|||||||
* ability to specify **which resources** to save or to exclude
|
* ability to specify **which resources** to save or to exclude
|
||||||
* small(er) save files (only a portion of the entities is saved)
|
* small(er) save files (only a portion of the entities is saved)
|
||||||
|
|
||||||
Particularly useful when using [Blender](https://www.blender.org/) as an editor for the [Bevy](https://bevyengine.org/) game engine, combined with the [Blender plugin](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/tools/gltf_auto_export) that does a lot of the work for you (including spliting generating seperate gltf files for your static vs dynamic assets)
|
Particularly useful when using [Blender](https://www.blender.org/) as an editor for the [Bevy](https://bevyengine.org/) game engine, combined with the [Blender plugin](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/tools/blenvy) that does a lot of the work for you (including spliting generating seperate gltf files for your static vs dynamic assets)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -290,37 +290,25 @@ particularly from https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy
|
|||||||
|
|
||||||
## Materials
|
## Materials
|
||||||
|
|
||||||
You have the option of using "material libraries" to share common textures/materials between blueprints, in order to avoid asset & memory bloat:
|
Ff you enable it on the blender side, Blenvy will be using "material libraries" to share common textures/materials between blueprints, in order to avoid asset & memory bloat:
|
||||||
|
|
||||||
Ie for example without this option, 56 different blueprints using the same material with a large texture would lead to the material/texture being embeded
|
Ie for example without this option, 56 different blueprints using the same material with a large texture would lead to the material/texture being embeded
|
||||||
56 times !!
|
56 times !!
|
||||||
|
|
||||||
|
|
||||||
you can configure this with the settings:
|
Generating optimised blueprints and material libraries can be automated using the latests version of the [Blender plugin](https://github.com/kaosat-dev/Blenvy/tree/main/tools/blenvy)
|
||||||
```rust
|
|
||||||
material_library: true // defaults to false, enable this to enable automatic injection of materials from material library files
|
|
||||||
```
|
|
||||||
|
|
||||||
> Important! you must take care of preloading your material librairy gltf files in advance, using for example ```bevy_asset_loader```since
|
|
||||||
```blenvy``` currently does NOT take care of loading those at runtime
|
|
||||||
|
|
||||||
|
|
||||||
see https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/materials for how to set it up correctly
|
|
||||||
|
|
||||||
Generating optimised blueprints and material libraries can be automated using the latests version of the [Blender plugin](https://github.com/kaosat-dev/Blenvy/tree/main/tools/gltf_auto_export)
|
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/basic
|
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/components
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/basic_xpbd_physics
|
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/blueprints
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/animation
|
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/animation
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/materials
|
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/save_load
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/multiple_levels_multiple_blendfiles
|
https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/demo (a full fledged demo)
|
||||||
|
|
||||||
|
|
||||||
## Compatible Bevy versions
|
## Compatible Bevy versions
|
||||||
|
@ -45,7 +45,7 @@ pub struct AnimationInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Stores information about animations, to make things a bit easier api wise:
|
/// Stores information about animations, to make things a bit easier api wise:
|
||||||
/// these components are automatically inserted by `gltf_auto_export` on entities that have animations
|
/// these components are automatically inserted by the `blenvy` Blender add-on on entities that have animations
|
||||||
#[derive(Component, Reflect, Default, Debug)]
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct AnimationInfos {
|
pub struct AnimationInfos {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# Materials example/demo
|
# Materials example/demo
|
||||||
|
|
||||||
Example of materials use & reuse (including textures) to avoid redundant materials in blueprints gltfs that lead to asset & memory bloat
|
Example of materials use & reuse (including textures) to avoid redundant materials in blueprints gltfs that lead to asset & memory bloat
|
||||||
- to be used together with ```gltf_auto_export``` version >0.6 with the "materials library" option for exports
|
- to be used together with ```blenvy``` version >0.6 with the "materials library" option for exports
|
||||||
- It shows you how ou can configure```Bevy_gltf_blueprints``` to support material libraries
|
- It shows you how ou can configure```Bevy_gltf_blueprints``` to support material libraries
|
||||||
- material library is [here](./assets/materials/)
|
- material library is [here](./assets/materials/)
|
||||||
|
|
||||||
|
@ -7,4 +7,3 @@ license = "MIT OR Apache-2.0"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = { version = "0.14", features = ["dynamic_linking"] }
|
bevy = { version = "0.14", features = ["dynamic_linking"] }
|
||||||
blenvy = { path = "../../../crates/blenvy" }
|
blenvy = { path = "../../../crates/blenvy" }
|
||||||
#bevy_gltf_worlflow_examples_common_rapier = { path = "../../common_rapier" }
|
|
||||||
|
@ -5,12 +5,9 @@ edition = "2021"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = { version = "0.13", features = ["dynamic_linking"] }
|
bevy = { version = "0.14", features = ["dynamic_linking"] }
|
||||||
bevy_gltf_blueprints = { path = "../../../crates/bevy_gltf_blueprints" }
|
blenvy = { path = "../../../crates/blenvy" }
|
||||||
bevy_gltf_save_load = { path = "../../../crates/bevy_gltf_save_load" }
|
|
||||||
bevy_gltf_worlflow_examples_common_rapier = { path = "../../common_rapier" }
|
|
||||||
|
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.108"
|
||||||
serde = "1.0.193"
|
serde = "1.0.193"
|
||||||
bevy_rapier3d = { version = "0.25.0", features = ["serde-serialize", "debug-render-3d", "enhanced-determinism"] }
|
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
@ -60,8 +60,8 @@ pub enum EnumTest {
|
|||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ComponentsTestPlugin;
|
pub struct ComponentsExamplesPlugin;
|
||||||
impl Plugin for ComponentsTestPlugin {
|
impl Plugin for ComponentsExamplesPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.register_type::<BasicTest>()
|
app.register_type::<BasicTest>()
|
||||||
.register_type::<UnitTest>()
|
.register_type::<UnitTest>()
|
@ -1,43 +0,0 @@
|
|||||||
use bevy::{
|
|
||||||
core_pipeline::tonemapping::Tonemapping,
|
|
||||||
prelude::*,
|
|
||||||
render::{camera::CameraRenderGraph, primitives::Frustum, view::VisibleEntities},
|
|
||||||
utils::HashSet,
|
|
||||||
};
|
|
||||||
use bevy_gltf_blueprints::*;
|
|
||||||
use bevy_gltf_save_load::*;
|
|
||||||
use bevy_gltf_worlflow_examples_common_rapier::{CameraTrackingOffset, Pickable};
|
|
||||||
use bevy_rapier3d::dynamics::Velocity;
|
|
||||||
use std::any::TypeId;
|
|
||||||
|
|
||||||
pub struct CorePlugin;
|
|
||||||
impl Plugin for CorePlugin {
|
|
||||||
fn build(&self, app: &mut App) {
|
|
||||||
app.add_plugins((
|
|
||||||
SaveLoadPlugin {
|
|
||||||
save_path: "scenes".into(),
|
|
||||||
component_filter: SceneFilter::Allowlist(HashSet::from([
|
|
||||||
TypeId::of::<Name>(),
|
|
||||||
TypeId::of::<Transform>(),
|
|
||||||
TypeId::of::<Velocity>(),
|
|
||||||
TypeId::of::<InheritedVisibility>(),
|
|
||||||
TypeId::of::<Camera>(),
|
|
||||||
TypeId::of::<Camera3d>(),
|
|
||||||
TypeId::of::<Tonemapping>(),
|
|
||||||
TypeId::of::<CameraTrackingOffset>(),
|
|
||||||
TypeId::of::<Projection>(),
|
|
||||||
TypeId::of::<CameraRenderGraph>(),
|
|
||||||
TypeId::of::<Frustum>(),
|
|
||||||
TypeId::of::<GlobalTransform>(),
|
|
||||||
TypeId::of::<VisibleEntities>(),
|
|
||||||
TypeId::of::<Pickable>(),
|
|
||||||
])),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
BlueprintsPlugin {
|
|
||||||
aabbs: true,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,8 @@
|
|||||||
use bevy::prelude::*;
|
use std::any::TypeId;
|
||||||
use bevy_gltf_worlflow_examples_common_rapier::CommonPlugin;
|
|
||||||
|
use bevy::{prelude::*, utils::hashbrown::HashSet};
|
||||||
|
use blenvy::{AddToGameWorld, BlenvyPlugin, BluePrintBundle, BlueprintInfo, DynamicBlueprintInstance, GameWorldTag, HideUntilReady, SpawnBlueprint};
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
mod core;
|
mod core;
|
||||||
use crate::core::*;
|
use crate::core::*;
|
||||||
@ -7,18 +10,99 @@ use crate::core::*;
|
|||||||
mod game;
|
mod game;
|
||||||
use game::*;
|
use game::*;
|
||||||
|
|
||||||
mod test_components;
|
mod component_examples;
|
||||||
use test_components::*;
|
use component_examples::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins((
|
.add_plugins((
|
||||||
DefaultPlugins.set(AssetPlugin::default()),
|
DefaultPlugins.set(AssetPlugin::default()),
|
||||||
|
BlenvyPlugin {
|
||||||
|
save_component_filter: SceneFilter::Allowlist(HashSet::from([
|
||||||
|
TypeId::of::<Name>(),
|
||||||
|
TypeId::of::<Transform>(),
|
||||||
|
//TypeId::of::<Velocity>(),
|
||||||
|
TypeId::of::<InheritedVisibility>(),
|
||||||
|
TypeId::of::<Camera>(),
|
||||||
|
TypeId::of::<Camera3d>(),
|
||||||
|
//TypeId::of::<Tonemapping>(),
|
||||||
|
//TypeId::of::<CameraTrackingOffset>(),
|
||||||
|
TypeId::of::<Projection>(),
|
||||||
|
//TypeId::of::<CameraRenderGraph>(),
|
||||||
|
//TypeId::of::<Frustum>(),
|
||||||
|
TypeId::of::<GlobalTransform>(),
|
||||||
|
//TypeId::of::<VisibleEntities>(),
|
||||||
|
//TypeId::of::<Pickable>(),
|
||||||
|
])),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
// our custom plugins
|
// our custom plugins
|
||||||
CommonPlugin,
|
|
||||||
CorePlugin, // reusable plugins
|
CorePlugin, // reusable plugins
|
||||||
GamePlugin, // specific to our game
|
GamePlugin, // specific to our game
|
||||||
ComponentsTestPlugin, // Showcases different type of components /structs
|
ComponentsExamplesPlugin, // Showcases different type of components /structs
|
||||||
))
|
))
|
||||||
|
|
||||||
|
.add_systems(Startup, setup_game)
|
||||||
|
.add_systems(Update, (spawn_blueprint_instance, save_game, load_game))
|
||||||
|
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is how you setup & spawn a level from a blueprint
|
||||||
|
fn setup_game(
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
|
||||||
|
// here we spawn our game world/level, which is also a blueprint !
|
||||||
|
commands.spawn((
|
||||||
|
BlueprintInfo::from_path("levels/World.glb"), // all we need is a Blueprint info...
|
||||||
|
SpawnBlueprint, // and spawnblueprint to tell blenvy to spawn the blueprint now
|
||||||
|
HideUntilReady, // only reveal the level once it is ready
|
||||||
|
GameWorldTag,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// you can also spawn blueprint instances at runtime
|
||||||
|
fn spawn_blueprint_instance(
|
||||||
|
keycode: Res<ButtonInput<KeyCode>>,
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
if keycode.just_pressed(KeyCode::KeyT) {
|
||||||
|
// random position
|
||||||
|
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);
|
||||||
|
|
||||||
|
// random name
|
||||||
|
let name_index: u64 = rng.gen();
|
||||||
|
|
||||||
|
commands
|
||||||
|
.spawn((
|
||||||
|
BlueprintInfo::from_path("blueprints/test.glb"),
|
||||||
|
SpawnBlueprint,
|
||||||
|
DynamicBlueprintInstance,
|
||||||
|
bevy::prelude::Name::from(format!("test{}", name_index)),
|
||||||
|
HideUntilReady,
|
||||||
|
AddToGameWorld,
|
||||||
|
TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_game(
|
||||||
|
keycode: Res<ButtonInput<KeyCode>>,
|
||||||
|
|
||||||
|
) {
|
||||||
|
if keycode.just_pressed(KeyCode::KeyS) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_game(
|
||||||
|
keycode: Res<ButtonInput<KeyCode>>,
|
||||||
|
) {
|
||||||
|
if keycode.just_pressed(KeyCode::KeyL) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bevy_gltf_blueprints_multiple_levels_multiple_blendfiles"
|
name = "blenvy_demo"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = { version = "0.13", features = ["dynamic_linking"] }
|
bevy = { version = "0.14", features = ["dynamic_linking"] }
|
||||||
bevy_gltf_blueprints = { path = "../../../crates/bevy_gltf_blueprints" }
|
blenvy = { path = "../../../crates/blenvy" }
|
||||||
bevy_gltf_worlflow_examples_common_rapier = { path = "../../common_rapier" }
|
|
||||||
bevy_rapier3d = { version = "0.25.0", features = ["serde-serialize", "debug-render-3d", "enhanced-determinism"] }
|
bevy_rapier3d = { version = "0.25.0", features = ["serde-serialize", "debug-render-3d", "enhanced-determinism"] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
@ -7,13 +7,6 @@ license = "MIT OR Apache-2.0"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = { version = "0.14", features = ["dynamic_linking"] }
|
bevy = { version = "0.14", features = ["dynamic_linking"] }
|
||||||
blenvy = { path = "../../crates/blenvy" }
|
blenvy = { path = "../../crates/blenvy" }
|
||||||
# bevy_gltf_blueprints = { path = "../../crates/bevy_gltf_blueprints" }
|
|
||||||
# bevy_registry_export = { path = "../../crates/bevy_registry_export" }
|
|
||||||
# bevy_gltf_worlflow_examples_common_rapier = { path = "../../examples/common_rapier" }
|
|
||||||
#bevy_gltf_worlflow_examples_common = { path = "../../examples/common" }
|
|
||||||
|
|
||||||
#evy_rapier3d = { version = "0.25.0", features = ["serde-serialize", "debug-render-3d", "enhanced-determinism"] }
|
|
||||||
#bevy_asset_loader = { version = "0.20", features = ["standard_dynamic_assets"] }
|
|
||||||
#bevy_editor_pls = { version = "0.8" }
|
#bevy_editor_pls = { version = "0.8" }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
json-writer ="0.3"
|
json-writer ="0.3"
|
@ -9,7 +9,7 @@ use bevy::{animation::RepeatAnimation, gltf::Gltf, prelude::*};
|
|||||||
|
|
||||||
use blenvy::{
|
use blenvy::{
|
||||||
AnimationInfos, AnimationMarkerReached, BlueprintAnimationPlayerLink, BlueprintAnimations,
|
AnimationInfos, AnimationMarkerReached, BlueprintAnimationPlayerLink, BlueprintAnimations,
|
||||||
BlueprintDisabled, SceneAnimationPlayerLink, SceneAnimations,
|
BlueprintInstanceDisabled, SceneAnimationPlayerLink, SceneAnimations,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Component, Reflect, Default, Debug)]
|
#[derive(Component, Reflect, Default, Debug)]
|
||||||
@ -87,7 +87,7 @@ pub fn check_animations(
|
|||||||
Option<&BlueprintAnimationPlayerLink>,
|
Option<&BlueprintAnimationPlayerLink>,
|
||||||
Option<&SceneAnimationPlayerLink>,
|
Option<&SceneAnimationPlayerLink>,
|
||||||
),
|
),
|
||||||
(With<MarkerAllFoxes>, Without<BlueprintDisabled>),
|
(With<MarkerAllFoxes>, Without<BlueprintInstanceDisabled>),
|
||||||
>,
|
>,
|
||||||
|
|
||||||
foo: Query<
|
foo: Query<
|
||||||
@ -96,7 +96,7 @@ pub fn check_animations(
|
|||||||
Option<&BlueprintAnimationPlayerLink>,
|
Option<&BlueprintAnimationPlayerLink>,
|
||||||
Option<&SceneAnimationPlayerLink>,
|
Option<&SceneAnimationPlayerLink>,
|
||||||
),
|
),
|
||||||
(With<Marker1>, Without<BlueprintDisabled>),
|
(With<Marker1>, Without<BlueprintInstanceDisabled>),
|
||||||
>,
|
>,
|
||||||
bar: Query<
|
bar: Query<
|
||||||
(
|
(
|
||||||
@ -104,7 +104,7 @@ pub fn check_animations(
|
|||||||
Option<&BlueprintAnimationPlayerLink>,
|
Option<&BlueprintAnimationPlayerLink>,
|
||||||
Option<&SceneAnimationPlayerLink>,
|
Option<&SceneAnimationPlayerLink>,
|
||||||
),
|
),
|
||||||
(With<Marker2>, Without<BlueprintDisabled>),
|
(With<Marker2>, Without<BlueprintInstanceDisabled>),
|
||||||
>,
|
>,
|
||||||
baz: Query<
|
baz: Query<
|
||||||
(
|
(
|
||||||
@ -112,7 +112,7 @@ pub fn check_animations(
|
|||||||
Option<&BlueprintAnimationPlayerLink>,
|
Option<&BlueprintAnimationPlayerLink>,
|
||||||
Option<&SceneAnimationPlayerLink>,
|
Option<&SceneAnimationPlayerLink>,
|
||||||
),
|
),
|
||||||
(With<Marker3>, Without<BlueprintDisabled>),
|
(With<Marker3>, Without<BlueprintInstanceDisabled>),
|
||||||
>,
|
>,
|
||||||
|
|
||||||
bli: Query<(Entity, &AnimationInfos)>,
|
bli: Query<(Entity, &AnimationInfos)>,
|
||||||
|
@ -1,229 +0,0 @@
|
|||||||
Basics
|
|
||||||
- [x] add panel
|
|
||||||
- [x] add a "create blueprint" button
|
|
||||||
- [x] when clicked:
|
|
||||||
- [x] create collection
|
|
||||||
- [x] add an empty inside collection and name it <COLLECTION_NAME>_components
|
|
||||||
- [x] add a **AutoExport** Boolean property to collection
|
|
||||||
- [x] add name imput(popup for name input ?)
|
|
||||||
|
|
||||||
- [x] add a list of existing components/custom properties
|
|
||||||
- [x] add an "edit blueprint" section
|
|
||||||
- [x] only filled when there is ONE selection, and that selection is a collection
|
|
||||||
- [x] add a dropdown of possible components
|
|
||||||
- [x] add a checkbox for enabling disabling a component (enabled by default)
|
|
||||||
- [x] add a button for copying a component
|
|
||||||
- [x] add a button for pasting a component
|
|
||||||
|
|
||||||
|
|
||||||
UI:
|
|
||||||
- [x] filterable list of components to DISPLAY for selection : ComponentDefinitionsList
|
|
||||||
|
|
||||||
- Filter out invalid objects for components that have no _components suffix ? (that is too limiting I think)
|
|
||||||
- -[x] How to deal with pre-existing custom properties that have NO metadata
|
|
||||||
* if there is one without metadata: find if there is an available component with the same name & type ?
|
|
||||||
* if there is , insert metadata
|
|
||||||
* otherwise, mark it in some way visually ?
|
|
||||||
|
|
||||||
- [x] for OBJECT enums: add two ui pieces
|
|
||||||
- [x] one for selecting the TYPE to choose (ie normal enum)
|
|
||||||
- [x] one for setting the VALUE inside that
|
|
||||||
|
|
||||||
|
|
||||||
- [x] vecs => (not vec2, vec3 etc) more complex UI to add items in a list
|
|
||||||
- [x] generate contained CollectionGroup
|
|
||||||
- [x] CollectionProperty => type = the above
|
|
||||||
- [x] find ways to "collapse" the different levels of nested data of structs/tupples into a single custom property (ideally on the fly, but we can do without)
|
|
||||||
|
|
||||||
- [x] for single tupple components that represent a single unit type, re_use the base type's UIPropertyGroup instead of creating specific ones (ie TuppleTestF32_ui...) => will not work, would cause overriden "update callback"
|
|
||||||
- [x] pre_generate default values/values for each main type
|
|
||||||
|
|
||||||
- [x] fix issues with vec2 etc not having the correct number of items
|
|
||||||
- [x] fix bad defaults in ui group
|
|
||||||
- [x] fix object enums handling on updates (??)
|
|
||||||
- [x] fix issues with lambads in loops
|
|
||||||
|
|
||||||
- [x] object enum should be <EntryName>(params)
|
|
||||||
ie *Collider:
|
|
||||||
* Cuboid(Vec3)
|
|
||||||
* Sphere(radius)
|
|
||||||
- [x] deal with enums variants that do not have any data: ex {
|
|
||||||
"long_name": "Mesh"
|
|
||||||
}
|
|
||||||
|
|
||||||
- [x] remove / change use of ComponentDefinitionsList
|
|
||||||
- when filling the list, use the long_name as index ie items.append((str(index), item.name, item.long_name)) => items.append((item.long_name, item.name, item.long_name))
|
|
||||||
- [x] when removing a component, reset the value of the attribute in the property group (or not ? could be a feature)
|
|
||||||
- [x] deal correctly with fields of types that are NOT in the schema.json (for ex PlayingAnimation in AnimationPlayer)
|
|
||||||
- [ ] deal correctly with complex types
|
|
||||||
CascadeShadowConfig: has an array/list
|
|
||||||
ClusterConfig: one of the enum variants is an object
|
|
||||||
- [ ] possibly allow Color to be an enum as it should be ?
|
|
||||||
- [x] for sub items , the update functions "Name" should be the one of the root object
|
|
||||||
- [x] fix copy & pasting
|
|
||||||
- it actually works, but the value of the custom property are not copied back to the UI, need to implement property_group_value_from_custom_property_value
|
|
||||||
- [ ] we need a notion of "root propertyGroup" =?
|
|
||||||
- [x] notify user of missing entries in schema (ie , unregistered data types)
|
|
||||||
- [x] clarify propgroup_ui vs named nested fields
|
|
||||||
- [x] fix basic enums handling
|
|
||||||
- [x] add a list of not found components to the registry, add to them on the fly
|
|
||||||
- [x] add configuration panel (open the first time, closed on further user once configured)
|
|
||||||
|
|
||||||
- [x] add limits to ixxx types vs utypes
|
|
||||||
- [x] only display the "generate components xx" when relevant ie:
|
|
||||||
- go through list of custom properties in current object
|
|
||||||
- if one does not have metadata and / or propgroup:
|
|
||||||
break
|
|
||||||
|
|
||||||
- [x] remove custom property of disabled component ? => NOpe, as we need custom properties to iterate over
|
|
||||||
- [x] what to do with components with n/a fields ? perhaps disable the component ? add a "invalid" field to meta ?
|
|
||||||
- [x] format output as correct RON
|
|
||||||
- [x] fix issue with empty strings
|
|
||||||
- [x] change custom property => propGroup to convert RON => Json first => obsolete
|
|
||||||
- [x] cleanup process_lists
|
|
||||||
|
|
||||||
- [x] fix issues with enum variants with only a long_name
|
|
||||||
|
|
||||||
- [x] display single item enums inline, others in a seperate row
|
|
||||||
|
|
||||||
- [x] add button to "apply all" (in configuration), to apply/update all custom properties to ALL objects where relevant
|
|
||||||
- [x] add button to "apply to current" to do the same with current
|
|
||||||
- [x] add warning sign to the above
|
|
||||||
|
|
||||||
- [x] what about metadata ?
|
|
||||||
- [x] only upgrade custom properties to metadata when asked/relevant
|
|
||||||
- [x] implement move list up/down
|
|
||||||
- [ ] change property_group_value_from_custom_property_value => just disregard it for now, its point is very limited (helping people with old custom properties by attempting to generate real values)
|
|
||||||
and give the change to a real ron format, it is too limiting
|
|
||||||
- [x] fix reload registry clearing list of missing types
|
|
||||||
- [x] clean up metadata module, a lot of repeated code
|
|
||||||
- [x] some fields when original is 0 or 0.0 are not copyable ? (seems like a bad boolean check )
|
|
||||||
- [x] fix issues with object variants in enums (see clusterconfig)
|
|
||||||
|
|
||||||
|
|
||||||
- perhaps directly export default values within the schema.json ?
|
|
||||||
- for most types , it is straighforward, but others, not so much: like the default color in Bevy , etc
|
|
||||||
|
|
||||||
- [x] change default schema.json to registry.json
|
|
||||||
- [x] pasted components do not get updated value in custom_property
|
|
||||||
- [x] finish documentation
|
|
||||||
- [x] add storage of registry path
|
|
||||||
- [x] save after setting the data (browse for)
|
|
||||||
- [x] load after each reload ?
|
|
||||||
|
|
||||||
# Additional
|
|
||||||
- [x] check if output "string" in custom properties are correct
|
|
||||||
|
|
||||||
- gltf_auto_export
|
|
||||||
- [x] add support for "enabled" flag
|
|
||||||
- [ ] add special components
|
|
||||||
- "AutoExport" => Needed
|
|
||||||
- "Dynamic" ? naah wait that should be exported by the Bevy side
|
|
||||||
- [x] filter out Components_meta ??
|
|
||||||
- [x] add legacy mode to the persisted parameters
|
|
||||||
|
|
||||||
- bevy_gltf_components:
|
|
||||||
- [x] first release patch for current issues
|
|
||||||
- [x] make configurable
|
|
||||||
- [x] add "compatibility mode" and deprecation warnings for the current hack-ish conversion of fake ron
|
|
||||||
- [x] update docs to show we need to use ComponentsFromGltfPlugin::default
|
|
||||||
|
|
||||||
- bevy_gltf_blueprints
|
|
||||||
- [x] update dependency
|
|
||||||
- [x] update version
|
|
||||||
- [x] add ability to set legacy mode for bevy_gltf_components ?
|
|
||||||
|
|
||||||
- [x] release all versions
|
|
||||||
- [x] update main documentation, add compatibility version grid
|
|
||||||
|
|
||||||
|
|
||||||
## Phase 2
|
|
||||||
|
|
||||||
- [x] fix handling of long component names
|
|
||||||
- [x] fix nesting level handling issue for new system : ie basic component DOES NOT work, but nestedLevel2 does
|
|
||||||
- add goddam tests !
|
|
||||||
- [ ] verify some weird prop => custom property values (Calculated Clip for example)
|
|
||||||
|
|
||||||
- [x] fix "reload registry" not clearing all previous data (reloading registry does not seem to account for added/removed components in the registry )
|
|
||||||
- add file watcher for registry
|
|
||||||
- [x] have the watcher work as expected
|
|
||||||
- [ ] add handling of removed registry file
|
|
||||||
- [ ] clear & reset handler when the file browser for the registry is used
|
|
||||||
- [ ] re-enable watcher
|
|
||||||
|
|
||||||
- tests
|
|
||||||
clear && pytest -svv --blender-executable <path_to_blender>/blender/blender-4.0.2-linux-x64/blender
|
|
||||||
|
|
||||||
- [x] load registry
|
|
||||||
- just check list of components vs lists in registry
|
|
||||||
- [x] try adding all components
|
|
||||||
- [x] select an object
|
|
||||||
- [x] call the add_component operator
|
|
||||||
|
|
||||||
- [x] change params
|
|
||||||
- use field names + component definitions to set values
|
|
||||||
- [x] find a way to shuffle params of ALL components based on a reliable, repeatable seed
|
|
||||||
|
|
||||||
- [x] test propgroup values => custom property values
|
|
||||||
- [x] test custom property value => propgroup value
|
|
||||||
|
|
||||||
- check if all went well
|
|
||||||
|
|
||||||
- [x] fix issues with incorect custom_property generation
|
|
||||||
- [x] fix issue with object variants for enums
|
|
||||||
|
|
||||||
- [ ] add handling for core::ops::Range<f32> & other ranges
|
|
||||||
- [x] add handling for alloc::borrow::Cow<str>
|
|
||||||
- [x] add handling of isize
|
|
||||||
|
|
||||||
- [x] indirection level
|
|
||||||
- currently
|
|
||||||
- short_name +_"ui => direct lookup
|
|
||||||
- problem : max 64 chars for propertyGroupNames
|
|
||||||
- possible solution
|
|
||||||
- propertyGroupName storage: simple , incremented INT (call it propGroupId for ex)
|
|
||||||
- lookup shortName => propGroupId
|
|
||||||
|
|
||||||
- do a first pass, by replacing manual propGroupNames creation with a function
|
|
||||||
- in a second pass, replace the innards
|
|
||||||
|
|
||||||
- add button to regenerate cutom prop values from custom properties (allows us to sidestep any future issues with internals changing)
|
|
||||||
- [x] fix lists
|
|
||||||
- [x] fix enums (see Clusterconfig)
|
|
||||||
- [x] need an example with one tupple one struct
|
|
||||||
- [x] projection
|
|
||||||
- [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
|
|
||||||
|
|
||||||
- [x] remove metadata when deleting components
|
|
||||||
- [x] add try catch around custom_prop => propGroup
|
|
||||||
- [x] enhance the BLENVY_OT_component_from_custom_property to use the new system to actually generate the stuff
|
|
||||||
|
|
||||||
- coherence in operators:
|
|
||||||
- component_name vs component_type
|
|
||||||
- [x] delete => remove
|
|
||||||
|
|
||||||
- [x] clean up reloading of registry settings
|
|
||||||
- [x] clean up file watcher
|
|
||||||
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Restructuring of storage of components
|
|
||||||
- [x] marking of invalid root propgroups/components should be based on long name
|
|
||||||
- [x] overhaul & check each prop group type's use of short names => long names
|
|
||||||
- [x] lists
|
|
||||||
- [x] property_name = short_name in process enum: will likely require to use another indirection helper to keep the propery names short
|
|
||||||
|
|
||||||
- [x] in conversions from propgroups
|
|
||||||
component_name = definition["short_name"]
|
|
||||||
- [ ] fix is_component_valid that is used in gltf_auto_export
|
|
||||||
- [x] update all tests
|
|
||||||
|
|
||||||
- Hashmap Support
|
|
||||||
- [x] fix parsing of keys's type either on Bevy side (prefered) or on the Blender side
|
|
||||||
- [x] fix weird issue with missing "0" property when adding new entry in empty hashmap => happens only if the values for the "setter" have never been set
|
|
||||||
- [ ] handle missing types in registry for keys & values
|
|
||||||
|
|
||||||
- [ ] Add correct upgrade handling from individual component to bevy_components
|
|
@ -28,7 +28,7 @@ def gltf_post_export_callback(data):
|
|||||||
gltf_settings_backup = tracker.gltf_settings_backup
|
gltf_settings_backup = tracker.gltf_settings_backup
|
||||||
gltf_filepath = data["gltf_filepath"]
|
gltf_filepath = data["gltf_filepath"]
|
||||||
gltf_export_id = data['gltf_export_id']
|
gltf_export_id = data['gltf_export_id']
|
||||||
if gltf_export_id == "gltf_auto_export":
|
if gltf_export_id == "blenvy":
|
||||||
# some more absurdity: apparently the file is not QUITE done when the export callback is called, so we have to introduce this timer to remove the temporary file correctly
|
# some more absurdity: apparently the file is not QUITE done when the export callback is called, so we have to introduce this timer to remove the temporary file correctly
|
||||||
tracker.dummy_file_path = gltf_filepath
|
tracker.dummy_file_path = gltf_filepath
|
||||||
try:
|
try:
|
||||||
|
@ -1,402 +0,0 @@
|
|||||||
bl_info = {
|
|
||||||
"name": "gltf_auto_export",
|
|
||||||
"author": "kaosigh",
|
|
||||||
"version": (0, 10, 0),
|
|
||||||
"blender": (3, 4, 0),
|
|
||||||
"location": "File > Import-Export",
|
|
||||||
"description": "glTF/glb auto-export",
|
|
||||||
"warning": "",
|
|
||||||
"wiki_url": "https://github.com/kaosat-dev/Blender_bevy_components_workflow",
|
|
||||||
"tracker_url": "https://github.com/kaosat-dev/Blender_bevy_components_workflow/issues/new",
|
|
||||||
"category": "Import-Export"
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
from bpy.props import (BoolProperty,
|
|
||||||
IntProperty,
|
|
||||||
StringProperty,
|
|
||||||
EnumProperty,
|
|
||||||
CollectionProperty
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# glTF extensions are named following a convention with known prefixes.
|
|
||||||
# See: https://github.com/KhronosGroup/glTF/tree/main/extensions#about-gltf-extensions
|
|
||||||
# also: https://github.com/KhronosGroup/glTF/blob/main/extensions/Prefixes.md
|
|
||||||
glTF_extension_name = "EXT_auto_export"
|
|
||||||
|
|
||||||
# Support for an extension is "required" if a typical glTF viewer cannot be expected
|
|
||||||
# to load a given model without understanding the contents of the extension.
|
|
||||||
# For example, a compression scheme or new image format (with no fallback included)
|
|
||||||
# would be "required", but physics metadata or app-specific settings could be optional.
|
|
||||||
extension_is_required = False
|
|
||||||
from io_scene_gltf2 import (GLTF_PT_export_main, GLTF_PT_export_include)
|
|
||||||
|
|
||||||
class ExampleExtensionProperties(bpy.types.PropertyGroup):
|
|
||||||
enabled: bpy.props.BoolProperty(
|
|
||||||
name=bl_info["name"],
|
|
||||||
description='Include this extension in the exported glTF file.',
|
|
||||||
default=True
|
|
||||||
)
|
|
||||||
|
|
||||||
auto_export_main_scene_name: StringProperty(
|
|
||||||
name='Main scene',
|
|
||||||
description='The name of the main scene/level/world to auto export',
|
|
||||||
default='Scene'
|
|
||||||
)
|
|
||||||
auto_export_output_folder: StringProperty(
|
|
||||||
name='Export folder (relative)',
|
|
||||||
description='The root folder for all exports(relative to current file) Defaults to current folder',
|
|
||||||
default=''
|
|
||||||
)
|
|
||||||
auto_export_library_scene_name: StringProperty(
|
|
||||||
name='Library scene',
|
|
||||||
description='The name of the library scene to auto export',
|
|
||||||
default='Library'
|
|
||||||
)
|
|
||||||
# scene components
|
|
||||||
auto_export_scene_settings: BoolProperty(
|
|
||||||
name='Export scene settings',
|
|
||||||
description='Export scene settings ie AmbientLighting, Bloom, AO etc',
|
|
||||||
default=False
|
|
||||||
)
|
|
||||||
|
|
||||||
# blueprint settings
|
|
||||||
auto_export_blueprints: BoolProperty(
|
|
||||||
name='Export Blueprints',
|
|
||||||
description='Replaces collection instances with an Empty with a BlueprintInfo custom property',
|
|
||||||
default=True
|
|
||||||
)
|
|
||||||
auto_export_blueprints_path: StringProperty(
|
|
||||||
name='Blueprints path',
|
|
||||||
description='path to export the blueprints to (relative to the Export folder)',
|
|
||||||
default='library'
|
|
||||||
)
|
|
||||||
|
|
||||||
auto_export_materials_library: BoolProperty(
|
|
||||||
name='Export materials library',
|
|
||||||
description='remove materials from blueprints and use the material library instead',
|
|
||||||
default=False
|
|
||||||
)
|
|
||||||
auto_export_materials_path: StringProperty(
|
|
||||||
name='Materials path',
|
|
||||||
description='path to export the materials libraries to (relative to the root folder)',
|
|
||||||
default='materials'
|
|
||||||
)
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.utils.register_class(ExampleExtensionProperties)
|
|
||||||
bpy.types.Scene.ExampleExtensionProperties = bpy.props.PointerProperty(type=ExampleExtensionProperties)
|
|
||||||
|
|
||||||
def register_panel():
|
|
||||||
# Register the panel on demand, we need to be sure to only register it once
|
|
||||||
# This is necessary because the panel is a child of the extensions panel,
|
|
||||||
# which may not be registered when we try to register this extension
|
|
||||||
try:
|
|
||||||
bpy.utils.register_class(GLTF_PT_UserExtensionPanel)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# If the glTF exporter is disabled, we need to unregister the extension panel
|
|
||||||
# Just return a function to the exporter so it can unregister the panel
|
|
||||||
return unregister_panel
|
|
||||||
|
|
||||||
|
|
||||||
def unregister_panel():
|
|
||||||
# Since panel is registered on demand, it is possible it is not registered
|
|
||||||
try:
|
|
||||||
bpy.utils.unregister_class(GLTF_PT_UserExtensionPanel)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
unregister_panel()
|
|
||||||
bpy.utils.unregister_class(ExampleExtensionProperties)
|
|
||||||
del bpy.types.Scene.ExampleExtensionProperties
|
|
||||||
|
|
||||||
class GLTF_PT_UserExtensionPanel(bpy.types.Panel):
|
|
||||||
|
|
||||||
bl_space_type = 'FILE_BROWSER'
|
|
||||||
bl_region_type = 'TOOL_PROPS'
|
|
||||||
bl_label = "Enabled"
|
|
||||||
bl_parent_id = "GLTF_PT_export_user_extensions"
|
|
||||||
bl_options = {'DEFAULT_CLOSED'}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
sfile = context.space_data
|
|
||||||
operator = sfile.active_operator
|
|
||||||
return operator.bl_idname == "EXPORT_SCENE_OT_gltf"
|
|
||||||
|
|
||||||
def draw_header(self, context):
|
|
||||||
props = bpy.context.scene.ExampleExtensionProperties
|
|
||||||
self.layout.prop(props, 'enabled')
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
layout.use_property_decorate = False # No animation.
|
|
||||||
|
|
||||||
props = bpy.context.scene.ExampleExtensionProperties
|
|
||||||
layout.active = props.enabled
|
|
||||||
|
|
||||||
props = bpy.context.scene.ExampleExtensionProperties
|
|
||||||
for bla in props.__annotations__:
|
|
||||||
layout.prop(props, bla)
|
|
||||||
|
|
||||||
|
|
||||||
class glTF2ExportUserExtension:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
# We need to wait until we create the gltf2UserExtension to import the gltf2 modules
|
|
||||||
# Otherwise, it may fail because the gltf2 may not be loaded yet
|
|
||||||
from io_scene_gltf2.io.com.gltf2_io_extensions import Extension
|
|
||||||
self.Extension = Extension
|
|
||||||
self.properties = bpy.context.scene.ExampleExtensionProperties
|
|
||||||
|
|
||||||
def gather_node_hook(self, gltf2_object, blender_object, gltf_export_settings):
|
|
||||||
if self.properties.enabled:
|
|
||||||
if gltf2_object.extensions is None:
|
|
||||||
gltf2_object.extensions = {}
|
|
||||||
print("bla bla")
|
|
||||||
gltf2_object.extensions[glTF_extension_name] = self.Extension(
|
|
||||||
name=glTF_extension_name,
|
|
||||||
extension={"auto_export_blueprints": self.properties.auto_export_blueprints},
|
|
||||||
required=extension_is_required
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def did_export_parameters_change(current_params, previous_params):
|
|
||||||
set1 = set(previous_params.items())
|
|
||||||
set2 = set(current_params.items())
|
|
||||||
difference = dict(set1 ^ set2)
|
|
||||||
|
|
||||||
changed_param_names = list(set(difference.keys())- set(AutoExportGltfPreferenceNames))
|
|
||||||
changed_parameters = len(changed_param_names) > 0
|
|
||||||
return changed_parameters
|
|
||||||
|
|
||||||
# original in export_blueprints => export_collections
|
|
||||||
# The part below is not necessary NORMALLY , but blender crashes in the "normal" case when using bpy.context.temp_override,
|
|
||||||
#if relevant we replace sub collections instances with placeholders too
|
|
||||||
# this is not needed if a collection/blueprint does not have sub blueprints or sub collections
|
|
||||||
collection_in_blueprint_hierarchy = collection_name in blueprint_hierarchy and len(blueprint_hierarchy[collection_name]) > 0
|
|
||||||
collection_has_child_collections = len(bpy.data.collections[collection_name].children) > 0
|
|
||||||
#if collection_in_blueprint_hierarchy or collection_has_child_collections:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""else:
|
|
||||||
print("standard export")
|
|
||||||
# set active scene to be the library scene
|
|
||||||
original_scene = bpy.context.window.scene
|
|
||||||
bpy.context.window.scene = library_scene
|
|
||||||
with bpy.context.temp_override(scene=library_scene):
|
|
||||||
print("active scene", bpy.context.scene)
|
|
||||||
export_gltf(gltf_output_path, gltf_export_settings)
|
|
||||||
bpy.context.window.scene = original_scene"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
blueprint_template = object['Template'] if 'Template' in object else False
|
|
||||||
if blueprint_template and parent_empty is None: # ONLY WORKS AT ROOT LEVEL
|
|
||||||
print("BLUEPRINT TEMPLATE", blueprint_template, destination_collection, parent_empty)
|
|
||||||
for object in source_collection.objects:
|
|
||||||
if object.type == 'EMPTY' and object.name.endswith("components"):
|
|
||||||
original_collection = bpy.data.collections[collection_name]
|
|
||||||
components_holder = object
|
|
||||||
print("WE CAN INJECT into", object, "data from", original_collection)
|
|
||||||
|
|
||||||
# now we look for components inside the collection
|
|
||||||
components = {}
|
|
||||||
for object in original_collection.objects:
|
|
||||||
if object.type == 'EMPTY' and object.name.endswith("components"):
|
|
||||||
for component_name in object.keys():
|
|
||||||
if component_name not in '_RNA_UI':
|
|
||||||
print( component_name , "-" , object[component_name] )
|
|
||||||
components[component_name] = object[component_name]
|
|
||||||
|
|
||||||
# copy template components into target object
|
|
||||||
for key in components:
|
|
||||||
print("copying ", key,"to", components_holder)
|
|
||||||
if not key in components_holder:
|
|
||||||
components_holder[key] = components[key]
|
|
||||||
"""
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if active_operator:
|
|
||||||
# print("Operator", active_operator.bl_label, active_operator.bl_idname, "bla", bpy.context.window_manager.gltf_exporter_running)
|
|
||||||
if active_operator.bl_idname == "EXPORT_SCENE_OT_gltf" : #and not bpy.context.window_manager.gltf_exporter_running:
|
|
||||||
# we force saving params
|
|
||||||
active_operator.will_save_settings = True
|
|
||||||
if active_operator.bl_idname == "EXPORT_SCENES_OT_auto_gltf":
|
|
||||||
# we force saving params
|
|
||||||
active_operator.will_save_settings = True
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
print("matching")
|
|
||||||
try:
|
|
||||||
bpy.app.timers.unregister(cls.gltf_exporter_handler)
|
|
||||||
except:pass
|
|
||||||
bpy.app.timers.register(cls.gltf_exporter_handler, first_interval=3)
|
|
||||||
# we backup any existing gltf export settings, if there where any
|
|
||||||
scene = bpy.context.scene
|
|
||||||
if "glTF2ExportSettings" in scene:
|
|
||||||
existing_setting = scene["glTF2ExportSettings"]
|
|
||||||
cls.existing_gltf_settings = existing_setting
|
|
||||||
bpy.context.window_manager.gltf_exporter_running = True
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
if bpy.context.window_manager.gltf_exporter_running:
|
|
||||||
bpy.context.window_manager.gltf_exporter_running = False"""
|
|
||||||
|
|
||||||
|
|
||||||
"""@classmethod
|
|
||||||
def gltf_exporter_handler(cls):
|
|
||||||
# FOr some reason, the active operator here is always None, so using a workaround
|
|
||||||
# active_operator = bpy.context.active_operator
|
|
||||||
print("here", bpy.context.window_manager.gltf_exporter_running)
|
|
||||||
|
|
||||||
if bpy.context.window_manager.gltf_exporter_running:
|
|
||||||
try:
|
|
||||||
dummy_file_path = "/home/ckaos/projects/bevy/Blender_bevy_components_worklflow/testing/bevy_example/assets/dummy.glb"
|
|
||||||
|
|
||||||
import os
|
|
||||||
if os.path.exists(dummy_file_path):
|
|
||||||
print("dummy file exists, assuming it worked")
|
|
||||||
os.unlink(dummy_file_path)
|
|
||||||
|
|
||||||
# get the parameters
|
|
||||||
scene = bpy.context.scene
|
|
||||||
if "glTF2ExportSettings" in scene:
|
|
||||||
settings = scene["glTF2ExportSettings"]
|
|
||||||
formatted_settings = dict(settings)
|
|
||||||
|
|
||||||
gltf_export_settings = bpy.data.texts[".blenvy_gltf_settings"] if ".blenvy_gltf_settings" in bpy.data.texts else bpy.data.texts.new(".blenvy_gltf_settings")
|
|
||||||
|
|
||||||
#check if params have changed
|
|
||||||
bpy.context.window_manager.gltf_settings_changed = sorted(json.loads(gltf_export_settings.as_string()).items()) != sorted(formatted_settings.items())
|
|
||||||
|
|
||||||
print("gltf NEW settings", formatted_settings, "OLD settings", gltf_export_settings, "CHANGED ?", bpy.context.window_manager.gltf_settings_changed)
|
|
||||||
|
|
||||||
# now write new settings
|
|
||||||
gltf_export_settings.clear()
|
|
||||||
gltf_export_settings.write(json.dumps(formatted_settings))
|
|
||||||
|
|
||||||
|
|
||||||
# now reset the original gltf_settings
|
|
||||||
if getattr(cls, "existing_gltf_settings", None) is not None:
|
|
||||||
print("resetting original gltf settings")
|
|
||||||
scene["glTF2ExportSettings"] = cls.existing_gltf_settings
|
|
||||||
else:
|
|
||||||
print("no pre_existing settings")
|
|
||||||
if "glTF2ExportSettings" in scene:
|
|
||||||
del scene["glTF2ExportSettings"]
|
|
||||||
cls.existing_gltf_settings = None
|
|
||||||
except:pass
|
|
||||||
bpy.context.window_manager.gltf_exporter_running = False
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
bpy.app.timers.unregister(cls.gltf_exporter_handler)
|
|
||||||
except:pass
|
|
||||||
return None
|
|
||||||
return 1"""
|
|
||||||
|
|
||||||
|
|
||||||
def invoke_override(self, context, event):
|
|
||||||
settings = context.scene.get(self.scene_key)
|
|
||||||
self.will_save_settings = False
|
|
||||||
if settings:
|
|
||||||
try:
|
|
||||||
for (k, v) in settings.items():
|
|
||||||
setattr(self, k, v)
|
|
||||||
self.will_save_settings = True
|
|
||||||
|
|
||||||
# Update filter if user saved settings
|
|
||||||
if hasattr(self, 'export_format'):
|
|
||||||
self.filter_glob = '*.glb' if self.export_format == 'GLB' else '*.gltf'
|
|
||||||
|
|
||||||
except (AttributeError, TypeError):
|
|
||||||
self.report({"ERROR"}, "Loading export settings failed. Removed corrupted settings")
|
|
||||||
del context.scene[self.scene_key]
|
|
||||||
|
|
||||||
import sys
|
|
||||||
preferences = bpy.context.preferences
|
|
||||||
for addon_name in preferences.addons.keys():
|
|
||||||
try:
|
|
||||||
if hasattr(sys.modules[addon_name], 'glTF2ExportUserExtension') or hasattr(sys.modules[addon_name], 'glTF2ExportUserExtensions'):
|
|
||||||
pass #exporter_extension_panel_unregister_functors.append(sys.modules[addon_name].register_panel())
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# self.has_active_exporter_extensions = len(exporter_extension_panel_unregister_functors) > 0
|
|
||||||
print("ovverride")
|
|
||||||
wm = context.window_manager
|
|
||||||
wm.fileselect_add(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from io_scene_gltf2 import (ExportGLTF2, GLTF_PT_export_main, GLTF_PT_export_include)
|
|
||||||
|
|
||||||
|
|
||||||
from io_scene_gltf2 import (ExportGLTF2, GLTF_PT_export_main,ExportGLTF2_Base, GLTF_PT_export_include)
|
|
||||||
import io_scene_gltf2 as gltf_exporter_original
|
|
||||||
#import io_scene_gltf2.GLTF_PT_export_data_scene as GLTF_PT_export_data_scene_original
|
|
||||||
"""
|
|
||||||
class GLTF_PT_export_data(gltf_exporter_original.GLTF_PT_export_data):
|
|
||||||
bl_space_type = 'FILE_BROWSER'
|
|
||||||
bl_region_type = 'TOOL_PROPS'
|
|
||||||
bl_label = "Data"
|
|
||||||
bl_parent_id = "GLTF_PT_auto_export_gltf"
|
|
||||||
bl_options = {'DEFAULT_CLOSED'}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
sfile = context.space_data
|
|
||||||
operator = sfile.active_operator
|
|
||||||
|
|
||||||
return operator.bl_idname == "EXPORT_SCENES_OT_auto_gltf"
|
|
||||||
|
|
||||||
class GLTF_PT_export_data_scene(gltf_exporter_original.GLTF_PT_export_data_scene):
|
|
||||||
bl_space_type = 'FILE_BROWSER'
|
|
||||||
bl_region_type = 'TOOL_PROPS'
|
|
||||||
bl_label = "Scene Graph"
|
|
||||||
bl_parent_id = "GLTF_PT_export_data"
|
|
||||||
bl_options = {'DEFAULT_CLOSED'}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
sfile = context.space_data
|
|
||||||
operator = sfile.active_operator
|
|
||||||
return operator.bl_idname == "EXPORT_SCENES_OT_auto_gltf"
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
return super().draw(context)"""
|
|
@ -86,7 +86,7 @@ class AutoExportTracker(PropertyGroup):
|
|||||||
active_operator = getattr(bpy.context, 'active_operator' , None)
|
active_operator = getattr(bpy.context, 'active_operator' , None)
|
||||||
if active_operator is not None:
|
if active_operator is not None:
|
||||||
#print("Operator", active_operator.bl_label, active_operator.bl_idname)
|
#print("Operator", active_operator.bl_label, active_operator.bl_idname)
|
||||||
if active_operator.bl_idname == "EXPORT_SCENE_OT_gltf" and active_operator.gltf_export_id == "gltf_auto_export":
|
if active_operator.bl_idname == "EXPORT_SCENE_OT_gltf" and active_operator.gltf_export_id == "blenvy":
|
||||||
# we backup any existing gltf export settings, if there were any
|
# we backup any existing gltf export settings, if there were any
|
||||||
scene = bpy.context.scene
|
scene = bpy.context.scene
|
||||||
if "glTF2ExportSettings" in scene:
|
if "glTF2ExportSettings" in scene:
|
||||||
|
@ -21,7 +21,7 @@ def draw_settings_ui(layout, auto_export_settings):
|
|||||||
op.use_active_collection_with_nested=True
|
op.use_active_collection_with_nested=True
|
||||||
op.use_active_scene = True
|
op.use_active_scene = True
|
||||||
op.filepath="____dummy____"
|
op.filepath="____dummy____"
|
||||||
op.gltf_export_id = "gltf_auto_export" # we specify that we are in a special case
|
op.gltf_export_id = "blenvy" # we specify that we are in a special case
|
||||||
|
|
||||||
section.prop(auto_export_settings, "export_scene_settings")
|
section.prop(auto_export_settings, "export_scene_settings")
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
import rna_prop_ui
|
|
||||||
|
|
||||||
# fake way to make our operator's changes be visible to the change/depsgraph update handler in gltf_auto_export
|
|
||||||
def ping_depsgraph_update(object):
|
|
||||||
rna_prop_ui.rna_idprop_ui_create(object, "________temp", default=0)
|
|
||||||
rna_prop_ui.rna_idprop_ui_prop_clear(object, "________temp")
|
|
@ -1,10 +0,0 @@
|
|||||||
import bpy
|
|
||||||
import rna_prop_ui
|
|
||||||
|
|
||||||
# fake way to make our operator's changes be visible to the change/depsgraph update handler in gltf_auto_export
|
|
||||||
def ping_depsgraph_update(object=None):
|
|
||||||
if object == None:
|
|
||||||
object = bpy.data.scenes[0]
|
|
||||||
rna_prop_ui.rna_idprop_ui_create(object, "________temp", default=0)
|
|
||||||
rna_prop_ui.rna_idprop_ui_prop_clear(object, "________temp")
|
|
||||||
return None
|
|
@ -26,7 +26,7 @@ class BLENVY_PT_SidePanel(bpy.types.Panel):
|
|||||||
bl_label = ""
|
bl_label = ""
|
||||||
bl_space_type = 'VIEW_3D'
|
bl_space_type = 'VIEW_3D'
|
||||||
bl_region_type = 'UI'
|
bl_region_type = 'UI'
|
||||||
bl_category = "Bevy"
|
bl_category = "Blenvy"
|
||||||
#bl_context = "objectmode"
|
#bl_context = "objectmode"
|
||||||
|
|
||||||
def draw_header(self, context):
|
def draw_header(self, context):
|
||||||
|
Loading…
Reference in New Issue
Block a user