vgpu-render 0.1.0 → 0.3.0
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/README.md +101 -34
- package/dist/curve.d.ts +26 -1
- package/dist/curve.js +53 -0
- package/dist/debug-draw-3d.d.ts +3 -3
- package/dist/debug-draw-3d.js +10 -10
- package/dist/frame-draw-list-2d.d.ts +286 -0
- package/dist/frame-draw-list-2d.js +668 -0
- package/dist/{frame-recorder.d.ts → frame-draw-list.d.ts} +60 -8
- package/dist/{frame-recorder.js → frame-draw-list.js} +51 -10
- package/dist/geometry-generators.d.ts +11 -2
- package/dist/geometry-generators.js +37 -1
- package/dist/gpu-debug-draw-2d.d.ts +1 -1
- package/dist/gpu-debug-draw-2d.js +10 -2
- package/dist/gpu-debug-draw-3d.d.ts +1 -1
- package/dist/gpu-debug-draw-3d.js +4 -2
- package/dist/gpu-text-3d.d.ts +1 -1
- package/dist/gpu-text-3d.js +49 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -3
- package/dist/mesh-batch-3d.d.ts +1 -1
- package/dist/shape2d-shader.js +295 -7
- package/dist/text-atlas.d.ts +6 -4
- package/dist/text-atlas.js +9 -6
- package/dist/text-font.d.ts +48 -7
- package/dist/text-font.js +63 -11
- package/dist/text-layout.d.ts +63 -4
- package/dist/text-layout.js +58 -8
- package/dist/text-msdf-baked.d.ts +9 -4
- package/dist/text-msdf-baked.js +9 -4
- package/dist/text-msdf-font.d.ts +10 -4
- package/dist/text-msdf-font.js +9 -3
- package/dist/vector-math.d.ts +19 -0
- package/dist/vector-math.js +37 -0
- package/package.json +1 -1
- package/dist/frame-recorder-2d.d.ts +0 -177
- package/dist/frame-recorder-2d.js +0 -378
- package/dist/layout-3d.d.ts +0 -227
- package/dist/layout-3d.js +0 -226
- package/dist/scene-examples.d.ts +0 -39
- package/dist/scene-examples.js +0 -200
- package/dist/scenes-2d.d.ts +0 -18
- package/dist/scenes-2d.js +0 -160
- package/dist/scenes-3d.d.ts +0 -46
- package/dist/scenes-3d.js +0 -1994
- package/dist/text-scenes.d.ts +0 -85
- package/dist/text-scenes.js +0 -338
package/dist/layout-3d.js
DELETED
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Layout and drawing specifications ported from `the upstream reference`.
|
|
3
|
-
*
|
|
4
|
-
* Every reference scene shares the same layout contract, which is why it lives here rather
|
|
5
|
-
* than being re-derived per scene:
|
|
6
|
-
*
|
|
7
|
-
* ```
|
|
8
|
-
* column_x(column) = column * COLUMN_SPACING + 0.5 // COLUMN_SPACING is 2.0, axes 2.2
|
|
9
|
-
* row_z(row) = SAMPLE_START_Z - row * spacing // START_Z is -0.45, rows go along -Z
|
|
10
|
-
* ```
|
|
11
|
-
*
|
|
12
|
-
* Each scene has its own `SAMPLE_SPACING`, and some columns override it (radius, size,
|
|
13
|
-
* angle, height). Coordinates are local to the scene root; the reference capture harness
|
|
14
|
-
* translates the whole root by `REFERENCE_OFFSET` without rescaling any geometry, so the
|
|
15
|
-
* same translation is applied here.
|
|
16
|
-
*/
|
|
17
|
-
/** `scene.position = Vector3(-10, 0, 1.5)` from `the reference capture script`. */
|
|
18
|
-
export const REFERENCE_OFFSET = [-10, 0, 1.5];
|
|
19
|
-
export function referenceOffset(p) {
|
|
20
|
-
return [p[0] + REFERENCE_OFFSET[0], p[1] + REFERENCE_OFFSET[1], p[2] + REFERENCE_OFFSET[2]];
|
|
21
|
-
}
|
|
22
|
-
/** Shared value tables used by the reference scenes. */
|
|
23
|
-
export const WIDTH_VALUES = [1, 2, 5.5, 10];
|
|
24
|
-
export const ALPHA_VALUES = [1, 0.65, 0.35, 0.1];
|
|
25
|
-
export const DASH_VALUES = [[0.1, 0.1], [0.2, 0.1], [0.4, 0.15], [0.04, 0.12]];
|
|
26
|
-
export const JOINT_VALUES = ["none", "round", "bevel", "miter"];
|
|
27
|
-
export const RADIUS_VALUES = [0.18, 0.28, 0.38, 0.5];
|
|
28
|
-
export const SEGMENT_VALUES = [8, 16, 32, 64];
|
|
29
|
-
export const ROTATION_SAMPLE_COUNT = 8;
|
|
30
|
-
export const NORMAL_SAMPLE_COUNT = 4;
|
|
31
|
-
export const WHITE = [1, 1, 1, 1];
|
|
32
|
-
export const CYAN = [0.15, 0.85, 1, 0.95];
|
|
33
|
-
export const LIME = [0.7, 1, 0.25, 1];
|
|
34
|
-
export const ORANGE = [1, 0.45, 0.2, 1];
|
|
35
|
-
export const ORANGE_SOFT = [1, 0.45, 0.2, 0.95];
|
|
36
|
-
export const VIOLET = [0.75, 0.45, 1, 1];
|
|
37
|
-
export const TEAL = [0.25, 0.95, 0.9, 1];
|
|
38
|
-
export const PINK = [1, 0.3, 0.6, 1];
|
|
39
|
-
export const GOLD = [1, 0.75, 0.25, 1];
|
|
40
|
-
/** Reference `_get_normal_sample_color` / `_get_normal_sample_width`, shared by most scenes. */
|
|
41
|
-
export function normalSampleColor(row) {
|
|
42
|
-
if (row === 1)
|
|
43
|
-
return [0.25, 0.95, 0.9, 0.35];
|
|
44
|
-
if (row === 2)
|
|
45
|
-
return [1, 0.45, 0.2, 1];
|
|
46
|
-
return [0.25, 0.95, 0.9, 1];
|
|
47
|
-
}
|
|
48
|
-
export function normalSampleWidth(row, baseWidth) {
|
|
49
|
-
return row === 3 ? 10 : baseWidth;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* reference `Color.from_hsv(h, s, v, a)`. The reference solid samples use this, so a fixed
|
|
53
|
-
* palette color cannot reproduce them. `h` is in `[0, 1]`, matching reference.
|
|
54
|
-
*/
|
|
55
|
-
export function fromHsv(h, s, v, a) {
|
|
56
|
-
const hue = ((h % 1) + 1) % 1;
|
|
57
|
-
const i = Math.floor(hue * 6);
|
|
58
|
-
const f = hue * 6 - i;
|
|
59
|
-
const p = v * (1 - s);
|
|
60
|
-
const q = v * (1 - s * f);
|
|
61
|
-
const t = v * (1 - s * (1 - f));
|
|
62
|
-
switch (i % 6) {
|
|
63
|
-
case 0: return [v, t, p, a];
|
|
64
|
-
case 1: return [q, v, p, a];
|
|
65
|
-
case 2: return [p, v, t, a];
|
|
66
|
-
case 3: return [p, q, v, a];
|
|
67
|
-
case 4: return [t, p, v, a];
|
|
68
|
-
default: return [v, p, q, a];
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
export function normalizeVector(p) {
|
|
72
|
-
const length = Math.hypot(p[0], p[1], p[2]) || 1;
|
|
73
|
-
return [p[0] / length, p[1] / length, p[2] / length];
|
|
74
|
-
}
|
|
75
|
-
export function crossVector(a, b) {
|
|
76
|
-
return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
|
|
77
|
-
}
|
|
78
|
-
/** reference `Vector3.rotated(axis, angle)` equivalent (right-handed Rodrigues). */
|
|
79
|
-
export function rotateAroundAxis(p, axis, angle) {
|
|
80
|
-
const a = normalizeVector(axis);
|
|
81
|
-
const cos = Math.cos(angle);
|
|
82
|
-
const sin = Math.sin(angle);
|
|
83
|
-
const dot = p[0] * a[0] + p[1] * a[1] + p[2] * a[2];
|
|
84
|
-
const cross = crossVector(a, p);
|
|
85
|
-
return [
|
|
86
|
-
p[0] * cos + cross[0] * sin + a[0] * dot * (1 - cos),
|
|
87
|
-
p[1] * cos + cross[1] * sin + a[1] * dot * (1 - cos),
|
|
88
|
-
p[2] * cos + cross[2] * sin + a[2] * dot * (1 - cos),
|
|
89
|
-
];
|
|
90
|
-
}
|
|
91
|
-
/** Port of `_get_circle_rotation(normal, angle)` from `circle.gd`. */
|
|
92
|
-
export function circleBasis(normal, angle) {
|
|
93
|
-
const n = normalizeVector(normal);
|
|
94
|
-
const reference = Math.abs(n[0]) > 0.95 ? [0, 0, 1] : [1, 0, 0];
|
|
95
|
-
const projection = reference[0] * n[0] + reference[1] * n[1] + reference[2] * n[2];
|
|
96
|
-
const planar = [reference[0] - n[0] * projection, reference[1] - n[1] * projection, reference[2] - n[2] * projection];
|
|
97
|
-
const widthAxis = normalizeVector(rotateAroundAxis(normalizeVector(planar), n, angle));
|
|
98
|
-
const heightAxis = normalizeVector(crossVector(n, widthAxis));
|
|
99
|
-
return { x: widthAxis, y: heightAxis, z: n };
|
|
100
|
-
}
|
|
101
|
-
/** Points on a circle in the plane spanned by a reference rotation basis. */
|
|
102
|
-
export function basisCirclePoints(centerLocal, radius, segments, basis) {
|
|
103
|
-
const center = referenceOffset(centerLocal);
|
|
104
|
-
const points = [];
|
|
105
|
-
for (let i = 0; i < segments; i++) {
|
|
106
|
-
const angle = i / segments * Math.PI * 2;
|
|
107
|
-
const cos = Math.cos(angle) * radius;
|
|
108
|
-
const sin = Math.sin(angle) * radius;
|
|
109
|
-
points.push([
|
|
110
|
-
center[0] + basis.x[0] * cos + basis.y[0] * sin,
|
|
111
|
-
center[1] + basis.x[1] * cos + basis.y[1] * sin,
|
|
112
|
-
center[2] + basis.x[2] * cos + basis.y[2] * sin,
|
|
113
|
-
]);
|
|
114
|
-
}
|
|
115
|
-
return points;
|
|
116
|
-
}
|
|
117
|
-
export function createLayout(layout, baseY) {
|
|
118
|
-
const columnX = (column) => column * layout.columnSpacing + layout.columnOffset;
|
|
119
|
-
const rowSpacing = (column) => layout.perColumnSpacing?.[column] ?? layout.sampleSpacing;
|
|
120
|
-
const rowZ = (column, row) => layout.sampleStartZ - row * rowSpacing(column);
|
|
121
|
-
const at = (column, row) => {
|
|
122
|
-
const y = layout.columnY === undefined ? baseY : layout.columnY(column, row, baseY);
|
|
123
|
-
return referenceOffset([columnX(column), y, rowZ(column, row)]);
|
|
124
|
-
};
|
|
125
|
-
/** Local (untranslated) centre, for functions that must offset before the scene shift. */
|
|
126
|
-
const atLocal = (column, row) => {
|
|
127
|
-
const y = layout.columnY === undefined ? baseY : layout.columnY(column, row, baseY);
|
|
128
|
-
return [columnX(column), y, rowZ(column, row)];
|
|
129
|
-
};
|
|
130
|
-
return { columnX, rowZ, rowSpacing, at, atLocal };
|
|
131
|
-
}
|
|
132
|
-
/** Reference `circle.gd` layout: radius column uses 1.15 row spacing, the rest 0.82. */
|
|
133
|
-
export const CIRCLE_REFERENCE_LAYOUT = {
|
|
134
|
-
columnSpacing: 2,
|
|
135
|
-
columnOffset: 0.5,
|
|
136
|
-
sampleSpacing: 0.82,
|
|
137
|
-
sampleStartZ: -0.45,
|
|
138
|
-
perColumnSpacing: { 1: 1.15 },
|
|
139
|
-
};
|
|
140
|
-
/**
|
|
141
|
-
* Per-scene layouts, copied from the constants at the top of each `examples/*.gd`.
|
|
142
|
-
*
|
|
143
|
-
* Every reference scene differs only in these numbers, so they are data here rather than
|
|
144
|
-
* duplicated coordinate math. `columnSpacing` is 2.0 everywhere except `axes` (2.2).
|
|
145
|
-
*/
|
|
146
|
-
export const SCENE_LAYOUTS = {
|
|
147
|
-
/** `index.gd`: absolute origin, its own row spacing, samples lifted to y = 0.55. */
|
|
148
|
-
index: { columnSpacing: 2, columnOffset: 1, sampleSpacing: 1.25, sampleStartZ: -1, baseY: 0.55 },
|
|
149
|
-
arrow: { columnSpacing: 2, columnOffset: 0.5, sampleSpacing: 0.78, sampleStartZ: -0.45, baseY: 0.1 },
|
|
150
|
-
axes: {
|
|
151
|
-
columnSpacing: 2.2,
|
|
152
|
-
columnOffset: 0.5,
|
|
153
|
-
sampleSpacing: 0.86,
|
|
154
|
-
sampleStartZ: -0.45,
|
|
155
|
-
baseY: 0.1,
|
|
156
|
-
perColumnSpacing: { 0: 1.05, 3: 1.05 },
|
|
157
|
-
},
|
|
158
|
-
grid: { columnSpacing: 2, columnOffset: 0.5, sampleSpacing: 0.72, sampleStartZ: -0.45, baseY: 0.06 },
|
|
159
|
-
rect: {
|
|
160
|
-
columnSpacing: 2,
|
|
161
|
-
columnOffset: 0.5,
|
|
162
|
-
sampleSpacing: 0.62,
|
|
163
|
-
sampleStartZ: -0.45,
|
|
164
|
-
baseY: 0.1,
|
|
165
|
-
perColumnSpacing: { 1: 0.9 },
|
|
166
|
-
},
|
|
167
|
-
box: {
|
|
168
|
-
columnSpacing: 2,
|
|
169
|
-
columnOffset: 0.5,
|
|
170
|
-
sampleSpacing: 0.82,
|
|
171
|
-
sampleStartZ: -0.45,
|
|
172
|
-
baseY: 0.08,
|
|
173
|
-
perColumnSpacing: { 1: 1.05 },
|
|
174
|
-
},
|
|
175
|
-
arc: {
|
|
176
|
-
columnSpacing: 2,
|
|
177
|
-
columnOffset: 0.5,
|
|
178
|
-
sampleSpacing: 0.92,
|
|
179
|
-
sampleStartZ: -0.45,
|
|
180
|
-
baseY: 0.1,
|
|
181
|
-
perColumnSpacing: { 1: 1.15, 2: 1.08 },
|
|
182
|
-
},
|
|
183
|
-
// `curve.gd`: rows start at EXAMPLE_START_Z = -2.0; the transform and closed
|
|
184
|
-
// columns widen their row spacing to 0.85x and 1.05x of SAMPLE_SPACING.
|
|
185
|
-
curve: {
|
|
186
|
-
columnSpacing: 2,
|
|
187
|
-
columnOffset: 0.5,
|
|
188
|
-
sampleSpacing: 0.82,
|
|
189
|
-
sampleStartZ: -2,
|
|
190
|
-
baseY: 0.1,
|
|
191
|
-
perColumnSpacing: { 2: 0.82 * 0.85, 4: 0.82 * 1.05 },
|
|
192
|
-
},
|
|
193
|
-
sphere: {
|
|
194
|
-
columnSpacing: 2,
|
|
195
|
-
columnOffset: 0.5,
|
|
196
|
-
sampleSpacing: 0.86,
|
|
197
|
-
sampleStartZ: -0.45,
|
|
198
|
-
baseY: 0.1,
|
|
199
|
-
perColumnSpacing: { 1: 1.08 },
|
|
200
|
-
},
|
|
201
|
-
cone: {
|
|
202
|
-
columnSpacing: 2,
|
|
203
|
-
columnOffset: 0.5,
|
|
204
|
-
sampleSpacing: 0.84,
|
|
205
|
-
sampleStartZ: -0.45,
|
|
206
|
-
baseY: 0.1,
|
|
207
|
-
perColumnSpacing: { 1: 1.05, 2: 1.08 },
|
|
208
|
-
},
|
|
209
|
-
cylinder: {
|
|
210
|
-
columnSpacing: 2,
|
|
211
|
-
columnOffset: 0.5,
|
|
212
|
-
sampleSpacing: 0.84,
|
|
213
|
-
sampleStartZ: -0.45,
|
|
214
|
-
baseY: 0.1,
|
|
215
|
-
perColumnSpacing: { 1: 1.05, 2: 1.08 },
|
|
216
|
-
},
|
|
217
|
-
capsule: {
|
|
218
|
-
columnSpacing: 2,
|
|
219
|
-
columnOffset: 0.5,
|
|
220
|
-
sampleSpacing: 0.86,
|
|
221
|
-
sampleStartZ: -0.45,
|
|
222
|
-
baseY: 0.1,
|
|
223
|
-
perColumnSpacing: { 1: 1.02, 2: 1.02 },
|
|
224
|
-
},
|
|
225
|
-
world_space_width: { columnSpacing: 2, columnOffset: 1, sampleSpacing: 1.25, sampleStartZ: -1, baseY: 0.55 },
|
|
226
|
-
};
|
package/dist/scene-examples.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
export type ExampleColumn = {
|
|
2
|
-
readonly label: string;
|
|
3
|
-
readonly samples: readonly string[];
|
|
4
|
-
readonly implemented: boolean;
|
|
5
|
-
};
|
|
6
|
-
export type SceneExample = {
|
|
7
|
-
readonly id: string;
|
|
8
|
-
readonly title: string;
|
|
9
|
-
readonly description: string;
|
|
10
|
-
readonly notes?: string;
|
|
11
|
-
readonly columns: readonly ExampleColumn[];
|
|
12
|
-
readonly implemented: boolean;
|
|
13
|
-
/** Which camera drives the page: the gallery's 3D orbit camera by default, or the 2D pan/zoom one. */
|
|
14
|
-
readonly family?: "2d" | "3d";
|
|
15
|
-
/**
|
|
16
|
-
* Sidebar grouping. Defaults to `family`, so the 2D pages land in "2D Graphics" and every 3D
|
|
17
|
-
* page in "3D Graphics"; the text pages name "text" explicitly, since they use the 3D camera
|
|
18
|
-
* without being 3D geometry pages.
|
|
19
|
-
*/
|
|
20
|
-
readonly group?: "3d" | "2d" | "text";
|
|
21
|
-
/**
|
|
22
|
-
* World-space extent the 2D camera fits to this page, in `world2d` units. Only read when
|
|
23
|
-
* `family` is "2d"; the page draws around the origin.
|
|
24
|
-
*/
|
|
25
|
-
readonly view2d?: {
|
|
26
|
-
readonly width: number;
|
|
27
|
-
readonly height: number;
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Hide the infinite grid while this example is selected.
|
|
31
|
-
*
|
|
32
|
-
* A screen-space page is its own content in pixel space, so the grid is a world-space reference
|
|
33
|
-
* that can only cross it as diagonal lines, so those pages set `true`. A world-space page that
|
|
34
|
-
* wants the grid as its ground plane says `false` explicitly; leaving the flag unset keeps whatever
|
|
35
|
-
* the sidebar shows, which is what every other world-space example wants.
|
|
36
|
-
*/
|
|
37
|
-
readonly hideGrid?: boolean;
|
|
38
|
-
};
|
|
39
|
-
export declare const SCENE_EXAMPLES: readonly SceneExample[];
|
package/dist/scene-examples.js
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
// Columns whose reference variants are only approximated by this vgpu port are flagged false so the
|
|
2
|
-
// gallery never claims parity it does not have: grid boundary (`outer`) handling still differs.
|
|
3
|
-
const approximated = /outer/;
|
|
4
|
-
const column = (label, samples) => ({
|
|
5
|
-
label,
|
|
6
|
-
samples,
|
|
7
|
-
implemented: !approximated.test(label),
|
|
8
|
-
});
|
|
9
|
-
const width = ["width = 1.0", "width = 2.0", "width = 5.5", "width = 10.0"];
|
|
10
|
-
const joints = ["none", "round", "bevel", "miter"];
|
|
11
|
-
const dash = ["dash = 0.10 / 0.10", "dash = 0.20 / 0.10", "dash = 0.40 / 0.15", "dash = 0.04 / 0.12"];
|
|
12
|
-
const normal = ["base", "alpha", "color", "wide"];
|
|
13
|
-
const rotation = Array.from({ length: 8 }, (_, index) => `step ${index}`);
|
|
14
|
-
// Arrow example samples copied from `examples/arrow.gd` `_get_sample_label`.
|
|
15
|
-
const arrowWidth = ["w = 1.0", "w = 2.0", "w = 5.5", "w = 10.0"];
|
|
16
|
-
const arrowDir = ["-63 deg", "-22 deg", "22 deg", "63 deg"];
|
|
17
|
-
const arrowHeadAngle = ["20 deg", "30 deg", "45 deg", "76 deg"];
|
|
18
|
-
const arrowJoints = ["NONE", "ROUND", "BEVEL", "MITER"];
|
|
19
|
-
const arrowHeadLength = ["head = 0.12", "head = 0.22", "head = 0.34", "head = 0.46"];
|
|
20
|
-
const arrowDash = ["0.10 / 0.10", "0.20 / 0.10", "0.40 / 0.15", "0.04 / 0.12"];
|
|
21
|
-
const radius = ["0.18", "0.28", "0.38", "0.50"];
|
|
22
|
-
const segments = ["8", "16", "32", "64"];
|
|
23
|
-
const jointNote = "Round, bevel and miter joins are rebuilt in the vertex stage from the reference joint shaders.";
|
|
24
|
-
const shapeWidth = ["w = 1.0", "w = 2.0", "w = 5.5", "w = 10.0"];
|
|
25
|
-
const shapeRadius = ["r = 0.18", "r = 0.28", "r = 0.38", "r = 0.50"];
|
|
26
|
-
const capsuleRadius = ["r = 0.16", "r = 0.24", "r = 0.32", "r = 0.40"];
|
|
27
|
-
const shapeSegments = ["8 seg", "16 seg", "32 seg", "64 seg"];
|
|
28
|
-
const smallSegments = ["3 seg", "4 seg", "8 seg", "16 seg"];
|
|
29
|
-
const sideSegments = ["3 side", "4 side", "8 side", "16 side"];
|
|
30
|
-
const capsuleSideSegments = ["1 side", "2 side", "4 side", "8 side"];
|
|
31
|
-
const coneHeights = ["h = 0.45", "h = 0.65", "h = 0.85", "h = 1.05"];
|
|
32
|
-
const cylinderHalfHeights = ["hh = 0.225", "hh = 0.325", "hh = 0.425", "hh = 0.525"];
|
|
33
|
-
const capsuleHalfHeights = ["hh = 0.000", "hh = 0.125", "hh = 0.225", "hh = 0.350"];
|
|
34
|
-
const yAxisSegments = ["y = 0", "y = 1", "y = 2", "y = 6"];
|
|
35
|
-
const zAxisSegments = ["z = 0", "z = 1", "z = 2", "z = 6"];
|
|
36
|
-
// Row labels copied from `examples/index.gd` ROW_LABELS (the full API matrix).
|
|
37
|
-
const indexRows = {
|
|
38
|
-
line: ["draw_line", "draw_line_n", "draw_line_d", "draw_line_n_d"],
|
|
39
|
-
ray: ["draw_ray", "draw_ray_n", "draw_ray_d", "draw_ray_n_d"],
|
|
40
|
-
arrow: ["draw_arrow", "draw_arrow_n", "draw_arrow_line", "draw_arrow_line_n", "draw_arrow_line_d", "draw_arrow_line_n_d"],
|
|
41
|
-
axes: ["draw_axes", "draw_axes_n"],
|
|
42
|
-
line_list: ["draw_line_list", "draw_line_list_n"],
|
|
43
|
-
strip: ["draw_line_strip", "draw_line_strip_n", "draw_line_strip_d", "draw_line_strip_n_d"],
|
|
44
|
-
loop: ["draw_line_loop", "draw_line_loop_n", "draw_line_loop_d", "draw_line_loop_n_d"],
|
|
45
|
-
curve: ["draw_curve", "draw_curve_d"],
|
|
46
|
-
grid: ["draw_grid", "draw_grid_n"],
|
|
47
|
-
rect: ["draw_rect", "draw_rect_s", "draw_rect_n", "draw_rect_d", "draw_rect_n_d"],
|
|
48
|
-
box: ["draw_box", "draw_box_s", "draw_box_n", "draw_box_d", "draw_box_n_d"],
|
|
49
|
-
circle: ["draw_circle", "draw_circle_s", "draw_circle_n", "draw_circle_d", "draw_circle_n_d"],
|
|
50
|
-
arc: ["draw_arc", "draw_arc_n", "draw_arc_d", "draw_arc_n_d"],
|
|
51
|
-
sphere: ["draw_sphere", "draw_sphere_s", "draw_sphere_n", "draw_sphere_d", "draw_sphere_n_d"],
|
|
52
|
-
cone: ["draw_cone", "draw_cone_s", "draw_cone_n"],
|
|
53
|
-
cylinder: ["draw_cylinder", "draw_cylinder_s", "draw_cylinder_n"],
|
|
54
|
-
capsule: ["draw_capsule", "draw_capsule_n"],
|
|
55
|
-
};
|
|
56
|
-
// `world_space_width.gd` ROW_LABELS: same matrix without the `*_s` solid columns.
|
|
57
|
-
const worldWidthRows = {
|
|
58
|
-
...indexRows,
|
|
59
|
-
rect: ["draw_rect", "draw_rect_n", "draw_rect_d", "draw_rect_n_d"],
|
|
60
|
-
box: ["draw_box", "draw_box_n", "draw_box_d", "draw_box_n_d"],
|
|
61
|
-
circle: ["draw_circle", "draw_circle_n", "draw_circle_d", "draw_circle_n_d"],
|
|
62
|
-
sphere: ["draw_sphere", "draw_sphere_n", "draw_sphere_d", "draw_sphere_n_d"],
|
|
63
|
-
cone: ["draw_cone", "draw_cone_n"],
|
|
64
|
-
cylinder: ["draw_cylinder", "draw_cylinder_n"],
|
|
65
|
-
};
|
|
66
|
-
// Column structure copied from the reference scenes. Capsule has no `_s` column.
|
|
67
|
-
const solidExamples = [
|
|
68
|
-
{
|
|
69
|
-
id: "sphere",
|
|
70
|
-
title: "Sphere",
|
|
71
|
-
description: "Sphere wire and solid meshes across width, radius, segment, axis, dash, joint and normal rows.",
|
|
72
|
-
notes: "Reference has 14 columns including y/z axis and sphere_s; the UV generator approximates the independent axis ring counts.",
|
|
73
|
-
implemented: true,
|
|
74
|
-
columns: [
|
|
75
|
-
column("sphere(width)", shapeWidth),
|
|
76
|
-
column("sphere(radius)", shapeRadius),
|
|
77
|
-
column("sphere(segments)", shapeSegments),
|
|
78
|
-
column("sphere(y axis)", yAxisSegments),
|
|
79
|
-
column("sphere(z axis)", zAxisSegments),
|
|
80
|
-
column("sphere(rotation)", rotation),
|
|
81
|
-
column("sphere(joint)", joints),
|
|
82
|
-
column("sphere_d(dash)", dash),
|
|
83
|
-
column("sphere_d(joint)", joints),
|
|
84
|
-
column("sphere_n", normal),
|
|
85
|
-
column("sphere_n(joint)", joints),
|
|
86
|
-
column("sphere_n_d(dash)", dash),
|
|
87
|
-
column("sphere_n_d(joint)", joints),
|
|
88
|
-
column("sphere_s", rotation),
|
|
89
|
-
],
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
id: "cone",
|
|
93
|
-
title: "Cone",
|
|
94
|
-
description: "Cone wire and solid meshes across width, radius, height, segment, rotation, joint and normal rows.",
|
|
95
|
-
notes: "Reference has 10 columns including cone_s; the generator uses one segment count for the base ring and side lines.",
|
|
96
|
-
implemented: true,
|
|
97
|
-
columns: [
|
|
98
|
-
column("cone(width)", shapeWidth),
|
|
99
|
-
column("cone(radius)", shapeRadius),
|
|
100
|
-
column("cone(height)", coneHeights),
|
|
101
|
-
column("cone(segments)", smallSegments),
|
|
102
|
-
column("cone(side segments)", sideSegments),
|
|
103
|
-
column("cone(rotation)", rotation),
|
|
104
|
-
column("cone(joint)", joints),
|
|
105
|
-
column("cone_n", normal),
|
|
106
|
-
column("cone_n(joint)", joints),
|
|
107
|
-
column("cone_s", rotation),
|
|
108
|
-
],
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
id: "cylinder",
|
|
112
|
-
title: "Cylinder",
|
|
113
|
-
description: "Cylinder wire and solid meshes across width, radius, half height, segment, rotation, joint and normal rows.",
|
|
114
|
-
notes: "Reference has 10 columns including cylinder_s; the generator uses one segment count for the base ring and side lines.",
|
|
115
|
-
implemented: true,
|
|
116
|
-
columns: [
|
|
117
|
-
column("cylinder(width)", shapeWidth),
|
|
118
|
-
column("cylinder(radius)", shapeRadius),
|
|
119
|
-
column("cylinder(half height)", cylinderHalfHeights),
|
|
120
|
-
column("cylinder(segments)", smallSegments),
|
|
121
|
-
column("cylinder(side segments)", sideSegments),
|
|
122
|
-
column("cylinder(rotation)", rotation),
|
|
123
|
-
column("cylinder(joint)", joints),
|
|
124
|
-
column("cylinder_n", normal),
|
|
125
|
-
column("cylinder_n(joint)", joints),
|
|
126
|
-
column("cylinder_s", rotation),
|
|
127
|
-
],
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
id: "capsule",
|
|
131
|
-
title: "Capsule",
|
|
132
|
-
description: "Capsule wire meshes across width, radius, half height, segment, rotation, joint and normal rows.",
|
|
133
|
-
notes: "Reference has 9 columns and no solid column: the capsule reference has no solid variant.",
|
|
134
|
-
implemented: true,
|
|
135
|
-
columns: [
|
|
136
|
-
column("capsule(width)", shapeWidth),
|
|
137
|
-
column("capsule(radius)", capsuleRadius),
|
|
138
|
-
column("capsule(half height)", capsuleHalfHeights),
|
|
139
|
-
column("capsule(segments)", shapeSegments),
|
|
140
|
-
column("capsule(side segments)", capsuleSideSegments),
|
|
141
|
-
column("capsule(rotation)", rotation),
|
|
142
|
-
column("capsule(joint)", joints),
|
|
143
|
-
column("capsule_n", normal),
|
|
144
|
-
column("capsule_n(joint)", joints),
|
|
145
|
-
],
|
|
146
|
-
},
|
|
147
|
-
];
|
|
148
|
-
export const SCENE_EXAMPLES = [
|
|
149
|
-
{ id: "index", title: "Index", description: "The DebugDraw3D API matrix: 17 primitive columns with the reference per-column row sets.", notes: "Overview of every primitive family; row labels mirror the reference draw calls.", implemented: true, columns: ["line", "ray", "arrow", "axes", "line_list", "strip", "loop", "curve", "grid", "rect", "box", "circle", "arc", "sphere", "cone", "cylinder", "capsule"].map((label) => column(label, indexRows[label])) },
|
|
150
|
-
{ id: "line", title: "Line", description: "Widths, alpha, dashes, strip and loop joints, dashed joints, and normal-aware lines.", notes: jointNote, implemented: true, columns: [column("line(width)", width), column("line(alpha)", ["alpha = 1.00", "alpha = 0.65", "alpha = 0.35", "alpha = 0.10"]), column("line_d(dash)", dash), column("strip(joint)", joints), column("loop(joint)", joints), column("strip_d(joint)", joints), column("line_n(normal)", normal)] },
|
|
151
|
-
{ id: "arrow", title: "Arrow", description: "Arrow direction, width, head length, head angle, joints, normal-aware arrows, and arrow-line variants.", notes: jointNote + " Head angle and length are wired to arrow geometry.", implemented: true, columns: [column("arrow(width)", arrowWidth), column("arrow(dir)", arrowDir), column("arrow(head angle)", arrowHeadAngle), column("arrow(joint)", arrowJoints), column("arrow_n", normal), column("arrow_n(joint)", arrowJoints), column("arrow_line(width)", arrowWidth), column("arrow_line(head length)", arrowHeadLength), column("arrow_line(head angle)", arrowHeadAngle), column("arrow_line(rotation)", rotation), column("arrow_line(joint)", arrowJoints), column("arrow_line_d(dash)", arrowDash), column("arrow_line_d(joint)", arrowJoints), column("arrow_line_n", normal), column("arrow_line_n(joint)", arrowJoints), column("arrow_line_n_d(dash)", arrowDash), column("arrow_line_n_d(joint)", arrowJoints)] },
|
|
152
|
-
{ id: "axes", title: "Axes", description: "Axis length, width, rotation, and normal-aware axis variants.", implemented: true, columns: [column("axes(length)", ["0.35", "0.55", "0.75", "1.00"]), column("axes(width)", width), column("axes(rotation)", rotation), column("axes_n(length)", ["0.35", "0.55", "0.75", "1.00"]), column("axes_n(width)", width), column("axes_n(rotation)", rotation)] },
|
|
153
|
-
{ id: "grid", title: "Grid", description: "Grid width, cell count, spacing, skew, outer edges, rotation, color, and normal rows.", notes: "Column spacing follows each column's measured bounds; rendered skew and outer edges use the library grid semantics.", implemented: true, columns: [column("grid(width)", ["w = 1.0", "w = 2.0", "w = 5.5", "w = 10.0"]), column("grid(cells)", ["4 x 4", "6 x 4", "10 x 3", "3 x 8"]), column("grid(spacing)", ["0.20 x 0.20", "0.28 x 0.28", "0.42 x 0.22", "0.55 x 0.28"]), column("grid(skew)", ["none", "0.28 / 0.00", "-0.28 / 0.00", "0.28 / -0.18"]), column("grid(outer)", ["none", "X", "Z", "XZ"]), column("grid(rotation)", ["step 0", "step 1", "step 2", "step 3", "step 4", "step 5"]), column("grid(color)", ["base", "alpha", "color", "blue"]), column("grid_n", normal)] },
|
|
154
|
-
{ id: "rect", title: "Rect", description: "Wire and solid rectangles with size, rotation, joints, dashes, and normal variants.", notes: jointNote, implemented: true, columns: [column("rect(width)", width), column("rect(size)", ["0.50 × 0.40", "0.80 × 0.40", "0.50 × 0.70", "0.55 × 0.55"]), column("rect(rotation)", rotation), column("rect(joint)", joints), column("rect_d(dash)", dash), column("rect_d(joint)", joints), column("rect_n", normal), column("rect_n_d(dash)", dash), column("rect_n(joint)", joints), column("rect_s(solid)", rotation)] },
|
|
155
|
-
{ id: "box", title: "Box", description: "Wire and solid boxes with size, rotation, dashes, and normal variants.", implemented: true, columns: [column("box(width)", width), column("box(size)", ["0.50 × 0.40 × 0.40", "0.80 × 0.40 × 0.40", "0.50 × 0.60 × 0.40", "0.50 × 0.40 × 0.60"]), column("box(rotation)", rotation), column("box_d(dash)", dash), column("box_n", normal), column("box_n_d(dash)", dash), column("box_s(solid)", rotation)] },
|
|
156
|
-
{ id: "circle", title: "Circle", description: "Circle width, radius, segment count, rotation, joints, dashes, solid and normal variants.", notes: jointNote, implemented: true, columns: [column("circle(width)", width), column("circle(radius)", radius), column("circle(segments)", segments), column("circle(rotation)", rotation), column("circle(joint)", joints), column("circle_d(dash)", dash), column("circle_d(joint)", joints), column("circle_n", normal), column("circle_n_d(dash)", dash), column("circle_n(joint)", joints), column("circle_s(solid)", segments)] },
|
|
157
|
-
{ id: "arc", title: "Arc", description: "Arc width, radius, angle, segments, rotation, joints, dashes, and normal variants.", notes: jointNote, implemented: true, columns: [column("arc(width)", width), column("arc(radius)", radius), column("arc(angle)", ["90°", "180°", "270°", "360°"]), column("arc(segments)", segments), column("arc(rotation)", rotation), column("arc(joint)", joints), column("arc_d(dash)", dash), column("arc_d(joint)", joints), column("arc_n", normal), column("arc_n_d(dash)", dash), column("arc_n(joint)", joints)] },
|
|
158
|
-
{ id: "curve", title: "Curve", description: "Curve widths, shape, transform, tolerance, closed paths, joints and dashes.", notes: jointNote + " Cubic Bezier control points are sampled adaptively from the tolerance row, and the construction band draws the reference anchor and control markers.", implemented: true, columns: [column("curve(width)", width), column("curve(shape)", ["mild", "soft", "base", "wide"]), column("curve(transform)", rotation), column("curve(tolerance)", ["0.04", "0.08", "0.16", "0.32"]), column("curve(closed)", ["open", "closed", "small", "wide"]), column("curve(joint)", joints), column("curve_d(dash)", dash), column("curve_d(joint)", joints)] },
|
|
159
|
-
...solidExamples,
|
|
160
|
-
{ id: "world_space_width", title: "World Space Width", description: "The 17-column primitive matrix rendered with world-space line widths and without the `*_s` solid columns.", notes: "Widths are `_world_width(px) = px * 0.01`; row labels mirror the reference.", implemented: true, columns: ["line", "ray", "arrow", "axes", "line_list", "strip", "loop", "curve", "grid", "rect", "box", "circle", "arc", "sphere", "cone", "cylinder", "capsule"].map((label) => column(label, worldWidthRows[label])) },
|
|
161
|
-
{ id: "text-compare", title: "Text Compare", description: "A matrix of one sentence: rows are glyph sources, columns are font sizes.", notes: "Not a reference port: there is no upstream text API, so this is vgpu's own capability. Transposed relative to the line/circle matrices — text grows sideways, so six source columns would be wider than a camera wants to frame. Read down a column to compare encodings at one size, across a row to compare sizes under one encoding. The last row is a fixed-orientation block rather than a camera-facing one, so it foreshortens as you orbit. Every row floats above the grid plane, which writes depth and would otherwise clip it.", implemented: true, group: "text", columns: [column("glyph source", ["bitmap 1x", "bitmap 4x", "sdf 1x", "sdf 4x", "msdf outline", "msdf baked"]), column("font size", ["16 px", "24 px", "36 px"]), column("placement", ["world-billboard", "world-plane", "foreshortens"]), column("what changes", ["coverage interpolation", "supersampled coverage", "distance reconstruction", "per-edge distance", "prebaked at 24 px"])] },
|
|
162
|
-
{ id: "text-encodings", title: "Text Encodings", description: "One sentence from four glyph sources, at two sizes, plus the outline pair.", notes: "Not a reference port: there is no upstream text API, so this is vgpu's own capability. Every block takes the default source — the one that rasterises each glyph at the size it covers on screen — except the columns that name one, so the page doubles as the gallery's own quality check. The lower band repeats the same ink at more than twice the size, which is where a coverage source and a distance field stop looking alike.", implemented: true, group: "text", hideGrid: true, columns: [column("source", ["bitmap 1x", "sdf 4x", "msdf 2x", "msdf baked"]), column("what changes", ["coverage interpolation", "distance reconstruction", "per-edge distance", "prebaked at 24 px"]), column("outline", ["reads the true distance in alpha", "samples coverage in eight directions"])] },
|
|
163
|
-
{ id: "text-scale", title: "Text Scale", description: "One sentence at six sizes, over three raster strategies at one size.", notes: "Not a reference port. The top row puts 26 px under the screen-driven ladder, a fixed 1x raster and a fixed 4x raster; the rows below run 8 px to 96 px, so the rung changes — and the absence of a soft step between them — are visible in one frame. The first strategy is what a caller gets by default.", implemented: true, group: "text", hideGrid: true, columns: [column("raster", ["screen decides the rung", "fixed 1x", "fixed 4x"]), column("sizes", ["8 px", "12 px", "18 px", "28 px", "48 px", "96 px"])] },
|
|
164
|
-
{ id: "text-world-zoom", title: "Text World Zoom", description: "Four sources in world space, made to be magnified with the camera.", notes: "Not a reference port. Screen-space text cannot be magnified — a larger block is simply a request for a new rasterisation — so world-space rows are the only honest test of what a source does past the size its glyphs were built at. Scroll to move the camera in and out: a coverage source runs into the texels it stored, a distance field keeps rebuilding the edge from them.", implemented: true, group: "text", hideGrid: false, columns: [column("source", ["bitmap 1x", "bitmap 4x", "sdf 4x", "msdf baked"]), column("past its raster", ["shows the stored texels", "shows smaller texels", "rebuilds the edge", "rebuilds from a 24 px page"])] },
|
|
165
|
-
{ id: "text-layout", title: "Text Layout", description: "Wrapping, justification, bounds, line height, letter spacing and spans.", notes: "Not a reference port. The layout follows the documented wrapping and justification semantics, and `docs/text-reference.md` records how each capability is verified. Each row is one capability, labelled on the left, and every bounded row draws the box it wrapped into — a wrapping rule is unreadable without it.", implemented: true, group: "text", hideGrid: true, columns: [column("capability", ["word wrap", "character wrap", "justify", "line height", "letter spacing", "spans"]), column("option", ["lineBreak", "lineBreak", "justify", "lineHeight", "letterSpacing", "TextSpan"])] },
|
|
166
|
-
{ id: "text-anchor", title: "Text Anchors", description: "The nine anchors against the position a block is handed and the bounds it lands in.", notes: "Not a reference port. The plus is the position the block is given, the box is the bounds it laid out into, and the label names the anchor — so both of the things an anchor moves between are visible at once.", implemented: true, group: "text", hideGrid: true, columns: [column("anchor", ["top-left", "top-center", "top-right", "center-left", "center", "center-right", "bottom-left", "bottom-center", "bottom-right"])] },
|
|
167
|
-
{ id: "text-cjk", title: "Text CJK", description: "Wrapping per character, kinsoku, mixed scripts and four sizes.", notes: "Not a reference port. CJK has no spaces to break at, so the layout breaks between characters and applies kinsoku: a closing mark never opens a line and an opening bracket never ends one, and the narrow column is tuned so those rules have to act. The family is the bundled latin face, and the canvas falls back to a system CJK face for the ideographs — the same arrangement a system font fallback provides.", implemented: true, group: "text", hideGrid: true, columns: [column("rule", ["per character", "kinsoku", "mixed script"]), column("sizes", ["12 px", "18 px", "28 px", "48 px"])] },
|
|
168
|
-
{
|
|
169
|
-
id: "2d-gizmos",
|
|
170
|
-
title: "2D Gizmos",
|
|
171
|
-
description: "Immediate-mode 2D strokes in the camera-centred world2d space: lines, rays, joined strips, boxes, rounded boxes, circles, ellipses, arcs, crosses, arrows, curves and a grid.",
|
|
172
|
-
notes: "Not a reference port: this page is built directly on frame.d2. world2d puts the origin at the canvas centre, +y up, one unit per canvas pixel before the camera's pan and zoom. Drag to pan, scroll to zoom.",
|
|
173
|
-
implemented: true,
|
|
174
|
-
family: "2d",
|
|
175
|
-
// The 2D grid is part of what these pages demonstrate, so it opens on even if the
|
|
176
|
-
// previous page had it off.
|
|
177
|
-
hideGrid: false,
|
|
178
|
-
view2d: { width: 1080, height: 640 },
|
|
179
|
-
columns: [
|
|
180
|
-
column("stroke", ["line", "ray", "linestrip", "rect", "roundedRect", "circle", "ellipse", "arc", "cross", "arrow", "curve", "grid"]),
|
|
181
|
-
column("option", ["width", "joint", "dash", "fill", "strokeWidth", "startAngle", "sweep", "rotation", "space"]),
|
|
182
|
-
],
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
id: "2d-shapes",
|
|
186
|
-
title: "2D Shapes",
|
|
187
|
-
description: "Twelve 2D primitives as filled shapes, with their stroked outlines underneath.",
|
|
188
|
-
notes: "Not a reference port: this page is built on frame.d2 shape primitives. Each shape is one instanced quad evaluated as a signed distance field, so an outline width is a pixel count at any zoom and nothing is triangulated on the CPU. Drag to pan, scroll to zoom.",
|
|
189
|
-
implemented: true,
|
|
190
|
-
family: "2d",
|
|
191
|
-
// The 2D grid is part of what these pages demonstrate, so it opens on even if the
|
|
192
|
-
// previous page had it off.
|
|
193
|
-
hideGrid: false,
|
|
194
|
-
view2d: { width: 1260, height: 560 },
|
|
195
|
-
columns: [
|
|
196
|
-
column("filled", ["circle", "sector", "segment", "ellipse", "annulus", "capsule", "rhombus", "rect", "polygon", "triangle", "segment2d", "polyline2d"]),
|
|
197
|
-
column("ring", ["circle", "sector", "segment", "ellipse", "annulus", "capsule", "rhombus", "rect", "polygon", "triangle"]),
|
|
198
|
-
],
|
|
199
|
-
},
|
|
200
|
-
];
|
package/dist/scenes-2d.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* reference 2D reference pages.
|
|
3
|
-
*
|
|
4
|
-
* These are vgpu's own capability pages built on `frame.d2`, not ports of a reference: the
|
|
5
|
-
* reference has no 2D API, so the models are reference `2d_gizmos` and `2d_shapes`. That also
|
|
6
|
-
* means the coordinate convention is reference: the origin sits at the canvas centre, +y points up,
|
|
7
|
-
* and one world unit covers one canvas pixel before the 2D camera's pan and zoom.
|
|
8
|
-
*
|
|
9
|
-
* Two conventions carry over from the text pages: a page heading in the top-left corner (a
|
|
10
|
-
* screen-space block, so the labels stay put while the 2D camera pans), and one shape per column
|
|
11
|
-
* with the row meaning stated once.
|
|
12
|
-
*/
|
|
13
|
-
import type { FrameRecorder } from "./frame-recorder.js";
|
|
14
|
-
/**
|
|
15
|
-
* Dispatches the 2D pages. Returns false for every other id so `buildScene` can fall through to
|
|
16
|
-
* the 3D scenes.
|
|
17
|
-
*/
|
|
18
|
-
export declare function buildScene2D(id: string, recorder: FrameRecorder, time: number): boolean;
|