Update GlobalTransform when changing FloatingOrigin (#10)

Currently, when the `FloatingOrigin` component is removed from one
entity and added to another, no `GlobalTransform`s are updated. This can
cause problems for things like switching between playable characters
that are in different `GridCell`s.

---------

Co-authored-by: Aevyrie <aevyrie@gmail.com>
This commit is contained in:
atomicbeef 2024-03-07 12:11:26 +02:00 committed by GitHub
parent a2e3f05a70
commit 946719c77e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 134 additions and 11 deletions

View File

@ -29,7 +29,7 @@ jobs:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2.7.0
- run: cargo check --all-features
- run: cargo check --all-features --all-targets
check-no-defaults:
runs-on: ubuntu-latest
@ -38,7 +38,7 @@ jobs:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2.7.0
- run: cargo check --no-default-features
- run: cargo check --no-default-features --all-targets
clippy:
runs-on: ubuntu-latest
@ -48,7 +48,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2.7.0
- run: rustup component add clippy
- run: cargo clippy --all-features -- -D warnings
- run: cargo clippy --all-features --all-targets -- -D warnings
doc:
runs-on: ubuntu-latest
@ -57,7 +57,7 @@ jobs:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2.7.0
- run: cargo doc --all-features
- run: cargo doc --all-features --no-deps
env:
RUSTDOCFLAGS: -D warnings
@ -68,4 +68,13 @@ jobs:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2.7.0
- run: cargo test --all-features
- run: cargo test --all-features --all-targets
doctest:
runs-on: ubuntu-latest
needs: [setup]
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2.7.0
- run: cargo test --all-features --doc

View File

@ -29,3 +29,21 @@ default = ["debug", "camera", "bevy_render"]
debug = ["bevy/bevy_gizmos"]
bevy_render = ["bevy/bevy_render"]
camera = ["bevy_render"]
[[example]]
name = "demo"
path = "examples/demo.rs"
required-features = ["default"]
doc-scrape-examples = true
[[example]]
name = "debug"
path = "examples/debug.rs"
required-features = ["default"]
doc-scrape-examples = true
[[example]]
name = "error"
path = "examples/error.rs"
required-features = ["default"]
doc-scrape-examples = true

View File

@ -1,7 +1,7 @@
use bevy::{
prelude::*,
transform::TransformSystem,
window::{CursorGrabMode, PrimaryWindow, Window, WindowMode},
window::{CursorGrabMode, PrimaryWindow, WindowMode},
};
use big_space::{
camera::{CameraController, CameraInput},

View File

@ -86,7 +86,7 @@
#![allow(clippy::type_complexity)]
#![deny(missing_docs)]
use bevy::{math::DVec3, prelude::*, reflect::TypePath, transform::TransformSystem};
use bevy::{math::DVec3, prelude::*, transform::TransformSystem};
use propagation::propagate_transforms;
use std::marker::PhantomData;
@ -311,7 +311,7 @@ pub fn recenter_transform_on_grid<P: GridPrecision>(
/// Compute the `GlobalTransform` relative to the floating origin's cell.
pub fn update_global_from_grid<P: GridPrecision>(
settings: Res<FloatingOriginSettings>,
origin: Query<Ref<GridCell<P>>, With<FloatingOrigin>>,
origin: Query<(Ref<GridCell<P>>, Ref<FloatingOrigin>)>,
mut entities: ParamSet<(
Query<
(&Transform, &mut GlobalTransform, &GridCell<P>),
@ -320,9 +320,9 @@ pub fn update_global_from_grid<P: GridPrecision>(
Query<(&Transform, &mut GlobalTransform, &GridCell<P>)>,
)>,
) {
let origin_cell = origin.single();
let (origin_cell, floating_origin) = origin.single();
if origin_cell.is_changed() {
if origin_cell.is_changed() || floating_origin.is_changed() {
let mut all_entities = entities.p1();
all_entities
.par_iter_mut()
@ -372,3 +372,93 @@ pub fn sync_simple_transforms<P: GridPrecision>(
*global_transform = GlobalTransform::from(*transform);
});
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn changing_floating_origin_updates_global_transform() {
let mut app = App::new();
app.add_plugins(FloatingOriginPlugin::<i32>::default());
let first = app
.world
.spawn((
TransformBundle::from_transform(Transform::from_translation(Vec3::new(
150.0, 0.0, 0.0,
))),
GridCell::<i32>::new(5, 0, 0),
FloatingOrigin,
))
.id();
let second = app
.world
.spawn((
TransformBundle::from_transform(Transform::from_translation(Vec3::new(
0.0, 0.0, 300.0,
))),
GridCell::<i32>::new(0, -15, 0),
))
.id();
app.update();
app.world.entity_mut(first).remove::<FloatingOrigin>();
app.world.entity_mut(second).insert(FloatingOrigin);
app.update();
let second_global_transform = app.world.get::<GlobalTransform>(second).unwrap();
assert_eq!(
second_global_transform.translation(),
Vec3::new(0.0, 0.0, 300.0)
);
}
#[test]
fn child_global_transforms_are_updated_when_floating_origin_changes() {
let mut app = App::new();
app.add_plugins(FloatingOriginPlugin::<i32>::default());
let first = app
.world
.spawn((
TransformBundle::from_transform(Transform::from_translation(Vec3::new(
150.0, 0.0, 0.0,
))),
GridCell::<i32>::new(5, 0, 0),
FloatingOrigin,
))
.id();
let second = app
.world
.spawn((
TransformBundle::from_transform(Transform::from_translation(Vec3::new(
0.0, 0.0, 300.0,
))),
GridCell::<i32>::new(0, -15, 0),
))
.with_children(|parent| {
parent.spawn((TransformBundle::from_transform(
Transform::from_translation(Vec3::new(0.0, 0.0, 300.0)),
),));
})
.id();
app.update();
app.world.entity_mut(first).remove::<FloatingOrigin>();
app.world.entity_mut(second).insert(FloatingOrigin);
app.update();
let child = app.world.get::<Children>(second).unwrap()[0];
let child_transform = app.world.get::<GlobalTransform>(child).unwrap();
assert_eq!(child_transform.translation(), Vec3::new(0.0, 0.0, 600.0));
}
}

View File

@ -8,7 +8,13 @@ use bevy::prelude::*;
/// Update [`GlobalTransform`] component of entities based on entity hierarchy and
/// [`Transform`] component.
pub fn propagate_transforms<P: GridPrecision>(
origin_moved: Query<(), (Changed<GridCell<P>>, With<FloatingOrigin>)>,
origin_moved: Query<
(),
(
Or<(Changed<GridCell<P>>, Changed<FloatingOrigin>)>,
With<FloatingOrigin>,
),
>,
mut root_query: Query<
(
Entity,