use crate::runner::{
DRAW_CUBE_POOL, DRAW_LINES_POOL, DRAW_MATERIAL, DRAW_SPHERE_POOL, lookup_named, register_named,
};
use nightshade::ecs::mesh::components::{create_cube_mesh, create_sphere_mesh};
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 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) {
ensure_pool_mesh(world, "Cube");
ensure_pool_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();
}
}
fn ensure_pool_mesh(world: &mut World, mesh_name: &str) {
if !world
.resources
.assets
.mesh_cache
.registry
.name_to_index
.contains_key(mesh_name)
{
let mesh = match mesh_name {
"Cube" => create_cube_mesh(),
_ => create_sphere_mesh(1.0, 16),
};
mesh_cache_insert(
&mut world.resources.assets.mesh_cache,
mesh_name.to_string(),
mesh,
);
}
if let Some((index, _)) =
registry_lookup_index(&world.resources.assets.mesh_cache.registry, mesh_name)
{
registry_add_reference(&mut world.resources.assets.mesh_cache.registry, index);
}
}