diff --git a/crates/bevy_gltf_blueprints/src/clone_entity.rs b/crates/bevy_gltf_blueprints/src/clone_entity.rs index 3702863..28336ab 100644 --- a/crates/bevy_gltf_blueprints/src/clone_entity.rs +++ b/crates/bevy_gltf_blueprints/src/clone_entity.rs @@ -1,66 +1,66 @@ -use bevy::prelude::*; use bevy::ecs::system::Command; +use bevy::prelude::*; // modified version from https://github.com/bevyengine/bevy/issues/1515, // more specifically https://gist.github.com/nwtnni/85d6b87ae75337a522166c500c9a8418 // to work with Bevy 0.11 pub struct CloneEntity { - pub source: Entity, - pub destination: Entity, + pub source: Entity, + pub destination: Entity, } impl CloneEntity { - // Copy all components from an entity to another. - // Using an entity with no components as the destination creates a copy of the source entity. - // Panics if: - // - the components are not registered in the type registry, - // - the world does not have a type registry - // - the source or destination entity do not exist - fn clone_entity(self, world: &mut World) { - let components = { - let registry = world.get_resource::().unwrap().read(); + // Copy all components from an entity to another. + // Using an entity with no components as the destination creates a copy of the source entity. + // Panics if: + // - the components are not registered in the type registry, + // - the world does not have a type registry + // - the source or destination entity do not exist + fn clone_entity(self, world: &mut World) { + let components = { + let registry = world.get_resource::().unwrap().read(); - world - .get_entity(self.source) - .unwrap() - .archetype() - .components() - .map(|component_id| { - world - .components() - .get_info(component_id) - .unwrap() - .type_id() - .unwrap() - }) - .map(|type_id| { - // println!("type_id {:?}", type_id); - registry - .get(type_id) - .unwrap() - .data::() - .unwrap() - .clone() - }) - .collect::>() - }; + world + .get_entity(self.source) + .unwrap() + .archetype() + .components() + .map(|component_id| { + world + .components() + .get_info(component_id) + .unwrap() + .type_id() + .unwrap() + }) + .map(|type_id| { + // println!("type_id {:?}", type_id); + registry + .get(type_id) + .unwrap() + .data::() + .unwrap() + .clone() + }) + .collect::>() + }; - for component in components { - let source = component - .reflect(world.get_entity(self.source).unwrap()) - .unwrap() - .clone_value(); + for component in components { + let source = component + .reflect(world.get_entity(self.source).unwrap()) + .unwrap() + .clone_value(); - let mut destination = world.get_entity_mut(self.destination).unwrap(); + let mut destination = world.get_entity_mut(self.destination).unwrap(); - component.apply_or_insert(&mut destination, &*source); - } - } + component.apply_or_insert(&mut destination, &*source); + } + } } // This allows the command to be used in systems impl Command for CloneEntity { - fn apply(self, world: &mut World) { - self.clone_entity(world) - } -} \ No newline at end of file + fn apply(self, world: &mut World) { + self.clone_entity(world) + } +} diff --git a/crates/bevy_gltf_blueprints/src/lib.rs b/crates/bevy_gltf_blueprints/src/lib.rs index b77c7be..b363262 100644 --- a/crates/bevy_gltf_blueprints/src/lib.rs +++ b/crates/bevy_gltf_blueprints/src/lib.rs @@ -1,5 +1,3 @@ - - pub mod spawn_from_blueprints; pub use spawn_from_blueprints::*; @@ -16,28 +14,27 @@ use bevy_gltf_components::GltfComponentsSet; #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] /// set for the two stages of blueprint based spawning : -pub enum GltfBlueprintsSet{ - Spawn, - AfterSpawn, +pub enum GltfBlueprintsSet { + Spawn, + AfterSpawn, } #[derive(Bundle)] pub struct BluePrintBundle { pub blueprint: BlueprintName, pub spawn_here: SpawnHere, - pub transform: TransformBundle + pub transform: TransformBundle, } impl Default for BluePrintBundle { - fn default() -> Self { - BluePrintBundle { - blueprint: BlueprintName("default".into()), - spawn_here: SpawnHere, - transform: TransformBundle::default() + fn default() -> Self { + BluePrintBundle { + blueprint: BlueprintName("default".into()), + spawn_here: SpawnHere, + transform: TransformBundle::default(), + } } - } } - #[derive(Clone, Resource)] pub(crate) struct BluePrintsConfig { pub(crate) library_folder: PathBuf, @@ -45,49 +42,49 @@ pub(crate) struct BluePrintsConfig { #[derive(Debug, Clone)] pub struct BlueprintsPlugin { - /// The base folder where library/blueprints assets are loaded from, relative to the executable. - pub library_folder: PathBuf, + /// The base folder where library/blueprints assets are loaded from, relative to the executable. + pub library_folder: PathBuf, } impl Default for BlueprintsPlugin { - fn default() -> Self { - Self { - library_folder: PathBuf::from("assets/models/library"), - } - } + fn default() -> Self { + Self { + library_folder: PathBuf::from("assets/models/library"), + } + } } impl Plugin for BlueprintsPlugin { - fn build(&self, app: &mut App) { - app - .register_type::() - .register_type::() - .insert_resource(BluePrintsConfig{library_folder: self.library_folder.clone()}) - - .configure_sets( - Update, - (GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn).chain().after(GltfComponentsSet::Injection) - ) - - .add_systems(Update, - (spawn_from_blueprints) - // .run_if(in_state(AppState::AppRunning).or_else(in_state(AppState::LoadingGame))) // FIXME: how to replace this with a crate compatible version ? - .in_set(GltfBlueprintsSet::Spawn), - ) - - .add_systems( - Update, - ( - // spawn_entities, - update_spawned_root_first_child, - apply_deferred, - cleanup_scene_instances, - apply_deferred, - ) - .chain() - // .run_if(in_state(AppState::LoadingGame).or_else(in_state(AppState::AppRunning))) // FIXME: how to replace this with a crate compatible version ? - .in_set(GltfBlueprintsSet::AfterSpawn), - ) - ; - } -} \ No newline at end of file + fn build(&self, app: &mut App) { + app.register_type::() + .register_type::() + .insert_resource(BluePrintsConfig { + library_folder: self.library_folder.clone(), + }) + .configure_sets( + Update, + (GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn) + .chain() + .after(GltfComponentsSet::Injection), + ) + .add_systems( + Update, + (spawn_from_blueprints) + // .run_if(in_state(AppState::AppRunning).or_else(in_state(AppState::LoadingGame))) // FIXME: how to replace this with a crate compatible version ? + .in_set(GltfBlueprintsSet::Spawn), + ) + .add_systems( + Update, + ( + // spawn_entities, + update_spawned_root_first_child, + apply_deferred, + cleanup_scene_instances, + apply_deferred, + ) + .chain() + // .run_if(in_state(AppState::LoadingGame).or_else(in_state(AppState::AppRunning))) // FIXME: how to replace this with a crate compatible version ? + .in_set(GltfBlueprintsSet::AfterSpawn), + ); + } +} diff --git a/crates/bevy_gltf_blueprints/src/spawn_from_blueprints.rs b/crates/bevy_gltf_blueprints/src/spawn_from_blueprints.rs index ed379f5..2e7c6e5 100644 --- a/crates/bevy_gltf_blueprints/src/spawn_from_blueprints.rs +++ b/crates/bevy_gltf_blueprints/src/spawn_from_blueprints.rs @@ -1,6 +1,6 @@ use std::path::Path; -use bevy::{prelude::*, gltf::Gltf}; +use bevy::{gltf::Gltf, prelude::*}; use crate::BluePrintsConfig; @@ -9,12 +9,12 @@ use crate::BluePrintsConfig; pub struct GameWorldTag; /// Main component for the blueprints -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] pub struct BlueprintName(pub String); /// flag component needed to signify the intent to spawn a Blueprint -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] pub struct SpawnHere; @@ -22,7 +22,6 @@ pub struct SpawnHere; /// FlagComponent for spawned entity pub struct Spawned; - #[derive(Component)] /// helper component, just to transfer some data pub(crate) struct Original(pub Entity); @@ -31,56 +30,69 @@ pub(crate) struct Original(pub Entity); /// FlagComponent for dynamically spawned scenes pub struct SpawnedRoot; -/// main spawning functions, +/// main spawning functions, /// * also takes into account the already exisiting "override" components, ie "override components" > components from blueprint pub(crate) fn spawn_from_blueprints( - spawn_placeholders: Query<(Entity, &Name, &BlueprintName, &Transform), (Added, Added, Without, Without)>, + spawn_placeholders: Query< + (Entity, &Name, &BlueprintName, &Transform), + ( + Added, + Added, + Without, + Without, + ), + >, mut commands: Commands, mut game_world: Query<(Entity, &Children), With>, assets_gltf: Res>, asset_server: Res, - blueprints_config: Res -){ - + blueprints_config: Res, +) { for (entity, name, blupeprint_name, global_transform) in spawn_placeholders.iter() { info!("need to spawn {:?}", blupeprint_name.0); let what = &blupeprint_name.0; - let model_file_name = format!("{}.glb",&what); - let model_path = Path::new(&blueprints_config.library_folder) - .join(Path::new(model_file_name.as_str())); - - info!("attempting to spawn {:?}",model_path); - let scene:Handle = asset_server.load(model_path); + let model_file_name = format!("{}.glb", &what); + let model_path = + Path::new(&blueprints_config.library_folder).join(Path::new(model_file_name.as_str())); + + info!("attempting to spawn {:?}", model_path); + let scene: Handle = asset_server.load(model_path); // let scene = game_assets.models.get(&model_path).expect(&format!("no matching model {:?} found", model_path)); let world = game_world.single_mut(); let world = world.1[0]; // FIXME: dangerous hack because our gltf data have a single child like this, but might not always be the case - - let gltf = assets_gltf.get(&scene).expect("this gltf should have been loaded"); + + let gltf = assets_gltf + .get(&scene) + .expect("this gltf should have been loaded"); // WARNING we work under the assumtion that there is ONLY ONE named scene, and that the first one is the right one - let main_scene_name =gltf.named_scenes.keys().nth(0).expect("there should be at least one named scene in the gltf file to spawn"); + let main_scene_name = gltf + .named_scenes + .keys() + .nth(0) + .expect("there should be at least one named scene in the gltf file to spawn"); let scene = &gltf.named_scenes[main_scene_name]; - //spawn_requested_events.send(SpawnRequestedEvent { what: "enemy".into(), position, amount: 1, spawner_id: None }); - let child_scene = commands.spawn( - ( - SceneBundle { - scene: scene.clone(), - transform: global_transform.clone(), - ..Default::default() - }, - bevy::prelude::Name::from(["scene_wrapper", &name.clone()].join("_") ), - // Parent(world) // FIXME/ would be good if this worked directly - SpawnedRoot, - /*AnimationHelper{ // TODO: insert this at the ENTITY level, not the scene level - named_animations: gltf.named_animations.clone(), - // animations: gltf.named_animations.values().clone() - },*/ - Original(entity) - )).id(); - commands.entity(world).add_child(child_scene); + let child_scene = commands + .spawn(( + SceneBundle { + scene: scene.clone(), + transform: global_transform.clone(), + ..Default::default() + }, + bevy::prelude::Name::from(["scene_wrapper", &name.clone()].join("_")), + // Parent(world) // FIXME/ would be good if this worked directly + SpawnedRoot, + /*AnimationHelper{ // TODO: insert this at the ENTITY level, not the scene level + named_animations: gltf.named_animations.clone(), + // animations: gltf.named_animations.values().clone() + },*/ + Original(entity), + )) + .id(); + commands.entity(world).add_child(child_scene); } -} \ No newline at end of file +} diff --git a/crates/bevy_gltf_blueprints/src/spawn_post_process.rs b/crates/bevy_gltf_blueprints/src/spawn_post_process.rs index 3534e75..012bb06 100644 --- a/crates/bevy_gltf_blueprints/src/spawn_post_process.rs +++ b/crates/bevy_gltf_blueprints/src/spawn_post_process.rs @@ -4,20 +4,17 @@ use bevy::utils::HashMap; use super::{CloneEntity, SpawnHere}; use super::{Original, SpawnedRoot}; - // FIXME: move to more relevant module -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] pub struct AnimationHelper { - pub named_animations: HashMap>, + pub named_animations: HashMap>, } #[derive(Component)] /// FlagComponent for dynamically spawned scenes pub(crate) struct SpawnedRootProcessed; - - /// this system updates the first (and normally only) child of a scene flaged SpawnedRoot /// - adds a name based on parent component (spawned scene) which is named on the scene name/prefab to be instanciated /// - adds the initial physics impulse (FIXME: we would need to add a temporary physics component to those who do not have it) @@ -26,112 +23,113 @@ pub(crate) struct SpawnedRootProcessed; // - scene instance -> does not work // it might be due to how we add components to the PARENT item in gltf to components pub(crate) fn update_spawned_root_first_child( - // all_children: Query<(Entity, &Children)>, - unprocessed_entities :Query<(Entity, &Children, &Name, &Parent, &Original ), (With, Without)>, - mut commands: Commands, + // all_children: Query<(Entity, &Children)>, + unprocessed_entities: Query< + (Entity, &Children, &Name, &Parent, &Original), + (With, Without), + >, + mut commands: Commands, - // FIXME: should be done at a more generic gltf level - animation_helpers: Query<&AnimationHelper>, - added_animation_helpers : Query<(Entity, &AnimationPlayer), Added> -){ - /* + // FIXME: should be done at a more generic gltf level + animation_helpers: Query<&AnimationHelper>, + added_animation_helpers: Query<(Entity, &AnimationPlayer), Added>, +) { + /* currently we have - - scene instance + - scene instance - root node ? - the actual stuff - we want to remove the root node - so we wend up with + we want to remove the root node + so we wend up with - scene instance - the actual stuff - so + so - get root node - add its children to the scene instance - remove root node - + Another issue is, the scene instance become empty if we have a pickabke as the "actual stuff", so that would lead to a lot of empty scenes if we spawn pickables - perhaps another system that cleans up empty scene instances ? FIME: this is all highly dependent on the hierachy ;.. */ - - for (scene_instance, children, name, parent, original) in unprocessed_entities.iter() { - // - if children.len() == 0 { - warn!("timing issue ! no children found, please restart your bevy app (bug being investigated)"); - // println!("children of scene {:?}", children); - continue; - } - // the root node is the first & normally only child inside a scene, it is the one that has all relevant components - let root_entity = children.first().unwrap(); //FIXME: and what about childless ones ?? => should not be possible normally - // let root_entity_data = all_children.get(*root_entity).unwrap(); - // fixme : randomization should be controlled via parameters, perhaps even the seed could be specified ? - // use this https://rust-random.github.io/book/guide-seeding.html#a-simple-number, blenders seeds are also uInts - // also this is not something we want every time, this should be a settable parameter when requesting a spawn - - - // add missing name of entity, based on the wrapper's name - let name= name.clone().replace("scene_wrapper_", ""); - - // this is our new actual entity - commands.entity(*root_entity).insert(( - bevy::prelude::Name::from(name.clone()), - // ItemType {name}, - // Spawned, // FIXME: not sure - )); - - // flag the spawned_root as being processed - commands.entity(scene_instance).insert(SpawnedRootProcessed); - - - // let original_transforms = - // parent is either the world or an entity with a marker (BlueprintName) - commands.entity(parent.get()).add_child(*root_entity); - // commands.entity(*root_entity).despawn_recursive(); - // commands.entity(parent.get()).push_children(&actual_stuff); - //commands.entity(*root_entity).log_components(); - - let matching_animation_helper = animation_helpers.get(scene_instance); - - // println!("WE HAVE SOME ADDED ANIMATION PLAYERS {:?}", matching_animation_helper); - if let Ok(anim_helper) = matching_animation_helper{ - for (added, _) in added_animation_helpers.iter(){ - commands.entity(added).insert( - AnimationHelper{ // TODO: insert this at the ENTITY level, not the scene level - named_animations: anim_helper.named_animations.clone(), - // animations: gltf.named_animations.values().clone() - }, - ); + for (scene_instance, children, name, parent, original) in unprocessed_entities.iter() { + // + if children.len() == 0 { + warn!("timing issue ! no children found, please restart your bevy app (bug being investigated)"); + // println!("children of scene {:?}", children); + continue; } - } + // the root node is the first & normally only child inside a scene, it is the one that has all relevant components + let root_entity = children.first().unwrap(); //FIXME: and what about childless ones ?? => should not be possible normally + // let root_entity_data = all_children.get(*root_entity).unwrap(); - commands.add(CloneEntity { - source: original.0, - destination: *root_entity, - }); + // fixme : randomization should be controlled via parameters, perhaps even the seed could be specified ? + // use this https://rust-random.github.io/book/guide-seeding.html#a-simple-number, blenders seeds are also uInts + // also this is not something we want every time, this should be a settable parameter when requesting a spawn - // remove the original entity, now that we have cloned it into the spawned scenes first child - commands.entity(original.0).despawn_recursive(); - commands.entity(*root_entity).remove::(); - } + // add missing name of entity, based on the wrapper's name + let name = name.clone().replace("scene_wrapper_", ""); + + // this is our new actual entity + commands.entity(*root_entity).insert(( + bevy::prelude::Name::from(name.clone()), + // ItemType {name}, + // Spawned, // FIXME: not sure + )); + + // flag the spawned_root as being processed + commands.entity(scene_instance).insert(SpawnedRootProcessed); + + // let original_transforms = + // parent is either the world or an entity with a marker (BlueprintName) + commands.entity(parent.get()).add_child(*root_entity); + // commands.entity(*root_entity).despawn_recursive(); + // commands.entity(parent.get()).push_children(&actual_stuff); + //commands.entity(*root_entity).log_components(); + + let matching_animation_helper = animation_helpers.get(scene_instance); + + // println!("WE HAVE SOME ADDED ANIMATION PLAYERS {:?}", matching_animation_helper); + if let Ok(anim_helper) = matching_animation_helper { + for (added, _) in added_animation_helpers.iter() { + commands.entity(added).insert(AnimationHelper { + // TODO: insert this at the ENTITY level, not the scene level + named_animations: anim_helper.named_animations.clone(), + // animations: gltf.named_animations.values().clone() + }); + } + } + + commands.add(CloneEntity { + source: original.0, + destination: *root_entity, + }); + + // remove the original entity, now that we have cloned it into the spawned scenes first child + commands.entity(original.0).despawn_recursive(); + commands.entity(*root_entity).remove::(); + } } /// cleans up dynamically spawned scenes so that they get despawned if they have no more children pub(crate) fn cleanup_scene_instances( - scene_instances: Query<(Entity, &Children), With>, - without_children: Query, Without)>,// if there are not children left, bevy removes Children ? - mut commands: Commands -){ - for (entity, children) in scene_instances.iter(){ - if children.len() == 0{ // it seems this does not happen ? - info!("cleaning up emptied spawned scene instance"); - commands.entity(entity).despawn_recursive(); - } - } - for entity in without_children.iter() { - info!("cleaning up emptied spawned scene instance"); - commands.entity(entity).despawn_recursive(); - } + scene_instances: Query<(Entity, &Children), With>, + without_children: Query, Without)>, // if there are not children left, bevy removes Children ? + mut commands: Commands, +) { + for (entity, children) in scene_instances.iter() { + if children.len() == 0 { + // it seems this does not happen ? + info!("cleaning up emptied spawned scene instance"); + commands.entity(entity).despawn_recursive(); + } + } + for entity in without_children.iter() { + info!("cleaning up emptied spawned scene instance"); + commands.entity(entity).despawn_recursive(); + } } diff --git a/crates/bevy_gltf_components/src/gltf_to_components.rs b/crates/bevy_gltf_components/src/gltf_to_components.rs index afcca23..1083cdd 100644 --- a/crates/bevy_gltf_components/src/gltf_to_components.rs +++ b/crates/bevy_gltf_components/src/gltf_to_components.rs @@ -3,13 +3,13 @@ use core::ops::Deref; use ron::Value; use serde::de::DeserializeSeed; -use bevy::prelude::{ResMut, Assets, info, debug, Name, Parent, warn}; use bevy::ecs::{entity::Entity, reflect::ReflectComponent}; +use bevy::gltf::{Gltf, GltfExtras}; +use bevy::prelude::{debug, info, warn, Assets, Name, Parent, ResMut}; +use bevy::reflect::serde::UntypedReflectDeserializer; +use bevy::reflect::{Reflect, TypeInfo, TypeRegistryInternal}; use bevy::scene::Scene; use bevy::utils::HashMap; -use bevy::reflect::serde::UntypedReflectDeserializer; -use bevy::reflect::{TypeRegistryInternal, TypeInfo, Reflect}; -use bevy::gltf::{Gltf, GltfExtras}; use super::capitalize_first_letter; @@ -18,216 +18,227 @@ pub fn gltf_extras_to_components( gltf: &mut Gltf, scenes: &mut ResMut>, type_registry: impl Deref, - gltf_name: &str -){ - let mut added_components = 0; + gltf_name: &str, +) { + let mut added_components = 0; for (_name, scene) in &gltf.named_scenes { - debug!("gltf: {:?} scene name {:?}", gltf_name, _name); - - let scene = scenes.get_mut(scene).unwrap(); + debug!("gltf: {:?} scene name {:?}", gltf_name, _name); - let mut query = scene.world.query::<(Entity, &Name, &GltfExtras, &Parent)>(); - let mut entity_components: HashMap> > = HashMap::new(); - for (entity, name, extras, parent) in query.iter(&scene.world) { - debug!("Name: {}, entity {:?}, parent: {:?}", name, entity, parent); - let reflect_components = ronstring_to_reflect_component(&extras.value, &type_registry); - added_components = reflect_components.len(); - debug!("Found components {}", added_components); + let scene = scenes.get_mut(scene).unwrap(); - // we assign the components specified /xxx_components objects to their parent node - let mut target_entity = entity; - // if the node contains "components" or ends with "_pa" (ie add to parent), the components will not be added to the entity itself but to its parent - // this is mostly used for Blender collections - if name.as_str().contains("components") || name.as_str().ends_with("_pa") { - debug!("adding components to parent"); - target_entity = parent.get(); + let mut query = scene.world.query::<(Entity, &Name, &GltfExtras, &Parent)>(); + let mut entity_components: HashMap>> = HashMap::new(); + for (entity, name, extras, parent) in query.iter(&scene.world) { + debug!("Name: {}, entity {:?}, parent: {:?}", name, entity, parent); + let reflect_components = ronstring_to_reflect_component(&extras.value, &type_registry); + added_components = reflect_components.len(); + debug!("Found components {}", added_components); + + // we assign the components specified /xxx_components objects to their parent node + let mut target_entity = entity; + // if the node contains "components" or ends with "_pa" (ie add to parent), the components will not be added to the entity itself but to its parent + // this is mostly used for Blender collections + if name.as_str().contains("components") || name.as_str().ends_with("_pa") { + debug!("adding components to parent"); + target_entity = parent.get(); + } + + debug!("adding to {:?}", target_entity); + + // if there where already components set to be added to this entity (for example when entity_data was refering to a parent), update the vec of entity_components accordingly + // this allows for example blender collection to provide basic ecs data & the instances to override/ define their own values + if entity_components.contains_key(&target_entity) { + let mut updated_components: Vec> = Vec::new(); + let current_components = &entity_components[&target_entity]; + // first inject the current components + for component in current_components { + updated_components.push(component.clone_value()); + } + // then inject the new components: this also enables overwrite components set in the collection + for component in reflect_components { + updated_components.push(component.clone_value()); + } + entity_components.insert(target_entity, updated_components); + } else { + entity_components.insert(target_entity, reflect_components); + } + // shorthand, did not manage to get it working + /* entity_components.insert( + target_entity, + if entity_components.contains_key(&target_entity) { + entity_components[&target_entity].push(reflect_components) } else { reflect_components } + );*/ + + debug!("-----value {:?}", &extras.value); } - - debug!("adding to {:?}", target_entity); - // if there where already components set to be added to this entity (for example when entity_data was refering to a parent), update the vec of entity_components accordingly - // this allows for example blender collection to provide basic ecs data & the instances to override/ define their own values - if entity_components.contains_key(&target_entity) { - let mut updated_components: Vec> = Vec::new(); - let current_components = &entity_components[&target_entity]; - // first inject the current components - for component in current_components { - updated_components.push(component.clone_value()); - } - // then inject the new components: this also enables overwrite components set in the collection - for component in reflect_components { - updated_components.push(component.clone_value()); - } - entity_components.insert(target_entity, updated_components); - - - }else { - entity_components.insert(target_entity, reflect_components); - } - // shorthand, did not manage to get it working - /* entity_components.insert( - target_entity, - if entity_components.contains_key(&target_entity) { - entity_components[&target_entity].push(reflect_components) } else { reflect_components } - );*/ + // GltfNode + // find a way to link this name to the current entity ? => WOULD BE VERY USEFULL for animations & co !! + debug!("done pre-processing components, now adding them to entities"); + for (entity, components) in entity_components { + if !components.is_empty() { + debug!("--entity {:?}, components {}", entity, components.len()); + } + for component in components { + let mut entity_mut = scene.world.entity_mut(entity); + debug!("------adding {} {:?}", component.type_name(), component); - debug!("-----value {:?}", &extras.value); - } + type_registry + .get_with_name(component.type_name()) + .unwrap() // Component was successfully deserialized, it has to be in the registry + .data::() + .unwrap() // Hopefully, the component deserializer ensures those are components + .insert(&mut entity_mut, &*component); - // GltfNode - // find a way to link this name to the current entity ? => WOULD BE VERY USEFULL for animations & co !! - debug!("done pre-processing components, now adding them to entities"); - for (entity, components) in entity_components { - if !components.is_empty() { - debug!("--entity {:?}, components {}", entity, components.len()); - } - for component in components { - let mut entity_mut = scene.world.entity_mut(entity); - debug!("------adding {} {:?}", component.type_name(), component); - - type_registry - .get_with_name(component.type_name()) - .unwrap() // Component was successfully deserialized, it has to be in the registry - .data::() - .unwrap() // Hopefully, the component deserializer ensures those are components - .insert(&mut entity_mut, &*component) - ; - - // info!("all components {:?}", scene.world.entity(entity).archetype().components()); - // scene.world.components(). + // info!("all components {:?}", scene.world.entity(entity).archetype().components()); + // scene.world.components(). // TODO: how can we insert any additional components "by hand" here ? - } - // let entity_mut = scene.world.entity_mut(entity); - // let archetype = entity_mut.archetype().clone(); - // let _all_components = archetype.components(); + } + // let entity_mut = scene.world.entity_mut(entity); + // let archetype = entity_mut.archetype().clone(); + // let _all_components = archetype.components(); - if added_components > 0 { - debug!("------done adding {} components", added_components); + if added_components > 0 { + debug!("------done adding {} components", added_components); + } } - } } - info!("done extracting gltf_extras /n"); - } - - pub fn ronstring_to_reflect_component( + info!("done extracting gltf_extras /n"); +} + +pub fn ronstring_to_reflect_component( ron_string: &String, - type_registry: &TypeRegistryInternal - ) -> Vec> { - let lookup: HashMap = ron::from_str(ron_string.as_str()).unwrap(); + type_registry: &TypeRegistryInternal, +) -> Vec> { + let lookup: HashMap = ron::from_str(ron_string.as_str()).unwrap(); let mut components: Vec> = Vec::new(); for (key, value) in lookup.into_iter() { - let type_string = key.replace("component: ", "").trim().to_string(); - let capitalized_type_name = capitalize_first_letter(type_string.as_str()); + let type_string = key.replace("component: ", "").trim().to_string(); + let capitalized_type_name = capitalize_first_letter(type_string.as_str()); - let mut parsed_value:String; - match value.clone() { - Value::String(str) => { - parsed_value = str; - } - _=> { - parsed_value = ron::to_string(&value).unwrap().to_string() - } - } - - if let Some(type_registration) = type_registry.get_with_short_name(capitalized_type_name.as_str()) { - // println!("TYPE INFO {:?}", type_registration.type_info()); - match type_registration.type_info() { - TypeInfo::TupleStruct (info) => { - // we handle tupple strucs with only one field differently, as Blender's custom properties with custom ui (float, int, bool, etc) always give us a tupple struct - if info.field_len() == 1 { - let field = info.field_at(0).expect("we should always have at least one field here"); - let field_name = field.type_name(); - // TODO: find a way to cast with typeId instead of this matching - /*match field.type_id(){ - TypeId::of::() => { - println!("WE HAVE A f32"); - } - } - Vec3 => { - println!("WE HAVE A VEC3"); - let bla:Vec3 = ron::from_str(&parsed_value).unwrap(); - println!("bla {}", bla) - } - _ =>{} - }*/ - let mut formated = parsed_value.clone(); - match field_name { - "f32" => { - formated = parsed_value.parse::().unwrap().to_string(); - } - "f64" => { - formated = parsed_value.parse::().unwrap().to_string(); - } - "u8" => { - formated = parsed_value.parse::().unwrap().to_string(); - } - "u16" => { - formated = parsed_value.parse::().unwrap().to_string(); - } - "u32" => { - formated = parsed_value.parse::().unwrap().to_string(); - } - "u64" => { - formated = parsed_value.parse::().unwrap().to_string(); - } - "u128" => { - formated = parsed_value.parse::().unwrap().to_string(); - } - "glam::f32::vec2::Vec2" => { - let parsed: Vec = ron::from_str(&parsed_value).unwrap(); - formated = format!("(x:{},y:{})", parsed[0], parsed[1]); - } - "glam::f32::vec3::Vec3" => { - let parsed: Vec = ron::from_str(&parsed_value).unwrap(); - formated = format!("(x:{},y:{},z:{})", parsed[0], parsed[1], parsed[2]); - }, - "bevy_render::color::Color" => { - let parsed: Vec = ron::from_str(&parsed_value).unwrap(); - if parsed.len() == 3 { - formated = format!("Rgba(red:{},green:{},blue:{}, alpha: 1.0)", parsed[0], parsed[1], parsed[2]); - } - if parsed.len() == 4 { - formated = format!("Rgba(red:{},green:{},blue:{}, alpha:{})", parsed[0], parsed[1], parsed[2], parsed[3]); - } - } - _ => {} - } - - parsed_value = format!("({formated})"); - + let mut parsed_value: String; + match value.clone() { + Value::String(str) => { + parsed_value = str; } - } - _ => {} + _ => parsed_value = ron::to_string(&value).unwrap().to_string(), } - // println!("parsed value {}",parsed_value); - if parsed_value.is_empty() { - parsed_value = "()".to_string(); - } - - let ron_string = format!("{{ \"{}\":{} }}", - type_registration.type_name(), - parsed_value - ); + if let Some(type_registration) = + type_registry.get_with_short_name(capitalized_type_name.as_str()) + { + // println!("TYPE INFO {:?}", type_registration.type_info()); + match type_registration.type_info() { + TypeInfo::TupleStruct(info) => { + // we handle tupple strucs with only one field differently, as Blender's custom properties with custom ui (float, int, bool, etc) always give us a tupple struct + if info.field_len() == 1 { + let field = info + .field_at(0) + .expect("we should always have at least one field here"); + let field_name = field.type_name(); + // TODO: find a way to cast with typeId instead of this matching + /*match field.type_id(){ + TypeId::of::() => { + println!("WE HAVE A f32"); + } + } + Vec3 => { + println!("WE HAVE A VEC3"); + let bla:Vec3 = ron::from_str(&parsed_value).unwrap(); + println!("bla {}", bla) + } + _ =>{} + }*/ + let mut formated = parsed_value.clone(); + match field_name { + "f32" => { + formated = parsed_value.parse::().unwrap().to_string(); + } + "f64" => { + formated = parsed_value.parse::().unwrap().to_string(); + } + "u8" => { + formated = parsed_value.parse::().unwrap().to_string(); + } + "u16" => { + formated = parsed_value.parse::().unwrap().to_string(); + } + "u32" => { + formated = parsed_value.parse::().unwrap().to_string(); + } + "u64" => { + formated = parsed_value.parse::().unwrap().to_string(); + } + "u128" => { + formated = parsed_value.parse::().unwrap().to_string(); + } + "glam::f32::vec2::Vec2" => { + let parsed: Vec = ron::from_str(&parsed_value).unwrap(); + formated = format!("(x:{},y:{})", parsed[0], parsed[1]); + } + "glam::f32::vec3::Vec3" => { + let parsed: Vec = ron::from_str(&parsed_value).unwrap(); + formated = + format!("(x:{},y:{},z:{})", parsed[0], parsed[1], parsed[2]); + } + "bevy_render::color::Color" => { + let parsed: Vec = ron::from_str(&parsed_value).unwrap(); + if parsed.len() == 3 { + formated = format!( + "Rgba(red:{},green:{},blue:{}, alpha: 1.0)", + parsed[0], parsed[1], parsed[2] + ); + } + if parsed.len() == 4 { + formated = format!( + "Rgba(red:{},green:{},blue:{}, alpha:{})", + parsed[0], parsed[1], parsed[2], parsed[3] + ); + } + } + _ => {} + } - // usefull to determine what an entity looks like Serialized - /*let test_struct = TuppleTestStr::default(); - let serializer = ReflectSerializer::new(&test_struct, &type_registry); - let serialized = - ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap(); - println!("serialized Component {}", serialized);*/ + parsed_value = format!("({formated})"); + } + } + _ => {} + } - // println!("component data ron string {}", ron_string); - let mut deserializer = ron::Deserializer::from_str(ron_string.as_str()).unwrap(); - let reflect_deserializer = UntypedReflectDeserializer::new(type_registry); - let component = reflect_deserializer.deserialize(&mut deserializer).expect(format!("failed to deserialize component {} with value: {:?}", key, value).as_str()); + // println!("parsed value {}",parsed_value); + if parsed_value.is_empty() { + parsed_value = "()".to_string(); + } - components.push(component); - debug!("found type registration for {}", capitalized_type_name); - } else { - warn!("no type registration for {}", capitalized_type_name); - } + let ron_string = format!( + "{{ \"{}\":{} }}", + type_registration.type_name(), + parsed_value + ); + + // usefull to determine what an entity looks like Serialized + /*let test_struct = TuppleTestStr::default(); + let serializer = ReflectSerializer::new(&test_struct, &type_registry); + let serialized = + ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap(); + println!("serialized Component {}", serialized);*/ + + // println!("component data ron string {}", ron_string); + let mut deserializer = ron::Deserializer::from_str(ron_string.as_str()).unwrap(); + let reflect_deserializer = UntypedReflectDeserializer::new(type_registry); + let component = reflect_deserializer.deserialize(&mut deserializer).expect( + format!( + "failed to deserialize component {} with value: {:?}", + key, value + ) + .as_str(), + ); + + components.push(component); + debug!("found type registration for {}", capitalized_type_name); + } else { + warn!("no type registration for {}", capitalized_type_name); + } } components - } - +} diff --git a/crates/bevy_gltf_components/src/lib.rs b/crates/bevy_gltf_components/src/lib.rs index 47b21a5..7f78a25 100644 --- a/crates/bevy_gltf_components/src/lib.rs +++ b/crates/bevy_gltf_components/src/lib.rs @@ -7,10 +7,7 @@ pub use gltf_to_components::*; pub mod process_gltfs; pub use process_gltfs::*; -use bevy::prelude::{ - App,Plugin, Update, SystemSet, IntoSystemConfigs -}; - +use bevy::prelude::{App, IntoSystemConfigs, Plugin, SystemSet, Update}; /// A Bevy plugin for extracting components from gltf files and automatically adding them to the relevant entities /// It will automatically run every time you load a gltf file @@ -19,7 +16,7 @@ use bevy::prelude::{ /// # use bevy::prelude::*; /// # use bevy::gltf::*; /// # use bevy_gltf_components::ComponentsFromGltfPlugin; -/// +/// /// //too barebones of an example to be meaningfull, please see https://github.com/kaosat-dev/Blender_bevy_components_workflow/examples/basic for a real example /// fn main() { /// App::new() @@ -28,9 +25,9 @@ use bevy::prelude::{ /// .add_system(spawn_level) /// .run(); /// } -/// +/// /// fn spawn_level( -/// asset_server: Res, +/// asset_server: Res, /// mut commands: bevy::prelude::Commands, /// keycode: Res>, @@ -45,30 +42,21 @@ use bevy::prelude::{ ///} /// ``` - #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] /// systemset to order your systems after the component injection when needed -pub enum GltfComponentsSet{ - Injection, +pub enum GltfComponentsSet { + Injection, } - #[derive(Default)] pub struct ComponentsFromGltfPlugin; impl Plugin for ComponentsFromGltfPlugin { - fn build(&self, app: &mut App) { - app - .insert_resource(GltfLoadingTracker::new()) - - .add_systems(Update, ( - track_new_gltf, - process_loaded_scenes, - )) - - .add_systems(Update, - (process_loaded_scenes) - .in_set(GltfComponentsSet::Injection) - ) - ; - } + fn build(&self, app: &mut App) { + app.insert_resource(GltfLoadingTracker::new()) + .add_systems(Update, (track_new_gltf, process_loaded_scenes)) + .add_systems( + Update, + (process_loaded_scenes).in_set(GltfComponentsSet::Injection), + ); + } } diff --git a/crates/bevy_gltf_components/src/process_gltfs.rs b/crates/bevy_gltf_components/src/process_gltfs.rs index dce20d4..10e5ea0 100644 --- a/crates/bevy_gltf_components/src/process_gltfs.rs +++ b/crates/bevy_gltf_components/src/process_gltfs.rs @@ -1,33 +1,32 @@ -use bevy::utils::HashSet; -use bevy::{prelude::*, asset::LoadState}; use bevy::gltf::Gltf; +use bevy::utils::HashSet; +use bevy::{asset::LoadState, prelude::*}; use super::gltf_extras_to_components; #[derive(Resource)] /// component to keep track of gltfs' loading state -pub struct GltfLoadingTracker{ +pub struct GltfLoadingTracker { pub loading_gltfs: HashSet>, - pub loaded_gltfs: HashSet> - } + pub loaded_gltfs: HashSet>, +} - impl GltfLoadingTracker { - pub fn new() -> GltfLoadingTracker { - GltfLoadingTracker { - loaded_gltfs : HashSet::new(), - loading_gltfs: HashSet::new() +impl GltfLoadingTracker { + pub fn new() -> GltfLoadingTracker { + GltfLoadingTracker { + loaded_gltfs: HashSet::new(), + loading_gltfs: HashSet::new(), } - } - pub fn add_scene(&mut self, handle: Handle) { + } + pub fn add_scene(&mut self, handle: Handle) { self.loading_gltfs.insert(handle); - } - } - + } +} - pub fn track_new_gltf( +pub fn track_new_gltf( mut tracker: ResMut, mut events: EventReader>, - ) { +) { for event in events.iter() { if let AssetEvent::Created { handle } = event { tracker.add_scene(handle.clone()); @@ -37,21 +36,22 @@ pub struct GltfLoadingTracker{ events.clear(); } - pub fn process_loaded_scenes( +pub fn process_loaded_scenes( mut gltfs: ResMut>, mut scenes: ResMut>, mut tracker: ResMut, app_type_registry: Res, asset_server: Res, - - ) { - +) { let mut loaded_gltfs = Vec::new(); for gltf in &tracker.loading_gltfs { - info!("checking for loaded gltfs {:?}", asset_server.get_load_state(gltf)); + info!( + "checking for loaded gltfs {:?}", + asset_server.get_load_state(gltf) + ); if asset_server.get_load_state(gltf.clone()) == LoadState::Loaded { - debug!("Adding scene to processing list"); + debug!("Adding scene to processing list"); loaded_gltfs.push(gltf.clone()); } } @@ -60,21 +60,17 @@ pub struct GltfLoadingTracker{ for gltf_handle in &loaded_gltfs { if let Some(gltf) = gltfs.get_mut(gltf_handle) { - - // TODO this is a temporary workaround for library management - if let Some(asset_path) = asset_server.get_handle_path(gltf_handle) { - let gltf_name = asset_path.path().file_stem().unwrap().to_str().unwrap(); - gltf_extras_to_components(gltf, &mut scenes, &*type_registry, gltf_name); - //gltf_extras_to_prefab_infos(gltf, &mut scenes, &*type_registry, gltf_name); - } - else { - gltf_extras_to_components(gltf, &mut scenes, &*type_registry, ""); - } + // TODO this is a temporary workaround for library management + if let Some(asset_path) = asset_server.get_handle_path(gltf_handle) { + let gltf_name = asset_path.path().file_stem().unwrap().to_str().unwrap(); + gltf_extras_to_components(gltf, &mut scenes, &*type_registry, gltf_name); + //gltf_extras_to_prefab_infos(gltf, &mut scenes, &*type_registry, gltf_name); + } else { + gltf_extras_to_components(gltf, &mut scenes, &*type_registry, ""); + } } tracker.loading_gltfs.remove(gltf_handle); tracker.loaded_gltfs.insert(gltf_handle.clone()); debug!("Done loading scene"); } - - } - +} diff --git a/crates/bevy_gltf_components/src/utils.rs b/crates/bevy_gltf_components/src/utils.rs index 3c35562..14d6da3 100644 --- a/crates/bevy_gltf_components/src/utils.rs +++ b/crates/bevy_gltf_components/src/utils.rs @@ -1,4 +1,3 @@ pub fn capitalize_first_letter(s: &str) -> String { s[0..1].to_uppercase() + &s[1..] } - \ No newline at end of file diff --git a/examples/advanced/assets/assets_core.rs b/examples/advanced/assets/assets_core.rs index 52a4c16..29b577a 100644 --- a/examples/advanced/assets/assets_core.rs +++ b/examples/advanced/assets/assets_core.rs @@ -2,6 +2,4 @@ use bevy::prelude::*; use bevy_asset_loader::prelude::*; #[derive(AssetCollection, Resource)] -pub struct CoreAssets { - -} +pub struct CoreAssets {} diff --git a/examples/advanced/assets/mod.rs b/examples/advanced/assets/mod.rs index a431113..08d6dc1 100644 --- a/examples/advanced/assets/mod.rs +++ b/examples/advanced/assets/mod.rs @@ -7,28 +7,29 @@ pub use assets_game::*; use bevy::prelude::*; use bevy_asset_loader::prelude::*; -use crate::state::{AppState}; +use crate::state::AppState; pub struct AssetsPlugin; impl Plugin for AssetsPlugin { - fn build(&self, app: &mut App) { - app - // load core assets (ie assets needed in the main menu, and everywhere else before loading more assets in game) - .add_loading_state(LoadingState::new(AppState::CoreLoading).continue_to_state(AppState::MenuRunning)) - .add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>( - AppState::CoreLoading, - "advanced/assets_core.assets.ron", - ) - .add_collection_to_loading_state::<_, CoreAssets>(AppState::CoreLoading) - - // load game assets - .add_loading_state(LoadingState::new(AppState::AppLoading).continue_to_state(AppState::AppRunning)) - .add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>( - AppState::AppLoading, - "advanced/assets_game.assets.ron", - ) - .add_collection_to_loading_state::<_, GameAssets>(AppState::AppLoading) - - ; + fn build(&self, app: &mut App) { + app + // load core assets (ie assets needed in the main menu, and everywhere else before loading more assets in game) + .add_loading_state( + LoadingState::new(AppState::CoreLoading).continue_to_state(AppState::MenuRunning), + ) + .add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>( + AppState::CoreLoading, + "advanced/assets_core.assets.ron", + ) + .add_collection_to_loading_state::<_, CoreAssets>(AppState::CoreLoading) + // load game assets + .add_loading_state( + LoadingState::new(AppState::AppLoading).continue_to_state(AppState::AppRunning), + ) + .add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>( + AppState::AppLoading, + "advanced/assets_game.assets.ron", + ) + .add_collection_to_loading_state::<_, GameAssets>(AppState::AppLoading); } -} \ No newline at end of file +} diff --git a/examples/advanced/core/camera/camera_replace_proxies.rs b/examples/advanced/core/camera/camera_replace_proxies.rs index 9bd5859..9055c95 100644 --- a/examples/advanced/core/camera/camera_replace_proxies.rs +++ b/examples/advanced/core/camera/camera_replace_proxies.rs @@ -1,34 +1,24 @@ - +use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings}; +use bevy::core_pipeline::tonemapping::{DebandDither, Tonemapping}; use bevy::prelude::*; -use bevy::core_pipeline::bloom::{BloomSettings, BloomCompositeMode}; -use bevy::core_pipeline::tonemapping::{Tonemapping, DebandDither}; use super::CameraTrackingOffset; -pub fn camera_replace_proxies ( +pub fn camera_replace_proxies( mut commands: Commands, mut added_cameras: Query<(Entity, &mut Camera), (Added, With)>, ) { - - for (entity, mut camera) in added_cameras.iter_mut(){ + for (entity, mut camera) in added_cameras.iter_mut() { info!("detected added camera, updating proxy"); camera.hdr = true; - commands.entity(entity) - .insert( - DebandDither::Enabled - ) - .insert( - Tonemapping::BlenderFilmic - ) - .insert( - BloomSettings{ - intensity: 0.01, - composite_mode:BloomCompositeMode::Additive, - ..default() - } - ) - - ; - } + commands + .entity(entity) + .insert(DebandDither::Enabled) + .insert(Tonemapping::BlenderFilmic) + .insert(BloomSettings { + intensity: 0.01, + composite_mode: BloomCompositeMode::Additive, + ..default() + }); + } } - diff --git a/examples/advanced/core/camera/camera_tracking.rs b/examples/advanced/core/camera/camera_tracking.rs index ec3a45f..62da84d 100644 --- a/examples/advanced/core/camera/camera_tracking.rs +++ b/examples/advanced/core/camera/camera_tracking.rs @@ -1,21 +1,21 @@ use bevy::prelude::*; - #[derive(Component, Reflect, Debug)] #[reflect(Component)] /// Component for cameras, with an offset from the Trackable target -/// -pub struct CameraTracking{ - pub offset: Vec3 +/// +pub struct CameraTracking { + pub offset: Vec3, } impl Default for CameraTracking { fn default() -> Self { - CameraTracking { offset: Vec3::new(0.0, 6.0, 8.0) } + CameraTracking { + offset: Vec3::new(0.0, 6.0, 8.0), + } } } - -#[derive(Component, Reflect, Debug, Deref, DerefMut)] +#[derive(Component, Reflect, Debug, Deref, DerefMut)] #[reflect(Component)] /// Component for cameras, with an offset from the Trackable target pub struct CameraTrackingOffset(Vec3); @@ -26,32 +26,33 @@ impl Default for CameraTrackingOffset { } impl CameraTrackingOffset { - fn new (input: Vec3) -> Self { + fn new(input: Vec3) -> Self { CameraTrackingOffset(input) } } - - - -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] /// Add this component to an entity if you want it to be tracked by a Camera pub struct CameraTrackable; pub fn camera_track( - mut tracking_cameras: Query<(&mut Transform, &CameraTrackingOffset), (With, With, Without)>, + mut tracking_cameras: Query< + (&mut Transform, &CameraTrackingOffset), + ( + With, + With, + Without, + ), + >, camera_tracked: Query<&Transform, With>, ) { - for (mut camera_transform, tracking_offset) in tracking_cameras.iter_mut() { - for tracked_transform in camera_tracked.iter(){ - + for tracked_transform in camera_tracked.iter() { let target_position = tracked_transform.translation + tracking_offset.0; let eased_position = camera_transform.translation.lerp(target_position, 0.1); - camera_transform.translation = eased_position;// + tracking.offset;// tracked_transform.translation + tracking.offset; + camera_transform.translation = eased_position; // + tracking.offset;// tracked_transform.translation + tracking.offset; *camera_transform = camera_transform.looking_at(tracked_transform.translation, Vec3::Y); } } - } diff --git a/examples/advanced/core/camera/mod.rs b/examples/advanced/core/camera/mod.rs index 28f3aaa..a6bbb65 100644 --- a/examples/advanced/core/camera/mod.rs +++ b/examples/advanced/core/camera/mod.rs @@ -9,18 +9,16 @@ use bevy_gltf_blueprints::GltfBlueprintsSet; pub struct CameraPlugin; impl Plugin for CameraPlugin { - fn build(&self, app: &mut App) { - app - .register_type::() - .register_type::() - .register_type::() - - .add_systems(Update, - ( - camera_replace_proxies.after(GltfBlueprintsSet::AfterSpawn), - camera_track, - ) - ) - ; - } -} \ No newline at end of file + fn build(&self, app: &mut App) { + app.register_type::() + .register_type::() + .register_type::() + .add_systems( + Update, + ( + camera_replace_proxies.after(GltfBlueprintsSet::AfterSpawn), + camera_track, + ), + ); + } +} diff --git a/examples/advanced/core/lighting/lighting_replace_proxies.rs b/examples/advanced/core/lighting/lighting_replace_proxies.rs index 9e1d31d..48c0908 100644 --- a/examples/advanced/core/lighting/lighting_replace_proxies.rs +++ b/examples/advanced/core/lighting/lighting_replace_proxies.rs @@ -1,29 +1,25 @@ use bevy::prelude::*; -use bevy::pbr::{CascadeShadowConfigBuilder, CascadeShadowConfig}; +use bevy::pbr::{CascadeShadowConfig, CascadeShadowConfigBuilder}; // fixme might be too specific to might needs, should it be moved out ? also these are all for lights, not models pub fn lighting_replace_proxies( - mut added_dirights: Query<(Entity, &mut DirectionalLight), Added>, - mut added_spotlights: Query<&mut SpotLight, Added>, - mut commands: Commands, - -){ - - for (entity, mut light) in added_dirights.iter_mut(){ - light.illuminance *= 5.0; - light.shadows_enabled = true; - let shadow_config:CascadeShadowConfig = CascadeShadowConfigBuilder { - first_cascade_far_bound: 15.0, - maximum_distance: 135.0, - ..default() - } - .into(); - commands.entity(entity) - .insert(shadow_config); - } - for mut light in added_spotlights.iter_mut(){ - light.shadows_enabled = true; - } + mut added_dirights: Query<(Entity, &mut DirectionalLight), Added>, + mut added_spotlights: Query<&mut SpotLight, Added>, + mut commands: Commands, +) { + for (entity, mut light) in added_dirights.iter_mut() { + light.illuminance *= 5.0; + light.shadows_enabled = true; + let shadow_config: CascadeShadowConfig = CascadeShadowConfigBuilder { + first_cascade_far_bound: 15.0, + maximum_distance: 135.0, + ..default() + } + .into(); + commands.entity(entity).insert(shadow_config); + } + for mut light in added_spotlights.iter_mut() { + light.shadows_enabled = true; + } } - diff --git a/examples/advanced/core/lighting/mod.rs b/examples/advanced/core/lighting/mod.rs index d1744b7..c9688cd 100644 --- a/examples/advanced/core/lighting/mod.rs +++ b/examples/advanced/core/lighting/mod.rs @@ -1,18 +1,18 @@ mod lighting_replace_proxies; use lighting_replace_proxies::*; +use bevy::pbr::{DirectionalLightShadowMap, NotShadowCaster}; use bevy::prelude::*; -use bevy::pbr::{NotShadowCaster, DirectionalLightShadowMap}; pub struct LightingPlugin; impl Plugin for LightingPlugin { - fn build(&self, app: &mut App) { - app + fn build(&self, app: &mut App) { + app .insert_resource(DirectionalLightShadowMap { size: 4096 }) // FIXME: adding these since they are missing .register_type::() .add_systems(PreUpdate, lighting_replace_proxies) // FIXME: you should actually run this in a specific state most likely ; - } -} \ No newline at end of file + } +} diff --git a/examples/advanced/core/mod.rs b/examples/advanced/core/mod.rs index 4e40b44..a3f81b1 100644 --- a/examples/advanced/core/mod.rs +++ b/examples/advanced/core/mod.rs @@ -22,73 +22,63 @@ use bevy_gltf_blueprints::*; use rand::Rng; - fn spawn_test( - keycode: Res>, - mut commands: Commands, - - mut game_world: Query<(Entity, &Children), With>, - + keycode: Res>, + mut commands: Commands, + mut game_world: Query<(Entity, &Children), With>, ) { - if keycode.just_pressed(KeyCode::T) { - let world = game_world.single_mut(); - let world = world.1[0]; + 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 = 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 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 name_index:u64 = rng.gen(); - - let new_entity = commands.spawn(( - BluePrintBundle{ - blueprint: BlueprintName("Health_Pickup".to_string()), - transform: TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)), - ..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); - } + let new_entity = commands + .spawn(( + BluePrintBundle { + blueprint: BlueprintName("Health_Pickup".to_string()), + transform: TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)), + ..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 struct CorePlugin; impl Plugin for CorePlugin { - fn build(&self, app: &mut App) { - app - .add_plugins(( + fn build(&self, app: &mut App) { + app.add_plugins(( LightingPlugin, CameraPlugin, - PhysicsPlugin, + PhysicsPlugin, SaveLoadPlugin, - BlueprintsPlugin{ - library_folder: "advanced/models/library".into() - } + BlueprintsPlugin { + library_folder: "advanced/models/library".into(), + }, )) - - // just for testing - .add_systems( - Update, - spawn_test - ) - ; - } + // just for testing + .add_systems(Update, spawn_test); + } } diff --git a/examples/advanced/core/physics/controls.rs b/examples/advanced/core/physics/controls.rs index 9c88bba..9ff42c9 100644 --- a/examples/advanced/core/physics/controls.rs +++ b/examples/advanced/core/physics/controls.rs @@ -1,12 +1,12 @@ -use bevy::prelude::{ResMut, info}; +use bevy::prelude::{info, ResMut}; use bevy_rapier3d::prelude::RapierConfiguration; -pub fn pause_physics(mut physics_config: ResMut){ +pub fn pause_physics(mut physics_config: ResMut) { info!("pausing physics"); physics_config.physics_pipeline_active = false; } -pub fn resume_physics(mut physics_config: ResMut){ +pub fn resume_physics(mut physics_config: ResMut) { info!("unpausing physics"); physics_config.physics_pipeline_active = true; -} \ No newline at end of file +} diff --git a/examples/advanced/core/physics/mod.rs b/examples/advanced/core/physics/mod.rs index 0c41c7f..ac2e616 100644 --- a/examples/advanced/core/physics/mod.rs +++ b/examples/advanced/core/physics/mod.rs @@ -6,33 +6,24 @@ pub mod utils; pub mod controls; pub use controls::*; -use bevy::prelude::*; use crate::state::GameState; +use bevy::prelude::*; // use super::blueprints::GltfBlueprintsSet; use bevy_gltf_blueprints::GltfBlueprintsSet; // use crate::Collider; pub struct PhysicsPlugin; impl Plugin for PhysicsPlugin { - fn build(&self, app: &mut App) { - app - .register_type::() - .register_type::() - - // find a way to make serde's stuff serializable - // .register_type::() - //bevy_rapier3d::dynamics::CoefficientCombineRule - - .add_systems(Update, physics_replace_proxies.after(GltfBlueprintsSet::AfterSpawn)) - - .add_systems( - OnEnter(GameState::InGame), - resume_physics - ) - .add_systems( - OnExit(GameState::InGame), - pause_physics - ) - ; - } + fn build(&self, app: &mut App) { + app.register_type::() + .register_type::() + // find a way to make serde's stuff serializable + // .register_type::() + //bevy_rapier3d::dynamics::CoefficientCombineRule + .add_systems( + Update, + physics_replace_proxies.after(GltfBlueprintsSet::AfterSpawn), + ) + .add_systems(OnEnter(GameState::InGame), resume_physics) + .add_systems(OnExit(GameState::InGame), pause_physics); + } } - diff --git a/examples/advanced/core/physics/physics_replace_proxies.rs b/examples/advanced/core/physics/physics_replace_proxies.rs index 4b29629..b91462c 100644 --- a/examples/advanced/core/physics/physics_replace_proxies.rs +++ b/examples/advanced/core/physics/physics_replace_proxies.rs @@ -1,11 +1,11 @@ use bevy::prelude::*; // use bevy::render::primitives::Aabb; use bevy_rapier3d::geometry::Collider as RapierCollider; -use bevy_rapier3d::prelude::{ComputedColliderShape, ActiveEvents, ActiveCollisionTypes}; +use bevy_rapier3d::prelude::{ActiveCollisionTypes, ActiveEvents, ComputedColliderShape}; use super::utils::*; -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] pub enum Collider { Ball(f32), @@ -15,35 +15,37 @@ pub enum Collider { Mesh, } - -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] pub enum AutoAABBCollider { #[default] Cuboid, Ball, - Capsule + Capsule, } -// replaces all physics stand-ins with the actual rapier types -pub fn physics_replace_proxies ( +// replaces all physics stand-ins with the actual rapier types +pub fn physics_replace_proxies( meshes: Res>, mesh_handles: Query<&Handle>, - mut proxy_colliders: Query<(Entity, &Collider, &Name, &mut Visibility), (Without, Added)>, + mut proxy_colliders: Query< + (Entity, &Collider, &Name, &mut Visibility), + (Without, Added), + >, // needed for tri meshes - children: Query<&Children>, + children: Query<&Children>, mut commands: Commands, ) { for proxy_colider in proxy_colliders.iter_mut() { let (entity, collider_proxy, name, mut visibility) = proxy_colider; // we hide the collider meshes: perhaps they should be removed altogether once processed ? - if name.ends_with( "_collider" ) || name.ends_with( "_sensor" ) { + if name.ends_with("_collider") || name.ends_with("_sensor") { *visibility = Visibility::Hidden; } - let mut rapier_collider:RapierCollider; - match collider_proxy{ + let mut rapier_collider: RapierCollider; + match collider_proxy { Collider::Ball(radius) => { info!("generating collider from proxy: ball"); rapier_collider = RapierCollider::ball(*radius); @@ -70,15 +72,25 @@ pub fn physics_replace_proxies ( } Collider::Mesh => { info!("generating collider from proxy: mesh"); - for (_, collider_mesh) in Mesh::search_in_children(entity, &children, &meshes, &mesh_handles) + for (_, collider_mesh) in + Mesh::search_in_children(entity, &children, &meshes, &mesh_handles) { - rapier_collider = RapierCollider::from_bevy_mesh(collider_mesh, &ComputedColliderShape::TriMesh).unwrap(); - commands.entity(entity) + rapier_collider = RapierCollider::from_bevy_mesh( + collider_mesh, + &ComputedColliderShape::TriMesh, + ) + .unwrap(); + commands + .entity(entity) .insert(rapier_collider) - // FIXME: this is just for demo purposes !!! - .insert(ActiveCollisionTypes::default() | ActiveCollisionTypes::KINEMATIC_STATIC | ActiveCollisionTypes::STATIC_STATIC | ActiveCollisionTypes::DYNAMIC_STATIC) - .insert(ActiveEvents::COLLISION_EVENTS) - ; + // FIXME: this is just for demo purposes !!! + .insert( + ActiveCollisionTypes::default() + | ActiveCollisionTypes::KINEMATIC_STATIC + | ActiveCollisionTypes::STATIC_STATIC + | ActiveCollisionTypes::DYNAMIC_STATIC, + ) + .insert(ActiveEvents::COLLISION_EVENTS); // .insert(ActiveEvents::COLLISION_EVENTS) // break; // RapierCollider::convex_hull(points) diff --git a/examples/advanced/core/relationships/mod.rs b/examples/advanced/core/relationships/mod.rs index 6345d35..4128453 100644 --- a/examples/advanced/core/relationships/mod.rs +++ b/examples/advanced/core/relationships/mod.rs @@ -5,7 +5,7 @@ use bevy::prelude::*; pub struct EcsRelationshipsPlugin; impl Plugin for EcsRelationshipsPlugin { - fn build(&self, app: &mut App) { - app; - } -} \ No newline at end of file + fn build(&self, app: &mut App) { + app; + } +} diff --git a/examples/advanced/core/relationships/relationships_insert_dependant_components.rs b/examples/advanced/core/relationships/relationships_insert_dependant_components.rs index afec54e..4e9ad17 100644 --- a/examples/advanced/core/relationships/relationships_insert_dependant_components.rs +++ b/examples/advanced/core/relationships/relationships_insert_dependant_components.rs @@ -1,16 +1,15 @@ use bevy::prelude::*; -pub fn insert_dependant_component( +pub fn insert_dependant_component< + Dependant: Component, + Dependency: Component + std::default::Default, +>( mut commands: Commands, entities_without_depency: Query<(Entity, &Name), (With, Without)>, ) { for (entity, name) in entities_without_depency.iter() { let name = name.clone().to_string(); - commands.entity(entity) - .insert( - Dependency::default() - ) - ; + commands.entity(entity).insert(Dependency::default()); warn!("found an entity called {} with a {} component but without an {}, please check your assets", name.clone(), std::any::type_name::(), std::any::type_name::()); } -} \ No newline at end of file +} diff --git a/examples/advanced/core/save_load/loading.rs b/examples/advanced/core/save_load/loading.rs index cc1e8e2..73ef523 100644 --- a/examples/advanced/core/save_load/loading.rs +++ b/examples/advanced/core/save_load/loading.rs @@ -1,19 +1,19 @@ use bevy::prelude::*; -use bevy_gltf_blueprints::{clone_entity::CloneEntity, SpawnHere, GameWorldTag}; +use bevy_gltf_blueprints::{clone_entity::CloneEntity, GameWorldTag, SpawnHere}; use crate::{ - assets::GameAssets, - state::{InAppRunning, AppState, GameState} + assets::GameAssets, + state::{AppState, GameState, InAppRunning}, }; use super::Saveable; const SCENE_FILE_PATH: &str = "scenes/save.scn.ron"; -#[derive(Component, Debug, )] +#[derive(Component, Debug)] pub struct TempLoadedSceneMarker; -#[derive(Component, Debug, )] +#[derive(Component, Debug)] pub struct SaveablesToRemove(Vec<(Entity, Name)>); #[derive(Component, Event)] @@ -21,18 +21,14 @@ pub struct LoadRequest { pub path: String, } - -pub fn should_load( - save_requested_events: EventReader, -) -> bool { - return save_requested_events.len() > 0 +pub fn should_load(save_requested_events: EventReader) -> bool { + return save_requested_events.len() > 0; } pub fn load_prepare( mut next_app_state: ResMut>, mut next_game_state: ResMut>, -){ - +) { next_app_state.set(AppState::LoadingGame); next_game_state.set(GameState::None); info!("--loading: prepare") @@ -42,7 +38,7 @@ pub fn load_prepare( pub fn _unload_world_old(world: &mut World) { let entities: Vec = world // .query_filtered::, With)>>() - .query_filtered::>()// our level/world contains this component + .query_filtered::>() // our level/world contains this component .iter(world) .collect(); for entity in entities { @@ -53,11 +49,8 @@ pub fn _unload_world_old(world: &mut World) { } } -pub fn unload_world( - mut commands: Commands, - gameworlds: Query> -){ - for e in gameworlds.iter(){ +pub fn unload_world(mut commands: Commands, gameworlds: Query>) { + for e in gameworlds.iter() { info!("--loading: despawn old world/level"); commands.entity(e).despawn_recursive(); } @@ -66,11 +59,11 @@ pub fn unload_world( // almost identical to setup_game, !!?? pub fn load_world( mut commands: Commands, - game_assets: Res, - // scenes: ResMut, -){ + game_assets: Res, + // scenes: ResMut, +) { info!("--loading: loading world/level"); - + commands.spawn(( SceneBundle { scene: game_assets.world.clone(), @@ -78,25 +71,18 @@ pub fn load_world( }, bevy::prelude::Name::from("world"), GameWorldTag, - InAppRunning + InAppRunning, )); } - - - -pub fn load_saved_scene( - mut commands: Commands, - asset_server: Res -) { - commands.spawn( - ( +pub fn load_saved_scene(mut commands: Commands, asset_server: Res) { + commands.spawn(( DynamicSceneBundle { // Scenes are loaded just like any other asset. scene: asset_server.load(SCENE_FILE_PATH), ..default() }, - TempLoadedSceneMarker + TempLoadedSceneMarker, )); // commands.entity(world).add_child(child_scene); info!("--loading: loaded saved scene"); @@ -105,25 +91,25 @@ pub fn load_saved_scene( pub fn process_loaded_scene( loaded_scene: Query<(Entity, &Children), With>, named_entities: Query<(Entity, &Name, &Parent)>, // FIXME: very inneficient - mut commands: Commands, + mut commands: Commands, mut game_world: Query<(Entity, &Children), With>, saveables: Query<(Entity, &Name), With>, - asset_server: Res -){ - for (loaded_scene, children) in loaded_scene.iter(){ + asset_server: Res, +) { + for (loaded_scene, children) in loaded_scene.iter() { info!("--loading: post processing loaded scene"); - let mut entities_to_load:Vec<(Entity, Name)> = vec![]; + let mut entities_to_load: Vec<(Entity, Name)> = vec![]; for loaded_entity in children.iter() { - if let Ok((source, name, _)) = named_entities.get(*loaded_entity) { + if let Ok((source, name, _)) = named_entities.get(*loaded_entity) { entities_to_load.push((source, name.clone())); let mut found = false; - for (e, n, p) in named_entities.iter(){ + for (e, n, p) in named_entities.iter() { // if we have an entity with the same name as in same file, overwrite - if e != source && name.as_str() == n.as_str(){ + if e != source && name.as_str() == n.as_str() { // println!("found entity with same name {} {} {:?} {:?}", name, n, source, e); // source is entity within the newly loaded scene (source), e is within the existing world (destination) info!("copying data from {:?} to {:?}", source, e); @@ -145,10 +131,9 @@ pub fn process_loaded_scene( let world = game_world.single_mut(); let world = world.1[0]; - let new_entity = commands.spawn(( - bevy::prelude::Name::from(name.clone()), - SpawnHere, - )).id(); + let new_entity = commands + .spawn((bevy::prelude::Name::from(name.clone()), SpawnHere)) + .id(); commands.add(CloneEntity { source: source, @@ -157,17 +142,11 @@ pub fn process_loaded_scene( commands.entity(world).add_child(new_entity); info!("copying data from {:?} to {:?}", source, new_entity); - - - } - - } + } } commands.spawn(SaveablesToRemove(entities_to_load.clone())); - - - + // if an entity is present in the world but NOT in the saved entities , it should be removed from the world // ideally this should be run between spawning of the world/level AND spawn_placeholders @@ -177,7 +156,6 @@ pub fn process_loaded_scene( asset_server.mark_unused_assets(); asset_server.free_unused_assets(); - } //for saveable in saveables.iter(){ // println!("SAVEABLE BEFORE {:?}", saveable) @@ -186,21 +164,19 @@ pub fn process_loaded_scene( pub fn final_cleanup( saveables_to_remove: Query<(Entity, &SaveablesToRemove)>, - mut commands: Commands, + mut commands: Commands, saveables: Query<(Entity, &Name), With>, mut next_app_state: ResMut>, mut next_game_state: ResMut>, - -){ - if let Ok((e, entities_to_load)) = saveables_to_remove.get_single() - { +) { + if let Ok((e, entities_to_load)) = saveables_to_remove.get_single() { info!("saveables to remove {:?}", entities_to_load); - for (e, n) in saveables.iter(){ + for (e, n) in saveables.iter() { let mut found = false; println!("SAVEABLE {}", n); - + //let entities_to_load = saveables_to_remove.single(); - for (en, na) in entities_to_load.0.iter(){ + for (en, na) in entities_to_load.0.iter() { found = na.as_str() == n.as_str(); if found { break; @@ -225,19 +201,18 @@ pub fn final_cleanup( fn process_loaded_scene_load_alt( entities: Query<(Entity, &Children), With>, named_entities: Query<(Entity, &Name, &Parent)>, // FIXME: very inneficient - mut commands: Commands, - -){ - for (entity, children) in entities.iter(){ - let mut entities_to_load:Vec<(Entity, Name)> = vec![]; + mut commands: Commands, +) { + for (entity, children) in entities.iter() { + let mut entities_to_load: Vec<(Entity, Name)> = vec![]; for saved_source in children.iter() { - if let Ok((source, name, _)) = named_entities.get(*saved_source) { - println!("AAAAAAA {}", name); - entities_to_load.push((source, name.clone())); - } + if let Ok((source, name, _)) = named_entities.get(*saved_source) { + println!("AAAAAAA {}", name); + entities_to_load.push((source, name.clone())); + } } println!("entities to load {:?}", entities_to_load); - commands.entity(entity).despawn_recursive(); + commands.entity(entity).despawn_recursive(); } -} \ No newline at end of file +} diff --git a/examples/advanced/core/save_load/mod.rs b/examples/advanced/core/save_load/mod.rs index 30784aa..3d0e91e 100644 --- a/examples/advanced/core/save_load/mod.rs +++ b/examples/advanced/core/save_load/mod.rs @@ -10,23 +10,21 @@ pub mod loading; pub use loading::*; use bevy::prelude::*; -use bevy::prelude::{App, Plugin, IntoSystemConfigs}; +use bevy::prelude::{App, IntoSystemConfigs, Plugin}; use bevy::utils::Uuid; use bevy_gltf_blueprints::GltfBlueprintsSet; - - #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] -pub enum LoadingSet{ - Load, - PostLoad, +pub enum LoadingSet { + Load, + PostLoad, } pub struct SaveLoadPlugin; impl Plugin for SaveLoadPlugin { - fn build(&self, app: &mut App) { - app + fn build(&self, app: &mut App) { + app .register_type::() .register_type::() .add_event::() @@ -42,7 +40,7 @@ impl Plugin for SaveLoadPlugin { .add_systems(PreUpdate, save_game.run_if(should_save)) - .add_systems(Update, + .add_systems(Update, ( load_prepare, unload_world, @@ -54,7 +52,7 @@ impl Plugin for SaveLoadPlugin { .run_if(should_load) // .run_if(in_state(AppState::AppRunning)) .in_set(LoadingSet::Load) ) - .add_systems(Update, + .add_systems(Update, ( process_loaded_scene, apply_deferred, @@ -67,7 +65,6 @@ impl Plugin for SaveLoadPlugin { ) // .add_systems(Update, bla) - ; - } + } } diff --git a/examples/advanced/core/save_load/saveable.rs b/examples/advanced/core/save_load/saveable.rs index c944fc0..67a4c65 100644 --- a/examples/advanced/core/save_load/saveable.rs +++ b/examples/advanced/core/save_load/saveable.rs @@ -1,17 +1,14 @@ use bevy::prelude::*; -use bevy::utils::{Uuid}; +use bevy::utils::Uuid; -#[derive(Component, Reflect, Debug, )] +#[derive(Component, Reflect, Debug)] #[reflect(Component)] -pub struct Saveable{ - id: Uuid +pub struct Saveable { + id: Uuid, } -impl Default for Saveable{ +impl Default for Saveable { fn default() -> Self { - Saveable{ - id: Uuid::new_v4() - } + Saveable { id: Uuid::new_v4() } } } - diff --git a/examples/advanced/core/save_load/saving.rs b/examples/advanced/core/save_load/saving.rs index 928bf68..46d0b1a 100644 --- a/examples/advanced/core/save_load/saving.rs +++ b/examples/advanced/core/save_load/saving.rs @@ -1,40 +1,37 @@ use bevy::pbr::{Clusters, VisiblePointLights}; use bevy::render::camera::CameraRenderGraph; use bevy::render::view::VisibleEntities; -use bevy::{prelude::*, gltf::GltfExtras}; use bevy::tasks::IoTaskPool; +use bevy::{gltf::GltfExtras, prelude::*}; use bevy_rapier3d::prelude::RigidBody; -use std::io::Write; use std::fs::File; +use std::io::Write; use crate::core::physics::Collider; use crate::game::{Pickable, Player}; use super::Saveable; - -const NEW_SCENE_FILE_PATH:&str="save.scn.ron"; +const NEW_SCENE_FILE_PATH: &str = "save.scn.ron"; #[derive(Component, Event)] pub struct SaveRequest { pub path: String, } - pub fn should_save( // keycode: Res>, - save_requested_events: EventReader, - + save_requested_events: EventReader, ) -> bool { return save_requested_events.len() > 0; - + // return keycode.just_pressed(KeyCode::S) } pub fn save_game( world: &mut World, - // save_requested_events: EventReader, -){ + // save_requested_events: EventReader, +) { info!("saving"); // world. /*for bli in save_requested_events.iter(){ @@ -42,9 +39,9 @@ pub fn save_game( }*/ let saveable_entities: Vec = world - .query_filtered::>() - .iter(world) - .collect(); + .query_filtered::>() + .iter(world) + .collect(); /*let static_entities: Vec = world .query_filtered::>() @@ -60,11 +57,9 @@ pub fn save_game( .deny::() .deny::() .deny::() - .deny::() .deny::() .deny::() - // camera stuff .deny::() .deny::() @@ -73,22 +68,20 @@ pub fn save_game( .deny::() .deny::() //.deny::() - - .extract_entities(saveable_entities.into_iter()); - + let dyn_scene = scene_builder.build(); + let serialized_scene = dyn_scene + .serialize_ron(world.resource::()) + .unwrap(); - let dyn_scene = scene_builder.build(); - let serialized_scene = dyn_scene.serialize_ron(world.resource::()).unwrap(); - - #[cfg(not(target_arch = "wasm32"))] - IoTaskPool::get() - .spawn(async move { - // Write the scene RON data to file - File::create(format!("assets/scenes/{NEW_SCENE_FILE_PATH}")) - .and_then(|mut file| file.write(serialized_scene.as_bytes())) - .expect("Error while writing scene to file"); - }) - .detach(); -} \ No newline at end of file + #[cfg(not(target_arch = "wasm32"))] + IoTaskPool::get() + .spawn(async move { + // Write the scene RON data to file + File::create(format!("assets/scenes/{NEW_SCENE_FILE_PATH}")) + .and_then(|mut file| file.write(serialized_scene.as_bytes())) + .expect("Error while writing scene to file"); + }) + .detach(); +} diff --git a/examples/advanced/game/in_game.rs b/examples/advanced/game/in_game.rs index 4167c1a..0374a1e 100644 --- a/examples/advanced/game/in_game.rs +++ b/examples/advanced/game/in_game.rs @@ -1,6 +1,9 @@ use bevy::prelude::*; -use crate::{assets::GameAssets, state::{InAppRunning, GameState}}; +use crate::{ + assets::GameAssets, + state::{GameState, InAppRunning}, +}; use bevy_gltf_blueprints::GameWorldTag; pub fn setup_game( @@ -8,7 +11,6 @@ pub fn setup_game( game_assets: Res, mut next_game_state: ResMut>, ) { - println!("setting up all stuff"); commands.insert_resource(AmbientLight { color: Color::WHITE, @@ -23,8 +25,8 @@ pub fn setup_game( }, bevy::prelude::Name::from("world"), GameWorldTag, - InAppRunning + InAppRunning, )); - + next_game_state.set(GameState::InGame) -} \ No newline at end of file +} diff --git a/examples/advanced/game/in_main_menu.rs b/examples/advanced/game/in_main_menu.rs index 138d6d6..1720ebd 100644 --- a/examples/advanced/game/in_main_menu.rs +++ b/examples/advanced/game/in_main_menu.rs @@ -1,8 +1,11 @@ use bevy::prelude::*; -use crate::{state::{AppState, GameState, InMainMenu}, core::save_load::{LoadRequest, SaveRequest}}; +use crate::{ + core::save_load::{LoadRequest, SaveRequest}, + state::{AppState, GameState, InMainMenu}, +}; -pub fn setup_main_menu(mut commands: Commands){ +pub fn setup_main_menu(mut commands: Commands) { commands.spawn((Camera2dBundle::default(), InMainMenu)); commands.spawn(( @@ -21,10 +24,9 @@ pub fn setup_main_menu(mut commands: Commands){ left: Val::Px(200.0), ..default() }), - InMainMenu + InMainMenu, )); - commands.spawn(( TextBundle::from_section( "New Game (press Enter to start, press T once the game is started for demo spawning)", @@ -41,10 +43,10 @@ pub fn setup_main_menu(mut commands: Commands){ left: Val::Px(200.0), ..default() }), - InMainMenu + InMainMenu, )); - /* + /* commands.spawn(( TextBundle::from_section( "Load Game", @@ -84,8 +86,8 @@ pub fn setup_main_menu(mut commands: Commands){ ));*/ } -pub fn teardown_main_menu(bla: Query>, mut commands: Commands){ - for bli in bla.iter(){ +pub fn teardown_main_menu(bla: Query>, mut commands: Commands) { + for bli in bla.iter() { commands.entity(bli).despawn_recursive(); } } @@ -95,11 +97,9 @@ pub fn main_menu( mut next_app_state: ResMut>, // mut next_game_state: ResMut>, - - mut save_requested_events: EventWriter, - mut load_requested_events: EventWriter, - -){ + mut save_requested_events: EventWriter, + mut load_requested_events: EventWriter, +) { if keycode.just_pressed(KeyCode::Return) { next_app_state.set(AppState::AppLoading); // next_game_state.set(GameState::None); @@ -113,4 +113,4 @@ pub fn main_menu( if keycode.just_pressed(KeyCode::S) { // save_requested_events.send(SaveRequest { path: "toto".into() }) } -} \ No newline at end of file +} diff --git a/examples/advanced/game/mod.rs b/examples/advanced/game/mod.rs index 81691c5..6587259 100644 --- a/examples/advanced/game/mod.rs +++ b/examples/advanced/game/mod.rs @@ -7,52 +7,46 @@ pub use in_main_menu::*; pub mod picking; pub use picking::*; +use crate::{ + insert_dependant_component, + state::{AppState, GameState}, +}; use bevy::prelude::*; use bevy_rapier3d::prelude::*; -use crate::{insert_dependant_component, state::{AppState, GameState}}; - - // this file is just for demo purposes, contains various types of components, systems etc -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] -pub enum SoundMaterial{ - Metal, - Wood, - Rock, - Cloth, - Squishy, - #[default] - None +pub enum SoundMaterial { + Metal, + Wood, + Rock, + Cloth, + Squishy, + #[default] + None, } - -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] /// Demo marker component pub struct Player; -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] -/// Demo component showing auto injection of components +/// Demo component showing auto injection of components pub struct ShouldBeWithPlayer; - -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] /// Demo marker component pub struct Interactible; - - - - fn player_move_demo( keycode: Res>, mut players: Query<&mut Transform, With>, -){ - +) { let speed = 0.2; if let Ok(mut player) = players.get_single_mut() { if keycode.pressed(KeyCode::Left) { @@ -75,17 +69,15 @@ fn player_move_demo( pub fn test_collision_events( mut collision_events: EventReader, mut contact_force_events: EventReader, -) -{ +) { for collision_event in collision_events.iter() { println!("collision"); match collision_event { - CollisionEvent::Started(_entity1, _entity2 ,_) => { + CollisionEvent::Started(_entity1, _entity2, _) => { println!("collision started") } - CollisionEvent::Stopped(_entity1, _entity2 ,_) => { + CollisionEvent::Stopped(_entity1, _entity2, _) => { println!("collision ended") - } } } @@ -95,42 +87,28 @@ pub fn test_collision_events( } } - pub struct GamePlugin; impl Plugin for GamePlugin { - fn build(&self, app: &mut App) { - app - .add_plugins(PickingPlugin) - - .register_type::() - .register_type::() - .register_type::() - // little helper utility, to automatically inject components that are dependant on an other component - // ie, here an Entity with a Player component should also always have a ShouldBeWithPlayer component - // you get a warning if you use this, as I consider this to be stop-gap solution (usually you should have either a bundle, or directly define all needed components) - .add_systems(Update, ( - // insert_dependant_component::, - player_move_demo, //.run_if(in_state(AppState::Running)), - // test_collision_events - ) - .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)) - - - .add_systems( - OnEnter(AppState::AppRunning), - setup_game - ) - ; - } + fn build(&self, app: &mut App) { + app.add_plugins(PickingPlugin) + .register_type::() + .register_type::() + .register_type::() + // little helper utility, to automatically inject components that are dependant on an other component + // ie, here an Entity with a Player component should also always have a ShouldBeWithPlayer component + // you get a warning if you use this, as I consider this to be stop-gap solution (usually you should have either a bundle, or directly define all needed components) + .add_systems( + Update, + ( + // insert_dependant_component::, + player_move_demo, //.run_if(in_state(AppState::Running)), + // test_collision_events + ) + .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)) + .add_systems(OnEnter(AppState::AppRunning), setup_game); + } } diff --git a/examples/advanced/game/picking.rs b/examples/advanced/game/picking.rs index 5f05cfa..23988c8 100644 --- a/examples/advanced/game/picking.rs +++ b/examples/advanced/game/picking.rs @@ -1,21 +1,22 @@ - -use bevy::prelude::*; use super::Player; +use bevy::prelude::*; -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] pub struct Pickable; -// very simple, crude picking (as in picking up objects) implementation +// very simple, crude picking (as in picking up objects) implementation pub fn picking( players: Query<&GlobalTransform, With>, pickables: Query<(Entity, &GlobalTransform), With>, - mut commands: Commands -){ - for player_transforms in players.iter(){ - for (pickable, pickable_transforms) in pickables.iter(){ - let distance = player_transforms.translation().distance(pickable_transforms.translation()); + mut commands: Commands, +) { + for player_transforms in players.iter() { + for (pickable, pickable_transforms) in pickables.iter() { + let distance = player_transforms + .translation() + .distance(pickable_transforms.translation()); if distance < 2.5 { commands.entity(pickable).despawn_recursive(); } @@ -25,16 +26,12 @@ pub fn picking( pub struct PickingPlugin; impl Plugin for PickingPlugin { - fn build(&self, app: &mut App) { - app - .register_type::() - - .add_systems(Update, ( - picking, //.run_if(in_state(AppState::Running)), - )) - - - - ; - } + fn build(&self, app: &mut App) { + app.register_type::().add_systems( + Update, + ( + picking, //.run_if(in_state(AppState::Running)), + ), + ); + } } diff --git a/examples/advanced/main.rs b/examples/advanced/main.rs index ecbee4e..c13d6f2 100644 --- a/examples/advanced/main.rs +++ b/examples/advanced/main.rs @@ -1,8 +1,8 @@ -use std::time::Duration; -use bevy::{prelude::*, asset::ChangeWatcher, gltf::Gltf}; +use bevy::{asset::ChangeWatcher, gltf::Gltf, prelude::*}; use bevy_editor_pls::prelude::*; -use bevy_rapier3d::prelude::*; use bevy_gltf_components::ComponentsFromGltfPlugin; +use bevy_rapier3d::prelude::*; +use std::time::Duration; mod core; use crate::core::*; @@ -19,33 +19,28 @@ use game::*; mod test_components; use test_components::*; - - -fn main(){ +fn main() { App::new() - .add_plugins(( - DefaultPlugins.set( - AssetPlugin { + .add_plugins(( + DefaultPlugins.set(AssetPlugin { // This tells the AssetServer to watch for changes to assets. // It enables our scenes to automatically reload in game when we modify their files. // practical in our case to be able to edit the shaders without needing to recompile // watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(50)), : FIXME: breaks scene save/loading ..default() - } - ), - // editor - EditorPlugin::default(), - // physics - RapierPhysicsPlugin::::default(), - RapierDebugRenderPlugin::default(), - // our custom plugins - ComponentsFromGltfPlugin, - - StatePlugin, - AssetsPlugin, - CorePlugin, // reusable plugins - GamePlugin, // specific to our game - ComponentsTestPlugin // Showcases different type of components /structs - )) - .run(); + }), + // editor + EditorPlugin::default(), + // physics + RapierPhysicsPlugin::::default(), + RapierDebugRenderPlugin::default(), + // our custom plugins + ComponentsFromGltfPlugin, + StatePlugin, + AssetsPlugin, + CorePlugin, // reusable plugins + GamePlugin, // specific to our game + ComponentsTestPlugin, // Showcases different type of components /structs + )) + .run(); } diff --git a/examples/advanced/state.rs b/examples/advanced/state.rs index 7d87c58..8e983d9 100644 --- a/examples/advanced/state.rs +++ b/examples/advanced/state.rs @@ -1,8 +1,8 @@ -use bevy::prelude::*; use bevy::app::AppExit; +use bevy::prelude::*; #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default, States)] -pub enum AppState{ +pub enum AppState { #[default] CoreLoading, MenuRunning, @@ -11,21 +11,21 @@ pub enum AppState{ AppEnding, // FIXME: not sure - LoadingGame + LoadingGame, } #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default, States)] pub enum GameState { #[default] None, - + InMenu, InGame, InGameOver, InSaving, - InLoading + InLoading, } // tag components for all entities within a certain state (for despawning them if needed) , FIXME: seems kinda hack-ish @@ -46,13 +46,9 @@ pub struct InMenu; #[derive(Component, Default)] pub struct InGame; - pub struct StatePlugin; impl Plugin for StatePlugin { - fn build(&self, app: &mut App) { - app - .add_state::() - .add_state::() - ; - } -} \ No newline at end of file + fn build(&self, app: &mut App) { + app.add_state::().add_state::(); + } +} diff --git a/examples/advanced/test_components.rs b/examples/advanced/test_components.rs index 79a45f6..d0e6fbd 100644 --- a/examples/advanced/test_components.rs +++ b/examples/advanced/test_components.rs @@ -1,7 +1,6 @@ use bevy::prelude::*; - -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct UnitTest; @@ -17,70 +16,65 @@ struct TuppleTestU64(u64); #[reflect(Component)] pub struct TuppleTestStr(String); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleTest2(f32, u64, String); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleTestBool(bool); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleVec2(Vec2); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleVec3(Vec3); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleVec(Vec); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleTestColor(Color); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] -struct BasicTest{ +struct BasicTest { a: f32, b: u64, - c: String + c: String, } -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] -pub enum EnumTest{ - Metal, - Wood, - Rock, - Cloth, - Squishy, - #[default] - None +pub enum EnumTest { + Metal, + Wood, + Rock, + Cloth, + Squishy, + #[default] + None, } - pub struct ComponentsTestPlugin; impl Plugin for ComponentsTestPlugin { - fn build(&self, app: &mut App) { - app - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - - .register_type::() - .register_type::>() - - ; - } + fn build(&self, app: &mut App) { + app.register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::>(); + } } diff --git a/examples/basic/core/camera/camera_replace_proxies.rs b/examples/basic/core/camera/camera_replace_proxies.rs index 9bd5859..9055c95 100644 --- a/examples/basic/core/camera/camera_replace_proxies.rs +++ b/examples/basic/core/camera/camera_replace_proxies.rs @@ -1,34 +1,24 @@ - +use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings}; +use bevy::core_pipeline::tonemapping::{DebandDither, Tonemapping}; use bevy::prelude::*; -use bevy::core_pipeline::bloom::{BloomSettings, BloomCompositeMode}; -use bevy::core_pipeline::tonemapping::{Tonemapping, DebandDither}; use super::CameraTrackingOffset; -pub fn camera_replace_proxies ( +pub fn camera_replace_proxies( mut commands: Commands, mut added_cameras: Query<(Entity, &mut Camera), (Added, With)>, ) { - - for (entity, mut camera) in added_cameras.iter_mut(){ + for (entity, mut camera) in added_cameras.iter_mut() { info!("detected added camera, updating proxy"); camera.hdr = true; - commands.entity(entity) - .insert( - DebandDither::Enabled - ) - .insert( - Tonemapping::BlenderFilmic - ) - .insert( - BloomSettings{ - intensity: 0.01, - composite_mode:BloomCompositeMode::Additive, - ..default() - } - ) - - ; - } + commands + .entity(entity) + .insert(DebandDither::Enabled) + .insert(Tonemapping::BlenderFilmic) + .insert(BloomSettings { + intensity: 0.01, + composite_mode: BloomCompositeMode::Additive, + ..default() + }); + } } - diff --git a/examples/basic/core/camera/camera_tracking.rs b/examples/basic/core/camera/camera_tracking.rs index ec3a45f..62da84d 100644 --- a/examples/basic/core/camera/camera_tracking.rs +++ b/examples/basic/core/camera/camera_tracking.rs @@ -1,21 +1,21 @@ use bevy::prelude::*; - #[derive(Component, Reflect, Debug)] #[reflect(Component)] /// Component for cameras, with an offset from the Trackable target -/// -pub struct CameraTracking{ - pub offset: Vec3 +/// +pub struct CameraTracking { + pub offset: Vec3, } impl Default for CameraTracking { fn default() -> Self { - CameraTracking { offset: Vec3::new(0.0, 6.0, 8.0) } + CameraTracking { + offset: Vec3::new(0.0, 6.0, 8.0), + } } } - -#[derive(Component, Reflect, Debug, Deref, DerefMut)] +#[derive(Component, Reflect, Debug, Deref, DerefMut)] #[reflect(Component)] /// Component for cameras, with an offset from the Trackable target pub struct CameraTrackingOffset(Vec3); @@ -26,32 +26,33 @@ impl Default for CameraTrackingOffset { } impl CameraTrackingOffset { - fn new (input: Vec3) -> Self { + fn new(input: Vec3) -> Self { CameraTrackingOffset(input) } } - - - -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] /// Add this component to an entity if you want it to be tracked by a Camera pub struct CameraTrackable; pub fn camera_track( - mut tracking_cameras: Query<(&mut Transform, &CameraTrackingOffset), (With, With, Without)>, + mut tracking_cameras: Query< + (&mut Transform, &CameraTrackingOffset), + ( + With, + With, + Without, + ), + >, camera_tracked: Query<&Transform, With>, ) { - for (mut camera_transform, tracking_offset) in tracking_cameras.iter_mut() { - for tracked_transform in camera_tracked.iter(){ - + for tracked_transform in camera_tracked.iter() { let target_position = tracked_transform.translation + tracking_offset.0; let eased_position = camera_transform.translation.lerp(target_position, 0.1); - camera_transform.translation = eased_position;// + tracking.offset;// tracked_transform.translation + tracking.offset; + camera_transform.translation = eased_position; // + tracking.offset;// tracked_transform.translation + tracking.offset; *camera_transform = camera_transform.looking_at(tracked_transform.translation, Vec3::Y); } } - } diff --git a/examples/basic/core/camera/mod.rs b/examples/basic/core/camera/mod.rs index a981650..9cc4bf3 100644 --- a/examples/basic/core/camera/mod.rs +++ b/examples/basic/core/camera/mod.rs @@ -8,18 +8,10 @@ use bevy::prelude::*; pub struct CameraPlugin; impl Plugin for CameraPlugin { - fn build(&self, app: &mut App) { - app - .register_type::() - .register_type::() - .register_type::() - - .add_systems(Update, - ( - camera_replace_proxies, - camera_track, - ) - ) - ; - } -} \ No newline at end of file + fn build(&self, app: &mut App) { + app.register_type::() + .register_type::() + .register_type::() + .add_systems(Update, (camera_replace_proxies, camera_track)); + } +} diff --git a/examples/basic/core/lighting/lighting_replace_proxies.rs b/examples/basic/core/lighting/lighting_replace_proxies.rs index 9e1d31d..48c0908 100644 --- a/examples/basic/core/lighting/lighting_replace_proxies.rs +++ b/examples/basic/core/lighting/lighting_replace_proxies.rs @@ -1,29 +1,25 @@ use bevy::prelude::*; -use bevy::pbr::{CascadeShadowConfigBuilder, CascadeShadowConfig}; +use bevy::pbr::{CascadeShadowConfig, CascadeShadowConfigBuilder}; // fixme might be too specific to might needs, should it be moved out ? also these are all for lights, not models pub fn lighting_replace_proxies( - mut added_dirights: Query<(Entity, &mut DirectionalLight), Added>, - mut added_spotlights: Query<&mut SpotLight, Added>, - mut commands: Commands, - -){ - - for (entity, mut light) in added_dirights.iter_mut(){ - light.illuminance *= 5.0; - light.shadows_enabled = true; - let shadow_config:CascadeShadowConfig = CascadeShadowConfigBuilder { - first_cascade_far_bound: 15.0, - maximum_distance: 135.0, - ..default() - } - .into(); - commands.entity(entity) - .insert(shadow_config); - } - for mut light in added_spotlights.iter_mut(){ - light.shadows_enabled = true; - } + mut added_dirights: Query<(Entity, &mut DirectionalLight), Added>, + mut added_spotlights: Query<&mut SpotLight, Added>, + mut commands: Commands, +) { + for (entity, mut light) in added_dirights.iter_mut() { + light.illuminance *= 5.0; + light.shadows_enabled = true; + let shadow_config: CascadeShadowConfig = CascadeShadowConfigBuilder { + first_cascade_far_bound: 15.0, + maximum_distance: 135.0, + ..default() + } + .into(); + commands.entity(entity).insert(shadow_config); + } + for mut light in added_spotlights.iter_mut() { + light.shadows_enabled = true; + } } - diff --git a/examples/basic/core/lighting/mod.rs b/examples/basic/core/lighting/mod.rs index d1744b7..c9688cd 100644 --- a/examples/basic/core/lighting/mod.rs +++ b/examples/basic/core/lighting/mod.rs @@ -1,18 +1,18 @@ mod lighting_replace_proxies; use lighting_replace_proxies::*; +use bevy::pbr::{DirectionalLightShadowMap, NotShadowCaster}; use bevy::prelude::*; -use bevy::pbr::{NotShadowCaster, DirectionalLightShadowMap}; pub struct LightingPlugin; impl Plugin for LightingPlugin { - fn build(&self, app: &mut App) { - app + fn build(&self, app: &mut App) { + app .insert_resource(DirectionalLightShadowMap { size: 4096 }) // FIXME: adding these since they are missing .register_type::() .add_systems(PreUpdate, lighting_replace_proxies) // FIXME: you should actually run this in a specific state most likely ; - } -} \ No newline at end of file + } +} diff --git a/examples/basic/core/mod.rs b/examples/basic/core/mod.rs index 478f449..d6d4775 100644 --- a/examples/basic/core/mod.rs +++ b/examples/basic/core/mod.rs @@ -13,12 +13,7 @@ pub use physics::*; use bevy::prelude::*; pub struct CorePlugin; impl Plugin for CorePlugin { - fn build(&self, app: &mut App) { - app - .add_plugins(( - LightingPlugin, - CameraPlugin, - PhysicsPlugin - )); - } + fn build(&self, app: &mut App) { + app.add_plugins((LightingPlugin, CameraPlugin, PhysicsPlugin)); + } } diff --git a/examples/basic/core/physics/controls.rs b/examples/basic/core/physics/controls.rs index 461c2ae..8ee2b95 100644 --- a/examples/basic/core/physics/controls.rs +++ b/examples/basic/core/physics/controls.rs @@ -1,10 +1,10 @@ use bevy::prelude::ResMut; use bevy_rapier3d::prelude::RapierConfiguration; -pub fn pause_physics(mut physics_config: ResMut){ +pub fn pause_physics(mut physics_config: ResMut) { physics_config.physics_pipeline_active = false; } -pub fn resume_physics(mut physics_config: ResMut){ +pub fn resume_physics(mut physics_config: ResMut) { physics_config.physics_pipeline_active = true; -} \ No newline at end of file +} diff --git a/examples/basic/core/physics/mod.rs b/examples/basic/core/physics/mod.rs index 0f1b15a..4b4b98b 100644 --- a/examples/basic/core/physics/mod.rs +++ b/examples/basic/core/physics/mod.rs @@ -10,8 +10,8 @@ use bevy::prelude::*; // use crate::Collider; pub struct PhysicsPlugin; impl Plugin for PhysicsPlugin { - fn build(&self, app: &mut App) { - app + fn build(&self, app: &mut App) { + app .register_type::() .register_type::() @@ -23,6 +23,5 @@ impl Plugin for PhysicsPlugin { //.add_system(pause_physics.in_schedule(OnEnter(GameState::InMenu))) //.add_system(resume_physics.in_schedule(OnEnter(GameState::InGame))) ; - } + } } - diff --git a/examples/basic/core/physics/physics_replace_proxies.rs b/examples/basic/core/physics/physics_replace_proxies.rs index 3f13ae8..37edfe5 100644 --- a/examples/basic/core/physics/physics_replace_proxies.rs +++ b/examples/basic/core/physics/physics_replace_proxies.rs @@ -1,11 +1,11 @@ use bevy::prelude::*; // use bevy::render::primitives::Aabb; use bevy_rapier3d::geometry::Collider as RapierCollider; -use bevy_rapier3d::prelude::{ComputedColliderShape, ActiveEvents, ActiveCollisionTypes}; +use bevy_rapier3d::prelude::{ActiveCollisionTypes, ActiveEvents, ComputedColliderShape}; use super::utils::*; -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] pub enum Collider { Ball(f32), @@ -15,34 +15,37 @@ pub enum Collider { Mesh, } -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] pub enum AutoAABBCollider { #[default] Cuboid, Ball, - Capsule + Capsule, } -// replaces all physics stand-ins with the actual rapier types -pub fn physics_replace_proxies ( +// replaces all physics stand-ins with the actual rapier types +pub fn physics_replace_proxies( meshes: Res>, mesh_handles: Query<&Handle>, - mut proxy_colliders: Query<(Entity, &Collider, &Name, &mut Visibility), (Without, Added)>, + mut proxy_colliders: Query< + (Entity, &Collider, &Name, &mut Visibility), + (Without, Added), + >, // needed for tri meshes - children: Query<&Children>, + children: Query<&Children>, mut commands: Commands, ) { for proxy_colider in proxy_colliders.iter_mut() { let (entity, collider_proxy, name, mut visibility) = proxy_colider; // we hide the collider meshes: perhaps they should be removed altogether once processed ? - if name.ends_with( "_collider" ) || name.ends_with( "_sensor" ) { + if name.ends_with("_collider") || name.ends_with("_sensor") { *visibility = Visibility::Hidden; } - let mut rapier_collider:RapierCollider; - match collider_proxy{ + let mut rapier_collider: RapierCollider; + match collider_proxy { Collider::Ball(radius) => { println!("proxy: ball"); rapier_collider = RapierCollider::ball(*radius); @@ -69,15 +72,25 @@ pub fn physics_replace_proxies ( } Collider::Mesh => { println!("proxy: mesh"); - for (_, collider_mesh) in Mesh::search_in_children(entity, &children, &meshes, &mesh_handles) + for (_, collider_mesh) in + Mesh::search_in_children(entity, &children, &meshes, &mesh_handles) { - rapier_collider = RapierCollider::from_bevy_mesh(collider_mesh, &ComputedColliderShape::TriMesh).unwrap(); - commands.entity(entity) + rapier_collider = RapierCollider::from_bevy_mesh( + collider_mesh, + &ComputedColliderShape::TriMesh, + ) + .unwrap(); + commands + .entity(entity) .insert(rapier_collider) - // FIXME: this is just for demo purposes !!! - .insert(ActiveCollisionTypes::default() | ActiveCollisionTypes::KINEMATIC_STATIC | ActiveCollisionTypes::STATIC_STATIC | ActiveCollisionTypes::DYNAMIC_STATIC) - .insert(ActiveEvents::COLLISION_EVENTS) - ; + // FIXME: this is just for demo purposes !!! + .insert( + ActiveCollisionTypes::default() + | ActiveCollisionTypes::KINEMATIC_STATIC + | ActiveCollisionTypes::STATIC_STATIC + | ActiveCollisionTypes::DYNAMIC_STATIC, + ) + .insert(ActiveEvents::COLLISION_EVENTS); // .insert(ActiveEvents::COLLISION_EVENTS) // break; // RapierCollider::convex_hull(points) diff --git a/examples/basic/core/relationships/mod.rs b/examples/basic/core/relationships/mod.rs index 6345d35..4128453 100644 --- a/examples/basic/core/relationships/mod.rs +++ b/examples/basic/core/relationships/mod.rs @@ -5,7 +5,7 @@ use bevy::prelude::*; pub struct EcsRelationshipsPlugin; impl Plugin for EcsRelationshipsPlugin { - fn build(&self, app: &mut App) { - app; - } -} \ No newline at end of file + fn build(&self, app: &mut App) { + app; + } +} diff --git a/examples/basic/core/relationships/relationships_insert_dependant_components.rs b/examples/basic/core/relationships/relationships_insert_dependant_components.rs index afec54e..4e9ad17 100644 --- a/examples/basic/core/relationships/relationships_insert_dependant_components.rs +++ b/examples/basic/core/relationships/relationships_insert_dependant_components.rs @@ -1,16 +1,15 @@ use bevy::prelude::*; -pub fn insert_dependant_component( +pub fn insert_dependant_component< + Dependant: Component, + Dependency: Component + std::default::Default, +>( mut commands: Commands, entities_without_depency: Query<(Entity, &Name), (With, Without)>, ) { for (entity, name) in entities_without_depency.iter() { let name = name.clone().to_string(); - commands.entity(entity) - .insert( - Dependency::default() - ) - ; + commands.entity(entity).insert(Dependency::default()); warn!("found an entity called {} with a {} component but without an {}, please check your assets", name.clone(), std::any::type_name::(), std::any::type_name::()); } -} \ No newline at end of file +} diff --git a/examples/basic/game.rs b/examples/basic/game.rs index 3366223..4364ee9 100644 --- a/examples/basic/game.rs +++ b/examples/basic/game.rs @@ -1,50 +1,45 @@ +use crate::insert_dependant_component; use bevy::prelude::*; use bevy_rapier3d::prelude::*; -use crate::insert_dependant_component; // this file is just for demo purposes, contains various types of components, systems etc -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] -pub enum SoundMaterial{ - Metal, - Wood, - Rock, - Cloth, - Squishy, - #[default] - None +pub enum SoundMaterial { + Metal, + Wood, + Rock, + Cloth, + Squishy, + #[default] + None, } - -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] /// Demo marker component pub struct Player; -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] -/// Demo component showing auto injection of components +/// Demo component showing auto injection of components pub struct ShouldBeWithPlayer; - -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] /// Demo marker component pub struct Interactible; -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] /// Demo marker component pub struct Pickable; - - fn player_move_demo( keycode: Res>, mut players: Query<&mut Transform, With>, -){ - +) { let speed = 0.2; if let Ok(mut player) = players.get_single_mut() { if keycode.pressed(KeyCode::Left) { @@ -67,17 +62,15 @@ fn player_move_demo( pub fn test_collision_events( mut collision_events: EventReader, mut contact_force_events: EventReader, -) -{ +) { for collision_event in collision_events.iter() { println!("collision"); match collision_event { - CollisionEvent::Started(_entity1, _entity2 ,_) => { + CollisionEvent::Started(_entity1, _entity2, _) => { println!("collision started") } - CollisionEvent::Stopped(_entity1, _entity2 ,_) => { + CollisionEvent::Stopped(_entity1, _entity2, _) => { println!("collision ended") - } } } @@ -87,23 +80,23 @@ pub fn test_collision_events( } } - pub struct DemoPlugin; impl Plugin for DemoPlugin { - fn build(&self, app: &mut App) { - app - .register_type::() - .register_type::() - .register_type::() - .register_type::() - // little helper utility, to automatically inject components that are dependant on an other component - // ie, here an Entity with a Player component should also always have a ShouldBeWithPlayer component - // you get a warning if you use this, as I consider this to be stop-gap solution (usually you should have either a bundle, or directly define all needed components) - .add_systems(Update, ( - insert_dependant_component::, - player_move_demo, //.run_if(in_state(AppState::Running)), - test_collision_events - )) - ; - } + fn build(&self, app: &mut App) { + app.register_type::() + .register_type::() + .register_type::() + .register_type::() + // little helper utility, to automatically inject components that are dependant on an other component + // ie, here an Entity with a Player component should also always have a ShouldBeWithPlayer component + // you get a warning if you use this, as I consider this to be stop-gap solution (usually you should have either a bundle, or directly define all needed components) + .add_systems( + Update, + ( + insert_dependant_component::, + player_move_demo, //.run_if(in_state(AppState::Running)), + test_collision_events, + ), + ); + } } diff --git a/examples/basic/main.rs b/examples/basic/main.rs index 5ddc261..1a9f109 100644 --- a/examples/basic/main.rs +++ b/examples/basic/main.rs @@ -1,8 +1,8 @@ -use std::time::Duration; -use bevy::{prelude::*, asset::ChangeWatcher, gltf::Gltf}; +use bevy::{asset::ChangeWatcher, gltf::Gltf, prelude::*}; use bevy_editor_pls::prelude::*; -use bevy_rapier3d::prelude::*; use bevy_gltf_components::ComponentsFromGltfPlugin; +use bevy_rapier3d::prelude::*; +use std::time::Duration; mod core; use crate::core::*; @@ -13,12 +13,11 @@ use game::*; mod test_components; use test_components::*; -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] /// helper marker component pub struct LoadedMarker; - #[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)] enum AppState { #[default] @@ -26,54 +25,41 @@ enum AppState { Running, } - - -fn main(){ +fn main() { App::new() - .add_plugins(( - DefaultPlugins.set( - AssetPlugin { + .add_plugins(( + DefaultPlugins.set(AssetPlugin { // This tells the AssetServer to watch for changes to assets. // It enables our scenes to automatically reload in game when we modify their files. // practical in our case to be able to edit the shaders without needing to recompile watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(50)), ..default() - } - ), - // editor - EditorPlugin::default(), - // physics - RapierPhysicsPlugin::::default(), - RapierDebugRenderPlugin::default(), - // our custom plugins - ComponentsFromGltfPlugin, - CorePlugin, // reusable plugins - DemoPlugin, // specific to our game - ComponentsTestPlugin // Showcases different type of components /structs - )) - - .add_state::() - .add_systems(Startup, setup) - .add_systems(Update, ( - spawn_level.run_if(in_state(AppState::Loading)), - )) - .run(); + }), + // editor + EditorPlugin::default(), + // physics + RapierPhysicsPlugin::::default(), + RapierDebugRenderPlugin::default(), + // our custom plugins + ComponentsFromGltfPlugin, + CorePlugin, // reusable plugins + DemoPlugin, // specific to our game + ComponentsTestPlugin, // Showcases different type of components /structs + )) + .add_state::() + .add_systems(Startup, setup) + .add_systems(Update, (spawn_level.run_if(in_state(AppState::Loading)),)) + .run(); } - - #[derive(Resource)] struct AssetLoadHelper(Handle); -// we preload the data here, but this is for DEMO PURPOSES ONLY !! Please use https://github.com/NiklasEi/bevy_asset_loader or a similar logic to seperate loading / pre processing +// we preload the data here, but this is for DEMO PURPOSES ONLY !! Please use https://github.com/NiklasEi/bevy_asset_loader or a similar logic to seperate loading / pre processing // of assets from the spawning // AssetLoadHelper is also just for the same purpose, you do not need it in a real scenario -// the states here are also for demo purposes only, -fn setup( - mut commands: Commands, - asset_server: Res, -) { - - let tmp: Handle = asset_server.load("basic/models/level1.glb#Scene0"); +// the states here are also for demo purposes only, +fn setup(mut commands: Commands, asset_server: Res) { + let tmp: Handle = asset_server.load("basic/models/level1.glb#Scene0"); commands.insert_resource(AssetLoadHelper(tmp)); } @@ -84,28 +70,25 @@ fn spawn_level( mut asset_event_reader: EventReader>, mut next_state: ResMut>, -){ - +) { if let Some(asset_event) = asset_event_reader.iter().next() { match asset_event { AssetEvent::Created { handle: _ } => { info!("GLTF loaded"); if scene_markers.is_empty() { info!("spawning scene"); - commands.spawn( - ( - SceneBundle { - scene: preloaded_scene.0.clone(), - ..default() - }, - LoadedMarker, - Name::new("Level1") - ) - ); + commands.spawn(( + SceneBundle { + scene: preloaded_scene.0.clone(), + ..default() + }, + LoadedMarker, + Name::new("Level1"), + )); next_state.set(AppState::Running); } } - _ => () + _ => (), } } } diff --git a/examples/basic/test_components.rs b/examples/basic/test_components.rs index 79a45f6..d0e6fbd 100644 --- a/examples/basic/test_components.rs +++ b/examples/basic/test_components.rs @@ -1,7 +1,6 @@ use bevy::prelude::*; - -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct UnitTest; @@ -17,70 +16,65 @@ struct TuppleTestU64(u64); #[reflect(Component)] pub struct TuppleTestStr(String); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleTest2(f32, u64, String); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleTestBool(bool); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleVec2(Vec2); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleVec3(Vec3); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleVec(Vec); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] struct TuppleTestColor(Color); -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] -struct BasicTest{ +struct BasicTest { a: f32, b: u64, - c: String + c: String, } -#[derive(Component, Reflect, Default, Debug, )] +#[derive(Component, Reflect, Default, Debug)] #[reflect(Component)] -pub enum EnumTest{ - Metal, - Wood, - Rock, - Cloth, - Squishy, - #[default] - None +pub enum EnumTest { + Metal, + Wood, + Rock, + Cloth, + Squishy, + #[default] + None, } - pub struct ComponentsTestPlugin; impl Plugin for ComponentsTestPlugin { - fn build(&self, app: &mut App) { - app - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - .register_type::() - - .register_type::() - .register_type::>() - - ; - } + fn build(&self, app: &mut App) { + app.register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::>(); + } }