nightshade 0.13.0

A cross-platform data-oriented game engine.
Documentation
use crate::ecs::world::{
    INSTANCED_MESH, LOCAL_TRANSFORM_DIRTY, PARENT, RENDER_MESH, SPRITE, World,
    components::GlobalTransform,
};

pub fn mark_local_transform_dirty(world: &mut World, entity: freecs::Entity) {
    if world.resources.children_cache.is_empty() && world.core.query_entities(PARENT).count() > 0 {
        world.validate_and_rebuild_children_cache();
    }

    if !world.core.entity_has_components(entity, PARENT)
        && !world.resources.children_cache.contains_key(&entity)
    {
        let new_global = match world.core.get_local_transform(entity) {
            Some(local_transform) => local_transform.as_matrix(),
            None => nalgebra_glm::Mat4::identity(),
        };
        if let Some(global_transform) = world.core.get_global_transform_mut(entity) {
            *global_transform = GlobalTransform(new_global);
        }
        if world
            .core
            .entity_has_components(entity, LOCAL_TRANSFORM_DIRTY)
        {
            world.core.remove_local_transform_dirty(entity);
        }
        if (world.core.entity_has_components(entity, RENDER_MESH)
            || world.core.entity_has_components(entity, INSTANCED_MESH))
            && !world.sprite2d.entity_has_components(entity, SPRITE)
        {
            world
                .resources
                .mesh_render_state
                .mark_transform_dirty(entity);
        }
        return;
    }

    let mut stack = vec![entity];

    while let Some(current) = stack.pop() {
        world.resources.transform_dirty_entities.push(current);

        if let Some(children) = world.resources.children_cache.get(&current) {
            for &child in children {
                stack.push(child);
            }
        }
    }
}