resonance 0.1.0

A modular game engine. Heavy work in progress.
Documentation

use super::components::{GlobalTransform, Transform};
use super::hierarchy::{Children, Parent};
use bevy_ecs::prelude::*;

pub fn propagate_transforms(
    mut root_query: Query<
        (Entity, &Transform, &mut GlobalTransform, Option<&Children>),
        Without<Parent>,
    >,
    mut child_query: Query<
        (Entity, &Transform, &mut GlobalTransform, &Parent, Option<&Children>),
    >,
    children_query: Query<&Children>,
) {

    for (_entity, transform, mut global_transform, children) in root_query.iter_mut() {
        *global_transform = GlobalTransform::from_transform(transform);

        if let Some(children) = children {
            for &child in children.iter() {
                propagate_recursive(child, global_transform.as_ref(), &mut child_query, &children_query);
            }
        }
    }
}

fn propagate_recursive(
    entity: Entity,
    parent_global: &GlobalTransform,
    child_query: &mut Query<
        (Entity, &Transform, &mut GlobalTransform, &Parent, Option<&Children>),
    >,
    children_query: &Query<&Children>,
) {

    let (new_global, children_list) = if let Ok((_entity, transform, mut global_transform, _parent, _)) = child_query.get_mut(entity) {
        *global_transform = GlobalTransform::from_transform_and_parent(transform, parent_global);
        let new_global = *global_transform;

        let children_list: Vec<Entity> = if let Ok(children) = children_query.get(entity) {
            children.iter().copied().collect()
        } else {
            Vec::new()
        };

        (new_global, children_list)
    } else {
        return;
    };

    for child in children_list {
        propagate_recursive(child, &new_global, child_query, children_query);
    }
}

pub fn sync_simple_transforms(
    mut query: Query<(&Transform, &mut GlobalTransform), (Without<Parent>, Without<Children>)>,
) {
    for (transform, mut global_transform) in query.iter_mut() {
        *global_transform = GlobalTransform::from_transform(transform);
    }
}