import { BaseMaterial3D, Color, ImmediateMesh, Mesh, MeshInstance3D, Node, Node3D, PackedVector3Array, StandardMaterial3D, Vector3 } from 'godot' function createDefaultMaterial(): StandardMaterial3D { const material = new StandardMaterial3D() material.shading_mode = BaseMaterial3D.ShadingMode.SHADING_MODE_UNSHADED material.no_depth_test = true material.vertex_color_use_as_albedo = true material.transparency = BaseMaterial3D.Transparency.TRANSPARENCY_DISABLED material.cull_mode = BaseMaterial3D.CullMode.CULL_DISABLED return material } class PooledMeshInstance { in_use: boolean = false instance: MeshInstance3D constructor(material: StandardMaterial3D) { this.instance = new MeshInstance3D() this.instance.material_override = material } } class MeshPool { target: Node pool: PooledMeshInstance[] default_material: StandardMaterial3D constructor(target: Node, initial: number = 10) { this.pool = [] this.target = target this.default_material = createDefaultMaterial() for (let i = 0; i < initial; i++) { this.create() } } create() { const instance = new PooledMeshInstance(this.default_material) instance.instance.mesh = new ImmediateMesh() this.pool.push(instance) this.target.add_child(instance.instance) return instance } get() { const next = this.pool.find(x => !x.in_use) if (next) { next.in_use = true return next } else { const instance = this.create() instance.in_use = true return instance } } release(instance: PooledMeshInstance) { instance.in_use = false } } export default class DebugDraw extends Node { private static _inst: DebugDraw static get instance() { return DebugDraw._inst } pool!: MeshPool _ready(): void { DebugDraw._inst = this this.pool = new MeshPool(this as Node) } static draw_line(begin: Vector3, end: Vector3, color: Color = Color.CYAN) { DebugDraw.draw_lines(new PackedVector3Array([begin, end]), color) } static draw_lines(points: PackedVector3Array, color: Color = Color.CYAN) { DebugDraw.instance._draw_lines(points, color) } _draw_lines(points: PackedVector3Array, color: Color = Color.CYAN) { const instance = this.pool.get() const mesh = instance.instance.mesh as ImmediateMesh mesh.clear_surfaces() mesh.surface_begin(Mesh.PrimitiveType.PRIMITIVE_LINES) mesh.surface_set_color(color) const len = points.size() for (let i = 0; i < len; i++) { mesh.surface_add_vertex(points.get_indexed(i)) } mesh.surface_end() this.pool.release(instance) } }