Skip to content

Commit

Permalink
storing computed matrix in a cache until obsolete
Browse files Browse the repository at this point in the history
  • Loading branch information
MarekLg committed Sep 28, 2020
1 parent 3664a85 commit 6da85b3
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 23 deletions.
75 changes: 69 additions & 6 deletions crates/bevy_transform/src/components/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use std::fmt;

#[derive(Debug, PartialEq, Clone, Copy, Properties)]
pub struct Transform {
pub translation: Vec3,
pub rotation: Quat,
pub scale: Vec3,
translation: Vec3,
rotation: Quat,
scale: Vec3,
matrix_cache: Option<Mat4>,
}

impl Transform {
Expand All @@ -16,6 +17,7 @@ impl Transform {
translation: Vec3::zero(),
rotation: Quat::identity(),
scale: Vec3::one(),
matrix_cache: Some(Mat4::identity()),
}
}

Expand All @@ -26,33 +28,38 @@ impl Transform {
translation,
rotation,
scale,
matrix_cache: Some(matrix),
}
}

pub fn from_translation(translation: Vec3) -> Self {
Transform {
translation,
matrix_cache: None,
..Default::default()
}
}

pub fn from_rotation(rotation: Quat) -> Self {
Transform {
rotation,
matrix_cache: None,
..Default::default()
}
}

pub fn from_scale(scale: f32) -> Self {
Transform {
scale: Vec3::one() * scale,
matrix_cache: None,
..Default::default()
}
}

pub fn from_non_uniform_scale(scale: Vec3) -> Self {
Transform {
scale,
matrix_cache: None,
..Default::default()
}
}
Expand All @@ -61,27 +68,32 @@ impl Transform {
Transform {
translation,
rotation,
matrix_cache: None,
..Default::default()
}
}

pub fn with_translation(mut self, translation: Vec3) -> Self {
self.translation = translation;
self.matrix_cache = None;
self
}

pub fn with_rotation(mut self, rotation: Quat) -> Self {
self.rotation = rotation;
self.matrix_cache = None;
self
}

pub fn with_scale(mut self, scale: f32) -> Self {
self.scale = Vec3::one() * scale;
self.matrix_cache = None;
self
}

pub fn with_non_uniform_scale(mut self, scale: Vec3) -> Self {
self.scale = scale;
self.matrix_cache = None;
self
}

Expand All @@ -93,11 +105,46 @@ impl Transform {
/// Returns transform with the same translation and scale, but rotation so that transform.forward() points at target
pub fn looking_at(mut self, target: Vec3, up: Vec3) -> Self {
self.look_at(target, up);
self.matrix_cache = None;
self
}

pub fn compute_matrix(&self) -> Mat4 {
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
pub fn translation(&self) -> &Vec3 {
&self.translation
}

pub fn translation_mut(&mut self) -> &mut Vec3 {
self.matrix_cache = None;
&mut self.translation
}

pub fn rotation(&self) -> &Quat {
&self.rotation
}

pub fn rotation_mut(&mut self) -> &mut Quat {
self.matrix_cache = None;
&mut self.rotation
}

pub fn scale(&self) -> &Vec3 {
&self.scale
}

pub fn scale_mut(&mut self) -> &mut Vec3 {
self.matrix_cache = None;
&mut self.scale
}

pub fn matrix(&mut self) -> Mat4 {
if self.matrix_cache.is_none() {
self.matrix_cache = Some(Mat4::from_scale_rotation_translation(
self.scale,
self.rotation,
self.translation,
));
}
self.matrix_cache.unwrap()
}

pub fn forward(&self) -> Vec3 {
Expand All @@ -107,26 +154,31 @@ impl Transform {
/// Translates the transform by the given translation relative to its orientation
pub fn translate(&mut self, translation: Vec3) {
self.translation += self.rotation * translation;
self.matrix_cache = None;
}

/// Rotate the transform by the given rotation
pub fn rotate(&mut self, rotation: Quat) {
self.rotation *= rotation;
self.matrix_cache = None;
}

pub fn apply_scale(&mut self, scale: f32) {
self.scale *= scale;
self.matrix_cache = None;
}

pub fn apply_non_uniform_scale(&mut self, scale: Vec3) {
self.scale *= scale;
self.matrix_cache = None;
}

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));
self.matrix_cache = None;
}
}

