mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
we glam now
This commit is contained in:
parent
7ed5b2252d
commit
03c1ec3405
31 changed files with 261 additions and 224 deletions
|
@ -6,9 +6,9 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
legion = { git = "https://github.com/TomGillen/legion.git", rev = "8628b227bcbe57582fffb5e80e73c634ec4eebd9" }
|
||||
legion_transform = { path = "src/legion_transform" }
|
||||
nalgebra-glm = "0.5.0"
|
||||
legion_transform = { path = "src/transform" }
|
||||
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "44fa1bc2fa208fa92f80944253e0da56cb7ac1fe"}
|
||||
glam = "0.8.3"
|
||||
winit = "0.20.0-alpha4"
|
||||
glsl-to-spirv = "0.1"
|
||||
zerocopy = "0.2"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use bevy::*;
|
||||
use bevy::{render::*, asset::{Asset, AssetStorage, Handle}, math, Schedulable, Parent};
|
||||
use bevy::{render::*, asset::{Asset, AssetStorage, Handle}, math::{Mat4, Quat, Vec3}, Schedulable, Parent};
|
||||
use rand::{rngs::StdRng, Rng, SeedableRng, random};
|
||||
|
||||
fn build_wander_system() -> Box<dyn Schedulable> {
|
||||
|
@ -25,10 +25,10 @@ fn build_wander_system() -> Box<dyn Schedulable> {
|
|||
rng.gen_range(-1.0, 1.0),
|
||||
rng.gen_range(0.0, 0.001),
|
||||
).normalize();
|
||||
let distance = rng.gen_range(wander.distance_bounds.x, wander.distance_bounds.y);
|
||||
navigation_point.target = translation.vector + direction * distance;
|
||||
let distance = rng.gen_range(wander.distance_bounds.x(), wander.distance_bounds.y());
|
||||
navigation_point.target = translation.0 + direction * distance;
|
||||
wander.elapsed = 0.0;
|
||||
wander.duration = rng.gen_range(wander.duration_bounds.x, wander.duration_bounds.y);
|
||||
wander.duration = rng.gen_range(wander.duration_bounds.x(), wander.duration_bounds.y());
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -46,8 +46,8 @@ fn build_navigate_system() -> Box<dyn Schedulable> {
|
|||
_, world,
|
||||
_, person_query| {
|
||||
for (_, translation, mut velocity, navigation_point) in person_query.iter(world) {
|
||||
let distance = navigation_point.target - translation.vector;
|
||||
if math::length(&distance) > 0.01 {
|
||||
let distance = navigation_point.target - translation.0;
|
||||
if distance.length() > 0.01 {
|
||||
let direction = distance.normalize();
|
||||
velocity.value = direction * 2.0;
|
||||
} else {
|
||||
|
@ -66,7 +66,7 @@ fn build_move_system() -> Box<dyn Schedulable> {
|
|||
)>::query())
|
||||
.build(move |_, world, time , person_query| {
|
||||
for (mut translation, velocity) in person_query.iter(world) {
|
||||
translation.vector += velocity.value * time.delta_seconds;
|
||||
translation.0 += velocity.value * time.delta_seconds;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -122,9 +122,8 @@ fn build_light_rotator_system() -> Box<dyn Schedulable> {
|
|||
Write<Rotation>,
|
||||
)>::query())
|
||||
.build(move |_, world, time , light_query| {
|
||||
for (mut light, mut rotation) in light_query.iter(world) {
|
||||
let euler = math::quat_euler_angles(rotation.quaternion());
|
||||
*rotation = Rotation::from_euler_angles(euler.z + time.delta_seconds, euler.y, euler.x);
|
||||
for (_, mut rotation) in light_query.iter(world) {
|
||||
rotation.0 = rotation.0 * Quat::from_rotation_x(3.0 * time.delta_seconds);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -235,15 +234,15 @@ fn main() {
|
|||
// camera
|
||||
(
|
||||
Camera::new(CameraType::Projection {
|
||||
fov: math::quarter_pi(),
|
||||
fov: std::f32::consts::PI / 4.0,
|
||||
near: 1.0,
|
||||
far: 20.0,
|
||||
far: 1000.0,
|
||||
aspect_ratio: 1.0,
|
||||
}),
|
||||
LocalToWorld(math::look_at_rh(
|
||||
&math::vec3(6.0, -40.0, 20.0),
|
||||
&math::vec3(0.0, 0.0, 0.0),
|
||||
&math::vec3(0.0, 0.0, 1.0),)),
|
||||
LocalToWorld(Mat4::look_at_rh(
|
||||
Vec3::new(6.0, -40.0, 20.0),
|
||||
Vec3::new(0.0, 0.0, 0.0),
|
||||
Vec3::new(0.0, 0.0, 1.0),)),
|
||||
// Translation::new(0.0, 0.0, 0.0),
|
||||
)
|
||||
]);
|
||||
|
|
|
@ -58,7 +58,7 @@ impl Application {
|
|||
|
||||
let light_count = <Read<Light>>::query().iter(&mut self.world).count();
|
||||
let forward_uniforms = ForwardUniforms {
|
||||
proj: math::Mat4::identity().into(),
|
||||
proj: math::Mat4::identity().to_cols_array_2d(),
|
||||
num_lights: [light_count as u32, 0, 0, 0],
|
||||
};
|
||||
|
||||
|
@ -110,7 +110,7 @@ impl Application {
|
|||
|
||||
for (mut camera, local_to_world) in <(Write<Camera>, Read<LocalToWorld>)>::query().iter(&mut self.world) {
|
||||
camera.update(self.swap_chain_descriptor.width, self.swap_chain_descriptor.height);
|
||||
let camera_matrix: [[f32; 4]; 4] = (camera.view_matrix * local_to_world.0).into();
|
||||
let camera_matrix: [[f32; 4]; 4] = (camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
||||
let temp_buf =
|
||||
self.device.create_buffer_with_data(camera_matrix.as_bytes(), wgpu::BufferUsage::COPY_SRC);
|
||||
for pass in self.render_passes.iter() {
|
||||
|
@ -152,13 +152,8 @@ impl Application {
|
|||
{
|
||||
slot.copy_from_slice(
|
||||
MaterialUniforms {
|
||||
model: transform.0.into(),
|
||||
color: [
|
||||
material.color.x as f32,
|
||||
material.color.y as f32,
|
||||
material.color.z as f32,
|
||||
material.color.w as f32,
|
||||
],
|
||||
model: transform.0.to_cols_array_2d(),
|
||||
color: material.color.into(),
|
||||
}
|
||||
.as_bytes(),
|
||||
);
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
use crate::math::UnitQuaternion;
|
||||
use shrinkwraprs::Shrinkwrap;
|
||||
|
||||
#[derive(Shrinkwrap, Debug, PartialEq, Clone, Copy)]
|
||||
#[shrinkwrap(mutable)]
|
||||
pub struct Rotation(pub UnitQuaternion<f32>);
|
||||
impl Rotation {
|
||||
#[inline(always)]
|
||||
pub fn identity() -> Self {
|
||||
Self(UnitQuaternion::identity())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_euler_angles(roll: f32, pitch: f32, yaw: f32) -> Self {
|
||||
Self(UnitQuaternion::from_euler_angles(roll, pitch, yaw))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Rotation {
|
||||
fn default() -> Self {
|
||||
Self::identity()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UnitQuaternion<f32>> for Rotation {
|
||||
fn from(rotation: UnitQuaternion<f32>) -> Self {
|
||||
Self(rotation)
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
use crate::math::{Translation3, Vector3};
|
||||
use shrinkwraprs::Shrinkwrap;
|
||||
|
||||
#[derive(Shrinkwrap, Debug, PartialEq, Clone, Copy)]
|
||||
#[shrinkwrap(mutable)]
|
||||
pub struct Translation(pub Translation3<f32>);
|
||||
|
||||
impl Translation {
|
||||
#[inline(always)]
|
||||
pub fn identity() -> Self {
|
||||
Self(Translation3::identity())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn new(x: f32, y: f32, z: f32) -> Self {
|
||||
Self(Translation3::new(x, y, z))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Translation {
|
||||
fn default() -> Self {
|
||||
Self::identity()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vector3<f32>> for Translation {
|
||||
fn from(translation: Vector3<f32>) -> Self {
|
||||
Self(Translation3::from(translation))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Translation3<f32>> for Translation {
|
||||
fn from(translation: Translation3<f32>) -> Self {
|
||||
Self(translation)
|
||||
}
|
||||
}
|
|
@ -14,4 +14,4 @@ pub use legion::prelude::*;
|
|||
pub use legion::schedule::Schedulable;
|
||||
pub use legion_transform::prelude::*;
|
||||
pub use legion_transform::transform_system_bundle;
|
||||
pub use nalgebra_glm as math;
|
||||
pub use glam as math;
|
|
@ -1,4 +1,4 @@
|
|||
use crate::math;
|
||||
use crate::math::Mat4;
|
||||
|
||||
pub enum CameraType {
|
||||
Projection {
|
||||
|
@ -10,14 +10,14 @@ pub enum CameraType {
|
|||
}
|
||||
|
||||
pub struct Camera {
|
||||
pub view_matrix: math::Mat4,
|
||||
pub view_matrix: Mat4,
|
||||
pub camera_type: CameraType,
|
||||
}
|
||||
|
||||
impl Camera {
|
||||
pub fn new(camera_type: CameraType) -> Self {
|
||||
Camera {
|
||||
view_matrix: math::identity(),
|
||||
view_matrix: Mat4::identity(),
|
||||
camera_type,
|
||||
}
|
||||
}
|
||||
|
@ -32,17 +32,17 @@ impl Camera {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_projection_matrix(fov: f32, aspect_ratio: f32, near: f32, far: f32) -> math::Mat4 {
|
||||
let projection = math::perspective(aspect_ratio, fov, near, far);
|
||||
pub fn get_projection_matrix(fov: f32, aspect_ratio: f32, near: f32, far: f32) -> Mat4 {
|
||||
let projection = Mat4::perspective_rh_gl(fov, aspect_ratio, near, far);
|
||||
|
||||
opengl_to_wgpu_matrix() * projection
|
||||
}
|
||||
|
||||
pub fn opengl_to_wgpu_matrix() -> math::Mat4 {
|
||||
math::mat4(
|
||||
pub fn opengl_to_wgpu_matrix() -> Mat4 {
|
||||
Mat4::from_cols_array(&[
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, -1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.5, 0.0,
|
||||
0.0, 0.0, 0.5, 1.0,
|
||||
)
|
||||
])
|
||||
}
|
|
@ -20,10 +20,11 @@ pub struct LightRaw {
|
|||
|
||||
impl LightRaw {
|
||||
pub fn from(light: &Light, transform: &math::Mat4, translation: &Translation) -> LightRaw {
|
||||
let proj = camera::get_projection_matrix(light.fov, 1.0, light.depth.start, light.depth.end) * transform;
|
||||
let proj = camera::get_projection_matrix(light.fov, 1.0, light.depth.start, light.depth.end) * *transform;
|
||||
let (x, y, z) = translation.0.into();
|
||||
LightRaw {
|
||||
proj: proj.into(),
|
||||
pos: [translation.vector.x, translation.vector.y, translation.vector.z, 1.0],
|
||||
proj: proj.to_cols_array_2d(),
|
||||
pos: [x, y, z, 1.0],
|
||||
color: [
|
||||
light.color.r as f32,
|
||||
light.color.g as f32,
|
||||
|
|
|
@ -9,8 +9,8 @@ license = "MIT"
|
|||
[dependencies]
|
||||
legion = { git = "https://github.com/TomGillen/legion.git", rev = "8628b227bcbe57582fffb5e80e73c634ec4eebd9" }
|
||||
#legion = { path = "../legion" }
|
||||
glam = "0.8.3"
|
||||
log = "0.4"
|
||||
nalgebra = { version = "0.19.0" }
|
||||
rayon = "1.2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
smallvec = "0.6"
|
|
@ -1,14 +1,14 @@
|
|||
use crate::math::Matrix4;
|
||||
use crate::math::Mat4;
|
||||
use shrinkwraprs::Shrinkwrap;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Shrinkwrap, Debug, PartialEq, Clone, Copy)]
|
||||
#[shrinkwrap(mutable)]
|
||||
pub struct LocalToParent(pub Matrix4<f32>);
|
||||
pub struct LocalToParent(pub Mat4);
|
||||
|
||||
impl LocalToParent {
|
||||
pub fn identity() -> Self {
|
||||
Self(Matrix4::identity())
|
||||
Self(Mat4::identity())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
use crate::math::Matrix4;
|
||||
use crate::math::Mat4;
|
||||
use shrinkwraprs::Shrinkwrap;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Shrinkwrap, Debug, PartialEq, Clone, Copy)]
|
||||
#[shrinkwrap(mutable)]
|
||||
pub struct LocalToWorld(pub Matrix4<f32>);
|
||||
pub struct LocalToWorld(pub Mat4);
|
||||
|
||||
impl LocalToWorld {
|
||||
#[inline(always)]
|
||||
pub fn identity() -> Self {
|
||||
Self(Matrix4::identity())
|
||||
Self(Mat4::identity())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +1,42 @@
|
|||
use crate::math::Vector3;
|
||||
use crate::math::Vec3;
|
||||
use shrinkwraprs::Shrinkwrap;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Shrinkwrap, Debug, PartialEq, Clone, Copy)]
|
||||
#[shrinkwrap(mutable)]
|
||||
pub struct NonUniformScale(pub Vector3<f32>);
|
||||
pub struct NonUniformScale(pub Vec3);
|
||||
|
||||
impl NonUniformScale {
|
||||
pub fn new(x: f32, y: f32, z: f32) -> Self {
|
||||
Self(Vector3::new(x, y, z))
|
||||
Self(Vec3::new(x, y, z))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vector3<f32>> for NonUniformScale {
|
||||
fn from(scale: Vector3<f32>) -> Self {
|
||||
impl From<Vec3> for NonUniformScale {
|
||||
fn from(scale: Vec3) -> Self {
|
||||
Self(scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Vector3<f32>> for NonUniformScale {
|
||||
fn from(scale: &Vector3<f32>) -> Self {
|
||||
impl From<&Vec3> for NonUniformScale {
|
||||
fn from(scale: &Vec3) -> Self {
|
||||
Self(*scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&mut Vector3<f32>> for NonUniformScale {
|
||||
fn from(scale: &mut Vector3<f32>) -> Self {
|
||||
impl From<&mut Vec3> for NonUniformScale {
|
||||
fn from(scale: &mut Vec3) -> Self {
|
||||
Self(*scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for NonUniformScale {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let (x, y, z) = self.0.into();
|
||||
write!(
|
||||
f,
|
||||
"NonUniformScale({}, {}, {})",
|
||||
self.0.x, self.0.y, self.0.z
|
||||
x, y, z
|
||||
)
|
||||
}
|
||||
}
|
29
src/transform/src/components/rotation.rs
Normal file
29
src/transform/src/components/rotation.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
use crate::math::Quat;
|
||||
use shrinkwraprs::Shrinkwrap;
|
||||
|
||||
#[derive(Shrinkwrap, Debug, PartialEq, Clone, Copy)]
|
||||
#[shrinkwrap(mutable)]
|
||||
pub struct Rotation(pub Quat);
|
||||
impl Rotation {
|
||||
#[inline(always)]
|
||||
pub fn identity() -> Self {
|
||||
Self(Quat::identity())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_euler_angles(yaw: f32, pitch: f32, roll: f32) -> Self {
|
||||
Self(Quat::from_rotation_ypr(yaw, pitch, roll))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Rotation {
|
||||
fn default() -> Self {
|
||||
Self::identity()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Quat> for Rotation {
|
||||
fn from(rotation: Quat) -> Self {
|
||||
Self(rotation)
|
||||
}
|
||||
}
|
30
src/transform/src/components/translation.rs
Normal file
30
src/transform/src/components/translation.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use crate::math::Vec3;
|
||||
use shrinkwraprs::Shrinkwrap;
|
||||
|
||||
#[derive(Shrinkwrap, Debug, PartialEq, Clone, Copy)]
|
||||
#[shrinkwrap(mutable)]
|
||||
pub struct Translation(pub Vec3);
|
||||
|
||||
impl Translation {
|
||||
#[inline(always)]
|
||||
pub fn identity() -> Self {
|
||||
Self(Vec3::default())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn new(x: f32, y: f32, z: f32) -> Self {
|
||||
Self(Vec3::new(x, y, z))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Translation {
|
||||
fn default() -> Self {
|
||||
Self::identity()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec3> for Translation {
|
||||
fn from(translation: Vec3) -> Self {
|
||||
Self(Vec3::from(translation))
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
pub use legion as ecs;
|
||||
pub use nalgebra as math;
|
||||
pub use glam as math;
|
||||
|
||||
pub mod components;
|
||||
pub mod hierarchy_maintenance_system;
|
|
@ -1,5 +1,5 @@
|
|||
#![allow(dead_code)]
|
||||
use crate::{components::*, ecs::prelude::*, math::Matrix4};
|
||||
use crate::{components::*, ecs::prelude::*, math::{Mat4, Vec3, Quat}};
|
||||
|
||||
pub fn build(_: &mut World) -> Box<dyn Schedulable> {
|
||||
SystemBuilder::<()>::new("LocalToParentUpdateSystem")
|
||||
|
@ -114,76 +114,81 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
|
|||
s.spawn(|_| unsafe {
|
||||
// Translation
|
||||
a.for_each_unchecked(world, |(mut ltw, translation)| {
|
||||
*ltw = LocalToParent(translation.to_homogeneous());
|
||||
*ltw = LocalToParent(Mat4::from_translation(translation.0));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Rotation
|
||||
b.for_each_unchecked(world, |(mut ltw, rotation)| {
|
||||
*ltw = LocalToParent(rotation.to_homogeneous());
|
||||
*ltw = LocalToParent(Mat4::from_quat(rotation.0));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Scale
|
||||
c.for_each_unchecked(world, |(mut ltw, scale)| {
|
||||
*ltw = LocalToParent(Matrix4::new_scaling(scale.0));
|
||||
*ltw = LocalToParent(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 = LocalToParent(Matrix4::new_nonuniform_scaling(&non_uniform_scale.0));
|
||||
*ltw = LocalToParent(Mat4::from_scale(non_uniform_scale.0));
|
||||
});
|
||||
|
||||
// Translation + Rotation
|
||||
e.for_each_unchecked(world, |(mut ltw, translation, rotation)| {
|
||||
*ltw = LocalToParent(
|
||||
rotation
|
||||
.to_homogeneous()
|
||||
.append_translation(&translation.vector),
|
||||
Mat4::from_rotation_translation(rotation.0, translation.0)
|
||||
);
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Translation + Scale
|
||||
f.for_each_unchecked(world, |(mut ltw, translation, scale)| {
|
||||
*ltw = LocalToParent(translation.to_homogeneous().prepend_scaling(scale.0));
|
||||
*ltw = LocalToParent(Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(scale.0, scale.0, scale.0),
|
||||
Quat::default(),
|
||||
translation.0,
|
||||
));
|
||||
});
|
||||
|
||||
// Translation + NonUniformScale
|
||||
g.for_each_unchecked(world, |(mut ltw, translation, non_uniform_scale)| {
|
||||
*ltw = LocalToParent(
|
||||
translation
|
||||
.to_homogeneous()
|
||||
.prepend_nonuniform_scaling(&non_uniform_scale.0),
|
||||
);
|
||||
*ltw = LocalToParent(Mat4::from_scale_rotation_translation(
|
||||
non_uniform_scale.0,
|
||||
Quat::default(),
|
||||
translation.0,
|
||||
));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Rotation + Scale
|
||||
h.for_each_unchecked(world, |(mut ltw, rotation, scale)| {
|
||||
*ltw = LocalToParent(rotation.to_homogeneous().prepend_scaling(scale.0));
|
||||
*ltw = LocalToParent(Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(scale.0, scale.0, scale.0),
|
||||
rotation.0,
|
||||
Vec3::default(),
|
||||
));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Rotation + NonUniformScale
|
||||
i.for_each_unchecked(world, |(mut ltw, rotation, non_uniform_scale)| {
|
||||
*ltw = LocalToParent(
|
||||
rotation
|
||||
.to_homogeneous()
|
||||
.prepend_nonuniform_scaling(&non_uniform_scale.0),
|
||||
);
|
||||
*ltw = LocalToParent(Mat4::from_scale_rotation_translation(
|
||||
non_uniform_scale.0,
|
||||
rotation.0,
|
||||
Vec3::default(),
|
||||
));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Translation + Rotation + Scale
|
||||
j.for_each_unchecked(world, |(mut ltw, translation, rotation, scale)| {
|
||||
*ltw = LocalToParent(
|
||||
rotation
|
||||
.to_homogeneous()
|
||||
.append_translation(&translation.vector)
|
||||
.prepend_scaling(scale.0),
|
||||
);
|
||||
*ltw = LocalToParent(Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(scale.0, scale.0, scale.0),
|
||||
rotation.0,
|
||||
translation.0,
|
||||
));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
|
@ -191,12 +196,11 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
|
|||
k.for_each_unchecked(
|
||||
world,
|
||||
|(mut ltw, translation, rotation, non_uniform_scale)| {
|
||||
*ltw = LocalToParent(
|
||||
rotation
|
||||
.to_homogeneous()
|
||||
.append_translation(&translation.vector)
|
||||
.prepend_nonuniform_scaling(&non_uniform_scale.0),
|
||||
);
|
||||
*ltw = LocalToParent(Mat4::from_scale_rotation_translation(
|
||||
non_uniform_scale.0,
|
||||
rotation.0,
|
||||
translation.0,
|
||||
));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
@ -249,75 +253,92 @@ mod test {
|
|||
// Verify that each was transformed correctly.
|
||||
assert_eq!(
|
||||
world.get_component::<LocalToParent>(translation).unwrap().0,
|
||||
t.to_homogeneous()
|
||||
Mat4::from_translation(t.0)
|
||||
);
|
||||
assert_eq!(
|
||||
world.get_component::<LocalToParent>(rotation).unwrap().0,
|
||||
r.to_homogeneous()
|
||||
Mat4::from_quat(r.0)
|
||||
);
|
||||
assert_eq!(
|
||||
world.get_component::<LocalToParent>(scale).unwrap().0,
|
||||
Matrix4::new_scaling(s.0),
|
||||
Mat4::from_scale(Vec3::new(s.0, s.0, s.0))
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToParent>(non_uniform_scale)
|
||||
.unwrap()
|
||||
.0,
|
||||
Matrix4::new_nonuniform_scaling(&nus.0),
|
||||
Mat4::from_scale(nus.0)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToParent>(translation_and_rotation)
|
||||
.unwrap()
|
||||
.0,
|
||||
r.to_homogeneous().append_translation(&t.vector),
|
||||
Mat4::from_rotation_translation(r.0, t.0)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToParent>(translation_and_scale)
|
||||
.unwrap()
|
||||
.0,
|
||||
t.to_homogeneous().prepend_scaling(s.0),
|
||||
Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(s.0, s.0, s.0),
|
||||
Quat::default(),
|
||||
t.0
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToParent>(translation_and_nus)
|
||||
.unwrap()
|
||||
.0,
|
||||
t.to_homogeneous().prepend_nonuniform_scaling(&nus.0),
|
||||
Mat4::from_scale_rotation_translation(
|
||||
nus.0,
|
||||
Quat::default(),
|
||||
t.0
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToParent>(rotation_scale)
|
||||
.unwrap()
|
||||
.0,
|
||||
r.to_homogeneous().prepend_scaling(s.0)
|
||||
Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(s.0, s.0, s.0),
|
||||
r.0,
|
||||
Vec3::default()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToParent>(rotation_nus)
|
||||
.unwrap()
|
||||
.0,
|
||||
r.to_homogeneous().prepend_nonuniform_scaling(&nus.0)
|
||||
world.get_component::<LocalToParent>(rotation_nus).unwrap().0,
|
||||
Mat4::from_scale_rotation_translation(
|
||||
nus.0,
|
||||
r.0,
|
||||
Vec3::default()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToParent>(translation_rotation_scale)
|
||||
.unwrap()
|
||||
.0,
|
||||
r.to_homogeneous()
|
||||
.append_translation(&t.vector)
|
||||
.prepend_scaling(s.0)
|
||||
Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(s.0, s.0, s.0),
|
||||
r.0,
|
||||
t.0
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToParent>(translation_rotation_nus)
|
||||
.unwrap()
|
||||
.0,
|
||||
r.to_homogeneous()
|
||||
.append_translation(&t.vector)
|
||||
.prepend_nonuniform_scaling(&nus.0)
|
||||
Mat4::from_scale_rotation_translation(
|
||||
nus.0,
|
||||
r.0,
|
||||
t.0
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -59,6 +59,7 @@ mod test {
|
|||
use crate::{
|
||||
hierarchy_maintenance_system, local_to_parent_system, local_to_world_propagate_system,
|
||||
local_to_world_system,
|
||||
math::{Vec3, Mat4}
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
@ -120,14 +121,14 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
world.get_component::<LocalToWorld>(e1).unwrap().0,
|
||||
Translation::new(1.0, 0.0, 0.0).to_homogeneous()
|
||||
* Translation::new(0.0, 2.0, 0.0).to_homogeneous()
|
||||
Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0))
|
||||
* Mat4::from_translation(Vec3::new(0.0, 2.0, 0.0))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
world.get_component::<LocalToWorld>(e2).unwrap().0,
|
||||
Translation::new(1.0, 0.0, 0.0).to_homogeneous()
|
||||
* Translation::new(0.0, 0.0, 3.0).to_homogeneous()
|
||||
Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0))
|
||||
* Mat4::from_translation(Vec3::new(0.0, 0.0, 3.0))
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#![allow(dead_code)]
|
||||
use crate::{components::*, ecs::prelude::*, math::Matrix4};
|
||||
use crate::{components::*, ecs::prelude::*, math::{Mat4, Vec3, Quat}};
|
||||
|
||||
pub fn build(_: &mut World) -> Box<dyn Schedulable> {
|
||||
SystemBuilder::<()>::new("LocalToWorldUpdateSystem")
|
||||
|
@ -128,78 +128,83 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
|
|||
s.spawn(|_| unsafe {
|
||||
// Translation
|
||||
a.for_each_unchecked(world, |(mut ltw, translation)| {
|
||||
*ltw = LocalToWorld(translation.to_homogeneous());
|
||||
*ltw = LocalToWorld(Mat4::from_translation(translation.0));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Rotation
|
||||
b.for_each_unchecked(world, |(mut ltw, rotation)| {
|
||||
*ltw = LocalToWorld(rotation.to_homogeneous());
|
||||
*ltw = LocalToWorld(Mat4::from_quat(rotation.0));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Scale
|
||||
c.for_each_unchecked(world, |(mut ltw, scale)| {
|
||||
*ltw = LocalToWorld(Matrix4::new_scaling(scale.0));
|
||||
*ltw = LocalToWorld(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(Matrix4::new_nonuniform_scaling(&non_uniform_scale.0));
|
||||
*ltw = LocalToWorld(Mat4::from_scale(non_uniform_scale.0));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Translation + Rotation
|
||||
e.for_each_unchecked(world, |(mut ltw, translation, rotation)| {
|
||||
*ltw = LocalToWorld(
|
||||
rotation
|
||||
.to_homogeneous()
|
||||
.append_translation(&translation.vector),
|
||||
Mat4::from_rotation_translation(rotation.0, translation.0)
|
||||
);
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Translation + Scale
|
||||
f.for_each_unchecked(world, |(mut ltw, translation, scale)| {
|
||||
*ltw = LocalToWorld(translation.to_homogeneous().prepend_scaling(scale.0));
|
||||
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(scale.0, scale.0, scale.0),
|
||||
Quat::default(),
|
||||
translation.0,
|
||||
));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Translation + NonUniformScale
|
||||
g.for_each_unchecked(world, |(mut ltw, translation, non_uniform_scale)| {
|
||||
*ltw = LocalToWorld(
|
||||
translation
|
||||
.to_homogeneous()
|
||||
.prepend_nonuniform_scaling(&non_uniform_scale.0),
|
||||
);
|
||||
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
|
||||
non_uniform_scale.0,
|
||||
Quat::default(),
|
||||
translation.0,
|
||||
));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Rotation + Scale
|
||||
h.for_each_unchecked(world, |(mut ltw, rotation, scale)| {
|
||||
*ltw = LocalToWorld(rotation.to_homogeneous().prepend_scaling(scale.0));
|
||||
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(scale.0, scale.0, scale.0),
|
||||
rotation.0,
|
||||
Vec3::default(),
|
||||
));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Rotation + NonUniformScale
|
||||
i.for_each_unchecked(world, |(mut ltw, rotation, non_uniform_scale)| {
|
||||
*ltw = LocalToWorld(
|
||||
rotation
|
||||
.to_homogeneous()
|
||||
.prepend_nonuniform_scaling(&non_uniform_scale.0),
|
||||
);
|
||||
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
|
||||
non_uniform_scale.0,
|
||||
rotation.0,
|
||||
Vec3::default(),
|
||||
));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
// Translation + Rotation + Scale
|
||||
j.for_each_unchecked(world, |(mut ltw, translation, rotation, scale)| {
|
||||
*ltw = LocalToWorld(
|
||||
rotation
|
||||
.to_homogeneous()
|
||||
.append_translation(&translation.vector)
|
||||
.prepend_scaling(scale.0),
|
||||
);
|
||||
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(scale.0, scale.0, scale.0),
|
||||
rotation.0,
|
||||
translation.0,
|
||||
));
|
||||
});
|
||||
});
|
||||
s.spawn(|_| unsafe {
|
||||
|
@ -207,12 +212,11 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
|
|||
k.for_each_unchecked(
|
||||
world,
|
||||
|(mut ltw, translation, rotation, non_uniform_scale)| {
|
||||
*ltw = LocalToWorld(
|
||||
rotation
|
||||
.to_homogeneous()
|
||||
.append_translation(&translation.vector)
|
||||
.prepend_nonuniform_scaling(&non_uniform_scale.0),
|
||||
);
|
||||
*ltw = LocalToWorld(Mat4::from_scale_rotation_translation(
|
||||
non_uniform_scale.0,
|
||||
rotation.0,
|
||||
translation.0,
|
||||
));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
@ -236,6 +240,7 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::math::{Mat4, Quat, Vec3};
|
||||
|
||||
#[test]
|
||||
fn correct_world_transformation() {
|
||||
|
@ -270,72 +275,92 @@ mod test {
|
|||
// Verify that each was transformed correctly.
|
||||
assert_eq!(
|
||||
world.get_component::<LocalToWorld>(translation).unwrap().0,
|
||||
t.to_homogeneous()
|
||||
Mat4::from_translation(t.0)
|
||||
);
|
||||
assert_eq!(
|
||||
world.get_component::<LocalToWorld>(rotation).unwrap().0,
|
||||
r.to_homogeneous()
|
||||
Mat4::from_quat(r.0)
|
||||
);
|
||||
assert_eq!(
|
||||
world.get_component::<LocalToWorld>(scale).unwrap().0,
|
||||
Matrix4::new_scaling(s.0),
|
||||
Mat4::from_scale(Vec3::new(s.0, s.0, s.0))
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToWorld>(non_uniform_scale)
|
||||
.unwrap()
|
||||
.0,
|
||||
Matrix4::new_nonuniform_scaling(&nus.0),
|
||||
Mat4::from_scale(nus.0)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToWorld>(translation_and_rotation)
|
||||
.unwrap()
|
||||
.0,
|
||||
r.to_homogeneous().append_translation(&t.vector),
|
||||
Mat4::from_rotation_translation(r.0, t.0)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToWorld>(translation_and_scale)
|
||||
.unwrap()
|
||||
.0,
|
||||
t.to_homogeneous().prepend_scaling(s.0),
|
||||
Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(s.0, s.0, s.0),
|
||||
Quat::default(),
|
||||
t.0
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToWorld>(translation_and_nus)
|
||||
.unwrap()
|
||||
.0,
|
||||
t.to_homogeneous().prepend_nonuniform_scaling(&nus.0),
|
||||
Mat4::from_scale_rotation_translation(
|
||||
nus.0,
|
||||
Quat::default(),
|
||||
t.0
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToWorld>(rotation_scale)
|
||||
.unwrap()
|
||||
.0,
|
||||
r.to_homogeneous().prepend_scaling(s.0)
|
||||
Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(s.0, s.0, s.0),
|
||||
r.0,
|
||||
Vec3::default()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world.get_component::<LocalToWorld>(rotation_nus).unwrap().0,
|
||||
r.to_homogeneous().prepend_nonuniform_scaling(&nus.0)
|
||||
Mat4::from_scale_rotation_translation(
|
||||
nus.0,
|
||||
r.0,
|
||||
Vec3::default()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToWorld>(translation_rotation_scale)
|
||||
.unwrap()
|
||||
.0,
|
||||
r.to_homogeneous()
|
||||
.append_translation(&t.vector)
|
||||
.prepend_scaling(s.0)
|
||||
Mat4::from_scale_rotation_translation(
|
||||
Vec3::new(s.0, s.0, s.0),
|
||||
r.0,
|
||||
t.0
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
world
|
||||
.get_component::<LocalToWorld>(translation_rotation_nus)
|
||||
.unwrap()
|
||||
.0,
|
||||
r.to_homogeneous()
|
||||
.append_translation(&t.vector)
|
||||
.prepend_nonuniform_scaling(&nus.0)
|
||||
Mat4::from_scale_rotation_translation(
|
||||
nus.0,
|
||||
r.0,
|
||||
t.0
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue