mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-26 21:37:01 +00:00
Compare commits
7 Commits
a633610dc4
...
d955de03a3
Author | SHA1 | Date | |
---|---|---|---|
|
d955de03a3 | ||
|
0b64de79da | ||
|
bb4b07b7af | ||
|
f438116ece | ||
|
67588ba3a4 | ||
|
4f5f3be317 | ||
|
ada54450a5 |
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bevy_gltf_blueprints"
|
name = "bevy_gltf_blueprints"
|
||||||
version = "0.10.0"
|
version = "0.10.2"
|
||||||
authors = ["Mark 'kaosat-dev' Moissette"]
|
authors = ["Mark 'kaosat-dev' Moissette"]
|
||||||
description = "Adds the ability to define Blueprints/Prefabs for Bevy inside gltf files and spawn them in Bevy."
|
description = "Adds the ability to define Blueprints/Prefabs for Bevy inside gltf files and spawn them in Bevy."
|
||||||
homepage = "https://github.com/kaosat-dev/Blender_bevy_components_workflow"
|
homepage = "https://github.com/kaosat-dev/Blender_bevy_components_workflow"
|
||||||
|
@ -224,7 +224,7 @@ Typically , the order of systems should be
|
|||||||
|
|
||||||
***bevy_gltf_components (GltfComponentsSet::Injection)*** => ***bevy_gltf_blueprints (GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn)*** => ***replace_proxies***
|
***bevy_gltf_components (GltfComponentsSet::Injection)*** => ***bevy_gltf_blueprints (GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn)*** => ***replace_proxies***
|
||||||
|
|
||||||
see https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/basic for how to set it up correctly
|
see an example [here](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/basic) for how to set it up correctly
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -278,9 +278,9 @@ pub fn animation_change_on_proximity_foxes(
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
see https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/animation for how to set it up correctly
|
see [here](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/animation) for how to set it up correctly
|
||||||
|
|
||||||
particularly from https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/animation/game/in_game.rs
|
particularly from [here](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/animation/src/game/in_game.rs)
|
||||||
|
|
||||||
|
|
||||||
## Materials
|
## Materials
|
||||||
@ -301,7 +301,7 @@ material_library_folder: "materials".into() //defaults to "materials" the folder
|
|||||||
```bevy_gltf_blueprints``` currently does NOT take care of loading those at runtime
|
```bevy_gltf_blueprints``` currently does NOT take care of loading those at runtime
|
||||||
|
|
||||||
|
|
||||||
see https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/materials for how to set it up correctly
|
see an example [here](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/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/Blender_bevy_components_workflow/tree/main/tools/gltf_auto_export)
|
Generating optimised blueprints and material libraries can be automated using the latests version of the [Blender plugin](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/tools/gltf_auto_export)
|
||||||
|
|
||||||
@ -326,15 +326,15 @@ As it create custom properties that are writen in real **ron** file format inste
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/basic
|
* [basic](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/basic)
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/basic_xpbd_physics
|
* [xbpd](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/basic_xpbd_physics)
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/animation
|
* [animation](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/animation)
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/materials
|
* [materials](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/materials)
|
||||||
|
|
||||||
https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/multiple_levels_multiple_blendfiles
|
* [multiple_levels_multiple_blendfiles](https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_blueprints/multiple_levels_multiple_blendfiles)
|
||||||
|
|
||||||
|
|
||||||
## Compatible Bevy versions
|
## Compatible Bevy versions
|
||||||
|
@ -19,7 +19,11 @@ pub use copy_components::*;
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use bevy::{prelude::*, render::primitives::Aabb, utils::HashMap};
|
use bevy::{
|
||||||
|
prelude::*,
|
||||||
|
render::{primitives::Aabb, view::VisibilitySystems},
|
||||||
|
utils::HashMap,
|
||||||
|
};
|
||||||
use bevy_gltf_components::{ComponentsFromGltfPlugin, GltfComponentsSet};
|
use bevy_gltf_components::{ComponentsFromGltfPlugin, GltfComponentsSet};
|
||||||
|
|
||||||
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
|
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
|
||||||
@ -167,10 +171,11 @@ impl Plugin for BlueprintsPlugin {
|
|||||||
.in_set(GltfBlueprintsSet::Spawn),
|
.in_set(GltfBlueprintsSet::Spawn),
|
||||||
)
|
)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
PostUpdate,
|
||||||
(spawned_blueprint_post_process, apply_deferred)
|
(spawned_blueprint_post_process, apply_deferred)
|
||||||
.chain()
|
.chain()
|
||||||
.in_set(GltfBlueprintsSet::AfterSpawn),
|
.in_set(GltfBlueprintsSet::AfterSpawn)
|
||||||
|
.before(VisibilitySystems::CheckVisibility),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3373,6 +3373,17 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"typeInfo": "Struct"
|
"typeInfo": "Struct"
|
||||||
},
|
},
|
||||||
|
"bevy_gltf_blueprints::animation::Animated": {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"isComponent": true,
|
||||||
|
"isResource": false,
|
||||||
|
"properties": {},
|
||||||
|
"required": [],
|
||||||
|
"short_name": "Animated",
|
||||||
|
"title": "bevy_gltf_blueprints::animation::Animated",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Struct"
|
||||||
|
},
|
||||||
"bevy_gltf_blueprints::animation::Animations": {
|
"bevy_gltf_blueprints::animation::Animations": {
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"isComponent": true,
|
"isComponent": true,
|
||||||
@ -3433,6 +3444,22 @@
|
|||||||
"type": "array",
|
"type": "array",
|
||||||
"typeInfo": "TupleStruct"
|
"typeInfo": "TupleStruct"
|
||||||
},
|
},
|
||||||
|
"bevy_gltf_blueprints::spawn_from_blueprints::BlueprintsList": {
|
||||||
|
"isComponent": true,
|
||||||
|
"isResource": false,
|
||||||
|
"items": false,
|
||||||
|
"prefixItems": [
|
||||||
|
{
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/bevy_utils::hashbrown::HashMap<alloc::string::String, alloc::vec::Vec<alloc::string::String>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"short_name": "BlueprintsList",
|
||||||
|
"title": "bevy_gltf_blueprints::spawn_from_blueprints::BlueprintsList",
|
||||||
|
"type": "array",
|
||||||
|
"typeInfo": "TupleStruct"
|
||||||
|
},
|
||||||
"bevy_gltf_blueprints::spawn_from_blueprints::SpawnHere": {
|
"bevy_gltf_blueprints::spawn_from_blueprints::SpawnHere": {
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"isComponent": true,
|
"isComponent": true,
|
||||||
@ -10691,6 +10718,19 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"typeInfo": "Value"
|
"typeInfo": "Value"
|
||||||
},
|
},
|
||||||
|
"bevy_utils::hashbrown::HashMap<alloc::string::String, alloc::vec::Vec<alloc::string::String>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/$defs/alloc::vec::Vec<alloc::string::String>"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isComponent": false,
|
||||||
|
"isResource": false,
|
||||||
|
"short_name": "HashMap<String, Vec<String>, DefaultHashBuilder>",
|
||||||
|
"title": "bevy_utils::hashbrown::HashMap<alloc::string::String, alloc::vec::Vec<alloc::string::String>, bevy_utils::hashbrown::hash_map::DefaultHashBuilder>",
|
||||||
|
"type": "object",
|
||||||
|
"typeInfo": "Map"
|
||||||
|
},
|
||||||
"bevy_utils::smallvec::SmallVec<[bevy_ecs::entity::Entity; 8]>": {
|
"bevy_utils::smallvec::SmallVec<[bevy_ecs::entity::Entity; 8]>": {
|
||||||
"isComponent": false,
|
"isComponent": false,
|
||||||
"isResource": false,
|
"isResource": false,
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 626 KiB After Width: | Height: | Size: 644 KiB |
@ -3,11 +3,11 @@ use std::{
|
|||||||
collections::HashMap, fs, time::Duration
|
collections::HashMap, fs, time::Duration
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy_gltf_blueprints::{AnimationPlayerLink, Animations, BlueprintName, BlueprintsList};
|
use bevy_gltf_blueprints::{Animated, AnimationPlayerLink, Animations, BlueprintName, BlueprintsList};
|
||||||
pub use in_game::*;
|
pub use in_game::*;
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
ecs::query, prelude::*, render::view::screenshot::ScreenshotManager, time::common_conditions::on_timer, window::PrimaryWindow
|
ecs::query, gltf::Gltf, prelude::*, render::view::screenshot::ScreenshotManager, time::common_conditions::on_timer, window::PrimaryWindow
|
||||||
};
|
};
|
||||||
use bevy_gltf_worlflow_examples_common_rapier::{AppState, GameState};
|
use bevy_gltf_worlflow_examples_common_rapier::{AppState, GameState};
|
||||||
|
|
||||||
@ -19,16 +19,10 @@ fn start_game(mut next_app_state: ResMut<NextState<AppState>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Node {
|
|
||||||
value: String,
|
|
||||||
children: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the export from Blender worked correctly, we should have animations (simplified here by using AnimationPlayerLink)
|
// if the export from Blender worked correctly, we should have animations (simplified here by using AnimationPlayerLink)
|
||||||
// if the export from Blender worked correctly, we should have an Entity called "Cylinder" that has two components: UnitTest, TupleTestF32
|
|
||||||
// if the export from Blender worked correctly, we should have an Entity called "Blueprint4_nested" that has a child called "Blueprint3" that has a "BlueprintName" component with value Blueprint3
|
// if the export from Blender worked correctly, we should have an Entity called "Blueprint4_nested" that has a child called "Blueprint3" that has a "BlueprintName" component with value Blueprint3
|
||||||
// if the export from Blender worked correctly, we should have a blueprints_list
|
// if the export from Blender worked correctly, we should have a blueprints_list
|
||||||
|
// if the export from Blender worked correctly, we should have the correct tree of entities
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn validate_export(
|
fn validate_export(
|
||||||
parents: Query<&Parent>,
|
parents: Query<&Parent>,
|
||||||
@ -36,7 +30,6 @@ fn validate_export(
|
|||||||
names: Query<&Name>,
|
names: Query<&Name>,
|
||||||
blueprints: Query<(Entity, &Name, &BlueprintName)>,
|
blueprints: Query<(Entity, &Name, &BlueprintName)>,
|
||||||
animation_player_links: Query<(Entity, &AnimationPlayerLink)>,
|
animation_player_links: Query<(Entity, &AnimationPlayerLink)>,
|
||||||
exported_cylinder: Query<(Entity, &Name, &UnitTest, &TupleTestF32)>,
|
|
||||||
empties_candidates: Query<(Entity, &Name, &GlobalTransform)>,
|
empties_candidates: Query<(Entity, &Name, &GlobalTransform)>,
|
||||||
|
|
||||||
blueprints_list: Query<(Entity, &BlueprintsList)>,
|
blueprints_list: Query<(Entity, &BlueprintsList)>,
|
||||||
@ -80,11 +73,10 @@ fn validate_export(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate parent/child tree
|
// generate parent/child "tree"
|
||||||
if !root.is_empty() {
|
if !root.is_empty() {
|
||||||
let root = root.single();
|
let root = root.single();
|
||||||
let mut tree: HashMap<String, Vec<String>> = HashMap::new();
|
let mut tree: HashMap<String, Vec<String>> = HashMap::new();
|
||||||
// println!("root {}", root.1);
|
|
||||||
|
|
||||||
for child in children.iter_descendants(root.0) {
|
for child in children.iter_descendants(root.0) {
|
||||||
let child_name:String = names.get(child).map_or(String::from("no_name"), |e| e.to_string() ); //|e| e.to_string(), || "no_name".to_string());
|
let child_name:String = names.get(child).map_or(String::from("no_name"), |e| e.to_string() ); //|e| e.to_string(), || "no_name".to_string());
|
||||||
@ -126,17 +118,64 @@ fn exit_game(mut app_exit_events: ResMut<Events<bevy::app::AppExit>>) {
|
|||||||
app_exit_events.send(bevy::app::AppExit);
|
app_exit_events.send(bevy::app::AppExit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
#[derive(Resource)]
|
|
||||||
struct Animations(Vec<Handle<AnimationClip>>);
|
|
||||||
*/
|
|
||||||
|
|
||||||
fn animations(
|
#[derive(Resource)]
|
||||||
foo:Query<(Entity, &Name, &AnimationPlayer),(Added<AnimationPlayer>)>,
|
struct MainAnimations(Vec<Handle<AnimationClip>>);
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
struct AnimTest(Handle<Gltf>);
|
||||||
|
fn setup_main_scene_animations(
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) {
|
) {
|
||||||
for bla in foo.iter() {
|
/*commands.insert_resource(MainAnimations(vec![
|
||||||
|
asset_server.load("models/World.glb#Blueprint1_jump"),
|
||||||
|
asset_server.load("models/World.glb#Blueprint1_move"),
|
||||||
|
|
||||||
|
// asset_server.load("models/library/Blueprint6_animated.glb#Run"),
|
||||||
|
|
||||||
|
]));*/
|
||||||
|
|
||||||
|
commands.insert_resource(AnimTest(asset_server.load("models/World.glb")));
|
||||||
|
}
|
||||||
|
fn animations(
|
||||||
|
foo:Query<(Entity, &Name, &AnimationPlayer),(Added<AnimationPlayer>)>,
|
||||||
|
bla:Query<(Entity, &Name, &Animated),(Added<Animated>, Without<AnimationPlayerLink>)>,
|
||||||
|
blurp: Res<AnimTest>,
|
||||||
|
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
mut commands: Commands,
|
||||||
|
assets_gltf: Res<Assets<Gltf>>,
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
|
||||||
|
for (entity, name, animated) in bla.iter() {
|
||||||
|
// println!("animated stuf {:?} on entity {}", animated, name);
|
||||||
|
|
||||||
|
let gltf = assets_gltf.get(&blurp.0).unwrap();
|
||||||
|
|
||||||
|
let animations_list = animated;
|
||||||
|
let mut matching_data = true;
|
||||||
|
for animation_name in &animations_list.animations {
|
||||||
|
if !gltf.named_animations.contains_key(animation_name){
|
||||||
|
matching_data = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if matching_data {
|
||||||
|
println!("inserting Animations components into {} ({:?})", name, entity);
|
||||||
|
println!("Found match {:?}", gltf.named_animations);
|
||||||
|
commands.entity(entity).remove::<Animations>();
|
||||||
|
commands.entity(entity).insert((
|
||||||
|
Animations {
|
||||||
|
named_animations: gltf.named_animations.clone()
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*for bla in foo.iter() {
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
counter +=1;
|
counter +=1;
|
||||||
println!("found some animations {} {}", counter, bla.1);
|
println!("found some animations {} {}", counter, bla.1);
|
||||||
@ -150,9 +189,7 @@ fn animations(
|
|||||||
named_animations:
|
named_animations:
|
||||||
})*/
|
})*/
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GamePlugin;
|
pub struct GamePlugin;
|
||||||
@ -162,12 +199,15 @@ impl Plugin for GamePlugin {
|
|||||||
.add_systems(Update, validate_export)
|
.add_systems(Update, validate_export)
|
||||||
.add_systems(OnEnter(AppState::MenuRunning), start_game)
|
.add_systems(OnEnter(AppState::MenuRunning), start_game)
|
||||||
.add_systems(OnEnter(AppState::AppRunning), setup_game)
|
.add_systems(OnEnter(AppState::AppRunning), setup_game)
|
||||||
.add_systems(Update, animations)
|
|
||||||
.add_systems(Update, generate_screenshot.run_if(on_timer(Duration::from_secs_f32(0.2)))) // TODO: run once
|
.add_systems(OnEnter(AppState::MenuRunning), setup_main_scene_animations)
|
||||||
|
|
||||||
|
.add_systems(Update, animations.run_if(in_state(AppState::AppRunning)))
|
||||||
|
/* .add_systems(Update, generate_screenshot.run_if(on_timer(Duration::from_secs_f32(0.2)))) // TODO: run once
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
exit_game.run_if(on_timer(Duration::from_secs_f32(0.5))),
|
exit_game.run_if(on_timer(Duration::from_secs_f32(0.5))),
|
||||||
) // shut down the app after this time
|
) // shut down the app after this time*/
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ def copy_animation_data(source, target):
|
|||||||
bpy.ops.object.make_links_data(type='ANIMATION')
|
bpy.ops.object.make_links_data(type='ANIMATION')
|
||||||
# we add an "animated" flag component
|
# we add an "animated" flag component
|
||||||
target['Animated'] = f'(animations: {animations})'.replace("'", '"') #'(animations: [])' #
|
target['Animated'] = f'(animations: {animations})'.replace("'", '"') #'(animations: [])' #
|
||||||
|
|
||||||
"""print("copying animation data for", source.name, target.animation_data)
|
"""print("copying animation data for", source.name, target.animation_data)
|
||||||
properties = [p.identifier for p in source.animation_data.bl_rna.properties if not p.is_readonly]
|
properties = [p.identifier for p in source.animation_data.bl_rna.properties if not p.is_readonly]
|
||||||
for prop in properties:
|
for prop in properties:
|
||||||
|
@ -30,6 +30,10 @@ def setup_data(request):
|
|||||||
diagnostics_file_path = os.path.join(root_path, "bevy_diagnostics.json")
|
diagnostics_file_path = os.path.join(root_path, "bevy_diagnostics.json")
|
||||||
if os.path.exists(diagnostics_file_path):
|
if os.path.exists(diagnostics_file_path):
|
||||||
os.remove(diagnostics_file_path)
|
os.remove(diagnostics_file_path)
|
||||||
|
|
||||||
|
hierarchy_file_path = os.path.join(root_path, "bevy_hierarchy.json")
|
||||||
|
if os.path.exists(hierarchy_file_path):
|
||||||
|
os.remove(hierarchy_file_path)
|
||||||
|
|
||||||
screenshot_observed_path = os.path.join(root_path, "screenshot.png")
|
screenshot_observed_path = os.path.join(root_path, "screenshot.png")
|
||||||
if os.path.exists(screenshot_observed_path):
|
if os.path.exists(screenshot_observed_path):
|
||||||
|
Loading…
Reference in New Issue
Block a user