mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
camera: add position and rotation components to Perspective camera. add "sync" toggle to LocalToWorld transform.
This commit is contained in:
parent
19bf386de9
commit
21a79c56a7
18 changed files with 69 additions and 35 deletions
|
@ -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(),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue