camera: add position and rotation components to Perspective camera. add "sync" toggle to LocalToWorld transform.

This commit is contained in:
Carter Anderson 2020-05-31 10:31:18 -07:00
parent 19bf386de9
commit 21a79c56a7
18 changed files with 69 additions and 35 deletions

View file

@ -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(),
);
}
},

View file

@ -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 {
@ -30,6 +32,8 @@ impl Default for PerspectiveCameraEntity {
},
perspective_projection: Default::default(),
local_to_world: Default::default(),
translation: Default::default(),
rotation: Default::default(),
}
}

View file

@ -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 {

View file

@ -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,
}
}
@ -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,
}
}
@ -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,
}
}

View file

@ -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 }
}
}
@ -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)
}
}

View file

@ -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

View file

@ -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,
));
@ -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,
@ -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,
@ -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(),
@ -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(),
@ -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,
@ -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,

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),