Expand All @@ -138,6 +190,17 @@ impl Default for Transform {

impl fmt::Display for Transform {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.compute_matrix())
write!(
f,
"translation: {}\nrotation: {}\nscale: {}\nmatrix {}computed",
self.translation,
self.rotation,
self.scale,
if self.matrix_cache.is_none() {
"not "
} else {
""
}
)
}
}
18 changes: 10 additions & 8 deletions crates/bevy_transform/src/transform_propagate_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ use bevy_ecs::prelude::*;
use bevy_math::Mat4;

pub fn transform_propagate_system(
mut root_query: Query<Without<Parent, (Option<&Children>, &Transform, &mut GlobalTransform)>>,
mut transform_query: Query<(&Transform, &mut GlobalTransform, Option<&Children>)>,
mut root_query: Query<
Without<Parent, (Option<&Children>, &mut Transform, &mut GlobalTransform)>,
>,
mut transform_query: Query<(&mut Transform, &mut GlobalTransform, Option<&Children>)>,
) {
for (children, transform, mut global_transform) in &mut root_query.iter() {
global_transform.value = transform.compute_matrix();
for (children, mut transform, mut global_transform) in &mut root_query.iter() {
global_transform.value = transform.matrix();

if let Some(children) = children {
for child in children.0.iter() {
Expand All @@ -19,17 +21,17 @@ pub fn transform_propagate_system(

fn propagate_recursive(
parent: &Mat4,
transform_query: &mut Query<(&Transform, &mut GlobalTransform, Option<&Children>)>,
transform_query: &mut Query<(&mut Transform, &mut GlobalTransform, Option<&Children>)>,
entity: Entity,
) {
log::trace!("Updating Transform for {:?}", entity);

let global_matrix = {
if let (Ok(transform), Ok(mut global_transform)) = (
transform_query.get::<Transform>(entity),
if let (Ok(mut transform), Ok(mut global_transform)) = (
transform_query.get_mut::<Transform>(entity),
transform_query.get_mut::<GlobalTransform>(entity),
) {
global_transform.value = *parent * transform.compute_matrix();
global_transform.value = *parent * transform.matrix();
global_transform.value
} else {
return;
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/flex/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ pub fn flex_node_system(
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 position = &mut transform.translation;
let position = transform.translation_mut();
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 {
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn update_node_entity(
let global_z = z + parent_global_z;

let mut transform = node_query.get_mut::<Transform>(entity).ok()?;
transform.translation.set_z(z);
transform.translation_mut().set_z(z);

Some(global_z)
}
8 changes: 4 additions & 4 deletions examples/ecs/parallel_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ fn bounce_system(
.par_iter(32)
// Filter out sprites that don't need to be bounced
.filter(|(transform, _)| {
!(left < transform.translation.x()
&& transform.translation.x() < right
&& bottom < transform.translation.y()
&& transform.translation.y() < top)
!(left < transform.translation().x()
&& transform.translation().x() < right
&& bottom < transform.translation().y()
&& transform.translation().y() < top)
})
// For simplicity, just reverse the velocity; don't use realistic bounces
.for_each(&pool, |(_, mut v)| {
Expand Down
6 changes: 3 additions & 3 deletions examples/game/breakout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ fn paddle_movement_system(
direction += 1.0;
}

let translation = &mut transform.translation;
let translation = transform.translation_mut();
// move the paddle horizontally
*translation.x_mut() += time.delta_seconds * direction * paddle.speed;
// bound the paddle within the walls
Expand Down Expand Up @@ -206,9 +206,9 @@ fn ball_collision_system(
// check collision with walls
for (collider_entity, collider, transform, sprite) in &mut collider_query.iter() {
let collision = collide(
ball_transform.translation,
*ball_transform.translation(),
ball_size,
transform.translation,
*transform.translation(),
sprite.size,
);
if let Some(collision) = collision {
Expand Down

0 comments on commit 6da85b3

Please sign in to comment.