#![allow(dead_code)] use crate::{ components::*, ecs::prelude::*, math::{Mat4, Quat, Vec3}, }; pub fn build(_: &mut World) -> Box { SystemBuilder::<()>::new("LocalToWorldUpdateSystem") // Translation .with_query(<(Write, Read)>::query().filter( !component::() & !component::() & !component::() & !component::() & (changed::()), )) // Rotation .with_query(<(Write, Read)>::query().filter( !component::() & !component::() & !component::() & !component::() & (changed::()), )) // Scale .with_query(<(Write, Read)>::query().filter( !component::() & !component::() & !component::() & !component::() & (changed::()), )) // NonUniformScale .with_query(<(Write, Read)>::query().filter( !component::() & !component::() & !component::() & !component::() & (changed::()), )) // Translation + Rotation .with_query( <(Write, Read, Read)>::query().filter( !component::() & !component::() & !component::() & (changed::() | changed::()), ), ) // Translation + Scale .with_query( <(Write, Read, Read)>::query().filter( !component::() & !component::() & !component::() & (changed::() | changed::()), ), ) // Translation + NonUniformScale .with_query( <(Write, Read, Read)>::query().filter( !component::() & !component::() & !component::() & (changed::() | changed::()), ), ) // Rotation + Scale .with_query( <(Write, Read, Read)>::query().filter( !component::() & !component::() & !component::() & (changed::() | changed::()), ), ) // Rotation + NonUniformScale .with_query( <(Write, Read, Read)>::query().filter( !component::() & !component::() & !component::() & (changed::() | changed::()), ), ) // Translation + Rotation + Scale .with_query( <( Write, Read, Read, Read, )>::query() .filter( !component::() & !component::() & (changed::() | changed::() | changed::()), ), ) // Translation + Rotation + NonUniformScale .with_query( <( Write, Read, Read, Read, )>::query() .filter( !component::() & !component::() & (changed::() | changed::() | changed::()), ), ) // Just to issue warnings: Scale + NonUniformScale .with_query( <(Read, Read, Read)>::query() .filter(!component::()), ) .build(move |_commands, world, _, queries| { let (a, b, c, d, e, f, g, h, i, j, k, l) = queries; rayon::scope(|s| { s.spawn(|_| unsafe { // Translation a.for_each_unchecked(world, |(mut ltw, translation)| { if !ltw.sync { return; } *ltw = Transform::new(Mat4::from_translation(translation.0)); }); }); s.spawn(|_| unsafe { // Rotation b.for_each_unchecked(world, |(mut ltw, rotation)| { if !ltw.sync { return; } *ltw = Transform::new(Mat4::from_quat(rotation.0)); }); }); s.spawn(|_| unsafe { // Scale c.for_each_unchecked(world, |(mut ltw, scale)| { if !ltw.sync { return; } *ltw = Transform::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)| { if !ltw.sync { return; } *ltw = Transform::new(Mat4::from_scale(non_uniform_scale.0)); }); }); s.spawn(|_| unsafe { // Translation + Rotation e.for_each_unchecked(world, |(mut ltw, translation, rotation)| { if !ltw.sync { return; } *ltw = Transform::new(Mat4::from_rotation_translation( rotation.0, translation.0, )); }); }); s.spawn(|_| unsafe { // Translation + Scale f.for_each_unchecked(world, |(mut ltw, translation, scale)| { if !ltw.sync { return; } *ltw = Transform::new(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)| { if !ltw.sync { return; } *ltw = Transform::new(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)| { if !ltw.sync { return; } *ltw = Transform::new(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)| { if !ltw.sync { return; } *ltw = Transform::new(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)| { if !ltw.sync { return; } *ltw = Transform::new(Mat4::from_scale_rotation_translation( Vec3::new(scale.0, scale.0, scale.0), rotation.0, translation.0, )); }); }); s.spawn(|_| unsafe { // Translation + Rotation + NonUniformScale k.for_each_unchecked( world, |(mut ltw, translation, rotation, non_uniform_scale)| { if !ltw.sync { return; } *ltw = Transform::new(Mat4::from_scale_rotation_translation( non_uniform_scale.0, rotation.0, translation.0, )); }, ); }); // Just to issue warnings: Scale + NonUniformScale #[allow(unused_unsafe)] unsafe { l.iter_entities(world).for_each( |(entity, (mut _ltw, _scale, _non_uniform_scale))| { log::warn!( "Entity {:?} has both a Scale and NonUniformScale component.", entity ); }, ); } }); }) } // #[cfg(test)] // mod test { // use super::*; // use crate::math::{Mat4, Quat, Vec3}; // #[test] // fn correct_world_transformation() { // let _ = env_logger::builder().is_test(true).try_init(); // let mut world = Universe::new().create_world(); // let system = build(&mut world); // let ltw = LocalToWorld::identity(); // let t = Translation::new(1.0, 2.0, 3.0); // let r = Rotation::from_euler_angles(1.0, 2.0, 3.0); // let s = Scale(2.0); // let nus = NonUniformScale::new(1.0, 2.0, 3.0); // // Add every combination of transform types. // let translation = *world.insert((), vec![(ltw, t)]).first().unwrap(); // let rotation = *world.insert((), vec![(ltw, r)]).first().unwrap(); // let scale = *world.insert((), vec![(ltw, s)]).first().unwrap(); // let non_uniform_scale = *world.insert((), vec![(ltw, nus)]).first().unwrap(); // let translation_and_rotation = *world.insert((), vec![(ltw, t, r)]).first().unwrap(); // let translation_and_scale = *world.insert((), vec![(ltw, t, s)]).first().unwrap(); // let translation_and_nus = *world.insert((), vec![(ltw, t, nus)]).first().unwrap(); // let rotation_scale = *world.insert((), vec![(ltw, r, s)]).first().unwrap(); // let rotation_nus = *world.insert((), vec![(ltw, r, nus)]).first().unwrap(); // let translation_rotation_scale = *world.insert((), vec![(ltw, t, r, s)]).first().unwrap(); // let translation_rotation_nus = *world.insert((), vec![(ltw, t, r, nus)]).first().unwrap(); // // Run the system // system.run(&mut world); // system.command_buffer_mut().write(&mut world); // // Verify that each was transformed correctly. // assert_eq!( // world.get_component::(translation).unwrap().0, // Mat4::from_translation(t.0) // ); // assert_eq!( // world.get_component::(rotation).unwrap().0, // Mat4::from_quat(r.0) // ); // assert_eq!( // world.get_component::(scale).unwrap().0, // Mat4::from_scale(Vec3::new(s.0, s.0, s.0)) // ); // assert_eq!( // world // .get_component::(non_uniform_scale) // .unwrap() // .0, // Mat4::from_scale(nus.0) // ); // assert_eq!( // world // .get_component::(translation_and_rotation) // .unwrap() // .0, // Mat4::from_rotation_translation(r.0, t.0) // ); // assert_eq!( // world // .get_component::(translation_and_scale) // .unwrap() // .0, // Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), Quat::default(), t.0) // ); // assert_eq!( // world // .get_component::(translation_and_nus) // .unwrap() // .0, // Mat4::from_scale_rotation_translation(nus.0, Quat::default(), t.0) // ); // assert_eq!( // world // .get_component::(rotation_scale) // .unwrap() // .0, // Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, Vec3::default()) // ); // assert_eq!( // world.get_component::(rotation_nus).unwrap().0, // Mat4::from_scale_rotation_translation(nus.0, r.0, Vec3::default()) // ); // assert_eq!( // world // .get_component::(translation_rotation_scale) // .unwrap() // .0, // Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, t.0) // ); // assert_eq!( // world // .get_component::(translation_rotation_nus) // .unwrap() // .0, // Mat4::from_scale_rotation_translation(nus.0, r.0, t.0) // ); // } // }