use crate::runner::{
DRAW_CUBE_POOL, DRAW_LINES_POOL, DRAW_MATERIAL, DRAW_SPHERE_POOL, lookup_named, register_named,
};
use nightshade::prelude::nalgebra_glm::Quat;
use nightshade::prelude::*;
pub fn draw_cube(world: &mut World, position: Vec3, scale: Vec3, color: [f32; 4]) {
push_instance(
world,
DRAW_CUBE_POOL,
InstanceTransform::new(position, Quat::identity(), scale),
color,
);
}
pub fn draw_sphere(world: &mut World, position: Vec3, radius: f32, color: [f32; 4]) {
push_instance(
world,
DRAW_SPHERE_POOL,
InstanceTransform::new(
position,
Quat::identity(),
Vec3::new(radius, radius, radius),
),
color,
);
}
pub fn draw_line(world: &mut World, start: Vec3, end: Vec3, color: [f32; 4]) {
let Some(entity) = lookup_named(world, DRAW_LINES_POOL) else {
return;
};
if let Some(lines) = world.core.get_lines_mut(entity) {
lines.push(Line {
start,
end,
color: Vec4::new(color[0], color[1], color[2], color[3]),
});
}
}
pub fn draw_text_3d(world: &mut World, text: &str, position: Vec3) {
for (index, name) in TEXT_POOL_NAMES.iter().enumerate() {
match lookup_named(world, name) {
Some(entity) => {
let parked = world
.core
.get_local_transform(entity)
.is_some_and(|transform| transform.translation.y < PARKED_THRESHOLD);
if parked || index == TEXT_POOL_NAMES.len() - 1 {
crate::text::set_text(world, entity, text);
crate::placement::set_position(world, entity, position);
return;
}
}
None => {
let entity = crate::text::spawn_label(world, text, position);
world.core.add_components(entity, NAME);
world.core.set_name(entity, Name(name.to_string()));
register_named(world, name, entity);
return;
}
}
}
}
pub fn spawn_lines(world: &mut World, lines: Vec<Line>) -> Entity {
let entity = spawn_entities(world, LINES, 1)[0];
world.core.set_lines(entity, Lines::new(lines));
entity
}
fn push_instance(
world: &mut World,
pool_name: &str,
transform: InstanceTransform,
color: [f32; 4],
) {
let Some(entity) = lookup_named(world, pool_name) else {
return;
};
if let Some(instanced) = world.core.get_instanced_mesh_mut(entity) {
instanced.add_instance(transform);
let index = instanced.instance_count() - 1;
instanced.set_instance_tint(index, color);
}
}
pub(crate) fn initialize_draw_pools(world: &mut World) {
crate::scene::ensure_primitive_mesh(world, "Cube");
crate::scene::ensure_primitive_mesh(world, "Sphere");
material_registry_insert(
&mut world.resources.assets.material_registry,
DRAW_MATERIAL.to_string(),
Material::default(),
);
if let Some((index, _)) = registry_lookup_index(
&world.resources.assets.material_registry.registry,
DRAW_MATERIAL,
) {
registry_add_reference(
&mut world.resources.assets.material_registry.registry,
index,
);
}
let cube_pool = spawn_instanced_mesh_with_material(world, "Cube", Vec::new(), DRAW_MATERIAL);
world
.core
.set_name(cube_pool, Name(DRAW_CUBE_POOL.to_string()));
register_named(world, DRAW_CUBE_POOL, cube_pool);
let sphere_pool =
spawn_instanced_mesh_with_material(world, "Sphere", Vec::new(), DRAW_MATERIAL);
world
.core
.set_name(sphere_pool, Name(DRAW_SPHERE_POOL.to_string()));
register_named(world, DRAW_SPHERE_POOL, sphere_pool);
let lines_pool = spawn_entities(world, LINES | NAME, 1)[0];
world
.core
.set_name(lines_pool, Name(DRAW_LINES_POOL.to_string()));
world.core.set_lines(lines_pool, Lines::new(Vec::new()));
register_named(world, DRAW_LINES_POOL, lines_pool);
}
pub(crate) fn clear_draw_pools(world: &mut World) {
for pool_name in [DRAW_CUBE_POOL, DRAW_SPHERE_POOL] {
if let Some(entity) = lookup_named(world, pool_name)
&& let Some(instanced) = world.core.get_instanced_mesh_mut(entity)
&& instanced.instance_count() > 0
{
instanced.clear_instances();
}
}
if let Some(entity) = lookup_named(world, DRAW_LINES_POOL)
&& let Some(lines) = world.core.get_lines_mut(entity)
&& !lines.lines.is_empty()
{
lines.clear();
}
for name in TEXT_POOL_NAMES.iter() {
let Some(entity) = lookup_named(world, name) else {
break;
};
let used = world
.core
.get_local_transform(entity)
.is_some_and(|transform| transform.translation.y > PARKED_THRESHOLD);
if used {
crate::placement::set_position(world, entity, Vec3::new(0.0, -100000.0, 0.0));
}
}
}
const PARKED_THRESHOLD: f32 = -90000.0;
const TEXT_POOL_NAMES: [&str; 64] = [
"api::draw::text::0",
"api::draw::text::1",
"api::draw::text::2",
"api::draw::text::3",
"api::draw::text::4",
"api::draw::text::5",
"api::draw::text::6",
"api::draw::text::7",
"api::draw::text::8",
"api::draw::text::9",
"api::draw::text::10",
"api::draw::text::11",
"api::draw::text::12",
"api::draw::text::13",
"api::draw::text::14",
"api::draw::text::15",
"api::draw::text::16",
"api::draw::text::17",
"api::draw::text::18",
"api::draw::text::19",
"api::draw::text::20",
"api::draw::text::21",
"api::draw::text::22",
"api::draw::text::23",
"api::draw::text::24",
"api::draw::text::25",
"api::draw::text::26",
"api::draw::text::27",
"api::draw::text::28",
"api::draw::text::29",
"api::draw::text::30",
"api::draw::text::31",
"api::draw::text::32",
"api::draw::text::33",
"api::draw::text::34",
"api::draw::text::35",
"api::draw::text::36",
"api::draw::text::37",
"api::draw::text::38",
"api::draw::text::39",
"api::draw::text::40",
"api::draw::text::41",
"api::draw::text::42",
"api::draw::text::43",
"api::draw::text::44",
"api::draw::text::45",
"api::draw::text::46",
"api::draw::text::47",
"api::draw::text::48",
"api::draw::text::49",
"api::draw::text::50",
"api::draw::text::51",
"api::draw::text::52",
"api::draw::text::53",
"api::draw::text::54",
"api::draw::text::55",
"api::draw::text::56",
"api::draw::text::57",
"api::draw::text::58",
"api::draw::text::59",
"api::draw::text::60",
"api::draw::text::61",
"api::draw::text::62",
"api::draw::text::63",
];