use cargo workspace

This commit is contained in:
Carter Anderson 2020-04-19 13:23:19 -07:00
parent e59693fe67
commit d8b183de02
12 changed files with 681 additions and 604 deletions

View File

@ -38,11 +38,29 @@ bevy_window = { path = "bevy_window", optional = true }
bevy_wgpu = { path = "bevy_wgpu", optional = true } bevy_wgpu = { path = "bevy_wgpu", optional = true }
bevy_winit = { path = "bevy_winit", optional = true } bevy_winit = { path = "bevy_winit", optional = true }
legion = { path = "bevy_legion" } legion = { path = "bevy_legion" }
# other # other
log = { version = "0.4", features = ["release_max_level_info"] } log = { version = "0.4", features = ["release_max_level_info"] }
glam = "0.8.6" glam = "0.8.6"
[workspace]
members = [
"bevy_app",
"bevy_asset",
"bevy_core",
"bevy_derive",
"bevy_diagnostic",
"bevy_gltf",
"bevy_input",
"bevy_render",
"bevy_serialization",
"bevy_transform",
"bevy_legion",
"bevy_ui",
"bevy_window",
"bevy_wgpu",
"bevy_winit",
]
[dev-dependencies] [dev-dependencies]
rand = "0.7.2" rand = "0.7.2"
serde = { version = "1", features = ["derive"]} serde = { version = "1", features = ["derive"]}

View File

@ -18,7 +18,7 @@ enum State {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use bevy::core::event::Events; /// use bevy_app::Events;
/// ///
/// struct MyEvent { /// struct MyEvent {
/// value: usize /// value: usize

View File

@ -22,11 +22,11 @@ ffi = ["legion-core/ffi"]
serialize = ["legion-core/serialize"] serialize = ["legion-core/serialize"]
metrics = ["legion-core/metrics"] metrics = ["legion-core/metrics"]
[workspace] # [workspace]
members = [ # members = [
"legion_core", # "legion_core",
"legion_systems", # "legion_systems",
] # ]
[dependencies] [dependencies]
legion-core = { path = "legion_core", version = "0.2.1", default-features = false } legion-core = { path = "legion_core", version = "0.2.1", default-features = false }

View File

@ -320,3 +320,56 @@ pub fn mesh_batcher_system() -> Box<dyn Schedulable> {
} }
}) })
} }
#[cfg(tests)]
mod tests {
#[test]
fn test_get_vertex_bytes() {
let vertices = &[
([0., 0., 0.], [1., 1., 1.], [2., 2.]),
([3., 3., 3.], [4., 4., 4.], [5., 5.]),
([6., 6., 6.], [7., 7., 7.], [8., 8.]),
];
let mut positions = Vec::new();
let mut normals = Vec::new();
let mut uvs = Vec::new();
for (position, normal, uv) in vertices.iter() {
positions.push(position.clone());
normals.push(normal.clone());
uvs.push(uv.clone());
}
let mesh = Mesh {
primitive_topology: PrimitiveTopology::TriangleStrip,
attributes: vec![
VertexAttribute::position(positions),
VertexAttribute::normal(normals),
VertexAttribute::uv(uvs),
],
indices: None,
};
let expected_vertices = &[
Vertex {
position: [0., 0., 0.],
normal: [1., 1., 1.],
uv: [2., 2.],
},
Vertex {
position: [3., 3., 3.],
normal: [4., 4., 4.],
uv: [5., 5.],
},
Vertex {
position: [6., 6., 6.],
normal: [7., 7., 7.],
uv: [8., 8.],
},
];
let descriptor = Vertex::get_vertex_buffer_descriptor();
assert_eq!(mesh.get_vertex_buffer_bytes(descriptor), expected_vertices.as_bytes(), "buffer bytes are equal");
}
}

View File

