nightshade 0.13.2

A cross-platform data-oriented game engine.
Documentation
use crate::prelude::*;

use super::{GizmoConfig, GizmoState};

pub fn destroy_gizmo(world: &mut World, gizmo: &GizmoState) {
    let descendants = crate::ecs::transform::queries::query_descendants(world, gizmo.root);
    let all_entities: Vec<Entity> = std::iter::once(gizmo.root)
        .chain(descendants.iter().copied())
        .collect();

    for &entity in &all_entities {
        if world
            .core
            .entity_has_components(entity, crate::ecs::world::RENDER_MESH)
        {
            if let Some(material_ref) = world.core.get_material_ref(entity) {
                let material_name = material_ref.name.clone();
                if let Some(&index) = world
                    .resources
                    .material_registry
                    .registry
                    .name_to_index
                    .get(&material_name)
                {
                    world
                        .resources
                        .material_registry
                        .registry
                        .remove_reference(index);
                }
            }
            world
                .resources
                .mesh_render_state
                .mark_entity_removed(entity);
        }
    }

    world.despawn_entities(&descendants);
    world.despawn_entities(&[gizmo.root]);
}

pub fn is_gizmo_entity(world: &World, gizmo: &GizmoState, entity: Entity) -> bool {
    if entity == gizmo.root {
        return true;
    }
    let descendants = crate::ecs::transform::queries::query_descendants(world, gizmo.root);
    descendants.contains(&entity)
}

pub fn update_gizmo_transform(
    world: &mut World,
    gizmo: &GizmoState,
    target_position: Vec3,
    target_rotation: Quat,
    camera_distance: f32,
) {
    let config = GizmoConfig::default();
    let scale = (camera_distance * config.scale_factor)
        .max(config.min_scale)
        .min(config.max_scale);
    if let Some(transform) = world.core.get_local_transform(gizmo.root) {
        let mut new_transform = *transform;
        new_transform.translation = target_position;
        new_transform.scale = nalgebra_glm::vec3(scale, scale, scale);
        new_transform.rotation = target_rotation;
        world.assign_local_transform(gizmo.root, new_transform);
    }
}

pub(super) fn set_entity_visible_recursive(world: &mut World, entity: Entity, visible: bool) {
    if let Some(vis) = world.core.get_visibility_mut(entity) {
        vis.visible = visible;
    }

    let descendants: Vec<Entity> = crate::ecs::transform::queries::query_descendants(world, entity)
        .into_iter()
        .collect();

    for descendant in descendants {
        if let Some(vis) = world.core.get_visibility_mut(descendant) {
            vis.visible = visible;
        }
    }
}

pub fn show_entities(world: &mut World, entities: &[Entity]) {
    for &entity in entities {
        if let Some(visibility) = world.core.get_visibility_mut(entity) {
            visibility.visible = true;
        }
    }
}

pub fn hide_entities(world: &mut World, entities: &[Entity]) {
    for &entity in entities {
        if let Some(visibility) = world.core.get_visibility_mut(entity) {
            visibility.visible = false;
        }
    }
}