@forgeax/engine-debug-draw 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +256 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/__tests__/errors.test-d.d.ts +2 -0
- package/dist/__tests__/errors.test-d.d.ts.map +1 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/debug-draw.d.ts +65 -0
- package/dist/debug-draw.d.ts.map +1 -0
- package/dist/errors.d.ts +65 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +835 -0
- package/dist/index.mjs.map +1 -0
- package/dist/shapes/aabb.d.ts +4 -0
- package/dist/shapes/aabb.d.ts.map +1 -0
- package/dist/shapes/arrow.d.ts +11 -0
- package/dist/shapes/arrow.d.ts.map +1 -0
- package/dist/shapes/axes.d.ts +18 -0
- package/dist/shapes/axes.d.ts.map +1 -0
- package/dist/shapes/frustum.d.ts +7 -0
- package/dist/shapes/frustum.d.ts.map +1 -0
- package/dist/shapes/line.d.ts +4 -0
- package/dist/shapes/line.d.ts.map +1 -0
- package/dist/shapes/sphere.d.ts +7 -0
- package/dist/shapes/sphere.d.ts.map +1 -0
- package/dist/types.d.ts +136 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +61 -0
- package/src/__tests__/errors.test-d.ts +89 -0
- package/src/constants.ts +13 -0
- package/src/debug-draw.ts +713 -0
- package/src/errors.ts +142 -0
- package/src/index.ts +14 -0
- package/src/shapes/aabb.ts +57 -0
- package/src/shapes/arrow.ts +75 -0
- package/src/shapes/axes.ts +60 -0
- package/src/shapes/frustum.ts +182 -0
- package/src/shapes/line.ts +14 -0
- package/src/shapes/sphere.ts +74 -0
- package/src/types.ts +176 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// @forgeax/engine-debug-draw -- public types + factory signature (M1 / w4)
|
|
2
|
+
//
|
|
3
|
+
// Decision anchors:
|
|
4
|
+
// - plan-strategy D-1: package depends only on rhi/math/types
|
|
5
|
+
// - plan-strategy D-2: depthMode single-instance single-PSO, no runtime switching
|
|
6
|
+
// - plan-strategy D-4 / D-9: vertex stride 16 B, capacities configurable
|
|
7
|
+
// - plan-strategy D-6: shape color = ColorLike (consumes engine-math existing type)
|
|
8
|
+
// - OOS-9: single-instance single-mode; two modes in one frame = two instances
|
|
9
|
+
//
|
|
10
|
+
// The DebugDraw interface is declared here as a type-only contract; its
|
|
11
|
+
// implementation lands in M2 (debug-draw.ts).
|
|
12
|
+
|
|
13
|
+
import type { ColorLike, Mat4, Vec3 } from '@forgeax/engine-math';
|
|
14
|
+
import type {
|
|
15
|
+
RhiCommandEncoder,
|
|
16
|
+
RhiDevice,
|
|
17
|
+
RhiError,
|
|
18
|
+
RhiQueue,
|
|
19
|
+
RhiRenderPassEncoder,
|
|
20
|
+
ShaderModule,
|
|
21
|
+
TextureFormat,
|
|
22
|
+
TextureView,
|
|
23
|
+
} from '@forgeax/engine-rhi';
|
|
24
|
+
import type { Result } from '@forgeax/engine-types';
|
|
25
|
+
import type { DebugDrawError } from './errors';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Async shader-module factory matching `createShaderModule(device, desc)`.
|
|
29
|
+
* Injected so the debug-draw package stays dependency-free of rhi-webgpu.
|
|
30
|
+
*/
|
|
31
|
+
export type CreateShaderModule = (
|
|
32
|
+
device: RhiDevice,
|
|
33
|
+
desc: { readonly label?: string | undefined; readonly code: string },
|
|
34
|
+
) => Promise<Result<ShaderModule, RhiError>>;
|
|
35
|
+
|
|
36
|
+
/** Depth comparison mode for the single-PSO line-list overlay. */
|
|
37
|
+
export type DepthMode = 'always' | 'less-equal';
|
|
38
|
+
|
|
39
|
+
/** Configuration passed to {@link createDebugDraw}. */
|
|
40
|
+
export interface DebugDrawOptions {
|
|
41
|
+
/** RHI device for buffer + PSO creation. */
|
|
42
|
+
readonly device: RhiDevice;
|
|
43
|
+
/** RHI queue for `queue.writeBuffer` per-frame uploads. */
|
|
44
|
+
readonly queue: RhiQueue;
|
|
45
|
+
/**
|
|
46
|
+
* Async WGSL shader-module factory.
|
|
47
|
+
* Required; pass `createShaderModule` from `@forgeax/engine-rhi-webgpu`.
|
|
48
|
+
* This callback lives in options (not a package dependency) to keep the
|
|
49
|
+
* debug-draw package clean of concrete backend imports (plan-strategy D-1).
|
|
50
|
+
*/
|
|
51
|
+
readonly createShaderModule: CreateShaderModule;
|
|
52
|
+
/**
|
|
53
|
+
* Swap-chain color target format.
|
|
54
|
+
* Defaults to `'bgra8unorm'` when omitted.
|
|
55
|
+
*/
|
|
56
|
+
readonly format?: TextureFormat | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Depth-stencil attachment format.
|
|
59
|
+
* Required when `depthMode === 'less-equal'`.
|
|
60
|
+
*/
|
|
61
|
+
readonly depthFormat?: TextureFormat | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Initial vertex buffer capacity in vertex count.
|
|
64
|
+
* Defaults to {@link INITIAL_VERTEX_CAPACITY} (1024).
|
|
65
|
+
*/
|
|
66
|
+
readonly initialVertexCapacity?: number | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Hard upper bound on vertex count per flush.
|
|
69
|
+
* Defaults to {@link MAX_VERTEX_CAPACITY} (1_000_000). Excess vertices are
|
|
70
|
+
* discarded with one bounded warning per frame; a successful flush resets the
|
|
71
|
+
* diagnostic and staging for the next frame.
|
|
72
|
+
*/
|
|
73
|
+
readonly maxVertexCapacity?: number | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Depth comparison mode for the overlay PSO.
|
|
76
|
+
* `'always'` draws on top of everything; `'less-equal'` respects scene depth.
|
|
77
|
+
* Defaults to `'always'`.
|
|
78
|
+
*/
|
|
79
|
+
readonly depthMode?: DepthMode | undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Immediate-mode debug-draw instance.
|
|
84
|
+
*
|
|
85
|
+
* Shape calls (line / sphere / aabb / frustum) append vertices to a CPU staging
|
|
86
|
+
* buffer. `flush(encoder, view, viewProj)` uploads staging to a GPU vertex buffer
|
|
87
|
+
* and issues a single `draw` call with line-list topology.
|
|
88
|
+
*
|
|
89
|
+
* After `destroy()`, shape calls are no-ops (with a single console.warn) and
|
|
90
|
+
* `flush()` returns `Result.err({ code: 'flushed-after-destroy' })`.
|
|
91
|
+
*/
|
|
92
|
+
export interface DebugDraw {
|
|
93
|
+
/** Whether the current frame has staged vertices that need an overlay pass. */
|
|
94
|
+
hasPendingWork(): boolean;
|
|
95
|
+
|
|
96
|
+
/** Push a line segment from `a` to `b` with the given color. */
|
|
97
|
+
line(a: Vec3, b: Vec3, color: ColorLike): void;
|
|
98
|
+
|
|
99
|
+
/** Push a wireframe axis-aligned bounding box (12 edges = 24 vertices). */
|
|
100
|
+
aabb(min: Vec3, max: Vec3, color: ColorLike): void;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Push a wireframe sphere as 3 orthogonal great-circle rings.
|
|
104
|
+
* `segments` defaults to 16, producing 96 vertices (3 * 2 * 16).
|
|
105
|
+
*/
|
|
106
|
+
sphere(center: Vec3, radius: number, color: ColorLike, segments?: number): void;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Push a wireframe frustum (12 edges = 24 vertices) derived from
|
|
110
|
+
* the given view-projection matrix.
|
|
111
|
+
*/
|
|
112
|
+
frustum(viewProj: Mat4, color: ColorLike): void;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Push an arrow (body line + 4-line arrowhead = 10 vertices) from `start` to `end`.
|
|
116
|
+
* `tipLength` defaults to `|end - start| / 10` (Bevy's default). A zero-length arrow
|
|
117
|
+
* emits only the body segment. Maps Bevy `gizmos.arrow`.
|
|
118
|
+
*/
|
|
119
|
+
arrow(start: Vec3, end: Vec3, color: ColorLike, tipLength?: number): void;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Push a transform's local coordinate frame as three colored arrows — X=red, Y=green,
|
|
123
|
+
* Z=blue — originating at the transform's translation and pointing `length` along its
|
|
124
|
+
* local X/Y/Z (the columns of the 16-float column-major `worldMat`, scale included).
|
|
125
|
+
* Maps Bevy `gizmos.axes(transform, length)`.
|
|
126
|
+
*/
|
|
127
|
+
axes(worldMat: Mat4, length: number): void;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Upload CPU staging to GPU vertex buffer, issue a single draw call,
|
|
131
|
+
* and reset staging for the next frame.
|
|
132
|
+
*
|
|
133
|
+
* `viewProj` is required; omitting it returns
|
|
134
|
+
* `Result.err({ code: 'viewProj-required' })`.
|
|
135
|
+
*/
|
|
136
|
+
flush(
|
|
137
|
+
encoder: RhiCommandEncoder,
|
|
138
|
+
view: TextureView,
|
|
139
|
+
viewProj: Mat4,
|
|
140
|
+
): Result<void, DebugDrawError>;
|
|
141
|
+
|
|
142
|
+
/** Encode into a render pass whose attachments and lifetime are owned by the caller. */
|
|
143
|
+
encode(pass: RhiRenderPassEncoder, viewProj: Mat4): Result<void, DebugDrawError>;
|
|
144
|
+
|
|
145
|
+
/** Release GPU buffer + PSO. Subsequent shape calls are no-ops. */
|
|
146
|
+
destroy(): void;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Create an immediate-mode debug-draw instance.
|
|
151
|
+
*
|
|
152
|
+
* Async because GPU shader module compilation (createShaderModule)
|
|
153
|
+
* must be awaited. Returns Promise<Result<DebugDraw, DebugDrawError>>.
|
|
154
|
+
*
|
|
155
|
+
* @example Low-path usage
|
|
156
|
+
* ```ts
|
|
157
|
+
* const r = await createDebugDraw({ device, queue });
|
|
158
|
+
* if (!r.ok) { ... }
|
|
159
|
+
* const dd = r.value;
|
|
160
|
+
* dd.line(a, b, [1, 0, 0, 1]);
|
|
161
|
+
* dd.flush(encoder, swapChainView, cameraViewProj);
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @example With less-equal depth testing
|
|
165
|
+
* ```ts
|
|
166
|
+
* const dd = await createDebugDraw({
|
|
167
|
+
* device, queue,
|
|
168
|
+
* format: 'bgra8unorm',
|
|
169
|
+
* depthFormat: 'depth24plus',
|
|
170
|
+
* depthMode: 'less-equal',
|
|
171
|
+
* });
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
export type CreateDebugDraw = (
|
|
175
|
+
opts: DebugDrawOptions,
|
|
176
|
+
) => Promise<Result<DebugDraw, DebugDrawError>>;
|