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