use crate::ecs::EditorWorld;
use nightshade::prelude::*;
const TAG_BRUSH: &str = "greybox_brush";
const TAG_FINAL: &str = "greybox_final";
pub fn set_mode(editor_world: &mut EditorWorld, world: &mut World, enabled: bool) {
editor_world.resources.greybox.enabled = enabled;
if enabled {
editor_world.resources.snap.enabled = true;
let tab_bar = editor_world.resources.ui_handles.tree.tab_bar;
ui_tab_bar_set_value(world, tab_bar, 1);
}
}
pub fn tag_brush(world: &mut World, entity: Entity) {
let tags = world.resources.entities.tags.entry(entity).or_default();
if !tags.iter().any(|tag| tag == TAG_BRUSH) {
tags.push(TAG_BRUSH.to_string());
}
}
#[cfg(not(target_arch = "wasm32"))]
fn tag_final(world: &mut World, entity: Entity) {
let tags = world.resources.entities.tags.entry(entity).or_default();
if !tags.iter().any(|tag| tag == TAG_FINAL) {
tags.push(TAG_FINAL.to_string());
}
}
pub fn mark_selection_as_brush(editor_world: &mut EditorWorld, world: &mut World) {
let mut targets: Vec<Entity> = editor_world.resources.ui.selected_entities.clone();
if targets.is_empty()
&& let Some(entity) = editor_world.resources.ui.selected_entity
{
targets.push(entity);
}
for entity in targets {
tag_brush(world, entity);
}
}
pub fn toggle_show_final(editor_world: &mut EditorWorld, world: &mut World) {
let next = !editor_world.resources.greybox.show_final;
editor_world.resources.greybox.show_final = next;
apply_brush_visibility(world, next);
}
fn ensure_visibility(world: &mut World, entity: Entity, visible: bool) {
world.core.add_components(entity, VISIBILITY);
world.core.set_visibility(entity, Visibility { visible });
}
fn apply_brush_visibility(world: &mut World, show_final: bool) {
let brushes: Vec<Entity> = world
.resources
.entities
.tags
.iter()
.filter(|(_, tags)| tags.iter().any(|tag| tag == TAG_BRUSH))
.map(|(entity, _)| *entity)
.collect();
for brush in brushes {
let descendants = nightshade::ecs::transform::queries::query_descendants(world, brush);
let final_child = descendants.into_iter().find(|descendant| {
world
.resources
.entities
.tags
.get(descendant)
.map(|tags| tags.iter().any(|tag| tag == TAG_FINAL))
.unwrap_or(false)
});
if let Some(final_child) = final_child {
ensure_visibility(world, brush, !show_final);
ensure_visibility(world, final_child, show_final);
}
}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn upgrade_selection_with_gltf(editor_world: &mut EditorWorld, world: &mut World) {
let Some(brush) = editor_world.resources.ui.selected_entity else {
return;
};
let Some(path) = rfd::FileDialog::new()
.add_filter("glTF", &["glb", "gltf"])
.set_title("Pick a glTF to upgrade this brush")
.pick_file()
else {
return;
};
let Ok(bytes) = std::fs::read(&path) else {
return;
};
let Ok(mut result) = nightshade::ecs::prefab::import_gltf_from_bytes(&bytes) else {
return;
};
tag_brush(world, brush);
let prefabs = std::mem::take(&mut result.prefabs);
let animations = result.animations.clone();
let skins = result.skins.clone();
nightshade::ecs::loading::queue_gltf_load(world, &mut result);
for prefab in &prefabs {
let child = nightshade::ecs::prefab::spawn_prefab_with_skins(
world,
prefab,
&animations,
&skins,
Vec3::zeros(),
);
world.core.add_components(child, IGNORE_PARENT_SCALE);
update_parent(world, child, Some(Parent(Some(brush))));
if let Some(transform) = world.core.get_local_transform_mut(child) {
transform.translation = Vec3::zeros();
}
mark_local_transform_dirty(world, child);
tag_final(world, child);
crate::scene_writeback::register_subtree(
&mut editor_world.resources.project,
&mut editor_world.resources.editor_scene,
world,
child,
);
}
editor_world.resources.greybox.show_final = true;
apply_brush_visibility(world, true);
}
#[cfg(target_arch = "wasm32")]
pub fn upgrade_selection_with_gltf(_editor_world: &mut EditorWorld, _world: &mut World) {}