From 5345af11d4ce138bacf5a9a3ab53d1c3b3b103c7 Mon Sep 17 00:00:00 2001 From: Aevyrie Date: Wed, 14 May 2025 21:10:58 -0700 Subject: [PATCH] Plugin Refactors (#45) Refactors plugins to make usage more flexible. Originally intended to allow for running in the fixed update schedule, but decided against this in favor of making plugins more granular, and realizing running in fixed update wouldn't actually be desirable. --------- Co-authored-by: Zachary Harrold --- CHANGELOG.md | 54 +++- Cargo.toml | 59 ++-- README.md | 2 +- assets/images/cubemap.png | Bin 0 -> 348 bytes assets/models/low_poly_spaceship/scene.gltf | 2 +- benches/benchmarks.rs | 32 +- examples/debug.rs | 3 +- examples/demo.rs | 18 +- examples/error.rs | 2 +- examples/error_child.rs | 6 +- examples/infinite.rs | 6 +- examples/minimal.rs | 14 +- examples/planets.rs | 99 ++++-- examples/small_scale.rs | 10 +- examples/spatial_hash.rs | 19 +- examples/split_screen.rs | 6 +- src/bevy_compat.rs | 154 +++++++++ src/camera.rs | 75 +++-- src/debug.rs | 5 +- src/floating_origins.rs | 6 +- src/grid/cell.rs | 16 +- src/grid/local_origin.rs | 32 +- src/grid/mod.rs | 2 +- src/grid/propagation.rs | 68 ++-- src/hash/component.rs | 6 +- src/hash/map.rs | 10 +- src/hash/mod.rs | 35 +- src/hash/partition.rs | 20 +- src/lib.rs | 15 +- src/plugin.rs | 335 +++++++------------- src/portable_par.rs | 13 +- src/tests.rs | 5 +- src/timing.rs | 6 +- src/validation.rs | 26 +- 34 files changed, 668 insertions(+), 493 deletions(-) create mode 100644 assets/images/cubemap.png create mode 100644 src/bevy_compat.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 117f5da..e135c7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,58 @@ ## UNRELEASED +### Updated: Bevy 0.16 + +Due to changes in bevy, this plugin once again requires you to disable bevy's built-in transform system: + +```rs +DefaultPlugins.build().disable::(), +``` + +### Changed: `BigSpaceDefaultPlugins` plugin group + +Instead of adding common plugins individually, they have been grouped into the `BigSpaceDefaultPlugins` plugin group, similar to the `DefaultPlugins` plugin group in Bevy. + +For example, the hierarchy validation plugin is enabled whenever debug assertions are enabled but can be manually enabled or disabled to override this behavior: + +```rs +BigSpaceDefaultPlugins + .build() + .enable::() +``` + +Plugins that are behind feature flags are automatically enabled when their corresponding feature is enabled. For example, you no longer need to manually add the camera controller plugin, you only need to enable the feature and add `BigSpaceDefaultPlugins` to your app. + +This replaces `BigSpacePlugin`. + +The existing plugin structure has been organized into more fine grained plugins, with the addition of the `BigSpaceMinimalPlugins` composed of `BigSpaceCorePlugin` and `BigSpacePropagationPlugin`. These are particularly useful for tests, benchmarks, and serverside applications. Future serverside physics will likely only use the `BigSpaceCorePlugin` to handle grid cell recentering, and not do any propagation which is only needed for rendering. + +### Changed: Naming consistency + +To avoid common name collisions and improve searchability, names have been standardized: + +- `FloatingOriginSystem` -> `BigSpaceSystems` +- `CameraControllerPlugin` -> `BigSpaceCameraControllerPlugin` + - `CameraController` -> `BigSpaceCameraController` + - `CameraInput` -> `BigSpaceCameraInput` +- `TimingStatsPlugin` -> `BigSpaceTimingStatsPlugin` +- `FloatingOriginDebugPlugin` -> `BigSpaceDebugPlugin` +- `BigSpaceValidationPlugin` (new) +- `BigSpaceDefaultPlugins` (new) +- `BigSpaceMinimalPlugins` (new) +- `BigSpaceCorePlugin` (new) +- `BigSpacePropagationPlugin` (new) + +### Changed: Default plugin filters + +Plugins that accept an optional query filter no longer require specifying the default empty filter tuple turbofish `::<()>`: + +- `GridHashPlugin::<()>::default()` -> `GridHashPlugin::default()` +- `GridPartitionPlugin::<()>::default()` -> `GridPartitionPlugin::default()` + +To construct a plugin with a custom filter, use the `new()` method: +`GridHashPlugin::>::new()` + ### New: `no_std` Support Thanks to `bushrat011899`'s efforts upstream and in this crate, it is now possible to use the plugin without the rust standard library. This is particularly useful when targeting embedded or console targets. @@ -24,7 +76,7 @@ The map has received a few rounds of optimization passes to make incremental upd Built on top of the new spatial hashing feature is the `GridPartitionMap`. This map tracks groups of adjacent grid cells that have at least one entity. Each of these partitions contains many entities, and each partition is independent. That is, entities in partition A are guaranteed to be unable to collide with entities in partition B. -This lays the groundwork for adding physics integrations. Because each partition is a clump of entities independent from all other entities, it should be possible to have independent physics simulations for each partition. Not only will this allow for extreme parallelism, it becomes possible to use 32-bit physics simulations in a 160-bit big_space. +This lays the groundwork for adding physics integrations. Because each partition is a clump of entities independent of all other entities, it should be possible to have independent physics simulations for each partition. Not only will this allow for extreme parallelism, it becomes possible to use 32-bit physics simulations in a 160-bit big_space. ### `ReferenceFrame` Renamed `Grid` diff --git a/Cargo.toml b/Cargo.toml index abd7483..a63b0d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,10 @@ license = "MIT OR Apache-2.0" keywords = ["bevy", "floating-origin", "large-scale", "space"] repository = "https://github.com/aevyrie/big_space" documentation = "https://docs.rs/crate/big_space/latest" +exclude = ["assets"] + +[package.metadata.docs.rs] +all-features = true [features] default = ["std"] @@ -26,7 +30,7 @@ std = [ "bevy_tasks/std", "bevy_transform/std", "bevy_utils/std", - "bevy_platform_support/std", + "bevy_platform/std", "bevy_color?/std", "bevy_input?/std", "bevy_time?/std", @@ -34,33 +38,40 @@ std = [ libm = ["bevy_math/libm", "dep:libm"] [dependencies] -tracing = { version = "0.1", default-features = false } # Less deps than pulling in bevy_log smallvec = { version = "1.13.2", default-features = false } # Already used by bevy in commands -bevy_app = { version = "0.16.0-rc.3", default-features = false, features = ["bevy_reflect"] } -bevy_ecs = { version = "0.16.0-rc.3", default-features = false } -bevy_math = { version = "0.16.0-rc.3", default-features = false } -bevy_reflect = { version = "0.16.0-rc.3", default-features = false, features = ["glam"] } -bevy_tasks = { version = "0.16.0-rc.3", default-features = false } -bevy_transform = { version = "0.16.0-rc.3", default-features = false, features = [ +bevy_app = { version = "0.16.0", default-features = false, features = [ + "bevy_reflect", +] } +bevy_ecs = { version = "0.16.0", default-features = false } +bevy_log = { version = "0.16.0", default-features = false } +bevy_math = { version = "0.16.0", default-features = false } +bevy_reflect = { version = "0.16.0", default-features = false, features = [ + "glam", +] } +bevy_tasks = { version = "0.16.0", default-features = false } +bevy_transform = { version = "0.16.0", default-features = false, features = [ "bevy-support", "bevy_reflect", ] } -bevy_utils = { version = "0.16.0-rc.3", default-features = false } -bevy_platform_support = { version = "0.16.0-rc.3", default-features = false, features = ["alloc"] } +bevy_utils = { version = "0.16.0", default-features = false } +bevy_platform = { version = "0.16.0", default-features = false, features = [ + "alloc", +] } # Optional -bevy_color = { version = "0.16.0-rc.3", default-features = false, optional = true } -bevy_gizmos = { version = "0.16.0-rc.3", default-features = false, optional = true } -bevy_render = { version = "0.16.0-rc.3", default-features = false, optional = true } -bevy_input = { version = "0.16.0-rc.3", default-features = false, optional = true } -bevy_time = { version = "0.16.0-rc.3", default-features = false, optional = true } +bevy_color = { version = "0.16.0", default-features = false, optional = true } +bevy_gizmos = { version = "0.16.0", default-features = false, optional = true } +bevy_render = { version = "0.16.0", default-features = false, optional = true } +bevy_input = { version = "0.16.0", default-features = false, optional = true } +bevy_time = { version = "0.16.0", default-features = false, optional = true } libm = { version = "0.2", default-features = false, optional = true } [dev-dependencies] -bevy = { version = "0.16.0-rc.3", default-features = false, features = [ +bevy = { version = "0.16.0", default-features = false, features = [ "bevy_scene", "bevy_asset", "bevy_color", "bevy_gltf", + "bevy_remote", "bevy_winit", "default_font", "bevy_ui", @@ -71,11 +82,13 @@ bevy = { version = "0.16.0-rc.3", default-features = false, features = [ "x11", "tonemapping_luts", "multi_threaded", + "png", ] } noise = "0.9" turborand = "0.10" criterion = "0.5" -bytemuck = "1.20" +bevy-inspector-egui = "0.31.0" +bevy_egui = "0.34.1" # bevy_hanabi = "0.14" # TODO: Update [lints.clippy] @@ -124,14 +137,14 @@ required-features = ["i128", "camera", "debug"] doc-scrape-examples = false [[example]] -name = "error_child" -path = "examples/error_child.rs" -required-features = ["camera", "debug"] +name = "error" +path = "examples/error.rs" doc-scrape-examples = false [[example]] -name = "error" -path = "examples/error.rs" +name = "error_child" +path = "examples/error_child.rs" +required-features = ["camera", "debug"] doc-scrape-examples = false [[example]] @@ -143,7 +156,7 @@ doc-scrape-examples = false [[example]] name = "minimal" path = "examples/minimal.rs" -required-features = ["camera"] +required-features = ["camera", "debug"] doc-scrape-examples = false # TODO: Uncomment once bevy_hanabi is updated diff --git a/README.md b/README.md index e804efc..5a29b68 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Big Space - +partitioning screenshot Huge worlds, high performance, no dependencies, ecosystem compatibility. [Read the docs](https://docs.rs/big_space) diff --git a/assets/images/cubemap.png b/assets/images/cubemap.png new file mode 100644 index 0000000000000000000000000000000000000000..1a71b91d459c352c1577dd72e3d257eb67f42051 GIT binary patch literal 348 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!2~3Gi;~ko0>we@P7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL5ULAh?3y^w370~qEv=}#LT=BJwMkF1yemk zJ)_@yn70AdY)g&sO!M^AV&DLBSQ(@kS;01Y0eR9;Hpn#^jLcwhkb4XnnHU6sbQBP0 zwzGi6vw&<6NC0Ax%V9K{r3}mr3=`NHSb!=FjEoH!7eGt}>0n&|F=+~r4FXI+bC|#? zgDfq8ET}F+0|Suk%d6ikPTk6>0y4QhT^vIs!jlsY@BzKdz{vV#c@s#9r>mdKI;Vst E0R4VC>i_@% literal 0 HcmV?d00001 diff --git a/assets/models/low_poly_spaceship/scene.gltf b/assets/models/low_poly_spaceship/scene.gltf index f637834..b6f9bda 100644 --- a/assets/models/low_poly_spaceship/scene.gltf +++ b/assets/models/low_poly_spaceship/scene.gltf @@ -310,7 +310,7 @@ "emissiveFactor": [ 0.0, 0.161466, - 1.0 + 50.0 ], "name": "Material.004" } diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index 24ecbc4..0c1663a 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -3,6 +3,7 @@ #![allow(missing_docs)] use bevy::prelude::*; +use big_space::plugin::BigSpaceMinimalPlugins; use big_space::prelude::*; use core::{iter::repeat_with, ops::Neg}; use criterion::{black_box, criterion_group, criterion_main, Criterion}; @@ -60,8 +61,8 @@ fn deep_hierarchy(c: &mut Criterion) { let mut app = App::new(); app.add_plugins(( MinimalPlugins, - GridHashPlugin::<()>::default(), - BigSpacePlugin::default(), + BigSpaceMinimalPlugins, + GridHashPlugin::default(), )) .add_systems(Startup, setup) .add_systems(Update, translate) @@ -99,8 +100,8 @@ fn wide_hierarchy(c: &mut Criterion) { let mut app = App::new(); app.add_plugins(( MinimalPlugins, - GridHashPlugin::<()>::default(), - BigSpacePlugin::default(), + BigSpaceMinimalPlugins, + GridHashPlugin::default(), )) .add_systems(Startup, setup) .add_systems(Update, translate) @@ -149,7 +150,7 @@ fn spatial_hashing(c: &mut Criterion) { } let mut app = App::new(); - app.add_plugins(GridHashPlugin::<()>::default()) + app.add_plugins(GridHashPlugin::default()) .add_systems(Startup, setup) .update(); @@ -221,7 +222,7 @@ fn spatial_hashing(c: &mut Criterion) { // Uniform Grid Population 1_000 let mut app = App::new(); - app.add_plugins(GridHashPlugin::<()>::default()) + app.add_plugins(GridHashPlugin::default()) .add_systems(Startup, setup_uniform::<5>) .update(); @@ -250,7 +251,7 @@ fn spatial_hashing(c: &mut Criterion) { // Uniform Grid Population 1_000_000 let mut app = App::new(); - app.add_plugins(GridHashPlugin::<()>::default()) + app.add_plugins(GridHashPlugin::default()) .add_systems(Startup, setup_uniform::<50>) .update(); @@ -321,7 +322,7 @@ fn hash_filtering(c: &mut Criterion) { .add_systems(Update, translate) .update(); app.update(); - app.add_plugins((GridHashPlugin::<()>::default(),)); + app.add_plugins((GridHashPlugin::default(),)); group.bench_function("No Filter Plugin", |b| { b.iter(|| { black_box(app.update()); @@ -333,7 +334,7 @@ fn hash_filtering(c: &mut Criterion) { .add_systems(Update, translate) .update(); app.update(); - app.add_plugins((GridHashPlugin::>::default(),)); + app.add_plugins((GridHashPlugin::>::new(),)); group.bench_function("With Player Plugin", |b| { b.iter(|| { black_box(app.update()); @@ -345,7 +346,7 @@ fn hash_filtering(c: &mut Criterion) { .add_systems(Update, translate) .update(); app.update(); - app.add_plugins((GridHashPlugin::>::default(),)); + app.add_plugins((GridHashPlugin::>::new(),)); group.bench_function("Without Player Plugin", |b| { b.iter(|| { black_box(app.update()); @@ -357,9 +358,9 @@ fn hash_filtering(c: &mut Criterion) { .add_systems(Update, translate) .update(); app.update(); - app.add_plugins((GridHashPlugin::<()>::default(),)) - .add_plugins((GridHashPlugin::>::default(),)) - .add_plugins((GridHashPlugin::>::default(),)); + app.add_plugins((GridHashPlugin::default(),)) + .add_plugins((GridHashPlugin::>::new(),)) + .add_plugins((GridHashPlugin::>::new(),)); group.bench_function("All Plugins", |b| { b.iter(|| { black_box(app.update()); @@ -372,7 +373,6 @@ fn vs_bevy(c: &mut Criterion) { let mut group = c.benchmark_group("transform_prop"); use bevy::prelude::*; - use BigSpacePlugin; const N_ENTITIES: usize = 1_000_000; @@ -407,7 +407,7 @@ fn vs_bevy(c: &mut Criterion) { }); let mut app = App::new(); - app.add_plugins((MinimalPlugins, BigSpacePlugin::default())) + app.add_plugins((MinimalPlugins, BigSpaceMinimalPlugins)) .add_systems(Startup, setup_big) .update(); @@ -436,7 +436,7 @@ fn vs_bevy(c: &mut Criterion) { }); let mut app = App::new(); - app.add_plugins((MinimalPlugins, BigSpacePlugin::default())) + app.add_plugins((MinimalPlugins, BigSpaceMinimalPlugins)) .add_systems(Startup, setup_big) .add_systems(Update, translate) .update(); diff --git a/examples/debug.rs b/examples/debug.rs index 98d7839..44611ff 100644 --- a/examples/debug.rs +++ b/examples/debug.rs @@ -8,8 +8,7 @@ fn main() { App::new() .add_plugins(( DefaultPlugins.build().disable::(), - BigSpacePlugin::default(), - FloatingOriginDebugPlugin::default(), + BigSpaceDefaultPlugins, )) .add_systems(Startup, setup) .add_systems(Update, (movement, rotation)) diff --git a/examples/demo.rs b/examples/demo.rs index 802de7d..6900198 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -6,19 +6,13 @@ use bevy::{ transform::TransformSystem, window::{CursorGrabMode, PrimaryWindow}, }; -use big_space::{ - camera::{CameraController, CameraInput}, - prelude::*, - world_query::GridTransformReadOnly, -}; +use big_space::prelude::*; fn main() { App::new() .add_plugins(( DefaultPlugins.build().disable::(), - BigSpacePlugin::default(), - FloatingOriginDebugPlugin::default(), - CameraControllerPlugin::default(), + BigSpaceDefaultPlugins, )) .insert_resource(ClearColor(Color::BLACK)) .add_systems(Startup, (setup, ui_setup)) @@ -44,7 +38,7 @@ fn setup( }), Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), FloatingOrigin, // Important: marks the floating origin entity for rendering. - CameraController::default() // Built-in camera controller + BigSpaceCameraController::default() // Built-in camera controller .with_speed_bounds([10e-18, 10e35]) .with_smoothness(0.9, 0.8) .with_speed(1.0), @@ -124,7 +118,7 @@ fn ui_setup(mut commands: Commands) { } fn highlight_nearest_sphere( - cameras: Query<&CameraController>, + cameras: Query<&BigSpaceCameraController>, objects: Query<&GlobalTransform>, mut gizmos: Gizmos, ) -> Result { @@ -154,7 +148,7 @@ fn ui_text_system( grids: Grids, time: Res