Skip to content

Commit

Permalink
camera: add position and rotation components to Perspective camera. a…
Browse files Browse the repository at this point in the history
…dd "sync" toggle to LocalToWorld transform.
  • Loading branch information
cart committed May 31, 2020
1 parent 19bf386 commit 21a79c5
Show file tree
Hide file tree
Showing 18 changed files with 69 additions and 35 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/nodes/lights_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl SystemNode for LightsNode {
query.iter(world).zip(data.chunks_exact_mut(size))
{
slot.copy_from_slice(
LightRaw::from(&light, &local_to_world.0, &translation).as_bytes(),
LightRaw::from(&light, &local_to_world.value, &translation).as_bytes(),
);
}
},
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_render/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pub struct PerspectiveCameraEntity {
pub camera: Camera,
pub perspective_projection: PerspectiveProjection,
pub local_to_world: LocalToWorld,
pub translation: Translation,
pub rotation: Rotation,
}

impl Default for PerspectiveCameraEntity {
Expand All @@ -30,6 +32,8 @@ impl Default for PerspectiveCameraEntity {
},
perspective_projection: Default::default(),
local_to_world: Default::default(),
translation: Default::default(),
rotation: Default::default(),
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/src/render_graph/nodes/camera_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl SystemNode for CameraNode {
.find(|(camera, _)| camera.name.as_ref().map(|n| n.as_str()) == Some(&uniform_name))
{
let camera_matrix: [[f32; 4]; 4] =
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
(camera.view_matrix * local_to_world.value).to_cols_array_2d();

let tmp_buffer = render_resources.create_buffer_mapped(
BufferInfo {
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_render/src/shader/uniforms/local_to_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl AsUniforms for bevy_transform::prelude::LocalToWorld {

fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>> {
match name {
"Object" => Some(self.0.get_bytes()),
"Object" => Some(self.value.get_bytes()),
_ => None,
}
}
Expand All @@ -65,7 +65,7 @@ impl AsUniforms for bevy_transform::prelude::LocalToWorld {
}
fn get_field_bind_type(&self, name: &str) -> Option<FieldBindType> {
match name {
"object" => self.0.get_bind_type(),
"object" => self.value.get_bind_type(),
_ => None,
}
}
Expand All @@ -75,7 +75,7 @@ impl AsUniforms for bevy_transform::prelude::LocalToWorld {

fn get_uniform_bytes_ref(&self, name: &str) -> Option<&[u8]> {
match name {
"Object" => self.0.get_bytes_ref(),
"Object" => self.value.get_bytes_ref(),
_ => None,
}
}
Expand Down
33 changes: 26 additions & 7 deletions crates/bevy_transform/src/components/local_to_world.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
use crate::math::Mat4;
use shrinkwraprs::Shrinkwrap;
use std::fmt;
use bevy_property::Properties;
use std::fmt;

#[derive(Shrinkwrap, Debug, PartialEq, Clone, Copy, Properties)]
#[shrinkwrap(mutable)]
pub struct LocalToWorld(pub Mat4);
#[derive(Debug, PartialEq, Clone, Copy, Properties)]
pub struct LocalToWorld {
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
}

impl LocalToWorld {
#[inline(always)]
pub fn identity() -> Self {
Self(Mat4::identity())
LocalToWorld {
value: Mat4::identity(),
sync: true,
}
}

#[inline(always)]
pub fn new(value: Mat4) -> Self {
LocalToWorld { value, sync: true }
}

/// 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::look_at_rh)
#[inline(always)]
pub fn new_sync_disabled(value: Mat4) -> Self {
LocalToWorld { value, sync: false }
}
}

Expand All @@ -22,6 +41,6 @@ impl Default for LocalToWorld {

impl fmt::Display for LocalToWorld {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
write!(f, "{}", self.value)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn propagate_recursive(
}
};

let new_local_to_world = LocalToWorld(parent_local_to_world.0 * local_to_parent.0);
let new_local_to_world = LocalToWorld { value: parent_local_to_world.value * local_to_parent.0, sync: true };
commands.add_component(entity, new_local_to_world);

// Collect children
Expand Down
33 changes: 22 additions & 11 deletions crates/bevy_transform/src/local_to_world_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,31 +132,36 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
s.spawn(|_| unsafe {
// Translation
a.for_each_unchecked(world, |(mut ltw, translation)| {
*ltw = LocalToWorld(Mat4::from_translation(translation.0));
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_translation(translation.0));
});
});
s.spawn(|_| unsafe {
// Rotation
b.for_each_unchecked(world, |(mut ltw, rotation)| {
*ltw = LocalToWorld(Mat4::from_quat(rotation.0));
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_quat(rotation.0));
});
});
s.spawn(|_| unsafe {
// Scale
c.for_each_unchecked(world, |(mut ltw, scale)| {
*ltw = LocalToWorld(Mat4::from_scale(Vec3::new(scale.0, scale.0, scale.0)));
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_scale(Vec3::new(scale.0, scale.0, scale.0)));
});
});
s.spawn(|_| unsafe {
// NonUniformScale
d.for_each_unchecked(world, |(mut ltw, non_uniform_scale)| {
*ltw = LocalToWorld(Mat4::from_scale(non_uniform_scale.0));
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_scale(non_uniform_scale.0));
});
});
s.spawn(|_| unsafe {
// Translation + Rotation
e.for_each_unchecked(world, |(mut ltw, translation, rotation)| {
*ltw = LocalToWorld(Mat4::from_rotation_translation(
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_rotation_translation(
rotation.0,
translation.0,
));
Expand All @@ -165,7 +170,8 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
s.spawn(|_| unsafe {
// Translation + Scale
f.for_each_unchecked(world, |(mut ltw, translation, scale)| {
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_scale_rotation_translation(
Vec3::new(scale.0, scale.0, scale.0),
Quat::default(),
translation.0,
Expand All @@ -175,7 +181,8 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
s.spawn(|_| unsafe {
// Translation + NonUniformScale
g.for_each_unchecked(world, |(mut ltw, translation, non_uniform_scale)| {
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_scale_rotation_translation(
non_uniform_scale.0,
Quat::default(),
translation.0,
Expand All @@ -185,7 +192,8 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
s.spawn(|_| unsafe {
// Rotation + Scale
h.for_each_unchecked(world, |(mut ltw, rotation, scale)| {
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_scale_rotation_translation(
Vec3::new(scale.0, scale.0, scale.0),
rotation.0,
Vec3::default(),
Expand All @@ -195,7 +203,8 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
s.spawn(|_| unsafe {
// Rotation + NonUniformScale
i.for_each_unchecked(world, |(mut ltw, rotation, non_uniform_scale)| {
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_scale_rotation_translation(
non_uniform_scale.0,
rotation.0,
Vec3::default(),
Expand All @@ -205,7 +214,8 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
s.spawn(|_| unsafe {
// Translation + Rotation + Scale
j.for_each_unchecked(world, |(mut ltw, translation, rotation, scale)| {
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_scale_rotation_translation(
Vec3::new(scale.0, scale.0, scale.0),
rotation.0,
translation.0,
Expand All @@ -217,7 +227,8 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
k.for_each_unchecked(
world,
|(mut ltw, translation, rotation, non_uniform_scale)| {
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
if !ltw.sync { return; }
*ltw = LocalToWorld::new(Mat4::from_scale_rotation_translation(
non_uniform_scale.0,
rotation.0,
translation.0,
Expand Down
2 changes: 1 addition & 1 deletion examples/3d/3d_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(3.0, 8.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
2 changes: 1 addition & 1 deletion examples/3d/load_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(2.0, -6.0, 2.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
2 changes: 1 addition & 1 deletion examples/3d/parenting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(5.0, 10.0, 10.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
2 changes: 1 addition & 1 deletion examples/3d/spawner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(3.0, 8.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
2 changes: 1 addition & 1 deletion examples/3d/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(3.0, -8.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(3.0, 8.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
2 changes: 1 addition & 1 deletion examples/asset/asset_loading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(0.0, -10.0, 3.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
2 changes: 1 addition & 1 deletion examples/asset/hot_asset_reloading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(2.0, -6.0, 2.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
2 changes: 1 addition & 1 deletion examples/input/input_keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(3.0, 8.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
2 changes: 1 addition & 1 deletion examples/shader/shader_custom_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(3.0, 8.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down
2 changes: 1 addition & 1 deletion examples/shader/shader_defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ fn setup(
})
// camera
.add_entity(PerspectiveCameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
local_to_world: LocalToWorld::new_sync_disabled(Mat4::look_at_rh(
Vec3::new(3.0, 8.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
Expand Down

0 comments on commit 21a79c5

Please sign in to comment.