Transform and GlobalTransform are now Similarities (#596)

Transform and GlobalTransform are now Similarities.

This resolves precision errors and simplifies the api

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
Marek Legris 2020-10-18 22:03:16 +02:00 committed by GitHub
parent 149c39950a
commit 5acebed731
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 332 additions and 384 deletions

View File

@ -44,8 +44,8 @@ impl LightRaw {
far: light.depth.end, far: light.depth.end,
}; };
let proj = perspective.get_projection_matrix() * *global_transform.value(); let proj = perspective.get_projection_matrix() * global_transform.compute_matrix();
let (x, y, z) = global_transform.translation().into(); let (x, y, z) = global_transform.translation.into();
LightRaw { LightRaw {
proj: proj.to_cols_array_2d(), proj: proj.to_cols_array_2d(),
pos: [x, y, z, 1.0], pos: [x, y, z, 1.0],

View File

@ -30,7 +30,7 @@ pub fn visible_entities_system(
) { ) {
for (camera, camera_global_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(); visible_entities.value.clear();
let camera_position = camera_global_transform.translation(); let camera_position = camera_global_transform.translation;
let mut no_transform_order = 0.0; let mut no_transform_order = 0.0;
let mut transparent_entities = Vec::new(); let mut transparent_entities = Vec::new();
@ -41,7 +41,7 @@ pub fn visible_entities_system(
let order = let order =
if let Ok(global_transform) = draw_transform_query.get::<GlobalTransform>(entity) { if let Ok(global_transform) = draw_transform_query.get::<GlobalTransform>(entity) {
let position = global_transform.translation(); let position = global_transform.translation;
// smaller distances are sorted to lower indices by using the distance from the camera // smaller distances are sorted to lower indices by using the distance from the camera
FloatOrd(match camera.depth_calculation { FloatOrd(match camera.depth_calculation {
DepthCalculation::ZDifference => camera_position.z() - position.z(), DepthCalculation::ZDifference => camera_position.z() - position.z(),

View File

@ -120,7 +120,7 @@ pub fn camera_node_system(
let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>(); let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
let camera_matrix: [f32; 16] = let camera_matrix: [f32; 16] =
(camera.projection_matrix * global_transform.value().inverse()).to_cols_array(); (camera.projection_matrix * global_transform.compute_matrix().inverse()).to_cols_array();
render_resource_context.write_mapped_buffer( render_resource_context.write_mapped_buffer(
staging_buffer, staging_buffer,

View File

@ -5,6 +5,7 @@ use bevy_asset::Handle;
use bevy_core::{Byteable, Bytes}; use bevy_core::{Byteable, Bytes};
pub use bevy_derive::{RenderResource, RenderResources}; pub use bevy_derive::{RenderResource, RenderResources};
use bevy_math::{Mat4, Vec2, Vec3, Vec4}; use bevy_math::{Mat4, Vec2, Vec3, Vec4};
use bevy_transform::components::GlobalTransform;
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
pub enum RenderResourceType { pub enum RenderResourceType {
@ -179,6 +180,25 @@ where
} }
} }
impl RenderResource for GlobalTransform {
fn resource_type(&self) -> Option<RenderResourceType> {
Some(RenderResourceType::Buffer)
}
fn write_buffer_bytes(&self, buffer: &mut [u8]) {
let mat4 = self.compute_matrix();
mat4.write_bytes(buffer);
}
fn buffer_byte_len(&self) -> Option<usize> {
Some(std::mem::size_of::<[f32; 16]>())
}
fn texture(&self) -> Option<Handle<Texture>> {
None
}
}
impl RenderResources for bevy_transform::prelude::GlobalTransform { impl RenderResources for bevy_transform::prelude::GlobalTransform {
fn render_resources_len(&self) -> usize { fn render_resources_len(&self) -> usize {
1 1
@ -186,7 +206,7 @@ impl RenderResources for bevy_transform::prelude::GlobalTransform {
fn get_render_resource(&self, index: usize) -> Option<&dyn RenderResource> { fn get_render_resource(&self, index: usize) -> Option<&dyn RenderResource> {
if index == 0 { if index == 0 {
Some(self.value()) Some(self)
} else { } else {
None None
} }

View File

@ -1,163 +1,121 @@
use bevy_math::{Mat3, Mat4, Quat, Vec3}; use bevy_math::{Mat3, Mat4, Quat, Vec3};
use bevy_property::Properties; use bevy_property::Properties;
use std::fmt; use std::ops::Mul;
use super::Transform;
#[derive(Debug, PartialEq, Clone, Copy, Properties)] #[derive(Debug, PartialEq, Clone, Copy, Properties)]
pub struct GlobalTransform { pub struct GlobalTransform {
value: Mat4, pub translation: Vec3,
pub rotation: Quat,
pub scale: Vec3,
} }
impl GlobalTransform { impl GlobalTransform {
#[inline(always)] #[inline]
pub fn new(value: Mat4) -> Self {
GlobalTransform { value }
}
#[inline(always)]
pub fn identity() -> Self { pub fn identity() -> Self {
GlobalTransform { GlobalTransform {
value: Mat4::identity(), translation: Vec3::zero(),
rotation: Quat::identity(),
scale: Vec3::one(),
} }
} }
#[inline]
pub fn from_matrix(matrix: Mat4) -> Self {
let (scale, rotation, translation) = matrix.to_scale_rotation_translation();
GlobalTransform {
translation,
rotation,
scale,
}
}
#[inline]
pub fn from_translation(translation: Vec3) -> Self { pub fn from_translation(translation: Vec3) -> Self {
GlobalTransform::new(Mat4::from_translation(translation)) GlobalTransform {
translation,
..Default::default()
}
} }
#[inline]
pub fn from_rotation(rotation: Quat) -> Self { pub fn from_rotation(rotation: Quat) -> Self {
GlobalTransform::new(Mat4::from_quat(rotation)) GlobalTransform {
}
pub fn from_scale(scale: f32) -> Self {
GlobalTransform::new(Mat4::from_scale(Vec3::splat(scale)))
}
pub fn from_translation_rotation(translation: Vec3, rotation: Quat) -> Self {
GlobalTransform::new(Mat4::from_scale_rotation_translation(
Vec3::splat(1.0),
rotation, rotation,
translation, ..Default::default()
)) }
} }
pub fn from_translation_rotation_scale(translation: Vec3, rotation: Quat, scale: f32) -> Self { #[inline]
GlobalTransform::new(Mat4::from_scale_rotation_translation( pub fn from_scale(scale: Vec3) -> Self {
Vec3::splat(scale), GlobalTransform {
rotation, scale,
translation, ..Default::default()
)) }
} }
pub fn from_non_uniform_scale(scale: Vec3) -> Self { /// Returns transform with the same translation and scale, but rotation so that transform.forward() points at the origin
GlobalTransform::new(Mat4::from_scale(scale)) #[inline]
pub fn looking_at_origin(self) -> Self {
self.looking_at(Vec3::zero(), Vec3::unit_y())
} }
pub fn with_translation(mut self, translation: Vec3) -> Self { /// Returns transform with the same translation and scale, but rotation so that transform.forward() points at target
self.set_translation(translation); #[inline]
pub fn looking_at(mut self, target: Vec3, up: Vec3) -> Self {
self.look_at(target, up);
self self
} }
pub fn with_rotation(mut self, rotation: Quat) -> Self { #[inline]
self.set_rotation(rotation); pub fn compute_matrix(&self) -> Mat4 {
self Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
} }
pub fn with_scale(mut self, scale: f32) -> Self { #[inline]
self.set_scale(scale); pub fn forward(&self) -> Vec3 {
self self.rotation * Vec3::unit_z()
}
pub fn with_non_uniform_scale(mut self, scale: Vec3) -> Self {
self.set_non_uniform_scale(scale);
self
}
pub fn with_translate(mut self, translation: Vec3) -> Self {
self.translate(translation);
self
}
pub fn with_rotate(mut self, rotation: Quat) -> Self {
self.rotate(rotation);
self
}
pub fn with_apply_scale(mut self, scale: f32) -> Self {
self.apply_scale(scale);
self
}
pub fn with_apply_non_uniform_scale(mut self, scale: Vec3) -> Self {
self.apply_non_uniform_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) {
self.value =
Mat4::from_scale_rotation_translation(self.scale(), rotation, self.translation());
}
pub fn set_scale(&mut self, scale: f32) {
self.value = Mat4::from_scale_rotation_translation(
Vec3::splat(scale),
self.rotation(),
self.translation(),
);
}
pub fn set_non_uniform_scale(&mut self, scale: Vec3) {
self.value =
Mat4::from_scale_rotation_translation(scale, self.rotation(), self.translation());
}
pub fn translate(&mut self, translation: Vec3) {
*self.value.w_axis_mut() += translation.extend(0.0);
} }
#[inline]
/// Rotate the transform by the given rotation
pub fn rotate(&mut self, rotation: Quat) { pub fn rotate(&mut self, rotation: Quat) {
self.value = Mat4::from_quat(rotation) * self.value; self.rotation *= rotation;
} }
pub fn apply_scale(&mut self, scale: f32) { #[inline]
self.value = Mat4::from_scale(Vec3::splat(scale)) * self.value; pub fn mul_transform(&self, transform: Transform) -> GlobalTransform {
let translation = self.mul_vec3(transform.translation);
let rotation = self.rotation * transform.rotation;
let scale = self.scale * transform.scale;
GlobalTransform {
scale,
rotation,
translation,
}
} }
#[inline]
pub fn mul_vec3(&self, mut value: Vec3) -> Vec3 {
value = self.rotation * value;
value = self.scale * value;
value += self.translation;
value
}
#[inline]
pub fn apply_non_uniform_scale(&mut self, scale: Vec3) { pub fn apply_non_uniform_scale(&mut self, scale: Vec3) {
self.value = Mat4::from_scale(scale) * self.value; self.scale *= scale;
}
#[inline]
pub fn look_at(&mut self, target: Vec3, up: Vec3) {
let forward = Vec3::normalize(self.translation - target);
let right = up.cross(forward).normalize();
let up = forward.cross(right);
self.rotation = Quat::from_rotation_mat3(&Mat3::from_cols(right, up, forward));
} }
} }
@ -167,8 +125,39 @@ impl Default for GlobalTransform {
} }
} }
impl fmt::Display for GlobalTransform { impl From<Transform> for GlobalTransform {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn from(transform: Transform) -> Self {
write!(f, "{}", self.value) Self {
translation: transform.translation,
rotation: transform.rotation,
scale: transform.scale,
}
}
}
impl Mul<GlobalTransform> for GlobalTransform {
type Output = GlobalTransform;
#[inline]
fn mul(self, global_transform: GlobalTransform) -> Self::Output {
self.mul_transform(global_transform.into())
}
}
impl Mul<Transform> for GlobalTransform {
type Output = GlobalTransform;
#[inline]
fn mul(self, transform: Transform) -> Self::Output {
self.mul_transform(transform)
}
}
impl Mul<Vec3> for GlobalTransform {
type Output = Vec3;
#[inline]
fn mul(self, value: Vec3) -> Self::Output {
self.mul_vec3(value)
} }
} }

View File

@ -1,167 +1,121 @@
use bevy_math::{Mat3, Mat4, Quat, Vec3, Vec4}; use bevy_math::{Mat3, Mat4, Quat, Vec3};
use bevy_property::Properties; use bevy_property::Properties;
use std::fmt; use std::ops::Mul;
use super::GlobalTransform;
#[derive(Debug, PartialEq, Clone, Copy, Properties)] #[derive(Debug, PartialEq, Clone, Copy, Properties)]
pub struct Transform { pub struct Transform {
value: Mat4, pub translation: Vec3,
pub rotation: Quat,
pub scale: Vec3,
} }
impl Transform { impl Transform {
#[inline(always)] #[inline]
pub fn new(value: Mat4) -> Self {
Transform { value }
}
#[inline(always)]
pub fn identity() -> Self { pub fn identity() -> Self {
Transform { Transform {
value: Mat4::identity(), translation: Vec3::zero(),
rotation: Quat::identity(),
scale: Vec3::one(),
} }
} }
#[inline]
pub fn from_matrix(matrix: Mat4) -> Self {
let (scale, rotation, translation) = matrix.to_scale_rotation_translation();
Transform {
translation,
rotation,
scale,
}
}
#[inline]
pub fn from_translation(translation: Vec3) -> Self { pub fn from_translation(translation: Vec3) -> Self {
Transform::new(Mat4::from_translation(translation)) Transform {
translation,
..Default::default()
}
} }
#[inline]
pub fn from_rotation(rotation: Quat) -> Self { pub fn from_rotation(rotation: Quat) -> Self {
Transform::new(Mat4::from_quat(rotation)) Transform {
}
pub fn from_scale(scale: f32) -> Self {
Transform::new(Mat4::from_scale(Vec3::splat(scale)))
}
pub fn from_translation_rotation(translation: Vec3, rotation: Quat) -> Self {
Transform::new(Mat4::from_scale_rotation_translation(
Vec3::splat(1.0),
rotation, rotation,
translation, ..Default::default()
)) }
} }
pub fn from_translation_rotation_scale(translation: Vec3, rotation: Quat, scale: f32) -> Self { #[inline]
Transform::new(Mat4::from_scale_rotation_translation( pub fn from_scale(scale: Vec3) -> Self {
Vec3::splat(scale), Transform {
rotation, scale,
translation, ..Default::default()
)) }
} }
pub fn from_non_uniform_scale(scale: Vec3) -> Self { /// Returns transform with the same translation and scale, but rotation so that transform.forward() points at the origin
Transform::new(Mat4::from_scale(scale)) #[inline]
pub fn looking_at_origin(self) -> Self {
self.looking_at(Vec3::zero(), Vec3::unit_y())
} }
pub fn with_translation(mut self, translation: Vec3) -> Self { /// Returns transform with the same translation and scale, but rotation so that transform.forward() points at target
self.set_translation(translation); #[inline]
pub fn looking_at(mut self, target: Vec3, up: Vec3) -> Self {
self.look_at(target, up);
self self
} }
pub fn with_rotation(mut self, rotation: Quat) -> Self { #[inline]
self.set_rotation(rotation); pub fn compute_matrix(&self) -> Mat4 {
self Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
} }
pub fn with_scale(mut self, scale: f32) -> Self { #[inline]
self.set_scale(scale); pub fn forward(&self) -> Vec3 {
self self.rotation * Vec3::unit_z()
}
pub fn with_non_uniform_scale(mut self, scale: Vec3) -> Self {
self.set_non_uniform_scale(scale);
self
}
pub fn with_translate(mut self, translation: Vec3) -> Self {
self.translate(translation);
self
}
pub fn with_rotate(mut self, rotation: Quat) -> Self {
self.rotate(rotation);
self
}
pub fn with_apply_scale(mut self, scale: f32) -> Self {
self.apply_scale(scale);
self
}
pub fn with_apply_non_uniform_scale(mut self, scale: Vec3) -> Self {
self.apply_non_uniform_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 translation_mut(&mut self) -> &mut Vec4 {
self.value.w_axis_mut()
}
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) {
self.value =
Mat4::from_scale_rotation_translation(self.scale(), rotation, self.translation());
}
pub fn set_scale(&mut self, scale: f32) {
self.value = Mat4::from_scale_rotation_translation(
Vec3::splat(scale),
self.rotation(),
self.translation(),
);
}
pub fn set_non_uniform_scale(&mut self, scale: Vec3) {
self.value =
Mat4::from_scale_rotation_translation(scale, self.rotation(), self.translation());
}
pub fn translate(&mut self, translation: Vec3) {
*self.value.w_axis_mut() += translation.extend(0.0);
} }
#[inline]
/// Rotate the transform by the given rotation
pub fn rotate(&mut self, rotation: Quat) { pub fn rotate(&mut self, rotation: Quat) {
self.value = Mat4::from_quat(rotation) * self.value; self.rotation *= rotation;
} }
pub fn apply_scale(&mut self, scale: f32) { #[inline]
self.value = Mat4::from_scale(Vec3::splat(scale)) * self.value; pub fn mul_transform(&self, transform: Transform) -> Self {
let translation = self.mul_vec3(transform.translation);
let rotation = self.rotation * transform.rotation;
let scale = self.scale * transform.scale;
Transform {
scale,
rotation,
translation,
}
} }
#[inline]
pub fn mul_vec3(&self, mut value: Vec3) -> Vec3 {
value = self.rotation * value;
value = self.scale * value;
value += self.translation;
value
}
#[inline]
pub fn apply_non_uniform_scale(&mut self, scale: Vec3) { pub fn apply_non_uniform_scale(&mut self, scale: Vec3) {
self.value = Mat4::from_scale(scale) * self.value; self.scale *= scale;
}
#[inline]
pub fn look_at(&mut self, target: Vec3, up: Vec3) {
let forward = Vec3::normalize(self.translation - target);
let right = up.cross(forward).normalize();
let up = forward.cross(right);
self.rotation = Quat::from_rotation_mat3(&Mat3::from_cols(right, up, forward));
} }
} }
@ -171,8 +125,28 @@ impl Default for Transform {
} }
} }
impl fmt::Display for Transform { impl From<GlobalTransform> for Transform {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn from(transform: GlobalTransform) -> Self {
write!(f, "{}", self.value) Self {
translation: transform.translation,
rotation: transform.rotation,
scale: transform.scale,
}
}
}
impl Mul<Transform> for Transform {
type Output = Transform;
fn mul(self, transform: Transform) -> Self::Output {
self.mul_transform(transform)
}
}
impl Mul<Vec3> for Transform {
type Output = Vec3;
fn mul(self, value: Vec3) -> Self::Output {
self.mul_vec3(value)
} }
} }

View File

@ -1,24 +1,23 @@
use crate::components::*; use crate::components::*;
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use bevy_math::Mat4;
pub fn transform_propagate_system( pub fn transform_propagate_system(
mut root_query: Query<Without<Parent, (Option<&Children>, &Transform, &mut GlobalTransform)>>, mut root_query: Query<Without<Parent, (Option<&Children>, &Transform, &mut GlobalTransform)>>,
mut transform_query: Query<(&Transform, &mut GlobalTransform, Option<&Children>)>, mut transform_query: Query<(&Transform, &mut GlobalTransform, Option<&Children>)>,
) { ) {
for (children, transform, mut global_transform) in &mut root_query.iter() { for (children, transform, mut global_transform) in &mut root_query.iter() {
*global_transform.value_mut() = *transform.value(); *global_transform = GlobalTransform::from(*transform);
if let Some(children) = children { if let Some(children) = children {
for child in children.0.iter() { for child in children.0.iter() {
propagate_recursive(*global_transform.value(), &mut transform_query, *child); propagate_recursive(&global_transform, &mut transform_query, *child);
} }
} }
} }
} }
fn propagate_recursive( fn propagate_recursive(
parent: Mat4, parent: &GlobalTransform,
transform_query: &mut Query<(&Transform, &mut GlobalTransform, Option<&Children>)>, transform_query: &mut Query<(&Transform, &mut GlobalTransform, Option<&Children>)>,
entity: Entity, entity: Entity,
) { ) {
@ -29,8 +28,8 @@ fn propagate_recursive(
transform_query.get::<Transform>(entity), transform_query.get::<Transform>(entity),
transform_query.get_mut::<GlobalTransform>(entity), transform_query.get_mut::<GlobalTransform>(entity),
) { ) {
*global_transform.value_mut() = parent * *transform.value(); *global_transform = parent.mul_transform(*transform);
*global_transform.value() *global_transform
} else { } else {
return; return;
} }
@ -43,7 +42,7 @@ fn propagate_recursive(
.unwrap_or_default(); .unwrap_or_default();
for child in children { for child in children {
propagate_recursive(global_matrix, transform_query, child); propagate_recursive(&global_matrix, transform_query, child);
} }
} }
@ -52,7 +51,7 @@ mod test {
use super::*; use super::*;
use crate::{hierarchy::BuildChildren, transform_systems}; use crate::{hierarchy::BuildChildren, transform_systems};
use bevy_ecs::{Resources, Schedule, World}; use bevy_ecs::{Resources, Schedule, World};
use bevy_math::{Mat4, Vec3}; use bevy_math::Vec3;
#[test] #[test]
fn did_propagate() { fn did_propagate() {
@ -92,15 +91,15 @@ mod test {
schedule.run(&mut world, &mut resources); schedule.run(&mut world, &mut resources);
assert_eq!( assert_eq!(
*world.get::<GlobalTransform>(children[0]).unwrap().value(), *world.get::<GlobalTransform>(children[0]).unwrap(),
Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) GlobalTransform::from_translation(Vec3::new(1.0, 0.0, 0.0))
* Mat4::from_translation(Vec3::new(0.0, 2.0, 0.0)) * Transform::from_translation(Vec3::new(0.0, 2.0, 0.0))
); );
assert_eq!( assert_eq!(
*world.get::<GlobalTransform>(children[1]).unwrap().value(), *world.get::<GlobalTransform>(children[1]).unwrap(),
Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) GlobalTransform::from_translation(Vec3::new(1.0, 0.0, 0.0))
* Mat4::from_translation(Vec3::new(0.0, 0.0, 3.0)) * Transform::from_translation(Vec3::new(0.0, 0.0, 3.0))
); );
} }
@ -141,15 +140,15 @@ mod test {
schedule.run(&mut world, &mut resources); schedule.run(&mut world, &mut resources);
assert_eq!( assert_eq!(
*world.get::<GlobalTransform>(children[0]).unwrap().value(), *world.get::<GlobalTransform>(children[0]).unwrap(),
Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) GlobalTransform::from_translation(Vec3::new(1.0, 0.0, 0.0))
* Mat4::from_translation(Vec3::new(0.0, 2.0, 0.0)) * Transform::from_translation(Vec3::new(0.0, 2.0, 0.0))
); );
assert_eq!( assert_eq!(
*world.get::<GlobalTransform>(children[1]).unwrap().value(), *world.get::<GlobalTransform>(children[1]).unwrap(),
Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) GlobalTransform::from_translation(Vec3::new(1.0, 0.0, 0.0))
* Mat4::from_translation(Vec3::new(0.0, 0.0, 3.0)) * Transform::from_translation(Vec3::new(0.0, 0.0, 3.0))
); );
} }
} }

View File

@ -203,7 +203,7 @@ pub fn flex_node_system(
for (entity, mut node, mut transform, 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(); let layout = flex_surface.get_layout(entity).unwrap();
node.size = Vec2::new(layout.size.width, layout.size.height); node.size = Vec2::new(layout.size.width, layout.size.height);
let position = transform.translation_mut(); let position = &mut transform.translation;
position.set_x(layout.location.x + layout.size.width / 2.0); position.set_x(layout.location.x + layout.size.width / 2.0);
position.set_y(layout.location.y + layout.size.height / 2.0); position.set_y(layout.location.y + layout.size.height / 2.0);
if let Some(parent) = parent { if let Some(parent) = parent {

View File

@ -76,7 +76,7 @@ pub fn ui_focus_system(
.iter() .iter()
.filter_map( .filter_map(
|(entity, node, global_transform, interaction, focus_policy)| { |(entity, node, global_transform, interaction, focus_policy)| {
let position = global_transform.translation(); let position = global_transform.translation;
let ui_position = position.truncate(); let ui_position = position.truncate();
let extents = node.size / 2.0; let extents = node.size / 2.0;
let min = ui_position - extents; let min = ui_position - extents;

View File

@ -47,7 +47,7 @@ fn update_node_entity(
let global_z = z + parent_global_z; let global_z = z + parent_global_z;
let mut transform = node_query.get_mut::<Transform>(entity).ok()?; let mut transform = node_query.get_mut::<Transform>(entity).ok()?;
transform.translation_mut().set_z(z); transform.translation.set_z(z);
Some(global_z) Some(global_z)
} }

View File

@ -104,7 +104,7 @@ pub fn draw_text_system(
) { ) {
for (mut draw, text, node, global_transform) in &mut query.iter() { for (mut draw, text, node, global_transform) in &mut query.iter() {
if let Some(font) = fonts.get(&text.font) { if let Some(font) = fonts.get(&text.font) {
let position = global_transform.translation() - (node.size / 2.0).extend(0.0); let position = global_transform.translation - (node.size / 2.0).extend(0.0);
let mut drawable_text = DrawableText { let mut drawable_text = DrawableText {
font, font,
font_atlas_set: font_atlas_sets font_atlas_set: font_atlas_sets

View File

@ -39,7 +39,7 @@ fn setup(
.spawn(Camera2dComponents::default()) .spawn(Camera2dComponents::default())
.spawn(SpriteSheetComponents { .spawn(SpriteSheetComponents {
texture_atlas: texture_atlas_handle, texture_atlas: texture_atlas_handle,
transform: Transform::from_scale(6.0), transform: Transform::from_scale(Vec3::splat(6.0)),
..Default::default() ..Default::default()
}) })
.with(Timer::from_seconds(0.1, true)); .with(Timer::from_seconds(0.1, true));

View File

@ -61,7 +61,11 @@ fn load_atlas(
.spawn(Camera2dComponents::default()) .spawn(Camera2dComponents::default())
// draw a sprite from the atlas // draw a sprite from the atlas
.spawn(SpriteSheetComponents { .spawn(SpriteSheetComponents {
transform: Transform::from_scale(4.0).with_translation(Vec3::new(150.0, 0.0, 0.0)), transform: Transform {
translation: Vec3::new(150.0, 0.0, 0.0),
scale: Vec3::splat(4.0),
..Default::default()
},
sprite: TextureAtlasSprite::new(vendor_index as u32), sprite: TextureAtlasSprite::new(vendor_index as u32),
texture_atlas: atlas_handle, texture_atlas: atlas_handle,
..Default::default() ..Default::default()

View File

@ -36,11 +36,7 @@ fn setup(
}) })
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(-3.0, 5.0, 8.0)).looking_at_origin(),
Vec3::new(-3.0, 5.0, 8.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -44,11 +44,7 @@ fn setup(
}) })
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(-2.0, 2.0, 6.0)).looking_at_origin(),
Vec3::new(-2.0, 2.0, 6.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -32,11 +32,7 @@ fn setup(
}) })
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(-3.0, 3.0, 5.0)).looking_at_origin(),
Vec3::new(-3.0, 3.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -17,7 +17,7 @@ struct Rotator;
/// rotates the parent, which will result in the child also rotating /// rotates the parent, which will result in the child also rotating
fn rotator_system(time: Res<Time>, mut query: Query<(&Rotator, &mut Transform)>) { fn rotator_system(time: Res<Time>, mut query: Query<(&Rotator, &mut Transform)>) {
for (_rotator, mut transform) in &mut query.iter() { for (_rotator, mut transform) in &mut query.iter() {
transform.rotate(Quat::from_rotation_x(3.0 * time.delta_seconds)); transform.rotation *= Quat::from_rotation_x(3.0 * time.delta_seconds);
} }
} }
@ -58,11 +58,7 @@ fn setup(
}) })
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(5.0, 10.0, 10.0)).looking_at_origin(),
Vec3::new(5.0, 10.0, 10.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -25,7 +25,7 @@ fn move_cubes(
) { ) {
for (mut transform, material_handle) in &mut query.iter() { for (mut transform, material_handle) in &mut query.iter() {
let material = materials.get_mut(&material_handle).unwrap(); let material = materials.get_mut(&material_handle).unwrap();
transform.translate(Vec3::new(1.0, 0.0, 0.0) * time.delta_seconds); transform.translation += Vec3::new(1.0, 0.0, 0.0) * time.delta_seconds;
material.albedo = material.albedo =
Color::BLUE * Vec3::splat((3.0 * time.seconds_since_startup as f32).sin()); Color::BLUE * Vec3::splat((3.0 * time.seconds_since_startup as f32).sin());
} }
@ -44,11 +44,7 @@ fn setup(
}) })
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(0.0, 15.0, 150.0)).looking_at_origin(),
Vec3::new(0.0, 15.0, 150.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
)),
..Default::default() ..Default::default()
}); });

View File

@ -59,10 +59,11 @@ fn setup(
.spawn(PbrComponents { .spawn(PbrComponents {
mesh: quad_handle, mesh: quad_handle,
material: material_handle, material: material_handle,
transform: Transform::from_translation_rotation( transform: Transform {
Vec3::new(0.0, 0.0, 1.5), translation: Vec3::new(0.0, 0.0, 1.5),
Quat::from_rotation_x(-std::f32::consts::PI / 5.0), rotation: Quat::from_rotation_x(-std::f32::consts::PI / 5.0),
), ..Default::default()
},
draw: Draw { draw: Draw {
is_transparent: true, is_transparent: true,
..Default::default() ..Default::default()
@ -73,10 +74,11 @@ fn setup(
.spawn(PbrComponents { .spawn(PbrComponents {
mesh: quad_handle, mesh: quad_handle,
material: red_material_handle, material: red_material_handle,
transform: Transform::from_translation_rotation( transform: Transform {
Vec3::new(0.0, 0.0, 0.0), translation: Vec3::new(0.0, 0.0, 0.0),
Quat::from_rotation_x(-std::f32::consts::PI / 5.0), rotation: Quat::from_rotation_x(-std::f32::consts::PI / 5.0),
), ..Default::default()
},
draw: Draw { draw: Draw {
is_transparent: true, is_transparent: true,
..Default::default() ..Default::default()
@ -87,10 +89,11 @@ fn setup(
.spawn(PbrComponents { .spawn(PbrComponents {
mesh: quad_handle, mesh: quad_handle,
material: blue_material_handle, material: blue_material_handle,
transform: Transform::from_translation_rotation( transform: Transform {
Vec3::new(0.0, 0.0, -1.5), translation: Vec3::new(0.0, 0.0, -1.5),
Quat::from_rotation_x(-std::f32::consts::PI / 5.0), rotation: Quat::from_rotation_x(-std::f32::consts::PI / 5.0),
), ..Default::default()
},
draw: Draw { draw: Draw {
is_transparent: true, is_transparent: true,
..Default::default() ..Default::default()
@ -99,11 +102,7 @@ fn setup(
}) })
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(3.0, 5.0, 8.0)).looking_at_origin(),
Vec3::new(3.0, 5.0, 8.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -21,8 +21,7 @@ struct Rotator;
/// rotates the parent, which will result in the child also rotating /// rotates the parent, which will result in the child also rotating
fn rotator_system(time: Res<Time>, mut query: Query<(&Rotator, &mut Transform)>) { fn rotator_system(time: Res<Time>, mut query: Query<(&Rotator, &mut Transform)>) {
for (_rotator, mut transform) in &mut query.iter() { for (_rotator, mut transform) in &mut query.iter() {
let rotation = transform.rotation() * Quat::from_rotation_x(3.0 * time.delta_seconds); transform.rotation *= Quat::from_rotation_x(3.0 * time.delta_seconds);
transform.set_rotation(rotation);
} }
} }
@ -86,11 +85,7 @@ fn setup(
}) })
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(5.0, 10.0, 10.0)).looking_at_origin(),
Vec3::new(5.0, 10.0, 10.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -73,11 +73,7 @@ fn setup(
}) })
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(0.0, 3.0, 10.0)).looking_at_origin(),
Vec3::new(0.0, 3.0, 10.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -47,11 +47,7 @@ fn setup(
}) })
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(2.0, 2.0, 6.0)).looking_at_origin(),
Vec3::new(2.0, 2.0, 6.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -19,7 +19,7 @@ fn setup(
// Spawn a root entity with no parent // Spawn a root entity with no parent
let parent = commands let parent = commands
.spawn(SpriteComponents { .spawn(SpriteComponents {
transform: Transform::from_scale(0.75), transform: Transform::from_scale(Vec3::splat(0.75)),
material: materials.add(ColorMaterial { material: materials.add(ColorMaterial {
color: Color::WHITE, color: Color::WHITE,
texture: Some(texture), texture: Some(texture),
@ -30,7 +30,11 @@ fn setup(
.with_children(|parent| { .with_children(|parent| {
// parent is a ChildBuilder, which has a similar API to Commands // parent is a ChildBuilder, which has a similar API to Commands
parent.spawn(SpriteComponents { parent.spawn(SpriteComponents {
transform: Transform::from_translation(Vec3::new(250.0, 0.0, 0.0)).with_scale(0.75), transform: Transform {
translation: Vec3::new(250.0, 0.0, 0.0),
scale: Vec3::splat(0.75),
..Default::default()
},
material: materials.add(ColorMaterial { material: materials.add(ColorMaterial {
color: Color::BLUE, color: Color::BLUE,
texture: Some(texture), texture: Some(texture),
@ -47,7 +51,11 @@ fn setup(
// Similarly, adding a Parent component will automatically add a Children component to the parent. // Similarly, adding a Parent component will automatically add a Children component to the parent.
commands commands
.spawn(SpriteComponents { .spawn(SpriteComponents {
transform: Transform::from_translation(Vec3::new(-250.0, 0.0, 0.0)).with_scale(0.75), transform: Transform {
translation: Vec3::new(-250.0, 0.0, 0.0),
scale: Vec3::splat(0.75),
..Default::default()
},
material: materials.add(ColorMaterial { material: materials.add(ColorMaterial {
color: Color::RED, color: Color::RED,
texture: Some(texture), texture: Some(texture),
@ -61,7 +69,11 @@ fn setup(
// entity has already been spawned. // entity has already been spawned.
let child = commands let child = commands
.spawn(SpriteComponents { .spawn(SpriteComponents {
transform: Transform::from_translation(Vec3::new(0.0, 250.0, 0.0)).with_scale(0.75), transform: Transform {
translation: Vec3::new(0.0, 250.0, 0.0),
scale: Vec3::splat(0.75),
..Default::default()
},
material: materials.add(ColorMaterial { material: materials.add(ColorMaterial {
color: Color::GREEN, color: Color::GREEN,
texture: Some(texture), texture: Some(texture),

View File

@ -15,7 +15,7 @@ fn spawn_system(
commands commands
.spawn(SpriteComponents { .spawn(SpriteComponents {
material, material,
transform: Transform::from_scale(0.1), transform: Transform::from_scale(Vec3::splat(0.1)),
..Default::default() ..Default::default()
}) })
.with(Velocity( .with(Velocity(
@ -38,7 +38,7 @@ fn move_system(pool: Res<ComputeTaskPool>, mut sprites: Query<(&mut Transform, &
.iter() .iter()
.par_iter(32) .par_iter(32)
.for_each(&pool, |(mut transform, velocity)| { .for_each(&pool, |(mut transform, velocity)| {
transform.translate(velocity.0.extend(0.0)); transform.translation += velocity.0.extend(0.0);
}); });
} }
@ -62,10 +62,10 @@ fn bounce_system(
.par_iter(32) .par_iter(32)
// Filter out sprites that don't need to be bounced // Filter out sprites that don't need to be bounced
.filter(|(transform, _)| { .filter(|(transform, _)| {
!(left < transform.translation().x() !(left < transform.translation.x()
&& transform.translation().x() < right && transform.translation.x() < right
&& bottom < transform.translation().y() && bottom < transform.translation.y()
&& transform.translation().y() < top) && transform.translation.y() < top)
}) })
// For simplicity, just reverse the velocity; don't use realistic bounces // For simplicity, just reverse the velocity; don't use realistic bounces
.for_each(&pool, |(_, mut v)| { .for_each(&pool, |(_, mut v)| {

View File

@ -171,7 +171,7 @@ fn paddle_movement_system(
direction += 1.0; direction += 1.0;
} }
let translation = transform.translation_mut(); let translation = &mut transform.translation;
// move the paddle horizontally // move the paddle horizontally
*translation.x_mut() += time.delta_seconds * direction * paddle.speed; *translation.x_mut() += time.delta_seconds * direction * paddle.speed;
// bound the paddle within the walls // bound the paddle within the walls
@ -184,7 +184,7 @@ fn ball_movement_system(time: Res<Time>, mut ball_query: Query<(&Ball, &mut Tran
let delta_seconds = f32::min(0.2, time.delta_seconds); let delta_seconds = f32::min(0.2, time.delta_seconds);
for (ball, mut transform) in &mut ball_query.iter() { for (ball, mut transform) in &mut ball_query.iter() {
transform.translate(ball.velocity * delta_seconds); transform.translation += ball.velocity * delta_seconds;
} }
} }
@ -207,9 +207,9 @@ fn ball_collision_system(
// check collision with walls // check collision with walls
for (collider_entity, collider, transform, sprite) in &mut collider_query.iter() { for (collider_entity, collider, transform, sprite) in &mut collider_query.iter() {
let collision = collide( let collision = collide(
ball_transform.translation(), ball_transform.translation,
ball_size, ball_size,
transform.translation(), transform.translation,
sprite.size, sprite.size,
); );
if let Some(collision) = collision { if let Some(collision) = collision {

View File

@ -108,11 +108,7 @@ fn setup(
.with(material) .with(material)
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(3.0, 5.0, -8.0)).looking_at_origin(),
Vec3::new(3.0, 5.0, -8.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -155,11 +155,7 @@ fn setup(
.with(blue_material) .with(blue_material)
// camera // camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(3.0, 5.0, -8.0)).looking_at_origin(),
Vec3::new(3.0, 5.0, -8.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }

View File

@ -178,11 +178,7 @@ fn setup(
}) })
// main camera // main camera
.spawn(Camera3dComponents { .spawn(Camera3dComponents {
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(0.0, 0.0, 6.0)).looking_at_origin(),
Vec3::new(0.0, 0.0, 6.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}) })
// second window camera // second window camera
@ -192,11 +188,7 @@ fn setup(
window: window_id, window: window_id,
..Default::default() ..Default::default()
}, },
transform: Transform::new(Mat4::face_toward( transform: Transform::from_translation(Vec3::new(6.0, 0.0, 0.0)).looking_at_origin(),
Vec3::new(6.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
)),
..Default::default() ..Default::default()
}); });
} }