2023-08-24 10:54:59 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2022-2023 Blender Authors
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2022-08-08 19:01:38 +02:00
|
|
|
|
2024-10-04 15:48:22 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
2025-09-25 10:57:02 +02:00
|
|
|
#include "draw_debug_infos.hh"
|
2024-11-13 12:32:39 +01:00
|
|
|
|
|
|
|
|
SHADER_LIBRARY_CREATE_INFO(draw_debug_draw)
|
|
|
|
|
|
2022-08-08 19:01:38 +02:00
|
|
|
/**
|
|
|
|
|
* Debugging drawing library
|
|
|
|
|
*
|
|
|
|
|
* Quick way to draw debug geometry. All input should be in world space and
|
|
|
|
|
* will be rendered in the default view. No additional setup required.
|
2023-08-19 17:13:05 +10:00
|
|
|
*/
|
2022-08-08 19:01:38 +02:00
|
|
|
|
2023-08-20 16:48:46 +02:00
|
|
|
#ifdef DRW_DEBUG_DRAW
|
|
|
|
|
|
2022-08-08 19:01:38 +02:00
|
|
|
/** Global switch option. */
|
|
|
|
|
bool drw_debug_draw_enable = true;
|
2025-04-14 13:46:41 +02:00
|
|
|
# define drw_debug_default_color float4(1.0f, 0.0f, 0.0f, 1.0f)
|
2025-04-09 21:37:23 +02:00
|
|
|
# define drw_debug_default_lifetime 1
|
|
|
|
|
# define drw_debug_persistent_lifetime (~0u)
|
2022-08-08 19:01:38 +02:00
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2022-08-15 13:28:12 +02:00
|
|
|
/** \name Internals
|
2022-08-08 19:01:38 +02:00
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
uint drw_debug_start_draw(uint v_needed)
|
|
|
|
|
{
|
2025-04-09 21:37:23 +02:00
|
|
|
uint vertid = atomicAdd(drw_debug_draw_v_count(drw_debug_lines_buf), v_needed);
|
2022-08-08 19:01:38 +02:00
|
|
|
return vertid;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_line(inout uint vertid, float3 v1, float3 v2, uint v_color, uint lifetime)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
2025-04-09 21:37:23 +02:00
|
|
|
uint out_line_id = vertid / 2u;
|
|
|
|
|
drw_debug_lines_buf[out_line_id + drw_debug_draw_offset] = debug_line_make(floatBitsToUint(v1.x),
|
|
|
|
|
floatBitsToUint(v1.y),
|
|
|
|
|
floatBitsToUint(v1.z),
|
|
|
|
|
floatBitsToUint(v2.x),
|
|
|
|
|
floatBitsToUint(v2.y),
|
|
|
|
|
floatBitsToUint(v2.z),
|
|
|
|
|
v_color,
|
|
|
|
|
lifetime);
|
|
|
|
|
vertid += 2;
|
2022-08-08 19:01:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name API
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Draw a line.
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_line(float3 v1, float3 v2, float4 v_color, uint lifetime)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
|
|
|
|
if (!drw_debug_draw_enable) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const uint v_needed = 2;
|
|
|
|
|
uint vertid = drw_debug_start_draw(v_needed);
|
|
|
|
|
if (vertid + v_needed < DRW_DEBUG_DRAW_VERT_MAX) {
|
2025-04-09 21:37:23 +02:00
|
|
|
drw_debug_line(vertid, v1, v2, debug_color_pack(v_color), lifetime);
|
2022-08-08 19:01:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_line(float3 v1, float3 v2, float4 v_color)
|
2025-04-09 21:37:23 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_line(v1, v2, v_color, drw_debug_default_lifetime);
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_line(float3 v1, float3 v2)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_line(v1, v2, drw_debug_default_color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Draw a quad contour.
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_quad(float3 v1, float3 v2, float3 v3, float3 v4, float4 v_color, uint lifetime)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
|
|
|
|
if (!drw_debug_draw_enable) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const uint v_needed = 8;
|
|
|
|
|
uint vertid = drw_debug_start_draw(v_needed);
|
|
|
|
|
if (vertid + v_needed < DRW_DEBUG_DRAW_VERT_MAX) {
|
2025-04-09 21:37:23 +02:00
|
|
|
uint pcolor = debug_color_pack(v_color);
|
|
|
|
|
drw_debug_line(vertid, v1, v2, pcolor, drw_debug_default_lifetime);
|
|
|
|
|
drw_debug_line(vertid, v2, v3, pcolor, drw_debug_default_lifetime);
|
|
|
|
|
drw_debug_line(vertid, v3, v4, pcolor, drw_debug_default_lifetime);
|
|
|
|
|
drw_debug_line(vertid, v4, v1, pcolor, drw_debug_default_lifetime);
|
2022-08-08 19:01:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_quad(float3 v1, float3 v2, float3 v3, float3 v4, float4 v_color)
|
2025-04-09 21:37:23 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_quad(v1, v2, v3, v4, v_color, drw_debug_default_lifetime);
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_quad(float3 v1, float3 v2, float3 v3, float3 v4)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_quad(v1, v2, v3, v4, drw_debug_default_color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Draw a point as octahedron wireframe.
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_point(float3 p, float radius, float4 v_color, uint lifetime)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
|
|
|
|
if (!drw_debug_draw_enable) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 c = float3(radius, -radius, 0);
|
|
|
|
|
float3 v1 = p + c.xzz;
|
|
|
|
|
float3 v2 = p + c.zxz;
|
|
|
|
|
float3 v3 = p + c.yzz;
|
|
|
|
|
float3 v4 = p + c.zyz;
|
|
|
|
|
float3 v5 = p + c.zzx;
|
|
|
|
|
float3 v6 = p + c.zzy;
|
2022-08-08 19:01:38 +02:00
|
|
|
|
|
|
|
|
const uint v_needed = 12 * 2;
|
|
|
|
|
uint vertid = drw_debug_start_draw(v_needed);
|
|
|
|
|
if (vertid + v_needed < DRW_DEBUG_DRAW_VERT_MAX) {
|
2025-04-09 21:37:23 +02:00
|
|
|
uint pcolor = debug_color_pack(v_color);
|
|
|
|
|
drw_debug_line(vertid, v1, v2, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v2, v3, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v3, v4, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v4, v1, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v1, v5, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v2, v5, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v3, v5, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v4, v5, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v1, v6, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v2, v6, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v3, v6, pcolor, lifetime);
|
|
|
|
|
drw_debug_line(vertid, v4, v6, pcolor, lifetime);
|
2022-08-08 19:01:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_point(float3 p, float radius, float4 v_color)
|
2025-04-09 21:37:23 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_point(p, radius, v_color, drw_debug_default_lifetime);
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_point(float3 p, float radius)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_point(p, radius, drw_debug_default_color);
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_point(float3 p)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
drw_debug_point(p, 0.01f);
|
2022-08-08 19:01:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Draw a sphere wireframe as 3 axes circle.
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_sphere(float3 p, float radius, float4 v_color, uint lifetime)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
|
|
|
|
if (!drw_debug_draw_enable) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const int circle_resolution = 16;
|
|
|
|
|
const uint v_needed = circle_resolution * 2 * 3;
|
|
|
|
|
uint vertid = drw_debug_start_draw(v_needed);
|
|
|
|
|
if (vertid + v_needed < DRW_DEBUG_DRAW_VERT_MAX) {
|
2025-04-09 21:37:23 +02:00
|
|
|
uint pcolor = debug_color_pack(v_color);
|
2022-08-08 19:01:38 +02:00
|
|
|
for (int axis = 0; axis < 3; axis++) {
|
|
|
|
|
for (int edge = 0; edge < circle_resolution; edge++) {
|
2025-04-11 18:28:45 +02:00
|
|
|
float angle1 = (2.0f * 3.141592f) * float(edge + 0) / float(circle_resolution);
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 p1 = float3(cos(angle1), sin(angle1), 0.0f) * radius;
|
|
|
|
|
p1 = float3(p1[(0 + axis) % 3], p1[(1 + axis) % 3], p1[(2 + axis) % 3]);
|
2022-08-08 19:01:38 +02:00
|
|
|
|
2025-04-11 18:28:45 +02:00
|
|
|
float angle2 = (2.0f * 3.141592f) * float(edge + 1) / float(circle_resolution);
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 p2 = float3(cos(angle2), sin(angle2), 0.0f) * radius;
|
|
|
|
|
p2 = float3(p2[(0 + axis) % 3], p2[(1 + axis) % 3], p2[(2 + axis) % 3]);
|
2022-08-08 19:01:38 +02:00
|
|
|
|
2025-04-09 21:37:23 +02:00
|
|
|
drw_debug_line(vertid, p + p1, p + p2, pcolor, lifetime);
|
2022-08-08 19:01:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_sphere(float3 p, float radius, float4 v_color)
|
2025-04-09 21:37:23 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_sphere(p, radius, v_color, drw_debug_default_lifetime);
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_sphere(float3 p, float radius)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_sphere(p, radius, drw_debug_default_color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Draw a matrix transformation as 3 colored axes.
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_matrix(float4x4 mat, uint lifetime)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 p[4] = float4_array(
|
|
|
|
|
float4(0, 0, 0, 1), float4(1, 0, 0, 1), float4(0, 1, 0, 1), float4(0, 0, 1, 1));
|
2022-08-08 19:01:38 +02:00
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
p[i] = mat * p[i];
|
|
|
|
|
p[i].xyz /= p[i].w;
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
drw_debug_line(p[0].xyz, p[0].xyz, float4(1, 0, 0, 1), lifetime);
|
|
|
|
|
drw_debug_line(p[0].xyz, p[1].xyz, float4(0, 1, 0, 1), lifetime);
|
|
|
|
|
drw_debug_line(p[0].xyz, p[2].xyz, float4(0, 0, 1, 1), lifetime);
|
2022-08-08 19:01:38 +02:00
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_matrix(float4x4 mat)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
2025-04-09 21:37:23 +02:00
|
|
|
drw_debug_matrix(mat, drw_debug_default_lifetime);
|
2022-08-08 19:01:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Draw a matrix as a 2 units length bounding box, centered on origin.
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_matrix_as_bbox(float4x4 mat, float4 v_color, uint lifetime)
|
|
|
|
|
{
|
|
|
|
|
float4 p[8] = float4_array(float4(-1, -1, -1, 1),
|
|
|
|
|
float4(1, -1, -1, 1),
|
|
|
|
|
float4(1, 1, -1, 1),
|
|
|
|
|
float4(-1, 1, -1, 1),
|
|
|
|
|
float4(-1, -1, 1, 1),
|
|
|
|
|
float4(1, -1, 1, 1),
|
|
|
|
|
float4(1, 1, 1, 1),
|
|
|
|
|
float4(-1, 1, 1, 1));
|
2022-08-08 19:01:38 +02:00
|
|
|
for (int i = 0; i < 8; i++) {
|
|
|
|
|
p[i] = mat * p[i];
|
|
|
|
|
p[i].xyz /= p[i].w;
|
|
|
|
|
}
|
2025-04-09 21:37:23 +02:00
|
|
|
drw_debug_quad(p[0].xyz, p[1].xyz, p[2].xyz, p[3].xyz, v_color, lifetime);
|
|
|
|
|
drw_debug_line(p[0].xyz, p[4].xyz, v_color, lifetime);
|
|
|
|
|
drw_debug_line(p[1].xyz, p[5].xyz, v_color, lifetime);
|
|
|
|
|
drw_debug_line(p[2].xyz, p[6].xyz, v_color, lifetime);
|
|
|
|
|
drw_debug_line(p[3].xyz, p[7].xyz, v_color, lifetime);
|
|
|
|
|
drw_debug_quad(p[4].xyz, p[5].xyz, p[6].xyz, p[7].xyz, v_color, lifetime);
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_matrix_as_bbox(float4x4 mat, float4 v_color)
|
2025-04-09 21:37:23 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_matrix_as_bbox(mat, v_color, drw_debug_default_lifetime);
|
2022-08-08 19:01:38 +02:00
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
void drw_debug_matrix_as_bbox(float4x4 mat)
|
2022-08-08 19:01:38 +02:00
|
|
|
{
|
|
|
|
|
drw_debug_matrix_as_bbox(mat, drw_debug_default_color);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-20 16:48:46 +02:00
|
|
|
#endif
|
|
|
|
|
|
2022-08-08 19:01:38 +02:00
|
|
|
/** \} */
|