@ -141,7 +141,7 @@ pub struct RenderResourceSetId(u64);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::render::pipeline::{ use crate::pipeline::{
BindType, BindingDescriptor, UniformProperty, UniformPropertyType, BindType, BindingDescriptor, UniformProperty, UniformPropertyType,
}; };
@ -178,17 +178,22 @@ mod tests {
], ],
); );
let resource1 = RenderResource::new();
let resource2 = RenderResource::new();
let resource3 = RenderResource::new();
let resource4 = RenderResource::new();
let mut assignments = RenderResourceAssignments::default(); let mut assignments = RenderResourceAssignments::default();
assignments.set("a", RenderResource(1)); assignments.set("a", resource1);
assignments.set("b", RenderResource(2)); assignments.set("b", resource2);
let mut different_assignments = RenderResourceAssignments::default(); let mut different_assignments = RenderResourceAssignments::default();
different_assignments.set("a", RenderResource(3)); different_assignments.set("a", resource3);
different_assignments.set("b", RenderResource(4)); different_assignments.set("b", resource4);
let mut equal_assignments = RenderResourceAssignments::default(); let mut equal_assignments = RenderResourceAssignments::default();
equal_assignments.set("a", RenderResource(1)); equal_assignments.set("a", resource1);
equal_assignments.set("b", RenderResource(2)); equal_assignments.set("b", resource2);
let set_id = assignments.update_render_resource_set_id(&bind_group_descriptor); let set_id = assignments.update_render_resource_set_id(&bind_group_descriptor);
assert_ne!(set_id, None); assert_ne!(set_id, None);
@ -203,7 +208,7 @@ mod tests {
assert_eq!(equal_set_id, set_id); assert_eq!(equal_set_id, set_id);
let mut unmatched_assignments = RenderResourceAssignments::default(); let mut unmatched_assignments = RenderResourceAssignments::default();
unmatched_assignments.set("a", RenderResource(1)); unmatched_assignments.set("a", resource1);
let unmatched_set_id = let unmatched_set_id =
unmatched_assignments.update_render_resource_set_id(&bind_group_descriptor); unmatched_assignments.update_render_resource_set_id(&bind_group_descriptor);
assert_eq!(unmatched_set_id, None); assert_eq!(unmatched_set_id, None);

View File

@ -332,7 +332,7 @@ fn reflect_vertex_format(type_description: &ReflectTypeDescription) -> VertexFor
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::render::shader::{Shader, ShaderStage}; use crate::shader::{Shader, ShaderStage};
#[test] #[test]
fn test_reflection() { fn test_reflection() {
@ -362,19 +362,19 @@ mod tests {
assert_eq!( assert_eq!(
layout, layout,
ShaderLayout { ShaderLayout {
entry_point: "main".to_string(), entry_point: "main".into(),
vertex_buffer_descriptors: vec![ vertex_buffer_descriptors: vec![
VertexBufferDescriptor { VertexBufferDescriptor {
name: "Vertex".to_string(), name: "Vertex".into(),
attributes: vec![ attributes: vec![
VertexAttributeDescriptor { VertexAttributeDescriptor {
name: "Vertex_Position".to_string(), name: "Vertex_Position".into(),
format: VertexFormat::Float4, format: VertexFormat::Float4,
offset: 0, offset: 0,
shader_location: 0, shader_location: 0,
}, },
VertexAttributeDescriptor { VertexAttributeDescriptor {
name: "Vertex_Normal".to_string(), name: "Vertex_Normal".into(),
format: VertexFormat::Uint4, format: VertexFormat::Uint4,
offset: 16, offset: 16,
shader_location: 1, shader_location: 1,
@ -384,9 +384,9 @@ mod tests {
stride: 32, stride: 32,
}, },
VertexBufferDescriptor { VertexBufferDescriptor {
name: "TestInstancing".to_string(), name: "TestInstancing".into(),
attributes: vec![VertexAttributeDescriptor { attributes: vec![VertexAttributeDescriptor {
name: "I_TestInstancing_Property".to_string(), name: "I_TestInstancing_Property".into(),
format: VertexFormat::Uint4, format: VertexFormat::Uint4,
offset: 0, offset: 0,
shader_location: 2, shader_location: 2,
@ -400,14 +400,14 @@ mod tests {
0, 0,
vec![BindingDescriptor { vec![BindingDescriptor {
index: 0, index: 0,
name: "Camera".to_string(), name: "Camera".into(),
bind_type: BindType::Uniform { bind_type: BindType::Uniform {
dynamic: false, dynamic: false,
properties: vec![UniformProperty { properties: vec![UniformProperty {
name: "Camera".to_string(), name: "Camera".into(),
property_type: UniformPropertyType::Struct(vec![ property_type: UniformPropertyType::Struct(vec![
UniformProperty { UniformProperty {
name: "".to_string(), name: "".into(),
property_type: UniformPropertyType::Mat4, property_type: UniformPropertyType::Mat4,
} }
]), ]),
@ -419,7 +419,7 @@ mod tests {
1, 1,
vec![BindingDescriptor { vec![BindingDescriptor {
index: 0, index: 0,
name: "Texture".to_string(), name: "Texture".into(),
bind_type: BindType::SampledTexture { bind_type: BindType::SampledTexture {
multisampled: false, multisampled: false,
dimension: TextureViewDimension::D2, dimension: TextureViewDimension::D2,

View File

@ -1,155 +1,156 @@
extern crate legion; // extern crate legion;
extern crate legion_transform; // extern crate legion_transform;
use legion::prelude::*; // use legion::prelude::*;
use legion_transform::prelude::*; // use legion_transform::prelude::*;
fn main() {}
#[allow(unused)] // #[allow(unused)]
fn tldr_sample() { // fn tldr_sample() {
// Create a normal Legion World // // Create a normal Legion World
let mut world = Universe::default().create_world(); // let mut world = Universe::default().create_world();
// Create a system bundle (vec of systems) for LegionTransform // // Create a system bundle (vec of systems) for LegionTransform
let transform_system_bundle = transform_system_bundle::build(&mut world); // let transform_system_bundle = transform_system_bundle::build(&mut world);
let parent_entity = *world // let parent_entity = *world
.insert( // .insert(
(), // (),
vec![( // vec![(
// Always needed for an Entity that has any space transform // // Always needed for an Entity that has any space transform
LocalToWorld::identity(), // LocalToWorld::identity(),
// The only mutable space transform a parent has is a translation. // // The only mutable space transform a parent has is a translation.
Translation::new(100.0, 0.0, 0.0), // Translation::new(100.0, 0.0, 0.0),
)], // )],
) // )
.first() // .first()
.unwrap(); // .unwrap();
world.insert( // world.insert(
(), // (),
vec![ // vec![
( // (
// Again, always need a `LocalToWorld` component for the Entity to have a custom // // Again, always need a `LocalToWorld` component for the Entity to have a custom
// space transform. // // space transform.
LocalToWorld::identity(), // LocalToWorld::identity(),
// Here we define a Translation, Rotation and uniform Scale. // // Here we define a Translation, Rotation and uniform Scale.
Translation::new(1.0, 2.0, 3.0), // Translation::new(1.0, 2.0, 3.0),
Rotation::from_euler_angles(3.14, 0.0, 0.0), // Rotation::from_euler_angles(3.14, 0.0, 0.0),
Scale(2.0), // Scale(2.0),
// Add a Parent and LocalToParent component to attach a child to a parent. // // Add a Parent and LocalToParent component to attach a child to a parent.
Parent(parent_entity), // Parent(parent_entity),
LocalToParent::identity(), // LocalToParent::identity(),
); // );
4 // 4
], // ],
); // );
} // }
fn main() { // fn main() {
// Create a normal Legion World // // Create a normal Legion World
let mut world = Universe::default().create_world(); // let mut world = Universe::default().create_world();
// Create a system bundle (vec of systems) for LegionTransform // // Create a system bundle (vec of systems) for LegionTransform
let transform_system_bundle = transform_system_bundle::build(&mut world); // let transform_system_bundle = transform_system_bundle::build(&mut world);
// See `./types_of_transforms.rs` for an explanation of space-transform types. // // See `./types_of_transforms.rs` for an explanation of space-transform types.
let parent_entity = *world // let parent_entity = *world
.insert( // .insert(
(), // (),
vec![(LocalToWorld::identity(), Translation::new(100.0, 0.0, 0.0))], // vec![(LocalToWorld::identity(), Translation::new(100.0, 0.0, 0.0))],
) // )
.first() // .first()
.unwrap(); // .unwrap();
let four_children: Vec<_> = world // let four_children: Vec<_> = world
.insert( // .insert(
(), // (),
vec![ // vec![
( // (
LocalToWorld::identity(), // LocalToWorld::identity(),
Translation::new(1.0, 2.0, 3.0), // Translation::new(1.0, 2.0, 3.0),
Rotation::from_euler_angles(3.14, 0.0, 0.0), // Rotation::from_euler_angles(3.14, 0.0, 0.0),
Scale(2.0), // Scale(2.0),
// Add a Parent and LocalToParent component to attach a child to a parent. // // Add a Parent and LocalToParent component to attach a child to a parent.
Parent(parent_entity), // Parent(parent_entity),
LocalToParent::identity(), // LocalToParent::identity(),
); // );
4 // 4
], // ],
) // )
.iter() // .iter()
.cloned() // .cloned()
.collect(); // .collect();
// At this point the parent does NOT have a `Children` component attached to it. The `Children` // // At this point the parent does NOT have a `Children` component attached to it. The `Children`
// component is updated by the transform system bundle and thus can be out of date (or // // component is updated by the transform system bundle and thus can be out of date (or
// non-existent for newly added members). By this logic, the `Parent` components should be // // non-existent for newly added members). By this logic, the `Parent` components should be
// considered the always-correct 'source of truth' for any hierarchy. // // considered the always-correct 'source of truth' for any hierarchy.
for system in transform_system_bundle.iter() { // for system in transform_system_bundle.iter() {
system.run(&mut world); // system.run(&mut world);
system.command_buffer_mut().write(&mut world); // system.command_buffer_mut().write(&mut world);
} // }
// At this point all parents with children have a correct `Children` component. // // At this point all parents with children have a correct `Children` component.
let parents_children = world // let parents_children = world
.get_component::<Children>(parent_entity) // .get_component::<Children>(parent_entity)
.unwrap() // .unwrap()
.0 // .0
.clone(); // .clone();
println!("Parent {}", parent_entity); // println!("Parent {}", parent_entity);
for child in parents_children.iter() { // for child in parents_children.iter() {
println!(" -> Has child: {}", child); // println!(" -> Has child: {}", child);
} // }
// Each child will also have a `LocalToParent` component attached to it, which is a // // Each child will also have a `LocalToParent` component attached to it, which is a
// space-transform from its local space to that of its parent. // // space-transform from its local space to that of its parent.
for child in four_children.iter() { // for child in four_children.iter() {
println!("The child {}", child); // println!("The child {}", child);
println!( // println!(
" -> Has a LocalToParent matrix: {}", // " -> Has a LocalToParent matrix: {}",
*world.get_component::<LocalToParent>(*child).unwrap() // *world.get_component::<LocalToParent>(*child).unwrap()
); // );
println!( // println!(
" -> Has a LocalToWorld matrix: {}", // " -> Has a LocalToWorld matrix: {}",
*world.get_component::<LocalToWorld>(*child).unwrap() // *world.get_component::<LocalToWorld>(*child).unwrap()
); // );
} // }
// Re-parent the second child to be a grandchild of the first. // // Re-parent the second child to be a grandchild of the first.
world.add_component(four_children[1], Parent(four_children[0])); // world.add_component(four_children[1], Parent(four_children[0]));
// Re-running the system will cleanup and fix all `Children` components. // // Re-running the system will cleanup and fix all `Children` components.
for system in transform_system_bundle.iter() { // for system in transform_system_bundle.iter() {
system.run(&world); // system.run(&world);
system.command_buffer_mut().write(&mut world); // system.command_buffer_mut().write(&mut world);
} // }
println!("After the second child was re-parented as a grandchild of the first child..."); // println!("After the second child was re-parented as a grandchild of the first child...");
for child in world // for child in world
.get_component::<Children>(parent_entity) // .get_component::<Children>(parent_entity)
.unwrap() // .unwrap()
.0 // .0
.iter() // .iter()
{ // {
println!("Parent {} has child: {}", parent_entity, child); // println!("Parent {} has child: {}", parent_entity, child);
} // }
for grandchild in world // for grandchild in world
.get_component::<Children>(four_children[0]) // .get_component::<Children>(four_children[0])
.unwrap() // .unwrap()
.0 // .0
.iter() // .iter()
{ // {
println!("Child {} has grandchild: {}", four_children[0], grandchild); // println!("Child {} has grandchild: {}", four_children[0], grandchild);
} // }
println!("Grandchild: {}", four_children[1]); // println!("Grandchild: {}", four_children[1]);
println!( // println!(
" -> Has a LocalToWorld matrix: {}", // " -> Has a LocalToWorld matrix: {}",
*world // *world
.get_component::<LocalToWorld>(four_children[1]) // .get_component::<LocalToWorld>(four_children[1])
.unwrap() // .unwrap()
); // );
} // }

View File

@ -1,94 +1,94 @@
extern crate legion; // extern crate legion;
extern crate legion_transform; // // extern crate legion_transform;
use legion::prelude::*; // use legion::prelude::*;
use legion_transform::prelude::*; // use legion_transform::prelude::*;
fn main() {}
// fn main() {
// // Create a normal Legion World
// let mut world = Universe::default().create_world();
fn main() { // // Create a system bundle (vec of systems) for LegionTransform
// Create a normal Legion World // let transform_system_bundle = transform_system_bundle::build(&mut world);
let mut world = Universe::default().create_world();
// Create a system bundle (vec of systems) for LegionTransform // // A user-defined space transform is split into 4 different components: [`Translation`,
let transform_system_bundle = transform_system_bundle::build(&mut world); // // `Rotation`, `Scale`, `NonUniformScale`]. Any combination of these components can be added to
// // an entity to transform it's space (exception: `Scale` and `NonUniformScale` are mutually
// // exclusive).
// A user-defined space transform is split into 4 different components: [`Translation`, // // Note that all entities need an explicitly added `LocalToWorld` component to be considered for
// `Rotation`, `Scale`, `NonUniformScale`]. Any combination of these components can be added to // // processing during transform system passes.
// an entity to transform it's space (exception: `Scale` and `NonUniformScale` are mutually
// exclusive).
// Note that all entities need an explicitly added `LocalToWorld` component to be considered for // // Add an entity with just a Translation
// processing during transform system passes. // // See: https://www.nalgebra.org/rustdoc/nalgebra/geometry/struct.Translation.html
// // API on Translation, as a LegionTransform `Translation` is just a nalgebra `Translation3`.
// world.insert(
// (),
// vec![(LocalToWorld::identity(), Translation::new(1.0, 2.0, 3.0))],
// );
// Add an entity with just a Translation // // Add an entity with just a Rotation.
// See: https://www.nalgebra.org/rustdoc/nalgebra/geometry/struct.Translation.html // // See: https://www.nalgebra.org/rustdoc/nalgebra/geometry/type.UnitQuaternion.html for the full
// API on Translation, as a LegionTransform `Translation` is just a nalgebra `Translation3`. // // API on Rotation, as a LegionTransform `Rotation` is just a nalgebra `UnityQuaternion`.
world.insert( // world.insert(
(), // (),
vec![(LocalToWorld::identity(), Translation::new(1.0, 2.0, 3.0))], // vec![(
); // LocalToWorld::identity(),
// Rotation::from_euler_angles(3.14, 0.0, 0.0),
// )],
// );
// Add an entity with just a Rotation. // // Add an entity with just a uniform Scale (the default and strongly-preferred scale component).
// See: https://www.nalgebra.org/rustdoc/nalgebra/geometry/type.UnitQuaternion.html for the full // // This is simply a `f32` wrapper.
// API on Rotation, as a LegionTransform `Rotation` is just a nalgebra `UnityQuaternion`. // world.insert((), vec![(LocalToWorld::identity(), Scale(2.0))]);
world.insert(
(),
vec![(
LocalToWorld::identity(),
Rotation::from_euler_angles(3.14, 0.0, 0.0),
)],
);
// Add an entity with just a uniform Scale (the default and strongly-preferred scale component). // // Add an entity with just a NonUniformScale (This should be avoided unless you **really** need
// This is simply a `f32` wrapper. // // non-uniform scaling as it breaks things like physics colliders.
world.insert((), vec![(LocalToWorld::identity(), Scale(2.0))]); // // See: https://docs.rs/nalgebra/0.10.1/nalgebra/struct.Vector3.html for the full API on
// // NonUniformScale, as a LegionTransform `NonUniformScale` is simply a nalgebra `Vector3`,
// // although note that it is wrapped in a tuple-struct.
// world.insert(
// (),
// vec![(
// LocalToWorld::identity(),
// NonUniformScale::new(1.0, 2.0, 1.0),
// )],
// );
// Add an entity with just a NonUniformScale (This should be avoided unless you **really** need // // Add an entity with a combination of Translation and Rotation
// non-uniform scaling as it breaks things like physics colliders. // world.insert(
// See: https://docs.rs/nalgebra/0.10.1/nalgebra/struct.Vector3.html for the full API on // (),
// NonUniformScale, as a LegionTransform `NonUniformScale` is simply a nalgebra `Vector3`, // vec![(
// although note that it is wrapped in a tuple-struct. // LocalToWorld::identity(),
world.insert( // Translation::new(1.0, 2.0, 3.0),
(), // Rotation::from_euler_angles(3.14, 0.0, 0.0),
vec![( // )],
LocalToWorld::identity(), // );
NonUniformScale::new(1.0, 2.0, 1.0),
)],
);
// Add an entity with a combination of Translation and Rotation // // Add an entity with a combination of Translation and Rotation and uniform Scale.
world.insert( // world.insert(
(), // (),
vec![( // vec![(
LocalToWorld::identity(), // LocalToWorld::identity(),
Translation::new(1.0, 2.0, 3.0), // Translation::new(1.0, 2.0, 3.0),
Rotation::from_euler_angles(3.14, 0.0, 0.0), // Rotation::from_euler_angles(3.14, 0.0, 0.0),
)], // Scale(2.0),
); // )],
// );
// Add an entity with a combination of Translation and Rotation and uniform Scale. // // Run the system bundle (this API will likely change).
world.insert( // for system in transform_system_bundle.iter() {
(), // system.run(&world);
vec![( // system.command_buffer_mut().write(&mut world);
LocalToWorld::identity(), // }
Translation::new(1.0, 2.0, 3.0),
Rotation::from_euler_angles(3.14, 0.0, 0.0),
Scale(2.0),
)],
);
// Run the system bundle (this API will likely change). // // At this point all `LocalToWorld` components have correct values in them. Running the system
for system in transform_system_bundle.iter() { // // again will result in a short-circuit as only changed components are considered for update.
system.run(&world); // let mut query = <Read<LocalToWorld>>::query();
system.command_buffer_mut().write(&mut world); // for (entity, local_to_world) in query.iter_entities(&mut world) {
} // println!(
// "Entity {} and a LocalToWorld matrix: {}",
// At this point all `LocalToWorld` components have correct values in them. Running the system // entity, *local_to_world
// again will result in a short-circuit as only changed components are considered for update. // );
let mut query = <Read<LocalToWorld>>::query(); // }
for (entity, local_to_world) in query.iter_entities(&mut world) { // }
println!(
"Entity {} and a LocalToWorld matrix: {}",
entity, *local_to_world
);
}
}

View File

@ -101,111 +101,111 @@ pub fn build(_: &mut World) -> Vec<Box<dyn Schedulable>> {
vec![missing_previous_parent_system, parent_update_system] vec![missing_previous_parent_system, parent_update_system]
} }
#[cfg(test)] // #[cfg(test)]
mod test { // mod test {
use super::*; // use super::*;
#[test] // #[test]
fn correct_children() { // fn correct_children() {
let _ = env_logger::builder().is_test(true).try_init(); // let _ = env_logger::builder().is_test(true).try_init();
let mut world = Universe::new().create_world(); // let mut world = Universe::new().create_world();
let systems = build(&mut world); // let systems = build(&mut world);
// Add parent entities // // Add parent entities
let parent = *world // let parent = *world
.insert( // .insert(
(), // (),
vec![(Translation::identity(), LocalToWorld::identity())], // vec![(Translation::identity(), LocalToWorld::identity())],
) // )
.first() // .first()
.unwrap(); // .unwrap();
let children = world.insert( // let children = world.insert(
(), // (),
vec![ // vec![
( // (
Translation::identity(), // Translation::identity(),
LocalToParent::identity(), // LocalToParent::identity(),
LocalToWorld::identity(), // LocalToWorld::identity(),
), // ),
( // (
Translation::identity(), // Translation::identity(),
LocalToParent::identity(), // LocalToParent::identity(),
LocalToWorld::identity(), // LocalToWorld::identity(),
), // ),
], // ],
); // );
let (e1, e2) = (children[0], children[1]); // let (e1, e2) = (children[0], children[1]);
// Parent `e1` and `e2` to `parent`. // // Parent `e1` and `e2` to `parent`.
world.add_component(e1, Parent(parent)); // world.add_component(e1, Parent(parent));
world.add_component(e2, Parent(parent)); // world.add_component(e2, Parent(parent));
for system in systems.iter() { // for system in systems.iter() {
system.run(&mut world); // system.run(&mut world);
system.command_buffer_mut().write(&mut world); // system.command_buffer_mut().write(&mut world);
} // }
assert_eq!( // assert_eq!(
world // world
.get_component::<Children>(parent) // .get_component::<Children>(parent)
.unwrap() // .unwrap()
.0 // .0
.iter() // .iter()
.cloned() // .cloned()
.collect::<Vec<_>>(), // .collect::<Vec<_>>(),
vec![e1, e2] // vec![e1, e2]
); // );
// Parent `e1` to `e2`. // // Parent `e1` to `e2`.
(*world.get_component_mut::<Parent>(e1).unwrap()).0 = e2; // (*world.get_component_mut::<Parent>(e1).unwrap()).0 = e2;
// Run the system on it // // Run the system on it
for system in systems.iter() { // for system in systems.iter() {
system.run(&mut world); // system.run(&mut world);
system.command_buffer_mut().write(&mut world); // system.command_buffer_mut().write(&mut world);
} // }
assert_eq!( // assert_eq!(
world // world
.get_component::<Children>(parent) // .get_component::<Children>(parent)
.unwrap() // .unwrap()
.0 // .0
.iter() // .iter()
.cloned() // .cloned()
.collect::<Vec<_>>(), // .collect::<Vec<_>>(),
vec![e2] // vec![e2]
); // );
assert_eq!( // assert_eq!(
world // world
.get_component::<Children>(e2) // .get_component::<Children>(e2)
.unwrap() // .unwrap()
.0 // .0
.iter() // .iter()
.cloned() // .cloned()
.collect::<Vec<_>>(), // .collect::<Vec<_>>(),
vec![e1] // vec![e1]
); // );
world.delete(e1); // world.delete(e1);
// Run the system on it // // Run the system on it
for system in systems.iter() { // for system in systems.iter() {
system.run(&mut world); // system.run(&mut world);
system.command_buffer_mut().write(&mut world); // system.command_buffer_mut().write(&mut world);
} // }
assert_eq!( // assert_eq!(
world // world
.get_component::<Children>(parent) // .get_component::<Children>(parent)
.unwrap() // .unwrap()
.0 // .0
.iter() // .iter()
.cloned() // .cloned()
.collect::<Vec<_>>(), // .collect::<Vec<_>>(),
vec![e2] // vec![e2]
); // );
} // }
} // }

View File

@ -222,108 +222,108 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
}) })
} }
#[cfg(test)] // #[cfg(test)]
mod test { // mod test {
use super::*; // use super::*;
#[test] // #[test]
fn correct_parent_transformation() { // fn correct_parent_transformation() {
let _ = env_logger::builder().is_test(true).try_init(); // let _ = env_logger::builder().is_test(true).try_init();
let mut world = Universe::new().create_world(); // let mut world = Universe::new().create_world();
let system = build(&mut world); // let system = build(&mut world);
let ltw = LocalToParent::identity(); // let ltw = LocalToParent::identity();
let t = Translation::new(1.0, 2.0, 3.0); // let t = Translation::new(1.0, 2.0, 3.0);
let r = Rotation::from_euler_angles(1.0, 2.0, 3.0); // let r = Rotation::from_euler_angles(1.0, 2.0, 3.0);
let s = Scale(2.0); // let s = Scale(2.0);
let nus = NonUniformScale::new(1.0, 2.0, 3.0); // let nus = NonUniformScale::new(1.0, 2.0, 3.0);
// Add every combination of transform types. // // Add every combination of transform types.
let translation = *world.insert((), vec![(ltw, t)]).first().unwrap(); // let translation = *world.insert((), vec![(ltw, t)]).first().unwrap();
let rotation = *world.insert((), vec![(ltw, r)]).first().unwrap(); // let rotation = *world.insert((), vec![(ltw, r)]).first().unwrap();
let scale = *world.insert((), vec![(ltw, s)]).first().unwrap(); // let scale = *world.insert((), vec![(ltw, s)]).first().unwrap();
let non_uniform_scale = *world.insert((), vec![(ltw, nus)]).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_rotation = *world.insert((), vec![(ltw, t, r)]).first().unwrap();
let translation_and_scale = *world.insert((), vec![(ltw, t, s)]).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 translation_and_nus = *world.insert((), vec![(ltw, t, nus)]).first().unwrap();
let rotation_scale = *world.insert((), vec![(ltw, r, s)]).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 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_scale = *world.insert((), vec![(ltw, t, r, s)]).first().unwrap();
let translation_rotation_nus = *world.insert((), vec![(ltw, t, r, nus)]).first().unwrap(); // let translation_rotation_nus = *world.insert((), vec![(ltw, t, r, nus)]).first().unwrap();
// Run the system // // Run the system
system.run(&mut world); // system.run(&mut world);
system.command_buffer_mut().write(&mut world); // system.command_buffer_mut().write(&mut world);
// 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,
Mat4::from_translation(t.0) // Mat4::from_translation(t.0)
); // );
assert_eq!( // assert_eq!(
world.get_component::<LocalToParent>(rotation).unwrap().0, // world.get_component::<LocalToParent>(rotation).unwrap().0,
Mat4::from_quat(r.0) // Mat4::from_quat(r.0)
); // );
assert_eq!( // assert_eq!(
world.get_component::<LocalToParent>(scale).unwrap().0, // world.get_component::<LocalToParent>(scale).unwrap().0,
Mat4::from_scale(Vec3::new(s.0, s.0, 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,
Mat4::from_scale(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,
Mat4::from_rotation_translation(r.0, t.0) // 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,
Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), Quat::default(), t.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,
Mat4::from_scale_rotation_translation(nus.0, Quat::default(), t.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,
Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, Vec3::default()) // 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) // .get_component::<LocalToParent>(rotation_nus)
.unwrap() // .unwrap()
.0, // .0,
Mat4::from_scale_rotation_translation(nus.0, r.0, Vec3::default()) // Mat4::from_scale_rotation_translation(nus.0, r.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,
Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, t.0) // Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, 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,
Mat4::from_scale_rotation_translation(nus.0, r.0, t.0) // Mat4::from_scale_rotation_translation(nus.0, r.0, t.0)
); // );
} // }
} // }

View File

@ -53,82 +53,82 @@ fn propagate_recursive(
} }
} }
#[cfg(test)] // #[cfg(test)]
mod test { // mod test {
use super::*; // use super::*;
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::{Mat4, Vec3}, // math::{Mat4, Vec3},
}; // };
#[test] // #[test]
fn did_propagate() { // fn did_propagate() {
let _ = env_logger::builder().is_test(true).try_init(); // let _ = env_logger::builder().is_test(true).try_init();
let mut world = Universe::new().create_world(); // let mut world = Universe::new().create_world();
let hierarchy_maintenance_systems = hierarchy_maintenance_system::build(&mut world); // let hierarchy_maintenance_systems = hierarchy_maintenance_system::build(&mut world);
let local_to_parent_system = local_to_parent_system::build(&mut world); // let local_to_parent_system = local_to_parent_system::build(&mut world);
let local_to_world_system = local_to_world_system::build(&mut world); // let local_to_world_system = local_to_world_system::build(&mut world);
let local_to_world_propagate_system = local_to_world_propagate_system::build(&mut world); // let local_to_world_propagate_system = local_to_world_propagate_system::build(&mut world);
// Root entity // // Root entity
let parent = *world // let parent = *world
.insert( // .insert(
(), // (),
vec![(Translation::new(1.0, 0.0, 0.0), LocalToWorld::identity())], // vec![(Translation::new(1.0, 0.0, 0.0), LocalToWorld::identity())],
) // )
.first() // .first()
.unwrap(); // .unwrap();
let children = world.insert( // let children = world.insert(
(), // (),
vec![ // vec![
( // (
Translation::new(0.0, 2.0, 0.0), // Translation::new(0.0, 2.0, 0.0),
LocalToParent::identity(), // LocalToParent::identity(),
LocalToWorld::identity(), // LocalToWorld::identity(),
), // ),
( // (
Translation::new(0.0, 0.0, 3.0), // Translation::new(0.0, 0.0, 3.0),
LocalToParent::identity(), // LocalToParent::identity(),
LocalToWorld::identity(), // LocalToWorld::identity(),
), // ),
], // ],
); // );
let (e1, e2) = (children[0], children[1]); // let (e1, e2) = (children[0], children[1]);
// Parent `e1` and `e2` to `parent`. // // Parent `e1` and `e2` to `parent`.
world.add_component(e1, Parent(parent)); // world.add_component(e1, Parent(parent));
world.add_component(e2, Parent(parent)); // world.add_component(e2, Parent(parent));
// Run the needed systems on it. // // Run the needed systems on it.
for system in hierarchy_maintenance_systems.iter() { // for system in hierarchy_maintenance_systems.iter() {
system.run(&mut world); // system.run(&mut world);
system.command_buffer_mut().write(&mut world); // system.command_buffer_mut().write(&mut world);
} // }
local_to_parent_system.run(&mut world); // local_to_parent_system.run(&mut world);
local_to_parent_system // local_to_parent_system
.command_buffer_mut() // .command_buffer_mut()
.write(&mut world); // .write(&mut world);
local_to_world_system.run(&mut world); // local_to_world_system.run(&mut world);
local_to_world_system.command_buffer_mut().write(&mut world); // local_to_world_system.command_buffer_mut().write(&mut world);
local_to_world_propagate_system.run(&mut world); // local_to_world_propagate_system.run(&mut world);
local_to_world_propagate_system // local_to_world_propagate_system
.command_buffer_mut() // .command_buffer_mut()
.write(&mut world); // .write(&mut world);
assert_eq!( // assert_eq!(
world.get_component::<LocalToWorld>(e1).unwrap().0, // world.get_component::<LocalToWorld>(e1).unwrap().0,
Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) // Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0))
* Mat4::from_translation(Vec3::new(0.0, 2.0, 0.0)) // * 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,
Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0)) // Mat4::from_translation(Vec3::new(1.0, 0.0, 0.0))
* Mat4::from_translation(Vec3::new(0.0, 0.0, 3.0)) // * Mat4::from_translation(Vec3::new(0.0, 0.0, 3.0))
); // );
} // }
} // }

View File

@ -242,106 +242,106 @@ 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}; // use crate::math::{Mat4, Quat, Vec3};
#[test] // #[test]
fn correct_world_transformation() { // fn correct_world_transformation() {
let _ = env_logger::builder().is_test(true).try_init(); // let _ = env_logger::builder().is_test(true).try_init();
let mut world = Universe::new().create_world(); // let mut world = Universe::new().create_world();
let system = build(&mut world); // let system = build(&mut world);
let ltw = LocalToWorld::identity(); // let ltw = LocalToWorld::identity();
let t = Translation::new(1.0, 2.0, 3.0); // let t = Translation::new(1.0, 2.0, 3.0);
let r = Rotation::from_euler_angles(1.0, 2.0, 3.0); // let r = Rotation::from_euler_angles(1.0, 2.0, 3.0);
let s = Scale(2.0); // let s = Scale(2.0);
let nus = NonUniformScale::new(1.0, 2.0, 3.0); // let nus = NonUniformScale::new(1.0, 2.0, 3.0);
// Add every combination of transform types. // // Add every combination of transform types.
let translation = *world.insert((), vec![(ltw, t)]).first().unwrap(); // let translation = *world.insert((), vec![(ltw, t)]).first().unwrap();
let rotation = *world.insert((), vec![(ltw, r)]).first().unwrap(); // let rotation = *world.insert((), vec![(ltw, r)]).first().unwrap();
let scale = *world.insert((), vec![(ltw, s)]).first().unwrap(); // let scale = *world.insert((), vec![(ltw, s)]).first().unwrap();
let non_uniform_scale = *world.insert((), vec![(ltw, nus)]).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_rotation = *world.insert((), vec![(ltw, t, r)]).first().unwrap();
let translation_and_scale = *world.insert((), vec![(ltw, t, s)]).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 translation_and_nus = *world.insert((), vec![(ltw, t, nus)]).first().unwrap();
let rotation_scale = *world.insert((), vec![(ltw, r, s)]).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 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_scale = *world.insert((), vec![(ltw, t, r, s)]).first().unwrap();
let translation_rotation_nus = *world.insert((), vec![(ltw, t, r, nus)]).first().unwrap(); // let translation_rotation_nus = *world.insert((), vec![(ltw, t, r, nus)]).first().unwrap();
// Run the system // // Run the system
system.run(&mut world); // system.run(&mut world);
system.command_buffer_mut().write(&mut world); // system.command_buffer_mut().write(&mut world);
// 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,
Mat4::from_translation(t.0) // Mat4::from_translation(t.0)
); // );
assert_eq!( // assert_eq!(
world.get_component::<LocalToWorld>(rotation).unwrap().0, // world.get_component::<LocalToWorld>(rotation).unwrap().0,
Mat4::from_quat(r.0) // Mat4::from_quat(r.0)
); // );
assert_eq!( // assert_eq!(
world.get_component::<LocalToWorld>(scale).unwrap().0, // world.get_component::<LocalToWorld>(scale).unwrap().0,
Mat4::from_scale(Vec3::new(s.0, s.0, 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,
Mat4::from_scale(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,
Mat4::from_rotation_translation(r.0, t.0) // 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,
Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), Quat::default(), t.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,
Mat4::from_scale_rotation_translation(nus.0, Quat::default(), t.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,
Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, Vec3::default()) // 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,
Mat4::from_scale_rotation_translation(nus.0, r.0, Vec3::default()) // 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,
Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, s.0), r.0, t.0) // Mat4::from_scale_rotation_translation(Vec3::new(s.0, s.0, 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,
Mat4::from_scale_rotation_translation(nus.0, r.0, t.0) // Mat4::from_scale_rotation_translation(nus.0, r.0, t.0)
); // );
} // }
} // }