bevy_transform split up to allow feature gate modularity (#13599)
# Objective Part of https://github.com/bevyengine/bevy/issues/13529 Helps https://github.com/bevyengine/bevy/pull/13533 Splitting up `bevy_transform` makes it easier to selectively include or exclude parts of it in such a way that it's possible to include only a small part with a small dependency tree. ## Solution Make the crate more modular. --------- Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com> Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
This commit is contained in:
		
							parent
							
								
									0f03e1d46e
								
							
						
					
					
						commit
						76d12fa2b3
					
				
							
								
								
									
										59
									
								
								crates/bevy_transform/src/bundles.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								crates/bevy_transform/src/bundles.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| use bevy_ecs::bundle::Bundle; | ||||
| 
 | ||||
| use crate::prelude::{GlobalTransform, Transform}; | ||||
| 
 | ||||
| /// A [`Bundle`] of the [`Transform`] and [`GlobalTransform`]
 | ||||
| /// [`Component`]s, which describe the position of an entity.
 | ||||
| ///
 | ||||
| /// * To place or move an entity, you should set its [`Transform`].
 | ||||
| /// * To get the global transform of an entity, you should get its [`GlobalTransform`].
 | ||||
| /// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`].
 | ||||
| ///   * You may use the [`TransformBundle`] to guarantee this.
 | ||||
| ///
 | ||||
| /// ## [`Transform`] and [`GlobalTransform`]
 | ||||
| ///
 | ||||
| /// [`Transform`] is the position of an entity relative to its parent position, or the reference
 | ||||
| /// frame if it doesn't have a parent.
 | ||||
| ///
 | ||||
| /// [`GlobalTransform`] is the position of an entity relative to the reference frame.
 | ||||
| ///
 | ||||
| /// [`GlobalTransform`] is updated from [`Transform`] by systems in the system set
 | ||||
| /// [`TransformPropagate`](TransformSystem::TransformPropagate).
 | ||||
| ///
 | ||||
| /// This system runs during [`PostUpdate`]. If you
 | ||||
| /// update the [`Transform`] of an entity in this schedule or after, you will notice a 1 frame lag
 | ||||
| /// before the [`GlobalTransform`] is updated.
 | ||||
| #[derive(Clone, Copy, Debug, Default, Bundle)] | ||||
| pub struct TransformBundle { | ||||
|     /// The transform of the entity.
 | ||||
|     pub local: Transform, | ||||
|     /// The global transform of the entity.
 | ||||
|     pub global: GlobalTransform, | ||||
| } | ||||
| 
 | ||||
| impl TransformBundle { | ||||
|     /// An identity [`TransformBundle`] with no translation, rotation, and a scale of 1 on all axes.
 | ||||
|     pub const IDENTITY: Self = TransformBundle { | ||||
|         local: Transform::IDENTITY, | ||||
|         global: GlobalTransform::IDENTITY, | ||||
|     }; | ||||
| 
 | ||||
|     /// Creates a new [`TransformBundle`] from a [`Transform`].
 | ||||
|     ///
 | ||||
|     /// This initializes [`GlobalTransform`] as identity, to be updated later by the
 | ||||
|     /// [`PostUpdate`] schedule.
 | ||||
|     #[inline] | ||||
|     pub const fn from_transform(transform: Transform) -> Self { | ||||
|         TransformBundle { | ||||
|             local: transform, | ||||
|             ..Self::IDENTITY | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<Transform> for TransformBundle { | ||||
|     #[inline] | ||||
|     fn from(transform: Transform) -> Self { | ||||
|         Self::from_transform(transform) | ||||
|     } | ||||
| } | ||||
| @ -1,11 +1,10 @@ | ||||
| //! Extension to [`EntityCommands`] to modify `bevy_hierarchy` hierarchies
 | ||||
| //! while preserving [`GlobalTransform`].
 | ||||
| 
 | ||||
| use crate::prelude::{GlobalTransform, Transform}; | ||||
| use bevy_ecs::{prelude::Entity, system::EntityCommands, world::Command, world::World}; | ||||
| use bevy_hierarchy::{PushChild, RemoveParent}; | ||||
| 
 | ||||
| use crate::{GlobalTransform, Transform}; | ||||
| 
 | ||||
| /// Command similar to [`PushChild`], but updating the child transform to keep
 | ||||
| /// it at the same [`GlobalTransform`].
 | ||||
| ///
 | ||||
|  | ||||
| @ -88,9 +88,10 @@ mod tests { | ||||
|     use bevy_math::{Quat, Vec3}; | ||||
| 
 | ||||
|     use crate::{ | ||||
|         bundles::TransformBundle, | ||||
|         components::{GlobalTransform, Transform}, | ||||
|         helper::TransformHelper, | ||||
|         TransformBundle, TransformPlugin, | ||||
|         plugins::TransformPlugin, | ||||
|     }; | ||||
| 
 | ||||
|     #[test] | ||||
|  | ||||
| @ -8,166 +8,31 @@ | ||||
| pub mod commands; | ||||
| /// The basic components of the transform crate
 | ||||
| pub mod components; | ||||
| 
 | ||||
| /// Transform related bundles
 | ||||
| pub mod bundles; | ||||
| 
 | ||||
| /// Transform related traits
 | ||||
| pub mod traits; | ||||
| 
 | ||||
| /// Transform related plugins
 | ||||
| pub mod plugins; | ||||
| 
 | ||||
| /// Helpers related to computing global transforms
 | ||||
| pub mod helper; | ||||
| /// Systems responsible for transform propagation
 | ||||
| pub mod systems; | ||||
| 
 | ||||
| #[doc(hidden)] | ||||
| pub mod prelude { | ||||
|     #[doc(hidden)] | ||||
|     pub use crate::components::*; | ||||
| 
 | ||||
|     #[doc(hidden)] | ||||
|     pub use crate::{ | ||||
|         commands::BuildChildrenTransformExt, components::*, helper::TransformHelper, | ||||
|         TransformBundle, TransformPlugin, TransformPoint, | ||||
|         bundles::TransformBundle, commands::BuildChildrenTransformExt, helper::TransformHelper, | ||||
|         plugins::TransformPlugin, plugins::TransformSystem, traits::TransformPoint, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| use bevy_app::prelude::*; | ||||
| use bevy_ecs::prelude::*; | ||||
| use bevy_hierarchy::ValidParentCheckPlugin; | ||||
| use bevy_math::{Affine3A, Mat4, Vec3}; | ||||
| 
 | ||||
| use prelude::{GlobalTransform, Transform}; | ||||
| use systems::{propagate_transforms, sync_simple_transforms}; | ||||
| 
 | ||||
| /// A [`Bundle`] of the [`Transform`] and [`GlobalTransform`]
 | ||||
| /// [`Component`]s, which describe the position of an entity.
 | ||||
| ///
 | ||||
| /// * To place or move an entity, you should set its [`Transform`].
 | ||||
| /// * To get the global transform of an entity, you should get its [`GlobalTransform`].
 | ||||
| /// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`].
 | ||||
| ///   * You may use the [`TransformBundle`] to guarantee this.
 | ||||
| ///
 | ||||
| /// ## [`Transform`] and [`GlobalTransform`]
 | ||||
| ///
 | ||||
| /// [`Transform`] is the position of an entity relative to its parent position, or the reference
 | ||||
| /// frame if it doesn't have a parent.
 | ||||
| ///
 | ||||
| /// [`GlobalTransform`] is the position of an entity relative to the reference frame.
 | ||||
| ///
 | ||||
| /// [`GlobalTransform`] is updated from [`Transform`] by systems in the system set
 | ||||
| /// [`TransformPropagate`](TransformSystem::TransformPropagate).
 | ||||
| ///
 | ||||
| /// This system runs during [`PostUpdate`]. If you
 | ||||
| /// update the [`Transform`] of an entity in this schedule or after, you will notice a 1 frame lag
 | ||||
| /// before the [`GlobalTransform`] is updated.
 | ||||
| #[derive(Bundle, Clone, Copy, Debug, Default)] | ||||
| pub struct TransformBundle { | ||||
|     /// The transform of the entity.
 | ||||
|     pub local: Transform, | ||||
|     /// The global transform of the entity.
 | ||||
|     pub global: GlobalTransform, | ||||
| } | ||||
| 
 | ||||
| impl TransformBundle { | ||||
|     /// An identity [`TransformBundle`] with no translation, rotation, and a scale of 1 on all axes.
 | ||||
|     pub const IDENTITY: Self = TransformBundle { | ||||
|         local: Transform::IDENTITY, | ||||
|         global: GlobalTransform::IDENTITY, | ||||
|     }; | ||||
| 
 | ||||
|     /// Creates a new [`TransformBundle`] from a [`Transform`].
 | ||||
|     ///
 | ||||
|     /// This initializes [`GlobalTransform`] as identity, to be updated later by the
 | ||||
|     /// [`PostUpdate`] schedule.
 | ||||
|     #[inline] | ||||
|     pub const fn from_transform(transform: Transform) -> Self { | ||||
|         TransformBundle { | ||||
|             local: transform, | ||||
|             ..Self::IDENTITY | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<Transform> for TransformBundle { | ||||
|     #[inline] | ||||
|     fn from(transform: Transform) -> Self { | ||||
|         Self::from_transform(transform) | ||||
|     } | ||||
| } | ||||
| /// Set enum for the systems relating to transform propagation
 | ||||
| #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] | ||||
| pub enum TransformSystem { | ||||
|     /// Propagates changes in transform to children's [`GlobalTransform`]
 | ||||
|     TransformPropagate, | ||||
| } | ||||
| 
 | ||||
| /// The base plugin for handling [`Transform`] components
 | ||||
| #[derive(Default)] | ||||
| pub struct TransformPlugin; | ||||
| 
 | ||||
| impl Plugin for TransformPlugin { | ||||
|     fn build(&self, app: &mut App) { | ||||
|         // A set for `propagate_transforms` to mark it as ambiguous with `sync_simple_transforms`.
 | ||||
|         // Used instead of the `SystemTypeSet` as that would not allow multiple instances of the system.
 | ||||
|         #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] | ||||
|         struct PropagateTransformsSet; | ||||
| 
 | ||||
|         app.register_type::<Transform>() | ||||
|             .register_type::<GlobalTransform>() | ||||
|             .add_plugins(ValidParentCheckPlugin::<GlobalTransform>::default()) | ||||
|             .configure_sets( | ||||
|                 PostStartup, | ||||
|                 PropagateTransformsSet.in_set(TransformSystem::TransformPropagate), | ||||
|             ) | ||||
|             // add transform systems to startup so the first update is "correct"
 | ||||
|             .add_systems( | ||||
|                 PostStartup, | ||||
|                 ( | ||||
|                     sync_simple_transforms | ||||
|                         .in_set(TransformSystem::TransformPropagate) | ||||
|                         // FIXME: https://github.com/bevyengine/bevy/issues/4381
 | ||||
|                         // These systems cannot access the same entities,
 | ||||
|                         // due to subtle query filtering that is not yet correctly computed in the ambiguity detector
 | ||||
|                         .ambiguous_with(PropagateTransformsSet), | ||||
|                     propagate_transforms.in_set(PropagateTransformsSet), | ||||
|                 ), | ||||
|             ) | ||||
|             .configure_sets( | ||||
|                 PostUpdate, | ||||
|                 PropagateTransformsSet.in_set(TransformSystem::TransformPropagate), | ||||
|             ) | ||||
|             .add_systems( | ||||
|                 PostUpdate, | ||||
|                 ( | ||||
|                     sync_simple_transforms | ||||
|                         .in_set(TransformSystem::TransformPropagate) | ||||
|                         .ambiguous_with(PropagateTransformsSet), | ||||
|                     propagate_transforms.in_set(PropagateTransformsSet), | ||||
|                 ), | ||||
|             ); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// A trait for point transformation methods.
 | ||||
| pub trait TransformPoint { | ||||
|     /// Transform a point.
 | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3; | ||||
| } | ||||
| 
 | ||||
| impl TransformPoint for Transform { | ||||
|     #[inline] | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3 { | ||||
|         self.transform_point(point.into()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TransformPoint for GlobalTransform { | ||||
|     #[inline] | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3 { | ||||
|         self.transform_point(point.into()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TransformPoint for Mat4 { | ||||
|     #[inline] | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3 { | ||||
|         self.transform_point3(point.into()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TransformPoint for Affine3A { | ||||
|     #[inline] | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3 { | ||||
|         self.transform_point3(point.into()) | ||||
|     } | ||||
| } | ||||
| pub use prelude::{TransformPlugin, TransformPoint, TransformSystem}; | ||||
|  | ||||
							
								
								
									
										62
									
								
								crates/bevy_transform/src/plugins.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								crates/bevy_transform/src/plugins.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | ||||
| use bevy_app::{App, Plugin, PostStartup, PostUpdate}; | ||||
| use bevy_ecs::schedule::{IntoSystemConfigs, IntoSystemSetConfigs, SystemSet}; | ||||
| use bevy_hierarchy::ValidParentCheckPlugin; | ||||
| 
 | ||||
| use crate::{ | ||||
|     prelude::{GlobalTransform, Transform}, | ||||
|     systems::{propagate_transforms, sync_simple_transforms}, | ||||
| }; | ||||
| 
 | ||||
| /// Set enum for the systems relating to transform propagation
 | ||||
| #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] | ||||
| pub enum TransformSystem { | ||||
|     /// Propagates changes in transform to children's [`GlobalTransform`]
 | ||||
|     TransformPropagate, | ||||
| } | ||||
| 
 | ||||
| /// The base plugin for handling [`Transform`] components
 | ||||
| #[derive(Default)] | ||||
| pub struct TransformPlugin; | ||||
| 
 | ||||
| impl Plugin for TransformPlugin { | ||||
|     fn build(&self, app: &mut App) { | ||||
|         // A set for `propagate_transforms` to mark it as ambiguous with `sync_simple_transforms`.
 | ||||
|         // Used instead of the `SystemTypeSet` as that would not allow multiple instances of the system.
 | ||||
|         #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] | ||||
|         struct PropagateTransformsSet; | ||||
| 
 | ||||
|         app.register_type::<Transform>() | ||||
|             .register_type::<GlobalTransform>() | ||||
|             .add_plugins(ValidParentCheckPlugin::<GlobalTransform>::default()) | ||||
|             .configure_sets( | ||||
|                 PostStartup, | ||||
|                 PropagateTransformsSet.in_set(TransformSystem::TransformPropagate), | ||||
|             ) | ||||
|             // add transform systems to startup so the first update is "correct"
 | ||||
|             .add_systems( | ||||
|                 PostStartup, | ||||
|                 ( | ||||
|                     sync_simple_transforms | ||||
|                         .in_set(TransformSystem::TransformPropagate) | ||||
|                         // FIXME: https://github.com/bevyengine/bevy/issues/4381
 | ||||
|                         // These systems cannot access the same entities,
 | ||||
|                         // due to subtle query filtering that is not yet correctly computed in the ambiguity detector
 | ||||
|                         .ambiguous_with(PropagateTransformsSet), | ||||
|                     propagate_transforms.in_set(PropagateTransformsSet), | ||||
|                 ), | ||||
|             ) | ||||
|             .configure_sets( | ||||
|                 PostUpdate, | ||||
|                 PropagateTransformsSet.in_set(TransformSystem::TransformPropagate), | ||||
|             ) | ||||
|             .add_systems( | ||||
|                 PostUpdate, | ||||
|                 ( | ||||
|                     sync_simple_transforms | ||||
|                         .in_set(TransformSystem::TransformPropagate) | ||||
|                         .ambiguous_with(PropagateTransformsSet), | ||||
|                     propagate_transforms.in_set(PropagateTransformsSet), | ||||
|                 ), | ||||
|             ); | ||||
|     } | ||||
| } | ||||
| @ -188,8 +188,8 @@ mod test { | ||||
|     use bevy_math::{vec3, Vec3}; | ||||
|     use bevy_tasks::{ComputeTaskPool, TaskPool}; | ||||
| 
 | ||||
|     use crate::bundles::TransformBundle; | ||||
|     use crate::systems::*; | ||||
|     use crate::TransformBundle; | ||||
|     use bevy_hierarchy::{BuildChildren, BuildWorldChildren}; | ||||
| 
 | ||||
|     #[test] | ||||
|  | ||||
							
								
								
									
										37
									
								
								crates/bevy_transform/src/traits.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								crates/bevy_transform/src/traits.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| use bevy_math::{Affine3A, Mat4, Vec3}; | ||||
| 
 | ||||
| use crate::prelude::{GlobalTransform, Transform}; | ||||
| 
 | ||||
| /// A trait for point transformation methods.
 | ||||
| pub trait TransformPoint { | ||||
|     /// Transform a point.
 | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3; | ||||
| } | ||||
| 
 | ||||
| impl TransformPoint for Transform { | ||||
|     #[inline] | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3 { | ||||
|         self.transform_point(point.into()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TransformPoint for GlobalTransform { | ||||
|     #[inline] | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3 { | ||||
|         self.transform_point(point.into()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TransformPoint for Mat4 { | ||||
|     #[inline] | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3 { | ||||
|         self.transform_point3(point.into()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TransformPoint for Affine3A { | ||||
|     #[inline] | ||||
|     fn transform_point(&self, point: impl Into<Vec3>) -> Vec3 { | ||||
|         self.transform_point3(point.into()) | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Torstein Grindvik
						Torstein Grindvik