signalis/src/debug_draw.ts
2025-04-30 21:51:53 -05:00

104 lines
2.6 KiB
TypeScript

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)
}
}