Files
tli/scripts/globals/debug_draw.gd

155 lines
3.7 KiB
GDScript

extends CanvasLayer
const LINE_WIDTH: float = 2
const MARKER_RADIUS: float = 0.2
const CIRCLE_RADIUS: float = 3
const DEFAULT_COLOR: Color = Color.RED
var enabled: bool = false
var control: Control = Control.new()
var label: RichTextLabel = RichTextLabel.new()
var vectors_to_draw: Array[Dictionary] = []
var markers_to_draw: Array[Dictionary] = []
var circles_to_draw: Array[Dictionary] = []
var text_to_draw: PackedStringArray = []
@onready var camera: Camera3D = get_viewport().get_camera_3d()
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
layer = 999
enabled = false
control.draw.connect(_on_control_draw)
control.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(control)
label.set_anchors_preset(Control.PRESET_FULL_RECT)
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(label)
func _process(_delta: float) -> void:
if not enabled:
return
control.queue_redraw()
text('fps: ' + str(Performance.get_monitor(Performance.TIME_FPS)))
text('draw calls: ' + str(Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME)))
func _input(event: InputEvent) -> void:
if event.is_action_pressed("toggle_debug"):
enabled = not enabled
visible = enabled
vectors_to_draw.clear()
func text(body: String) -> void:
if not enabled:
return
text_to_draw.append(body)
func vector(from: Vector3, to: Vector3, color: Color = DEFAULT_COLOR) -> void:
if not enabled:
return
vectors_to_draw.append({"from": from, "to": to, "color": color})
func marker(
pos: Vector3,
radius: float = MARKER_RADIUS,
color: Color = DEFAULT_COLOR,
) -> void:
if not enabled:
return
markers_to_draw.append({"pos": pos, "radius": radius, "color": color})
func circle(pos: Vector3, color: Color = DEFAULT_COLOR) -> void:
if not enabled:
return
circles_to_draw.append({"pos": pos, "color": color})
func _unproject(pos: Vector3) -> Vector2:
return camera.unproject_position(pos)
func _draw_text() -> void:
label.text = '\n'.join(text_to_draw)
func _draw_vector(from: Vector3, to: Vector3, color: Color) -> void:
var start := _unproject(from)
var end := _unproject(to)
control.draw_line(start, end, color, LINE_WIDTH)
_draw_triangle(end, start.direction_to(end), 5, color)
func _draw_triangle(
pos: Vector2,
dir: Vector2,
size: float,
color: Color,
) -> void:
var a := pos + dir * size
var b := pos + dir.rotated(2 * PI / 3) * size
var c := pos + dir.rotated(4 * PI / 3) * size
var points := PackedVector2Array([a, b, c])
control.draw_polygon(points, PackedColorArray([color]))
func _draw_marker(pos: Vector3, radius: float, color: Color) -> void:
var x_start := _unproject(pos + (Vector3.LEFT * radius))
var x_end := _unproject(pos + (Vector3.RIGHT * radius))
control.draw_line(x_start, x_end, color, LINE_WIDTH)
var y_start := _unproject(pos + (Vector3.UP * radius))
var y_end := _unproject(pos + (Vector3.DOWN * radius))
control.draw_line(y_start, y_end, color, LINE_WIDTH)
var z_start := _unproject(pos + (Vector3.FORWARD * radius))
var z_end := _unproject(pos + (Vector3.BACK * radius))
control.draw_line(z_start, z_end, color, LINE_WIDTH)
func _draw_circle(pos: Vector3, color: Color) -> void:
var point := _unproject(pos)
control.draw_circle(point, CIRCLE_RADIUS, color)
func _on_control_draw() -> void:
if not enabled:
return
for v in vectors_to_draw:
_draw_vector(
v["from"] as Vector3,
v["to"] as Vector3,
v["color"] as Color,
)
vectors_to_draw.clear()
for v in markers_to_draw:
_draw_marker(
v["pos"] as Vector3,
v["radius"] as float,
v["color"] as Color,
)
markers_to_draw.clear()
for v in circles_to_draw:
_draw_circle(v["pos"] as Vector3, v["color"] as Color)
circles_to_draw.clear()
_draw_text()
text_to_draw.clear()