diff --git a/.gitignore b/.gitignore index dc30af69dfa81..e690fffaad245 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ Cargo.lock .cargo/config /.idea /.vscode -/benches/target +/benches/target \ No newline at end of file diff --git a/crates/bevy_pbr/src/entity.rs b/crates/bevy_pbr/src/entity.rs index d8afaa1506034..935e7fa0cdc23 100644 --- a/crates/bevy_pbr/src/entity.rs +++ b/crates/bevy_pbr/src/entity.rs @@ -7,7 +7,7 @@ use bevy_render::{ pipeline::{DynamicBinding, PipelineSpecialization, RenderPipeline, RenderPipelines}, render_graph::base::MainPass, }; -use bevy_transform::prelude::{Rotation, Scale, Transform, Translation}; +use bevy_transform::prelude::{GlobalTransform, Transform}; /// A component bundle for "pbr mesh" entities #[derive(Bundle)] @@ -18,9 +18,7 @@ pub struct PbrComponents { pub draw: Draw, pub render_pipelines: RenderPipelines, pub transform: Transform, - pub translation: Translation, - pub rotation: Rotation, - pub scale: Scale, + pub global_transform: GlobalTransform, } impl Default for PbrComponents { @@ -49,9 +47,7 @@ impl Default for PbrComponents { main_pass: Default::default(), draw: Default::default(), transform: Default::default(), - translation: Default::default(), - rotation: Default::default(), - scale: Default::default(), + global_transform: Default::default(), } } } @@ -61,6 +57,5 @@ impl Default for PbrComponents { pub struct LightComponents { pub light: Light, pub transform: Transform, - pub translation: Translation, - pub rotation: Rotation, + pub global_transform: GlobalTransform, } diff --git a/crates/bevy_pbr/src/light.rs b/crates/bevy_pbr/src/light.rs index 47f238df167fc..d291e722e5701 100644 --- a/crates/bevy_pbr/src/light.rs +++ b/crates/bevy_pbr/src/light.rs @@ -1,11 +1,10 @@ use bevy_core::Byteable; -use bevy_math::Mat4; use bevy_property::Properties; use bevy_render::{ camera::{CameraProjection, PerspectiveProjection}, color::Color, }; -use bevy_transform::components::Translation; +use bevy_transform::components::GlobalTransform; use std::ops::Range; /// A point light @@ -37,7 +36,7 @@ pub(crate) struct LightRaw { unsafe impl Byteable for LightRaw {} impl LightRaw { - pub fn from(light: &Light, transform: &Mat4, translation: &Translation) -> LightRaw { + pub fn from(light: &Light, global_transform: &GlobalTransform) -> LightRaw { let perspective = PerspectiveProjection { fov: light.fov, aspect_ratio: 1.0, @@ -45,8 +44,8 @@ impl LightRaw { far: light.depth.end, }; - let proj = perspective.get_projection_matrix() * *transform; - let (x, y, z) = translation.0.into(); + let proj = perspective.get_projection_matrix() * *global_transform.value(); + let (x, y, z) = global_transform.translation().into(); LightRaw { proj: proj.to_cols_array_2d(), pos: [x, y, z, 1.0], diff --git a/crates/bevy_pbr/src/render_graph/lights_node.rs b/crates/bevy_pbr/src/render_graph/lights_node.rs index dbbc48b1ffae4..fb1ac16253aed 100644 --- a/crates/bevy_pbr/src/render_graph/lights_node.rs +++ b/crates/bevy_pbr/src/render_graph/lights_node.rs @@ -80,7 +80,7 @@ pub fn lights_node_system( render_resource_context: Res>, // TODO: this write on RenderResourceBindings will prevent this system from running in parallel with other systems that do the same mut render_resource_bindings: ResMut, - mut query: Query<(&Light, &Transform, &Translation)>, + mut query: Query<(&Light, &GlobalTransform)>, ) { let state = &mut state; let render_resource_context = &**render_resource_context; @@ -132,14 +132,12 @@ pub fn lights_node_system( data[0..light_count_size].copy_from_slice([light_count as u32, 0, 0, 0].as_bytes()); // light array - for ((light, transform, translation), slot) in query + for ((light, global_transform), slot) in query .iter() .iter() .zip(data[light_count_size..current_light_uniform_size].chunks_exact_mut(size)) { - slot.copy_from_slice( - LightRaw::from(&light, &transform.value, &translation).as_bytes(), - ); + slot.copy_from_slice(LightRaw::from(&light, &global_transform).as_bytes()); } }, ); diff --git a/crates/bevy_pbr/src/render_graph/mod.rs b/crates/bevy_pbr/src/render_graph/mod.rs index 89899731d01bb..845ae4b65ad31 100644 --- a/crates/bevy_pbr/src/render_graph/mod.rs +++ b/crates/bevy_pbr/src/render_graph/mod.rs @@ -24,10 +24,13 @@ use bevy_render::{ render_graph::{base, AssetRenderResourcesNode, RenderGraph, RenderResourcesNode}, shader::Shader, }; -use bevy_transform::prelude::Transform; +use bevy_transform::prelude::GlobalTransform; pub(crate) fn add_pbr_graph(graph: &mut RenderGraph, resources: &Resources) { - graph.add_system_node(node::TRANSFORM, RenderResourcesNode::::new(true)); + graph.add_system_node( + node::TRANSFORM, + RenderResourcesNode::::new(true), + ); graph.add_system_node( node::STANDARD_MATERIAL, AssetRenderResourcesNode::::new(true), diff --git a/crates/bevy_render/src/camera/visible_entities.rs b/crates/bevy_render/src/camera/visible_entities.rs index a7c2b3da59fd2..fa29e950a3fc1 100644 --- a/crates/bevy_render/src/camera/visible_entities.rs +++ b/crates/bevy_render/src/camera/visible_entities.rs @@ -3,7 +3,7 @@ use crate::Draw; use bevy_core::FloatOrd; use bevy_ecs::{Entity, Query}; use bevy_property::Properties; -use bevy_transform::prelude::Transform; +use bevy_transform::prelude::GlobalTransform; #[derive(Debug)] pub struct VisibleEntity { @@ -24,13 +24,13 @@ impl VisibleEntities { } pub fn visible_entities_system( - mut camera_query: Query<(&Camera, &Transform, &mut VisibleEntities)>, + mut camera_query: Query<(&Camera, &GlobalTransform, &mut VisibleEntities)>, mut draw_query: Query<(Entity, &Draw)>, - draw_transform_query: Query<(&Draw, &Transform)>, + draw_transform_query: Query<(&Draw, &GlobalTransform)>, ) { - for (camera, camera_transform, mut visible_entities) in &mut camera_query.iter() { + for (camera, camera_global_transform, mut visible_entities) in &mut camera_query.iter() { visible_entities.value.clear(); - let camera_position = camera_transform.value.w_axis().truncate(); + let camera_position = camera_global_transform.translation(); let mut no_transform_order = 0.0; let mut transparent_entities = Vec::new(); @@ -39,18 +39,19 @@ pub fn visible_entities_system( continue; } - let order = if let Ok(transform) = draw_transform_query.get::(entity) { - let position = transform.value.w_axis().truncate(); - // smaller distances are sorted to lower indices by using the distance from the camera - FloatOrd(match camera.depth_calculation { - DepthCalculation::ZDifference => camera_position.z() - position.z(), - DepthCalculation::Distance => (camera_position - position).length(), - }) - } else { - let order = FloatOrd(no_transform_order); - no_transform_order += 0.1; - order - }; + let order = + if let Ok(global_transform) = draw_transform_query.get::(entity) { + let position = global_transform.translation(); + // smaller distances are sorted to lower indices by using the distance from the camera + FloatOrd(match camera.depth_calculation { + DepthCalculation::ZDifference => camera_position.z() - position.z(), + DepthCalculation::Distance => (camera_position - position).length(), + }) + } else { + let order = FloatOrd(no_transform_order); + no_transform_order += 0.1; + order + }; if draw.is_transparent { transparent_entities.push(VisibleEntity { entity, order }) diff --git a/crates/bevy_render/src/entity.rs b/crates/bevy_render/src/entity.rs index 417e6a3709b72..384f66b638d72 100644 --- a/crates/bevy_render/src/entity.rs +++ b/crates/bevy_render/src/entity.rs @@ -7,7 +7,8 @@ use crate::{ use base::MainPass; use bevy_asset::Handle; use bevy_ecs::Bundle; -use bevy_transform::components::{Rotation, Scale, Transform, Translation}; +use bevy_math::Vec3; +use bevy_transform::components::{GlobalTransform, Transform}; /// A component bundle for "mesh" entities #[derive(Bundle, Default)] @@ -17,9 +18,7 @@ pub struct MeshComponents { pub render_pipelines: RenderPipelines, pub main_pass: MainPass, pub transform: Transform, - pub translation: Translation, - pub rotation: Rotation, - pub scale: Scale, + pub global_transform: GlobalTransform, } /// A component bundle for "3d camera" entities @@ -29,9 +28,7 @@ pub struct Camera3dComponents { pub perspective_projection: PerspectiveProjection, pub visible_entities: VisibleEntities, pub transform: Transform, - pub translation: Translation, - pub rotation: Rotation, - pub scale: Scale, + pub global_transform: GlobalTransform, } impl Default for Camera3dComponents { @@ -44,9 +41,7 @@ impl Default for Camera3dComponents { perspective_projection: Default::default(), visible_entities: Default::default(), transform: Default::default(), - translation: Default::default(), - rotation: Default::default(), - scale: Default::default(), + global_transform: Default::default(), } } } @@ -58,9 +53,7 @@ pub struct Camera2dComponents { pub orthographic_projection: OrthographicProjection, pub visible_entities: VisibleEntities, pub transform: Transform, - pub translation: Translation, - pub rotation: Rotation, - pub scale: Scale, + pub global_transform: GlobalTransform, } impl Default for Camera2dComponents { @@ -78,10 +71,8 @@ impl Default for Camera2dComponents { ..Default::default() }, visible_entities: Default::default(), - transform: Default::default(), - translation: Translation::new(0.0, 0.0, far - 0.1), - rotation: Default::default(), - scale: Default::default(), + transform: Transform::from_translation(Vec3::new(0.0, 0.0, far - 0.1)), + global_transform: Default::default(), } } } diff --git a/crates/bevy_render/src/render_graph/nodes/camera_node.rs b/crates/bevy_render/src/render_graph/nodes/camera_node.rs index 247d9abbc7ba8..d057311a0f7e7 100644 --- a/crates/bevy_render/src/render_graph/nodes/camera_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/camera_node.rs @@ -73,18 +73,19 @@ pub fn camera_node_system( // PERF: this write on RenderResourceAssignments will prevent this system from running in parallel // with other systems that do the same mut render_resource_bindings: ResMut, - query: Query<(&Camera, &Transform)>, + query: Query<(&Camera, &GlobalTransform)>, ) { let render_resource_context = &**render_resource_context; - let (camera, transform) = if let Some(camera_entity) = active_cameras.get(&state.camera_name) { - ( - query.get::(camera_entity).unwrap(), - query.get::(camera_entity).unwrap(), - ) - } else { - return; - }; + let (camera, global_transform) = + if let Some(camera_entity) = active_cameras.get(&state.camera_name) { + ( + query.get::(camera_entity).unwrap(), + query.get::(camera_entity).unwrap(), + ) + } else { + return; + }; let staging_buffer = if let Some(staging_buffer) = state.staging_buffer { render_resource_context.map_buffer(staging_buffer); @@ -118,7 +119,7 @@ pub fn camera_node_system( let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>(); let camera_matrix: [f32; 16] = - (camera.projection_matrix * transform.value.inverse()).to_cols_array(); + (camera.projection_matrix * global_transform.value().inverse()).to_cols_array(); render_resource_context.write_mapped_buffer( staging_buffer, diff --git a/crates/bevy_render/src/renderer/render_resource/render_resource.rs b/crates/bevy_render/src/renderer/render_resource/render_resource.rs index 5be16d1b2b1be..3778647ae7acf 100644 --- a/crates/bevy_render/src/renderer/render_resource/render_resource.rs +++ b/crates/bevy_render/src/renderer/render_resource/render_resource.rs @@ -179,14 +179,14 @@ where } } -impl RenderResources for bevy_transform::prelude::Transform { +impl RenderResources for bevy_transform::prelude::GlobalTransform { fn render_resources_len(&self) -> usize { 1 } fn get_render_resource(&self, index: usize) -> Option<&dyn RenderResource> { if index == 0 { - Some(&self.value) + Some(self.value()) } else { None } diff --git a/crates/bevy_sprite/src/entity.rs b/crates/bevy_sprite/src/entity.rs index 126fc68edf080..491d929d51567 100644 --- a/crates/bevy_sprite/src/entity.rs +++ b/crates/bevy_sprite/src/entity.rs @@ -10,7 +10,7 @@ use bevy_render::{ prelude::Draw, render_graph::base::MainPass, }; -use bevy_transform::prelude::{Rotation, Scale, Transform, Translation}; +use bevy_transform::prelude::{GlobalTransform, Transform}; #[derive(Bundle)] pub struct SpriteComponents { @@ -21,9 +21,7 @@ pub struct SpriteComponents { pub draw: Draw, pub render_pipelines: RenderPipelines, pub transform: Transform, - pub translation: Translation, - pub rotation: Rotation, - pub scale: Scale, + pub global_transform: GlobalTransform, } impl Default for SpriteComponents { @@ -56,9 +54,7 @@ impl Default for SpriteComponents { main_pass: MainPass, material: Default::default(), transform: Default::default(), - translation: Default::default(), - rotation: Default::default(), - scale: Default::default(), + global_transform: Default::default(), } } } @@ -77,9 +73,7 @@ pub struct SpriteSheetComponents { pub main_pass: MainPass, pub mesh: Handle, // TODO: maybe abstract this out pub transform: Transform, - pub translation: Translation, - pub rotation: Rotation, - pub scale: Scale, + pub global_transform: GlobalTransform, } impl Default for SpriteSheetComponents { @@ -112,9 +106,7 @@ impl Default for SpriteSheetComponents { sprite: Default::default(), texture_atlas: Default::default(), transform: Default::default(), - translation: Default::default(), - rotation: Default::default(), - scale: Default::default(), + global_transform: Default::default(), } } } diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs new file mode 100644 index 0000000000000..9bddeb3bff430 --- /dev/null +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -0,0 +1,119 @@ +use bevy_math::{Mat3, Mat4, Quat, Vec3}; +use bevy_property::Properties; +use std::fmt; + +#[derive(Debug, PartialEq, Clone, Copy, Properties)] +pub struct GlobalTransform { + value: Mat4, +} + +impl GlobalTransform { + #[inline(always)] + pub fn new(value: Mat4) -> Self { + GlobalTransform { value } + } + + #[inline(always)] + pub fn identity() -> Self { + GlobalTransform { + value: Mat4::identity(), + } + } + + pub fn from_translation(translation: Vec3) -> Self { + GlobalTransform::new(Mat4::from_translation(translation)) + } + + pub fn from_rotation(rotation: Quat) -> Self { + GlobalTransform::new(Mat4::from_quat(rotation)) + } + + // TODO: make sure scale is positive + pub fn from_scale(scale: Vec3) -> Self { + GlobalTransform::new(Mat4::from_scale(scale)) + } + + pub fn with_translation(mut self, translation: Vec3) -> Self { + self.translate(translation); + self + } + + pub fn with_rotation(mut self, rotation: Quat) -> Self { + self.rotate(rotation); + self + } + + pub fn with_scale(mut self, scale: Vec3) -> Self { + self.apply_scale(scale); + self + } + + pub fn value(&self) -> &Mat4 { + &self.value + } + + pub fn value_mut(&mut self) -> &mut Mat4 { + &mut self.value + } + + pub fn translation(&self) -> Vec3 { + Vec3::from(self.value.w_axis().truncate()) + } + + pub fn rotation(&self) -> Quat { + let scale = self.scale(); + + Quat::from_rotation_mat3(&Mat3::from_cols( + Vec3::from(self.value.x_axis().truncate()) / scale.x(), + Vec3::from(self.value.y_axis().truncate()) / scale.y(), + Vec3::from(self.value.z_axis().truncate()) / scale.z(), + )) + } + + pub fn scale(&self) -> Vec3 { + Vec3::new( + self.value.x_axis().truncate().length(), + self.value.y_axis().truncate().length(), + self.value.z_axis().truncate().length(), + ) + } + + pub fn set_translation(&mut self, translation: Vec3) { + *self.value.w_axis_mut() = translation.extend(1.0); + } + + pub fn set_rotation(&mut self, rotation: Quat) { + let rotation = rotation * self.rotation().conjugate(); + rotation.normalize(); + self.value = Mat4::from_quat(rotation) * self.value; + } + + pub fn set_scale(&mut self, scale: Vec3) { + let scale = scale / self.scale(); + self.value = Mat4::from_scale(scale) * self.value; + } + + pub fn translate(&mut self, translation: Vec3) { + *self.value.w_axis_mut() += translation.extend(0.0); + } + + pub fn rotate(&mut self, rotation: Quat) { + self.value = Mat4::from_quat(rotation) * self.value; + } + + pub fn apply_scale(&mut self, scale: Vec3) { + self.value = Mat4::from_scale(scale) * self.value; + } +} + +impl Default for GlobalTransform { + fn default() -> Self { + Self::identity() + } +} + +impl fmt::Display for GlobalTransform { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.value) + } +} diff --git a/crates/bevy_transform/src/components/local_transform.rs b/crates/bevy_transform/src/components/local_transform.rs deleted file mode 100644 index 887e5186dfcc0..0000000000000 --- a/crates/bevy_transform/src/components/local_transform.rs +++ /dev/null @@ -1,41 +0,0 @@ -use bevy_math::Mat4; -use bevy_property::Properties; -use std::{ - fmt, - ops::{Deref, DerefMut}, -}; - -#[derive(Debug, PartialEq, Clone, Copy, Properties)] -pub struct LocalTransform(pub Mat4); - -impl LocalTransform { - pub fn identity() -> Self { - Self(Mat4::identity()) - } -} - -impl Default for LocalTransform { - fn default() -> Self { - Self::identity() - } -} - -impl fmt::Display for LocalTransform { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) - } -} - -impl Deref for LocalTransform { - type Target = Mat4; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for LocalTransform { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} diff --git a/crates/bevy_transform/src/components/mod.rs b/crates/bevy_transform/src/components/mod.rs index 979b255607e01..67720a2b4e08e 100644 --- a/crates/bevy_transform/src/components/mod.rs +++ b/crates/bevy_transform/src/components/mod.rs @@ -1,17 +1,9 @@ mod children; -mod local_transform; -mod non_uniform_scale; +mod global_transform; mod parent; -mod rotation; -mod scale; mod transform; -mod translation; pub use children::Children; -pub use local_transform::*; -pub use non_uniform_scale::*; +pub use global_transform::*; pub use parent::{Parent, PreviousParent}; -pub use rotation::*; -pub use scale::*; pub use transform::*; -pub use translation::*; diff --git a/crates/bevy_transform/src/components/non_uniform_scale.rs b/crates/bevy_transform/src/components/non_uniform_scale.rs deleted file mode 100644 index 76dd7165980f6..0000000000000 --- a/crates/bevy_transform/src/components/non_uniform_scale.rs +++ /dev/null @@ -1,60 +0,0 @@ -use bevy_math::Vec3; -use bevy_property::Properties; -use std::{ - fmt, - ops::{Deref, DerefMut}, -}; - -#[derive(Debug, PartialEq, Clone, Copy, Properties)] -pub struct NonUniformScale(pub Vec3); - -impl NonUniformScale { - pub fn new(x: f32, y: f32, z: f32) -> Self { - Self(Vec3::new(x, y, z)) - } -} - -impl Default for NonUniformScale { - fn default() -> Self { - NonUniformScale(Vec3::new(1.0, 1.0, 1.0)) - } -} - -impl From for NonUniformScale { - fn from(scale: Vec3) -> Self { - Self(scale) - } -} - -impl From<&Vec3> for NonUniformScale { - fn from(scale: &Vec3) -> Self { - Self(*scale) - } -} - -impl From<&mut Vec3> for NonUniformScale { - fn from(scale: &mut Vec3) -> Self { - Self(*scale) - } -} - -impl fmt::Display for NonUniformScale { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let (x, y, z) = self.0.into(); - write!(f, "NonUniformScale({}, {}, {})", x, y, z) - } -} - -impl Deref for NonUniformScale { - type Target = Vec3; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for NonUniformScale { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} diff --git a/crates/bevy_transform/src/components/rotation.rs b/crates/bevy_transform/src/components/rotation.rs deleted file mode 100644 index 758b1bc982881..0000000000000 --- a/crates/bevy_transform/src/components/rotation.rs +++ /dev/null @@ -1,63 +0,0 @@ -use bevy_math::Quat; -use bevy_property::Properties; -use std::ops::{Deref, DerefMut}; - -#[derive(Debug, PartialEq, Clone, Copy, Properties)] -pub struct Rotation(pub Quat); -impl Rotation { - #[inline(always)] - pub fn identity() -> Self { - Self(Quat::identity()) - } - - #[inline(always)] - pub fn from_rotation_yxz(yaw: f32, pitch: f32, roll: f32) -> Self { - Self(Quat::from_rotation_ypr(yaw, pitch, roll)) - } - - #[inline(always)] - pub fn from_rotation_xyz(x: f32, y: f32, z: f32) -> Self { - Self(Quat::from_rotation_ypr(y, x, z)) - } - - #[inline(always)] - pub fn from_rotation_x(x: f32) -> Self { - Self(Quat::from_rotation_x(x)) - } - - #[inline(always)] - pub fn from_rotation_y(y: f32) -> Self { - Self(Quat::from_rotation_y(y)) - } - - #[inline(always)] - pub fn from_rotation_z(z: f32) -> Self { - Self(Quat::from_rotation_z(z)) - } -} - -impl Default for Rotation { - fn default() -> Self { - Self::identity() - } -} - -impl From for Rotation { - fn from(rotation: Quat) -> Self { - Self(rotation) - } -} - -impl Deref for Rotation { - type Target = Quat; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for Rotation { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} diff --git a/crates/bevy_transform/src/components/scale.rs b/crates/bevy_transform/src/components/scale.rs deleted file mode 100644 index f9a118a55ac6e..0000000000000 --- a/crates/bevy_transform/src/components/scale.rs +++ /dev/null @@ -1,48 +0,0 @@ -use bevy_property::Properties; -use std::{ - fmt, - ops::{Deref, DerefMut}, -}; - -#[derive(Debug, PartialEq, Clone, Copy, Properties)] -pub struct Scale(pub f32); - -impl From for Scale { - #[inline(always)] - fn from(scale: f32) -> Self { - Self(scale) - } -} - -impl Scale { - #[inline(always)] - pub fn identity() -> Self { - Scale(1.0) - } -} - -impl Default for Scale { - fn default() -> Self { - Self::identity() - } -} - -impl fmt::Display for Scale { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Scale({})", self.0) - } -} - -impl Deref for Scale { - type Target = f32; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for Scale { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index 8b2904d28f9b5..9a09011ec27e4 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -1,35 +1,108 @@ -use bevy_math::Mat4; +use bevy_math::{Mat3, Mat4, Quat, Vec3}; use bevy_property::Properties; use std::fmt; #[derive(Debug, PartialEq, Clone, Copy, Properties)] pub struct Transform { - pub value: Mat4, - pub sync: bool, // NOTE: this is hopefully a temporary measure to allow setting the transform directly. - // ideally setting the transform automatically propagates back to position / translation / rotation, - // but right now they are always considered the source of truth + value: Mat4, } impl Transform { + #[inline(always)] + pub fn new(value: Mat4) -> Self { + Transform { value } + } + #[inline(always)] pub fn identity() -> Self { Transform { value: Mat4::identity(), - sync: true, } } - #[inline(always)] - pub fn new(value: Mat4) -> Self { - Transform { value, sync: true } + pub fn from_translation(translation: Vec3) -> Self { + Transform::new(Mat4::from_translation(translation)) } - /// This creates a new `LocalToWorld` transform with the `sync` field set to `false`. - /// While `sync` is false, position, rotation, and scale components will not be synced to the transform. - /// This is helpful if you want to manually set the transform to a value (ex: Mat4::face_toward) - #[inline(always)] - pub fn new_sync_disabled(value: Mat4) -> Self { - Transform { value, sync: false } + pub fn from_rotation(rotation: Quat) -> Self { + Transform::new(Mat4::from_quat(rotation)) + } + + // TODO: make sure scale is positive + pub fn from_scale(scale: Vec3) -> Self { + Transform::new(Mat4::from_scale(scale)) + } + + pub fn with_translation(mut self, translation: Vec3) -> Self { + self.translate(translation); + self + } + + pub fn with_rotation(mut self, rotation: Quat) -> Self { + self.rotate(rotation); + self + } + + pub fn with_scale(mut self, scale: Vec3) -> Self { + self.apply_scale(scale); + self + } + + pub fn value(&self) -> &Mat4 { + &self.value + } + + pub fn value_mut(&mut self) -> &mut Mat4 { + &mut self.value + } + + pub fn translation(&self) -> Vec3 { + Vec3::from(self.value.w_axis().truncate()) + } + + pub fn rotation(&self) -> Quat { + let scale = self.scale(); + + Quat::from_rotation_mat3(&Mat3::from_cols( + Vec3::from(self.value.x_axis().truncate()) / scale.x(), + Vec3::from(self.value.y_axis().truncate()) / scale.y(), + Vec3::from(self.value.z_axis().truncate()) / scale.z(), + )) + } + + pub fn scale(&self) -> Vec3 { + Vec3::new( + self.value.x_axis().truncate().length(), + self.value.y_axis().truncate().length(), + self.value.z_axis().truncate().length(), + ) + } + + pub fn set_translation(&mut self, translation: Vec3) { + *self.value.w_axis_mut() = translation.extend(1.0); + } + + pub fn set_rotation(&mut self, rotation: Quat) { + let rotation = rotation * self.rotation().conjugate(); + rotation.normalize(); + self.value = Mat4::from_quat(rotation) * self.value; + } + + pub fn set_scale(&mut self, scale: Vec3) { + let scale = scale / self.scale(); + self.value = Mat4::from_scale(scale) * self.value; + } + + pub fn translate(&mut self, translation: Vec3) { + *self.value.w_axis_mut() += translation.extend(0.0); + } + + pub fn rotate(&mut self, rotation: Quat) { + self.value = Mat4::from_quat(rotation) * self.value; + } + + pub fn apply_scale(&mut self, scale: Vec3) { + self.value = Mat4::from_scale(scale) * self.value; } } diff --git a/crates/bevy_transform/src/components/translation.rs b/crates/bevy_transform/src/components/translation.rs deleted file mode 100644 index 50574c3a016b8..0000000000000 --- a/crates/bevy_transform/src/components/translation.rs +++ /dev/null @@ -1,44 +0,0 @@ -use bevy_math::Vec3; -use bevy_property::Properties; -use std::ops::{Deref, DerefMut}; - -#[derive(Debug, PartialEq, Copy, Clone, Properties)] -pub struct Translation(pub Vec3); - -impl Translation { - #[inline(always)] - pub fn identity() -> Self { - Self(Vec3::default()) - } - - #[inline(always)] - pub fn new(x: f32, y: f32, z: f32) -> Self { - Self(Vec3::new(x, y, z)) - } -} - -impl Default for Translation { - fn default() -> Self { - Self::identity() - } -} - -impl From for Translation { - fn from(translation: Vec3) -> Self { - Self(translation) - } -} - -impl Deref for Translation { - type Target = Vec3; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for Translation { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} diff --git a/crates/bevy_transform/src/hierarchy/child_builder.rs b/crates/bevy_transform/src/hierarchy/child_builder.rs index f9c4cc0ac6643..1c0e64e30dc5b 100644 --- a/crates/bevy_transform/src/hierarchy/child_builder.rs +++ b/crates/bevy_transform/src/hierarchy/child_builder.rs @@ -1,4 +1,4 @@ -use crate::prelude::{Children, LocalTransform, Parent, PreviousParent}; +use crate::prelude::{Children, Parent, PreviousParent}; use bevy_ecs::{Commands, CommandsInternal, Component, DynamicBundle, Entity, WorldWriter}; use smallvec::SmallVec; @@ -14,11 +14,7 @@ impl WorldWriter for InsertChildren { world .insert( *child, - ( - Parent(self.parent), - PreviousParent(Some(self.parent)), - LocalTransform::default(), - ), + (Parent(self.parent), PreviousParent(Some(self.parent))), ) .unwrap(); } @@ -55,11 +51,7 @@ impl WorldWriter for PushChildren { world .insert( *child, - ( - Parent(self.parent), - PreviousParent(Some(self.parent)), - LocalTransform::default(), - ), + (Parent(self.parent), PreviousParent(Some(self.parent))), ) .unwrap(); } @@ -215,7 +207,7 @@ impl<'a> BuildChildren for ChildBuilder<'a> { #[cfg(test)] mod tests { use super::BuildChildren; - use crate::prelude::{Children, LocalTransform, Parent, PreviousParent}; + use crate::prelude::{Children, Parent, PreviousParent}; use bevy_ecs::{Commands, Entity, Resources, World}; use smallvec::{smallvec, SmallVec}; @@ -261,9 +253,6 @@ mod tests { *world.get::(child2).unwrap(), PreviousParent(Some(parent)) ); - - assert!(world.get::(child1).is_ok()); - assert!(world.get::(child2).is_ok()); } #[test] @@ -301,9 +290,6 @@ mod tests { PreviousParent(Some(parent)) ); - assert!(world.get::(child1).is_ok()); - assert!(world.get::(child2).is_ok()); - commands.insert_children(parent, 1, &entities[3..]); commands.apply(&mut world, &mut resources); @@ -322,8 +308,5 @@ mod tests { *world.get::(child4).unwrap(), PreviousParent(Some(parent)) ); - - assert!(world.get::(child3).is_ok()); - assert!(world.get::(child4).is_ok()); } } diff --git a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs index 245742d6d1336..8a7f1637358b5 100644 --- a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs +++ b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs @@ -110,6 +110,7 @@ mod test { use super::*; use crate::{hierarchy::BuildChildren, transform_systems}; use bevy_ecs::{Resources, Schedule, World}; + use bevy_math::Vec3; #[test] fn correct_children() { @@ -127,13 +128,13 @@ mod test { let mut parent = None; let mut children = Vec::new(); commands - .spawn((Translation::new(1.0, 0.0, 0.0), Transform::identity())) + .spawn((Transform::from_translation(Vec3::new(1.0, 0.0, 0.0)),)) .for_current_entity(|entity| parent = Some(entity)) .with_children(|parent| { parent - .spawn((Translation::new(0.0, 2.0, 0.0), Transform::identity())) + .spawn((Transform::from_translation(Vec3::new(0.0, 2.0, 0.0)),)) .for_current_entity(|entity| children.push(entity)) - .spawn((Translation::new(0.0, 0.0, 3.0), Transform::identity())) + .spawn((Transform::from_translation(Vec3::new(0.0, 0.0, 3.0)),)) .for_current_entity(|entity| children.push(entity)); }); let parent = parent.unwrap(); diff --git a/crates/bevy_transform/src/hierarchy/world_child_builder.rs b/crates/bevy_transform/src/hierarchy/world_child_builder.rs index 54230ab712536..c3ebd39d10e2f 100644 --- a/crates/bevy_transform/src/hierarchy/world_child_builder.rs +++ b/crates/bevy_transform/src/hierarchy/world_child_builder.rs @@ -1,4 +1,4 @@ -use crate::prelude::{Children, LocalTransform, Parent, PreviousParent}; +use crate::prelude::{Children, Parent, PreviousParent}; use bevy_ecs::{Component, DynamicBundle, Entity, WorldBuilder}; pub struct WorldChildBuilder<'a, 'b> { @@ -23,11 +23,7 @@ impl<'a, 'b> WorldChildBuilder<'a, 'b> { .expect("There should always be a parent at this point."); self.world_builder .spawn_as_entity(entity, components) - .with_bundle(( - Parent(parent_entity), - PreviousParent(Some(parent_entity)), - LocalTransform::default(), - )); + .with_bundle((Parent(parent_entity), PreviousParent(Some(parent_entity)))); { let world = &mut self.world_builder.world; let mut added = false; diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 66c59e0c5d263..90ddb3ac8bafe 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -1,8 +1,6 @@ pub mod components; pub mod hierarchy; -pub mod local_transform_systems; pub mod transform_propagate_system; -pub mod transform_systems; pub mod prelude { pub use crate::{components::*, hierarchy::*, TransformPlugin}; @@ -11,16 +9,12 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_ecs::prelude::*; use bevy_type_registry::RegisterType; -use prelude::{ - Children, LocalTransform, NonUniformScale, Parent, Rotation, Scale, Transform, Translation, -}; +use prelude::{Children, Parent, Transform}; pub(crate) fn transform_systems() -> Vec> { let mut systems = Vec::with_capacity(5); systems.append(&mut hierarchy::hierarchy_maintenance_systems()); - systems.append(&mut local_transform_systems::local_transform_systems()); - systems.append(&mut transform_systems::transform_systems()); systems.push(transform_propagate_system::transform_propagate_system.system()); systems @@ -33,12 +27,7 @@ impl Plugin for TransformPlugin { fn build(&self, app: &mut AppBuilder) { app.register_component::() .register_component::() - .register_component::() .register_component::() - .register_component::() - .register_component::() - .register_component::() - .register_component::() // add transform systems to startup so the first update is "correct" .add_startup_systems(transform_systems()) .add_systems_to_stage(stage::POST_UPDATE, transform_systems()); diff --git a/crates/bevy_transform/src/local_transform_systems.rs b/crates/bevy_transform/src/local_transform_systems.rs deleted file mode 100644 index 3e9cf0b063f37..0000000000000 --- a/crates/bevy_transform/src/local_transform_systems.rs +++ /dev/null @@ -1,365 +0,0 @@ -use crate::components::*; -use bevy_ecs::prelude::*; -use bevy_math::{Mat4, Quat, Vec3}; - -// TODO: "on changed" for all of these systems -pub fn local_transform_translation_system( - mut query: Query< - Without< - Rotation, - Without)>>, - >, - >, -) { - for (mut local, translation) in &mut query.iter() { - *local = LocalTransform(Mat4::from_translation(translation.0)); - } -} - -pub fn local_transform_rotation_system( - mut query: Query< - Without< - Translation, - Without)>>, - >, - >, -) { - for (mut local, rotation) in &mut query.iter() { - *local = LocalTransform(Mat4::from_quat(rotation.0)); - } -} - -pub fn local_transform_scale_system( - mut query: Query< - Without< - Translation, - Without)>>, - >, - >, -) { - for (mut local, scale) in &mut query.iter() { - *local = LocalTransform(Mat4::from_scale(Vec3::new(scale.0, scale.0, scale.0))); - } -} - -pub fn local_transform_non_uniform_scale_system( - mut query: Query< - Without< - Translation, - Without)>>, - >, - >, -) { - for (mut local, non_uniform_scale) in &mut query.iter() { - *local = LocalTransform(Mat4::from_scale(non_uniform_scale.0)); - } -} - -pub fn local_transform_translation_rotation_system( - mut query: Query< - Without< - Scale, - Without< - NonUniformScale, - ( - &mut LocalTransform, - Or<(Changed, Changed)>, - ), - >, - >, - >, -) { - for (mut local, (translation, rotation)) in &mut query.iter() { - *local = LocalTransform(Mat4::from_rotation_translation(rotation.0, translation.0)); - } -} - -pub fn local_transform_translation_scale_system( - mut query: Query< - Without< - Rotation, - Without< - NonUniformScale, - ( - &mut LocalTransform, - Or<(Changed, Changed)>, - ), - >, - >, - >, -) { - for (mut local, (translation, scale)) in &mut query.iter() { - *local = LocalTransform(Mat4::from_scale_rotation_translation( - Vec3::new(scale.0, scale.0, scale.0), - Quat::default(), - translation.0, - )); - } -} - -pub fn local_transform_translation_non_uniform_scale_system( - mut query: Query< - Without< - Rotation, - Without< - Scale, - ( - &mut LocalTransform, - Or<(Changed, Changed)>, - ), - >, - >, - >, -) { - for (mut local, (translation, non_uniform_scale)) in &mut query.iter() { - *local = LocalTransform(Mat4::from_scale_rotation_translation( - non_uniform_scale.0, - Quat::default(), - translation.0, - )); - } -} - -pub fn local_transform_rotation_scale_system( - mut query: Query< - Without< - Translation, - Without< - NonUniformScale, - (&mut LocalTransform, Or<(Changed, Changed)>), - >, - >, - >, -) { - for (mut local, (rotation, scale)) in &mut query.iter() { - *local = LocalTransform(Mat4::from_scale_rotation_translation( - Vec3::new(scale.0, scale.0, scale.0), - rotation.0, - Vec3::default(), - )); - } -} - -pub fn local_transform_rotation_non_uniform_scale_system( - mut query: Query< - Without< - Translation, - Without< - Scale, - ( - &mut LocalTransform, - Or<(Changed, Changed)>, - ), - >, - >, - >, -) { - for (mut local, (rotation, non_uniform_scale)) in &mut query.iter() { - *local = LocalTransform(Mat4::from_scale_rotation_translation( - non_uniform_scale.0, - rotation.0, - Vec3::default(), - )); - } -} - -pub fn local_transform_translation_rotation_scale_system( - mut query: Query< - Without< - NonUniformScale, - ( - &mut LocalTransform, - Or<(Changed, Changed, Changed)>, - ), - >, - >, -) { - for (mut local, (translation, rotation, scale)) in &mut query.iter() { - *local = LocalTransform(Mat4::from_scale_rotation_translation( - Vec3::new(scale.0, scale.0, scale.0), - rotation.0, - translation.0, - )); - } -} - -pub fn local_transform_translation_rotation_non_uniform_scale_system( - mut query: Query< - Without< - Scale, - ( - &mut LocalTransform, - Or<( - Changed, - Changed, - Changed, - )>, - ), - >, - >, -) { - for (mut local, (translation, rotation, non_uniform_scale)) in &mut query.iter() { - *local = LocalTransform(Mat4::from_scale_rotation_translation( - non_uniform_scale.0, - rotation.0, - translation.0, - )); - } -} - -pub fn local_transform_systems() -> Vec> { - vec![ - local_transform_translation_system.system(), - local_transform_rotation_system.system(), - local_transform_scale_system.system(), - local_transform_non_uniform_scale_system.system(), - local_transform_translation_rotation_system.system(), - local_transform_translation_scale_system.system(), - local_transform_translation_non_uniform_scale_system.system(), - local_transform_rotation_scale_system.system(), - local_transform_rotation_non_uniform_scale_system.system(), - local_transform_translation_rotation_scale_system.system(), - local_transform_translation_rotation_non_uniform_scale_system.system(), - ] -} - -#[cfg(test)] -mod test { - use super::*; - use bevy_ecs::{Resources, Schedule, World}; - use bevy_math::{Mat4, Quat, Vec3}; - - #[test] - fn correct_local_transformation() { - let mut world = World::default(); - let mut resources = Resources::default(); - - let mut schedule = Schedule::default(); - schedule.add_stage("update"); - for system in local_transform_systems() { - schedule.add_system_to_stage("update", system); - } - - let local_transform = LocalTransform::identity(); - let t = Translation::new(1.0, 2.0, 3.0); - let r = Rotation(Quat::from_rotation_ypr(1.0, 2.0, 3.0)); - let s = Scale(2.0); - let nus = NonUniformScale::new(1.0, 2.0, 3.0); - - // Add every combination of transform types. - let translation = world.spawn((local_transform, t)); - let rotation = world.spawn((local_transform, r)); - let scale = world.spawn((local_transform, s)); - let non_uniform_scale = world.spawn((local_transform, nus)); - let translation_and_rotation = world.spawn((local_transform, t, r)); - let translation_and_scale = world.spawn((local_transform, t, s)); - let translation_and_nus = world.spawn((local_transform, t, nus)); - let rotation_scale = world.spawn((local_transform, r, s)); - let rotation_nus = world.spawn((local_transform, r, nus)); - let translation_rotation_scale = world.spawn((local_transform, t, r, s)); - let translation_rotation_nus = world.spawn((local_transform, t, r, nus)); - - // Run the system - schedule.run(&mut world, &mut resources); - - // Verify that each was transformed correctly. - assert_eq!( - world.get::(translation).unwrap().0, - Mat4::from_translation(t.0) - ); - assert_eq!( - world.get::(rotation).unwrap().0, - Mat4::from_quat(r.0) - ); - assert_eq!( - world.get::(scale).unwrap().0, - Mat4::from_scale(Vec3::new(s.0, s.0, s.0)) - ); - assert_eq!( - world.get::(non_uniform_scale).unwrap().0, - Mat4::from_scale(nus.0) - ); - assert_eq!( - world - .get::(translation_and_rotation) - .unwrap() - .0, - Mat4::from_rotation_translation(r.0, t.0) - ); - assert_eq!( - world - .get::(translation_and_scale) - .unwrap() - .0, - Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), Quat::default(), t.0) - ); - assert_eq!( - world.get::(translation_and_nus).unwrap().0, - Mat4::from_scale_rotation_translation(nus.0, Quat::default(), t.0) - ); - assert_eq!( - world.get::(rotation_scale).unwrap().0, - Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, Vec3::default()) - ); - assert_eq!( - world.get::(rotation_nus).unwrap().0, - Mat4::from_scale_rotation_translation(nus.0, r.0, Vec3::default()) - ); - assert_eq!( - world - .get::(translation_rotation_scale) - .unwrap() - .0, - Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, t.0) - ); - assert_eq!( - world - .get::(translation_rotation_nus) - .unwrap() - .0, - Mat4::from_scale_rotation_translation(nus.0, r.0, t.0) - ); - } - - #[test] - fn only_propagates_local_transform_on_change() { - let mut world = World::default(); - let mut resources = Resources::default(); - - let mut schedule = Schedule::default(); - schedule.add_stage("update"); - for system in local_transform_systems() { - schedule.add_system_to_stage("update", system); - } - - let local_transform = LocalTransform::identity(); - let t = Translation::new(1.0, 2.0, 3.0); - let r = Rotation(Quat::from_rotation_ypr(1.0, 2.0, 3.0)); - let s = Scale(2.0); - let nus = NonUniformScale::new(1.0, 2.0, 3.0); - - // Add every combination of transform types. - world.spawn((local_transform, t)); - world.spawn((local_transform, r)); - world.spawn((local_transform, s)); - world.spawn((local_transform, nus)); - world.spawn((local_transform, t, r)); - world.spawn((local_transform, t, s)); - world.spawn((local_transform, t, nus)); - world.spawn((local_transform, r, s)); - world.spawn((local_transform, r, nus)); - world.spawn((local_transform, t, r, s)); - world.spawn((local_transform, t, r, nus)); - - // Run the system, local transforms should mutate since they are new - schedule.run(&mut world, &mut resources); - - // Verify that the local transform is not mutated on the second frame - fn assert_no_local_transforms_changed_system(_: Changed) { - assert!(false) - } - - schedule.add_system_to_stage("update", assert_no_local_transforms_changed_system.system()); - schedule.run(&mut world, &mut resources); - } -} diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index 6068cfcc6f3be..9f6622c095eb8 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -1,61 +1,49 @@ use crate::components::*; use bevy_ecs::prelude::*; +use bevy_math::Mat4; pub fn transform_propagate_system( - mut root_query: Query< - Without, &mut Transform, Option<&LocalTransform>)>, - >, - mut local_transform_query: Query<(&mut Transform, &LocalTransform, Option<&Children>)>, + mut root_query: Query, &Transform, &mut GlobalTransform)>>, + mut transform_query: Query<(&Transform, &mut GlobalTransform, Option<&Children>)>, ) { - for (children, mut transform, local_transform) in &mut root_query.iter() { - if let Some(local_transform) = local_transform { - transform.value = local_transform.0; - } + for (children, transform, mut global_transform) in &mut root_query.iter() { + *global_transform.value_mut() = *transform.value(); if let Some(children) = children { for child in children.0.iter() { - propagate_recursive(*transform, &mut local_transform_query, *child); + propagate_recursive(*global_transform.value(), &mut transform_query, *child); } } } } fn propagate_recursive( - parent_local_to_world: Transform, - local_transform_query: &mut Query<(&mut Transform, &LocalTransform, Option<&Children>)>, + parent: Mat4, + transform_query: &mut Query<(&Transform, &mut GlobalTransform, Option<&Children>)>, entity: Entity, ) { log::trace!("Updating Transform for {:?}", entity); - let local_transform = { - if let Ok(local_transform) = local_transform_query.get::(entity) { - *local_transform + + let global_matrix = { + if let (Ok(transform), Ok(mut global_transform)) = ( + transform_query.get::(entity), + transform_query.get_mut::(entity), + ) { + *global_transform.value_mut() = parent * *transform.value(); + *global_transform.value() } else { - log::warn!( - "Entity {:?} is a child in the hierarchy but does not have a LocalTransform", - entity - ); return; } }; - let new_transform = Transform { - value: parent_local_to_world.value * local_transform.0, - sync: true, - }; - - { - let mut transform = local_transform_query.get_mut::(entity).unwrap(); - transform.value = new_transform.value; - } - // Collect children - let children = local_transform_query + let children = transform_query .get::(entity) .map(|e| e.0.iter().cloned().collect::>()) .unwrap_or_default(); for child in children { - propagate_recursive(new_transform, local_transform_query, child); + propagate_recursive(global_matrix, transform_query, child); } } @@ -78,20 +66,21 @@ mod test { } // Root entity - let parent = world.spawn((Translation::new(1.0, 0.0, 0.0), Transform::identity())); + let parent = world.spawn(( + Transform::from_translation(Vec3::new(1.0, 0.0, 0.0)), + GlobalTransform::identity(), + )); let children = world .spawn_batch(vec![ ( - Translation::new(0.0, 2.0, 0.0), - LocalTransform::identity(), - Transform::identity(), + Transform::from_translation(Vec3::new(0.0, 2.0, 0.)), Parent(parent), + GlobalTransform::identity(), ), ( - Translation::new(0.0, 0.0, 3.0), - LocalTransform::identity(), - Transform::identity(), + Transform::from_translation(Vec3::new(0.0, 0.0, 3.)), Parent(parent), + GlobalTransform::identity(), ), ]) .collect::>(); @@ -103,13 +92,13 @@ mod test { schedule.run(&mut world, &mut resources); assert_eq!( - world.get::(children[0]).unwrap().value, + *world.get::(children[0]).unwrap().value(), Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) * Mat4::from_translation(Vec3::new(0.0, 2.0, 0.0)) ); assert_eq!( - world.get::(children[1]).unwrap().value, + *world.get::(children[1]).unwrap().value(), Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) * Mat4::from_translation(Vec3::new(0.0, 0.0, 3.0)) ); @@ -130,25 +119,34 @@ mod test { let mut commands = Commands::default(); let mut children = Vec::new(); commands - .spawn((Translation::new(1.0, 0.0, 0.0), Transform::identity())) + .spawn(( + Transform::from_translation(Vec3::new(1.0, 0.0, 0.0)), + GlobalTransform::identity(), + )) .with_children(|parent| { parent - .spawn((Translation::new(0.0, 2.0, 0.0), Transform::identity())) + .spawn(( + Transform::from_translation(Vec3::new(0.0, 2.0, 0.0)), + GlobalTransform::identity(), + )) .for_current_entity(|entity| children.push(entity)) - .spawn((Translation::new(0.0, 0.0, 3.0), Transform::identity())) + .spawn(( + Transform::from_translation(Vec3::new(0.0, 0.0, 3.0)), + GlobalTransform::identity(), + )) .for_current_entity(|entity| children.push(entity)); }); commands.apply(&mut world, &mut resources); schedule.run(&mut world, &mut resources); assert_eq!( - world.get::(children[0]).unwrap().value, + *world.get::(children[0]).unwrap().value(), Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) * Mat4::from_translation(Vec3::new(0.0, 2.0, 0.0)) ); assert_eq!( - world.get::(children[1]).unwrap().value, + *world.get::(children[1]).unwrap().value(), Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) * Mat4::from_translation(Vec3::new(0.0, 0.0, 3.0)) ); diff --git a/crates/bevy_transform/src/transform_systems.rs b/crates/bevy_transform/src/transform_systems.rs deleted file mode 100644 index df5e68d1bc42f..0000000000000 --- a/crates/bevy_transform/src/transform_systems.rs +++ /dev/null @@ -1,433 +0,0 @@ -use crate::components::*; -use bevy_ecs::prelude::*; -use bevy_math::{Mat4, Quat, Vec3}; - -// TODO: on changed for all of these systems -pub fn transform_translation_system( - mut query: Query< - Without< - LocalTransform, - Without< - Rotation, - Without)>>, - >, - >, - >, -) { - for (mut transform, translation) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_translation(translation.0)); - } -} - -pub fn transform_rotation_system( - mut query: Query< - Without< - LocalTransform, - Without< - Translation, - Without)>>, - >, - >, - >, -) { - for (mut transform, rotation) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_quat(rotation.0)); - } -} - -pub fn transform_scale_system( - mut query: Query< - Without< - LocalTransform, - Without< - Translation, - Without)>>, - >, - >, - >, -) { - for (mut transform, scale) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_scale(Vec3::new(scale.0, scale.0, scale.0))); - } -} - -pub fn transform_non_uniform_scale_system( - mut query: Query< - Without< - LocalTransform, - Without< - Translation, - Without)>>, - >, - >, - >, -) { - for (mut transform, non_uniform_scale) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_scale(non_uniform_scale.0)); - } -} - -pub fn transform_translation_rotation_system( - mut query: Query< - Without< - LocalTransform, - Without< - Scale, - Without< - NonUniformScale, - ( - &mut Transform, - Or<(Changed, Changed)>, - ), - >, - >, - >, - >, -) { - for (mut transform, (translation, rotation)) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_rotation_translation(rotation.0, translation.0)); - } -} - -pub fn transform_translation_scale_system( - mut query: Query< - Without< - LocalTransform, - Without< - Rotation, - Without< - NonUniformScale, - (&mut Transform, Or<(Changed, Changed)>), - >, - >, - >, - >, -) { - for (mut transform, (translation, scale)) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_scale_rotation_translation( - Vec3::new(scale.0, scale.0, scale.0), - Quat::default(), - translation.0, - )); - } -} - -pub fn transform_translation_non_uniform_scale_system( - mut query: Query< - Without< - LocalTransform, - Without< - Rotation, - Without< - Scale, - ( - &mut Transform, - Or<(Changed, Changed)>, - ), - >, - >, - >, - >, -) { - for (mut transform, (translation, non_uniform_scale)) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_scale_rotation_translation( - non_uniform_scale.0, - Quat::default(), - translation.0, - )); - } -} - -pub fn transform_rotation_scale_system( - mut query: Query< - Without< - LocalTransform, - Without< - Translation, - Without, Changed)>)>, - >, - >, - >, -) { - for (mut transform, (rotation, scale)) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_scale_rotation_translation( - Vec3::new(scale.0, scale.0, scale.0), - rotation.0, - Vec3::default(), - )); - } -} - -pub fn transform_rotation_non_uniform_scale_system( - mut query: Query< - Without< - LocalTransform, - Without< - Translation, - Without< - Scale, - ( - &mut Transform, - Or<(Changed, Changed)>, - ), - >, - >, - >, - >, -) { - for (mut transform, (rotation, non_uniform_scale)) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_scale_rotation_translation( - non_uniform_scale.0, - rotation.0, - Vec3::default(), - )); - } -} - -pub fn transform_translation_rotation_scale_system( - mut query: Query< - Without< - LocalTransform, - Without< - NonUniformScale, - ( - &mut Transform, - Or<(Changed, Changed, Changed)>, - ), - >, - >, - >, -) { - for (mut transform, (translation, rotation, scale)) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_scale_rotation_translation( - Vec3::new(scale.0, scale.0, scale.0), - rotation.0, - translation.0, - )); - } -} - -pub fn transform_translation_rotation_non_uniform_scale_system( - mut query: Query< - Without< - LocalTransform, - Without< - Scale, - ( - &mut Transform, - Or<( - Changed, - Changed, - Changed, - )>, - ), - >, - >, - >, -) { - for (mut transform, (translation, rotation, non_uniform_scale)) in &mut query.iter() { - if !transform.sync { - continue; - } - - *transform = Transform::new(Mat4::from_scale_rotation_translation( - non_uniform_scale.0, - rotation.0, - translation.0, - )); - } -} - -pub fn transform_systems() -> Vec> { - vec![ - transform_translation_system.system(), - transform_rotation_system.system(), - transform_scale_system.system(), - transform_non_uniform_scale_system.system(), - transform_translation_rotation_system.system(), - transform_translation_scale_system.system(), - transform_translation_non_uniform_scale_system.system(), - transform_rotation_scale_system.system(), - transform_rotation_non_uniform_scale_system.system(), - transform_translation_rotation_scale_system.system(), - transform_translation_rotation_non_uniform_scale_system.system(), - ] -} - -#[cfg(test)] -mod test { - use super::*; - use bevy_ecs::{Resources, Schedule, World}; - use bevy_math::{Mat4, Quat, Vec3}; - - #[test] - fn correct_world_transformation() { - let mut world = World::default(); - let mut resources = Resources::default(); - - let mut schedule = Schedule::default(); - schedule.add_stage("update"); - for system in transform_systems() { - schedule.add_system_to_stage("update", system); - } - - let transform = Transform::identity(); - let t = Translation::new(1.0, 2.0, 3.0); - let r = Rotation(Quat::from_rotation_ypr(1.0, 2.0, 3.0)); - let s = Scale(2.0); - let nus = NonUniformScale::new(1.0, 2.0, 3.0); - - // Add every combination of transform types. - let translation = world.spawn((transform, t)); - let rotation = world.spawn((transform, r)); - let scale = world.spawn((transform, s)); - let non_uniform_scale = world.spawn((transform, nus)); - let translation_and_rotation = world.spawn((transform, t, r)); - let translation_and_scale = world.spawn((transform, t, s)); - let translation_and_nus = world.spawn((transform, t, nus)); - let rotation_scale = world.spawn((transform, r, s)); - let rotation_nus = world.spawn((transform, r, nus)); - let translation_rotation_scale = world.spawn((transform, t, r, s)); - let translation_rotation_nus = world.spawn((transform, t, r, nus)); - - // Run the system - schedule.run(&mut world, &mut resources); - - // Verify that each was transformed correctly. - assert_eq!( - world.get::(translation).unwrap().value, - Mat4::from_translation(t.0) - ); - assert_eq!( - world.get::(rotation).unwrap().value, - Mat4::from_quat(r.0) - ); - assert_eq!( - world.get::(scale).unwrap().value, - Mat4::from_scale(Vec3::new(s.0, s.0, s.0)) - ); - assert_eq!( - world.get::(non_uniform_scale).unwrap().value, - Mat4::from_scale(nus.0) - ); - assert_eq!( - world - .get::(translation_and_rotation) - .unwrap() - .value, - Mat4::from_rotation_translation(r.0, t.0) - ); - assert_eq!( - world.get::(translation_and_scale).unwrap().value, - Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), Quat::default(), t.0) - ); - assert_eq!( - world.get::(translation_and_nus).unwrap().value, - Mat4::from_scale_rotation_translation(nus.0, Quat::default(), t.0) - ); - assert_eq!( - world.get::(rotation_scale).unwrap().value, - Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, Vec3::default()) - ); - assert_eq!( - world.get::(rotation_nus).unwrap().value, - Mat4::from_scale_rotation_translation(nus.0, r.0, Vec3::default()) - ); - assert_eq!( - world - .get::(translation_rotation_scale) - .unwrap() - .value, - Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, t.0) - ); - assert_eq!( - world - .get::(translation_rotation_nus) - .unwrap() - .value, - Mat4::from_scale_rotation_translation(nus.0, r.0, t.0) - ); - } - - #[test] - fn only_propagates_transform_on_change() { - let mut world = World::default(); - let mut resources = Resources::default(); - - let mut schedule = Schedule::default(); - schedule.add_stage("update"); - for system in transform_systems() { - schedule.add_system_to_stage("update", system); - } - - let transform = Transform::identity(); - let t = Translation::new(1.0, 2.0, 3.0); - let r = Rotation(Quat::from_rotation_ypr(1.0, 2.0, 3.0)); - let s = Scale(2.0); - let nus = NonUniformScale::new(1.0, 2.0, 3.0); - - // Add every combination of transform types. - world.spawn((transform, t)); - world.spawn((transform, r)); - world.spawn((transform, s)); - world.spawn((transform, nus)); - world.spawn((transform, t, r)); - world.spawn((transform, t, s)); - world.spawn((transform, t, nus)); - world.spawn((transform, r, s)); - world.spawn((transform, r, nus)); - world.spawn((transform, t, r, s)); - world.spawn((transform, t, r, nus)); - - // Run the system, transforms should mutate since they are new - schedule.run(&mut world, &mut resources); - - // Verify that the transform is not mutated on the second frame - fn assert_no_transforms_changed_system(_: Changed) { - assert!(false) - } - - schedule.add_system_to_stage("update", assert_no_transforms_changed_system.system()); - schedule.run(&mut world, &mut resources); - } -} diff --git a/crates/bevy_ui/src/entity.rs b/crates/bevy_ui/src/entity.rs index c92177292391c..a4de6dc9c1547 100644 --- a/crates/bevy_ui/src/entity.rs +++ b/crates/bevy_ui/src/entity.rs @@ -6,6 +6,7 @@ use crate::{ }; use bevy_asset::Handle; use bevy_ecs::Bundle; +use bevy_math::Vec3; use bevy_render::{ camera::{Camera, OrthographicProjection, VisibleEntities, WindowOrigin}, draw::Draw, @@ -13,10 +14,7 @@ use bevy_render::{ pipeline::{DynamicBinding, PipelineSpecialization, RenderPipeline, RenderPipelines}, }; use bevy_sprite::{ColorMaterial, QUAD_HANDLE}; -use bevy_transform::{ - components::LocalTransform, - prelude::{Rotation, Scale, Transform, Translation}, -}; +use bevy_transform::prelude::{GlobalTransform, Transform}; #[derive(Bundle, Clone)] pub struct NodeComponents { @@ -27,7 +25,7 @@ pub struct NodeComponents { pub draw: Draw, pub render_pipelines: RenderPipelines, pub transform: Transform, - pub local_transform: LocalTransform, + pub global_transform: GlobalTransform, } impl Default for NodeComponents { @@ -57,7 +55,7 @@ impl Default for NodeComponents { material: Default::default(), draw: Default::default(), transform: Default::default(), - local_transform: Default::default(), + global_transform: Default::default(), } } } @@ -73,7 +71,7 @@ pub struct ImageComponents { pub draw: Draw, pub render_pipelines: RenderPipelines, pub transform: Transform, - pub local_transform: LocalTransform, + pub global_transform: GlobalTransform, } impl Default for ImageComponents { @@ -105,7 +103,7 @@ impl Default for ImageComponents { material: Default::default(), draw: Default::default(), transform: Default::default(), - local_transform: Default::default(), + global_transform: Default::default(), } } } @@ -119,7 +117,7 @@ pub struct TextComponents { pub calculated_size: CalculatedSize, pub focus_policy: FocusPolicy, pub transform: Transform, - pub local_transform: LocalTransform, + pub global_transform: GlobalTransform, } impl Default for TextComponents { @@ -135,7 +133,7 @@ impl Default for TextComponents { calculated_size: Default::default(), style: Default::default(), transform: Default::default(), - local_transform: Default::default(), + global_transform: Default::default(), } } } @@ -152,7 +150,7 @@ pub struct ButtonComponents { pub draw: Draw, pub render_pipelines: RenderPipelines, pub transform: Transform, - pub local_transform: LocalTransform, + pub global_transform: GlobalTransform, } impl Default for ButtonComponents { @@ -185,7 +183,7 @@ impl Default for ButtonComponents { material: Default::default(), draw: Default::default(), transform: Default::default(), - local_transform: Default::default(), + global_transform: Default::default(), } } } @@ -196,9 +194,7 @@ pub struct UiCameraComponents { pub orthographic_projection: OrthographicProjection, pub visible_entities: VisibleEntities, pub transform: Transform, - pub translation: Translation, - pub rotation: Rotation, - pub scale: Scale, + pub global_transform: GlobalTransform, } impl Default for UiCameraComponents { @@ -216,11 +212,9 @@ impl Default for UiCameraComponents { window_origin: WindowOrigin::BottomLeft, ..Default::default() }, - translation: Translation::new(0.0, 0.0, far - 0.1), visible_entities: Default::default(), - transform: Default::default(), - rotation: Default::default(), - scale: Default::default(), + transform: Transform::from_translation(Vec3::new(0.0, 0.0, far - 0.1)), + global_transform: Default::default(), } } } diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index 17ee8be6ba5d5..87d4a2ba24103 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -3,7 +3,7 @@ mod convert; use crate::{CalculatedSize, Node, Style}; use bevy_ecs::{Changed, Entity, Query, Res, ResMut, With, Without}; use bevy_math::Vec2; -use bevy_transform::prelude::{Children, LocalTransform, Parent}; +use bevy_transform::prelude::{Children, Parent, Transform}; use bevy_utils::HashMap; use bevy_window::{Window, WindowId, Windows}; use stretch::{number::Number, Stretch}; @@ -154,7 +154,7 @@ pub fn flex_node_system( mut node_query: Query, Option<&CalculatedSize>)>>, mut changed_size_query: Query)>>, mut children_query: Query)>>, - mut node_transform_query: Query<(Entity, &mut Node, &mut LocalTransform, Option<&Parent>)>, + mut node_transform_query: Query<(Entity, &mut Node, &mut Transform, Option<&Parent>)>, ) { // update window root nodes for window in windows.iter() { @@ -190,10 +190,10 @@ pub fn flex_node_system( // compute layouts flex_surface.compute_window_layouts(); - for (entity, mut node, mut local, parent) in &mut node_transform_query.iter() { + for (entity, mut node, mut transform, parent) in &mut node_transform_query.iter() { let layout = flex_surface.get_layout(entity).unwrap(); node.size = Vec2::new(layout.size.width, layout.size.height); - let mut position = local.w_axis(); + let mut position = transform.translation(); position.set_x(layout.location.x + layout.size.width / 2.0); position.set_y(layout.location.y + layout.size.height / 2.0); if let Some(parent) = parent { @@ -203,6 +203,6 @@ pub fn flex_node_system( } } - local.set_w_axis(position); + transform.set_translation(position); } } diff --git a/crates/bevy_ui/src/focus.rs b/crates/bevy_ui/src/focus.rs index 9006ef20d5c9b..8ca9a4ddb0191 100644 --- a/crates/bevy_ui/src/focus.rs +++ b/crates/bevy_ui/src/focus.rs @@ -4,7 +4,7 @@ use bevy_core::FloatOrd; use bevy_ecs::prelude::*; use bevy_input::{mouse::MouseButton, Input}; use bevy_math::Vec2; -use bevy_transform::components::Transform; +use bevy_transform::components::GlobalTransform; use bevy_window::CursorMoved; #[derive(Copy, Clone, Eq, PartialEq, Debug)] @@ -46,7 +46,7 @@ pub fn ui_focus_system( mut node_query: Query<( Entity, &Node, - &Transform, + &GlobalTransform, Option<&mut Interaction>, Option<&FocusPolicy>, )>, @@ -56,7 +56,9 @@ pub fn ui_focus_system( } if mouse_button_input.just_released(MouseButton::Left) { - for (_entity, _node, _transform, interaction, _focus_policy) in &mut node_query.iter() { + for (_entity, _node, _global_transform, interaction, _focus_policy) in + &mut node_query.iter() + { if let Some(mut interaction) = interaction { if *interaction == Interaction::Clicked { *interaction = Interaction::None; @@ -72,26 +74,28 @@ pub fn ui_focus_system( let mut query_iter = node_query.iter(); let mut moused_over_z_sorted_nodes = query_iter .iter() - .filter_map(|(entity, node, transform, interaction, focus_policy)| { - let position = transform.value.w_axis(); - let ui_position = position.truncate().truncate(); - let extents = node.size / 2.0; - let min = ui_position - extents; - let max = ui_position + extents; - // if the current cursor position is within the bounds of the node, consider it for clicking - if (min.x()..max.x()).contains(&state.cursor_position.x()) - && (min.y()..max.y()).contains(&state.cursor_position.y()) - { - Some((entity, focus_policy, interaction, FloatOrd(position.z()))) - } else { - if let Some(mut interaction) = interaction { - if *interaction == Interaction::Hovered { - *interaction = Interaction::None; + .filter_map( + |(entity, node, global_transform, interaction, focus_policy)| { + let position = global_transform.translation(); + let ui_position = position.truncate(); + let extents = node.size / 2.0; + let min = ui_position - extents; + let max = ui_position + extents; + // if the current cursor position is within the bounds of the node, consider it for clicking + if (min.x()..max.x()).contains(&state.cursor_position.x()) + && (min.y()..max.y()).contains(&state.cursor_position.y()) + { + Some((entity, focus_policy, interaction, FloatOrd(position.z()))) + } else { + if let Some(mut interaction) = interaction { + if *interaction == Interaction::Hovered { + *interaction = Interaction::None; + } } + None } - None - } - }) + }, + ) .collect::>(); moused_over_z_sorted_nodes.sort_by_key(|(_, _, _, z)| -*z); diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 93e54b6358874..9aa21824bb22d 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -2,14 +2,14 @@ use super::Node; use bevy_ecs::{Entity, Query, With, Without}; use bevy_transform::{ hierarchy, - prelude::{Children, LocalTransform, Parent}, + prelude::{Children, Parent, Transform}, }; pub const UI_Z_STEP: f32 = 0.001; pub fn ui_z_system( mut root_node_query: Query>>, - mut node_query: Query<(Entity, &Node, &mut LocalTransform)>, + mut node_query: Query<(Entity, &Node, &mut Transform)>, children_query: Query<&Children>, ) { let mut current_global_z = 0.0; @@ -34,12 +34,12 @@ pub fn ui_z_system( } fn update_node_entity( - node_query: &mut Query<(Entity, &Node, &mut LocalTransform)>, + node_query: &mut Query<(Entity, &Node, &mut Transform)>, entity: Entity, parent_result: Option, previous_result: Option, ) -> Option { - let mut transform = node_query.get_mut::(entity).ok()?; + let mut transform = node_query.get_mut::(entity).ok()?; let mut z = UI_Z_STEP; let parent_global_z = parent_result.unwrap(); if let Some(previous_global_z) = previous_result { @@ -47,9 +47,9 @@ fn update_node_entity( }; let global_z = z + parent_global_z; - let mut position = transform.w_axis(); + let mut position = transform.translation(); position.set_z(z); - transform.set_w_axis(position); + transform.set_translation(position); Some(global_z) } diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index 5ad87c66224d3..f4dd93972ec09 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -10,7 +10,7 @@ use bevy_render::{ }; use bevy_sprite::TextureAtlas; use bevy_text::{DrawableText, Font, FontAtlasSet, TextStyle}; -use bevy_transform::prelude::Transform; +use bevy_transform::prelude::GlobalTransform; #[derive(Default, Clone)] pub struct Text { @@ -58,11 +58,11 @@ pub fn draw_text_system( texture_atlases: Res>, mut render_resource_bindings: ResMut, mut asset_render_resource_bindings: ResMut, - mut query: Query<(&mut Draw, &Text, &Node, &Transform)>, + mut query: Query<(&mut Draw, &Text, &Node, &GlobalTransform)>, ) { - for (mut draw, text, node, transform) in &mut query.iter() { - let position = - Vec3::from(transform.value.w_axis().truncate()) - (node.size / 2.0).extend(0.0); + for (mut draw, text, node, global_transform) in &mut query.iter() { + let position = Vec3::from(global_transform.value().w_axis().truncate()) + - (node.size / 2.0).extend(0.0); let mut drawable_text = DrawableText { font: fonts.get(&text.font).unwrap(), diff --git a/examples/2d/sprite_sheet.rs b/examples/2d/sprite_sheet.rs index edc559718cbd6..32a8f473d601a 100644 --- a/examples/2d/sprite_sheet.rs +++ b/examples/2d/sprite_sheet.rs @@ -39,7 +39,7 @@ fn setup( .spawn(Camera2dComponents::default()) .spawn(SpriteSheetComponents { texture_atlas: texture_atlas_handle, - scale: Scale(6.0), + transform: Transform::from_scale(Vec3::one() * 6.0), ..Default::default() }) .with(Timer::from_seconds(0.1, true)); diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 7299bd14ea519..377602ce71333 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -61,8 +61,8 @@ fn load_atlas( .spawn(Camera2dComponents::default()) // draw a sprite from the atlas .spawn(SpriteSheetComponents { - scale: Scale(4.0), - translation: Translation(Vec3::new(150.0, 0.0, 0.0)), + transform: Transform::from_translation(Vec3::new(150.0, 0.0, 0.0)) + .with_scale(Vec3::one() * 4.0), sprite: TextureAtlasSprite::new(vendor_index as u32), texture_atlas: atlas_handle, ..Default::default() @@ -70,7 +70,7 @@ fn load_atlas( // draw the atlas itself .spawn(SpriteComponents { material: materials.add(texture_atlas_texture.into()), - translation: Vec3::new(-300.0, 0., 0.0).into(), + transform: Transform::from_translation(Vec3::new(-300.0, 0.0, 0.0)), ..Default::default() }); diff --git a/examples/3d/3d_scene.rs b/examples/3d/3d_scene.rs index 3f219d087d686..ce4348f77f290 100644 --- a/examples/3d/3d_scene.rs +++ b/examples/3d/3d_scene.rs @@ -26,7 +26,7 @@ fn setup( .spawn(PbrComponents { mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), material: materials.add(Color::rgb(0.5, 0.4, 0.3).into()), - translation: Translation::new(0.0, 1.0, 0.0), + transform: Transform::from_translation(Vec3::new(0.0, 1.0, 0.0)), ..Default::default() }) // sphere @@ -36,17 +36,17 @@ fn setup( radius: 0.5, })), material: materials.add(Color::rgb(0.1, 0.4, 0.8).into()), - translation: Translation::new(1.5, 1.5, 1.5), + transform: Transform::from_translation(Vec3::new(1.5, 1.5, 1.5)), ..Default::default() }) // light .spawn(LightComponents { - translation: Translation::new(4.0, 8.0, 4.0), + transform: Transform::from_translation(Vec3::new(4.0, 8.0, 4.0)), ..Default::default() }) // camera .spawn(Camera3dComponents { - transform: Transform::new_sync_disabled(Mat4::face_toward( + transform: Transform::new(Mat4::face_toward( Vec3::new(-3.0, 5.0, 8.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 1.0, 0.0), diff --git a/examples/3d/load_model.rs b/examples/3d/load_model.rs index f83f94a8751ff..f08f23b302f93 100644 --- a/examples/3d/load_model.rs +++ b/examples/3d/load_model.rs @@ -23,7 +23,7 @@ fn setup( .unwrap(), // create a material for the mesh material: materials.add(Color::rgb(0.5, 0.4, 0.3).into()), - translation: Translation::new(-1.5, 0.0, 0.0), + transform: Transform::from_translation(Vec3::new(-1.5, 0.0, 0.0)), ..Default::default() }) // mesh @@ -34,17 +34,17 @@ fn setup( .unwrap(), // create a material for the mesh material: materials.add(Color::rgb(0.5, 0.4, 0.3).into()), - translation: Translation::new(1.5, 0.0, 0.0), + transform: Transform::from_translation(Vec3::new(1.5, 0.0, 0.0)), ..Default::default() }) // light .spawn(LightComponents { - translation: Translation::new(4.0, 5.0, 4.0), + transform: Transform::from_translation(Vec3::new(4.0, 5.0, 4.0)), ..Default::default() }) // camera .spawn(Camera3dComponents { - transform: Transform::new_sync_disabled(Mat4::face_toward( + transform: Transform::new(Mat4::face_toward( Vec3::new(-2.0, 2.0, 6.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 1.0, 0.0), diff --git a/examples/3d/msaa.rs b/examples/3d/msaa.rs index fa70a2deaa7f4..37b21875f14fe 100644 --- a/examples/3d/msaa.rs +++ b/examples/3d/msaa.rs @@ -27,12 +27,12 @@ fn setup( }) // light .spawn(LightComponents { - translation: Translation::new(4.0, 8.0, 4.0), + transform: Transform::from_translation(Vec3::new(4.0, 8.0, 4.0)), ..Default::default() }) // camera .spawn(Camera3dComponents { - transform: Transform::new_sync_disabled(Mat4::face_toward( + transform: Transform::new(Mat4::face_toward( Vec3::new(-3.0, 3.0, 5.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 1.0, 0.0), diff --git a/examples/3d/parenting.rs b/examples/3d/parenting.rs index 16ebd93c5f6b9..832c5c221adae 100644 --- a/examples/3d/parenting.rs +++ b/examples/3d/parenting.rs @@ -15,9 +15,9 @@ fn main() { struct Rotator; /// rotates the parent, which will result in the child also rotating -fn rotator_system(time: Res