@yali-engine/render 0.0.0-stage → 0.4.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.
Files changed (131) hide show
  1. package/dist/bvh.d.ts +66 -0
  2. package/dist/bvh.js +493 -0
  3. package/dist/bvh.js.map +1 -0
  4. package/dist/camera.d.ts +34 -0
  5. package/dist/camera.js +66 -0
  6. package/dist/camera.js.map +1 -0
  7. package/dist/cluster-build.d.ts +46 -0
  8. package/dist/cluster-build.js +179 -0
  9. package/dist/cluster-build.js.map +1 -0
  10. package/dist/cluster-pages.d.ts +70 -0
  11. package/dist/cluster-pages.js +203 -0
  12. package/dist/cluster-pages.js.map +1 -0
  13. package/dist/cluster-stream.d.ts +83 -0
  14. package/dist/cluster-stream.js +226 -0
  15. package/dist/cluster-stream.js.map +1 -0
  16. package/dist/culled-draws.d.ts +30 -0
  17. package/dist/culled-draws.js +103 -0
  18. package/dist/culled-draws.js.map +1 -0
  19. package/dist/debug-lines.d.ts +51 -0
  20. package/dist/debug-lines.js +158 -0
  21. package/dist/debug-lines.js.map +1 -0
  22. package/dist/device-profile.d.ts +100 -0
  23. package/dist/device-profile.js +131 -0
  24. package/dist/device-profile.js.map +1 -0
  25. package/dist/device.d.ts +39 -0
  26. package/dist/device.js +79 -0
  27. package/dist/device.js.map +1 -0
  28. package/dist/environment.d.ts +60 -0
  29. package/dist/environment.js +204 -0
  30. package/dist/environment.js.map +1 -0
  31. package/dist/extract.d.ts +74 -0
  32. package/dist/extract.js +194 -0
  33. package/dist/extract.js.map +1 -0
  34. package/dist/frame-graph.d.ts +112 -0
  35. package/dist/frame-graph.js +226 -0
  36. package/dist/frame-graph.js.map +1 -0
  37. package/dist/gpu-health.d.ts +74 -0
  38. package/dist/gpu-health.js +106 -0
  39. package/dist/gpu-health.js.map +1 -0
  40. package/dist/gpu-timer.d.ts +26 -0
  41. package/dist/gpu-timer.js +93 -0
  42. package/dist/gpu-timer.js.map +1 -0
  43. package/dist/headless.d.ts +28 -0
  44. package/dist/headless.js +91 -0
  45. package/dist/headless.js.map +1 -0
  46. package/dist/index.d.ts +34 -0
  47. package/dist/index.js +36 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/lights.d.ts +81 -0
  50. package/dist/lights.js +247 -0
  51. package/dist/lights.js.map +1 -0
  52. package/dist/matrix.d.ts +6 -0
  53. package/dist/matrix.js +59 -0
  54. package/dist/matrix.js.map +1 -0
  55. package/dist/meshes.d.ts +411 -0
  56. package/dist/meshes.js +545 -0
  57. package/dist/meshes.js.map +1 -0
  58. package/dist/meshlets-decoder.d.ts +20 -0
  59. package/dist/meshlets-decoder.js +47 -0
  60. package/dist/meshlets-decoder.js.map +1 -0
  61. package/dist/meshlets.d.ts +186 -0
  62. package/dist/meshlets.js +1040 -0
  63. package/dist/meshlets.js.map +1 -0
  64. package/dist/occlusion.d.ts +51 -0
  65. package/dist/occlusion.js +188 -0
  66. package/dist/occlusion.js.map +1 -0
  67. package/dist/pick-decoder.d.ts +19 -0
  68. package/dist/pick-decoder.js +45 -0
  69. package/dist/pick-decoder.js.map +1 -0
  70. package/dist/pick.d.ts +86 -0
  71. package/dist/pick.js +452 -0
  72. package/dist/pick.js.map +1 -0
  73. package/dist/pipeline-cache.d.ts +53 -0
  74. package/dist/pipeline-cache.js +96 -0
  75. package/dist/pipeline-cache.js.map +1 -0
  76. package/dist/post-options.d.ts +109 -0
  77. package/dist/post-options.js +23 -0
  78. package/dist/post-options.js.map +1 -0
  79. package/dist/post-shaders.gen.d.ts +40 -0
  80. package/dist/post-shaders.gen.js +43 -0
  81. package/dist/post-shaders.gen.js.map +1 -0
  82. package/dist/post.d.ts +101 -0
  83. package/dist/post.js +555 -0
  84. package/dist/post.js.map +1 -0
  85. package/dist/render-plugin.d.ts +239 -0
  86. package/dist/render-plugin.js +633 -0
  87. package/dist/render-plugin.js.map +1 -0
  88. package/dist/scene.d.ts +406 -0
  89. package/dist/scene.js +2005 -0
  90. package/dist/scene.js.map +1 -0
  91. package/dist/shaders.gen.d.ts +40 -0
  92. package/dist/shaders.gen.js +43 -0
  93. package/dist/shaders.gen.js.map +1 -0
  94. package/dist/shadows.d.ts +104 -0
  95. package/dist/shadows.js +227 -0
  96. package/dist/shadows.js.map +1 -0
  97. package/dist/staging-ring.d.ts +41 -0
  98. package/dist/staging-ring.js +125 -0
  99. package/dist/staging-ring.js.map +1 -0
  100. package/dist/textures.d.ts +165 -0
  101. package/dist/textures.js +361 -0
  102. package/dist/textures.js.map +1 -0
  103. package/dist/tonemap.d.ts +45 -0
  104. package/dist/tonemap.js +141 -0
  105. package/dist/tonemap.js.map +1 -0
  106. package/dist/viewport.d.ts +78 -0
  107. package/dist/viewport.js +130 -0
  108. package/dist/viewport.js.map +1 -0
  109. package/dist/webgl2/plugin.d.ts +40 -0
  110. package/dist/webgl2/plugin.js +190 -0
  111. package/dist/webgl2/plugin.js.map +1 -0
  112. package/dist/webgl2/program.d.ts +27 -0
  113. package/dist/webgl2/program.js +74 -0
  114. package/dist/webgl2/program.js.map +1 -0
  115. package/dist/webgl2/renderer.d.ts +128 -0
  116. package/dist/webgl2/renderer.js +976 -0
  117. package/dist/webgl2/renderer.js.map +1 -0
  118. package/dist/webgl2/shaders.glsl.gen.d.ts +27 -0
  119. package/dist/webgl2/shaders.glsl.gen.js +20 -0
  120. package/dist/webgl2/shaders.glsl.gen.js.map +1 -0
  121. package/dist/webgl2/textures.d.ts +11 -0
  122. package/dist/webgl2/textures.js +82 -0
  123. package/dist/webgl2/textures.js.map +1 -0
  124. package/dist/webgl2/webgl2.d.ts +1 -0
  125. package/dist/webgl2/webgl2.js +4 -0
  126. package/dist/webgl2/webgl2.js.map +1 -0
  127. package/dist/worker-mode.d.ts +85 -0
  128. package/dist/worker-mode.js +204 -0
  129. package/dist/worker-mode.js.map +1 -0
  130. package/package.json +47 -3
  131. package/README.md +0 -3
package/dist/camera.js ADDED
@@ -0,0 +1,66 @@
1
+ import { frustum, mat4 } from '@yali-engine/math';
2
+ const ORIGIN = [0, 0, 0];
3
+ const UP = [0, 1, 0];
4
+ /**
5
+ * An orbit camera for camera-relative rendering (ADR-0008).
6
+ *
7
+ * - The eye position is f64 (`eye`). The renderer subtracts it from every instance before
8
+ * the f32 conversion (the core's extract step), so the GPU only sees numbers near zero.
9
+ * - The view matrix therefore carries rotation only.
10
+ * - The projection is reverse-Z with an infinite far plane: depth is 1 at `near` and goes
11
+ * to 0 at infinity. Clear depth to 0 and compare `greater`.
12
+ *
13
+ * `uniform` is the 176-byte `Camera` struct of `shaders/core/camera.wesl`, rewritten in
14
+ * place by `update()`, which allocates nothing.
15
+ */
16
+ export class OrbitCamera {
17
+ /** Orbit centre (f64 world space). */
18
+ target = new Float64Array(3);
19
+ /** Eye position (f64 world space), derived by `update()`. */
20
+ eye = new Float64Array(3);
21
+ yaw = 0.6;
22
+ pitch = 0.35;
23
+ distance = 120;
24
+ fovY = (55 * Math.PI) / 180;
25
+ near = 0.1;
26
+ /** Direction towards the light (camera-relative = world, the view has no translation). */
27
+ lightDir = new Float32Array([0.45, 0.8, 0.4]);
28
+ /** Seconds for node materials' `time` (the render plugin sets the app's virtual time). */
29
+ time = 0;
30
+ /** viewProj (16) + 6 frustum planes (24) + lightDir (xyz) and time (w) = 44 floats. */
31
+ uniform = new Float32Array(44);
32
+ #view = new Float32Array(16);
33
+ #proj = new Float32Array(16);
34
+ #forward = new Float64Array(3);
35
+ /** The view matrix (rotation only, camera-relative; column-major), as of the last `update`. */
36
+ get view() {
37
+ return this.#view;
38
+ }
39
+ /** Recomputes the eye, matrices and frustum for `aspect` (width / height). */
40
+ update(aspect) {
41
+ const cp = Math.cos(this.pitch);
42
+ const t = this.target;
43
+ const e = this.eye;
44
+ e[0] = t[0] + this.distance * cp * Math.sin(this.yaw);
45
+ e[1] = t[1] + this.distance * Math.sin(this.pitch);
46
+ e[2] = t[2] + this.distance * cp * Math.cos(this.yaw);
47
+ // The view looks from the origin (camera-relative, ADR-0008) towards the target; the
48
+ // projection is reverse-Z with an infinite far plane. All from @yali-engine/math (ADR-0054).
49
+ const f = this.#forward;
50
+ f[0] = t[0] - e[0];
51
+ f[1] = t[1] - e[1];
52
+ f[2] = t[2] - e[2];
53
+ mat4.lookTo(this.#view, ORIGIN, f, UP);
54
+ mat4.perspectiveInfiniteReverse(this.#proj, this.fovY, aspect, this.near);
55
+ const m = this.uniform;
56
+ mat4.multiply(m, this.#proj, this.#view);
57
+ // Frustum planes (left, right, bottom, top, near, far) right after viewProj.
58
+ frustum.setFromProjectionMatrix(m, m, 16, 0);
59
+ const ll = Math.hypot(this.lightDir[0], this.lightDir[1], this.lightDir[2]) || 1;
60
+ m[40] = this.lightDir[0] / ll;
61
+ m[41] = this.lightDir[1] / ll;
62
+ m[42] = this.lightDir[2] / ll;
63
+ m[43] = this.time;
64
+ }
65
+ }
66
+ //# sourceMappingURL=camera.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera.js","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /** Bytes per cluster record (`Cluster` in shaders/scene/clusters.wesl): 32 words since ADR-0111. */
2
+ export declare const CLUSTER_BYTES = 128;
3
+ /** Words per cluster record. */
4
+ export declare const CLUSTER_WORDS: number;
5
+ /** A cluster of a mesh: its triangles (mesh vertex ids) and, in a hierarchy, its error spheres (ADR-0111). */
6
+ export interface LodCluster {
7
+ readonly indices: Uint32Array;
8
+ /** Its own error (mesh units) and the sphere it is measured from; its parent group's (-1: a root, none). */
9
+ selfError: number;
10
+ selfSphere: [number, number, number, number];
11
+ parentError: number;
12
+ parentSphere: [number, number, number, number];
13
+ readonly level: number;
14
+ /** The hierarchy group it is a child of (-1: a root), and the group it was simplified from (-1: level 0). For streaming pages (ADR-0134). */
15
+ group?: number;
16
+ madeFrom?: number;
17
+ }
18
+ /**
19
+ * A mesh's cluster LOD hierarchy (ADR-0111; Nanite-style): level 0 is its own clusters; each next
20
+ * level groups the last level's clusters by shared vertices, simplifies each group to half its
21
+ * triangles with the group's border locked (neighbouring groups still meet), and clusters the
22
+ * result. A cluster's error is its group's simplification error (at least its children's), its
23
+ * parent's the group it went into, each measured from a sphere holding its children's. A group that
24
+ * will not halve, and the last level, are roots (parent error -1).
25
+ */
26
+ export declare function buildClusterLod(vertices: Float32Array, indices: Uint32Array, maxLevels?: number): LodCluster[];
27
+ /**
28
+ * One mesh's clusters in the layout the shaders read, with offsets from 0 (ADR-0113): `ClusterData.append`
29
+ * moves them to where they land and sets the mesh's base vertex and side. Typed arrays only, so a
30
+ * decode worker transfers it back without a copy.
31
+ */
32
+ export interface PackedClusters {
33
+ /** CLUSTER_WORDS per cluster: base vertex 0, vertex and triangle offsets from 0, flags 0. */
34
+ readonly words: Uint32Array;
35
+ /** The clusters' local vertex indices (mesh vertex ids). */
36
+ readonly vertices: Uint32Array;
37
+ /** Their triangle bytes, each cluster's start rounded to 4. */
38
+ readonly triangles: Uint8Array;
39
+ /** Index count over every cluster (an instance's most). */
40
+ readonly corners: number;
41
+ }
42
+ /**
43
+ * Clusters a mesh (interleaved vertices, 8 floats each; its finest LOD's indices); with `lod`, its
44
+ * whole hierarchy (ADR-0111). Needs `MeshoptClusterizer.ready` (and the simplifier's for `lod`).
45
+ */
46
+ export declare function packClusters(vertices: Float32Array, indices: Uint32Array, lod: boolean): PackedClusters;
@@ -0,0 +1,179 @@
1
+ // Building a mesh's clusters (ADR-0100) and its cluster LOD hierarchy (ADR-0111), pure: no GPU,
2
+ // no scene. `@yali-engine/render/meshlets` runs it on the main thread, and the `cluster-lod` decoder
3
+ // (`@yali-engine/render/meshlets-decoder`) on a decode worker (ADR-0113), so both import only this and
4
+ // meshoptimizer.
5
+ import { MeshoptClusterizer } from 'meshoptimizer/clusterizer';
6
+ import { MeshoptSimplifier } from 'meshoptimizer/simplifier';
7
+ /** Bytes per cluster record (`Cluster` in shaders/scene/clusters.wesl): 32 words since ADR-0111. */
8
+ export const CLUSTER_BYTES = 128;
9
+ /** Words per cluster record. */
10
+ export const CLUSTER_WORDS = CLUSTER_BYTES / 4;
11
+ const MAX_VERTICES = 64;
12
+ const MAX_TRIANGLES = 124;
13
+ /** Clusters merged and simplified together per hierarchy group. */
14
+ const GROUP = 4;
15
+ /** A mesh's clusters (meshoptimizer's meshlets), each as its own triangle list of mesh vertex ids. */
16
+ function clusterize(indices, vertices) {
17
+ const m = MeshoptClusterizer.buildMeshlets(indices, vertices, 8, MAX_VERTICES, MAX_TRIANGLES, 0.25);
18
+ const out = [];
19
+ for (let k = 0; k < m.meshletCount; k++) {
20
+ const [vo, to, , tc] = [m.meshlets[k * 4], m.meshlets[k * 4 + 1], m.meshlets[k * 4 + 2], m.meshlets[k * 4 + 3]];
21
+ const ix = new Uint32Array(tc * 3);
22
+ for (let t = 0; t < tc * 3; t++)
23
+ ix[t] = m.vertices[vo + m.triangles[to + t]];
24
+ out.push(ix);
25
+ }
26
+ return out;
27
+ }
28
+ function sphereOf(indices, vertices) {
29
+ const b = MeshoptClusterizer.computeClusterBounds(indices, vertices, 8);
30
+ return [b.centerX, b.centerY, b.centerZ, b.radius];
31
+ }
32
+ /** A sphere holding every sphere in `ss`. */
33
+ function mergeSpheres(ss) {
34
+ const pos = new Float32Array(ss.length * 3);
35
+ const rad = new Float32Array(ss.length);
36
+ ss.forEach((q, i) => {
37
+ pos.set(q.slice(0, 3), i * 3);
38
+ rad[i] = q[3];
39
+ });
40
+ const b = MeshoptClusterizer.computeSphereBounds(pos, 3, rad, 1);
41
+ return [b.centerX, b.centerY, b.centerZ, b.radius];
42
+ }
43
+ /** Groups of up to GROUP clusters that share vertices (greedy: each grows by the cluster sharing the most). */
44
+ function groupClusters(clusters) {
45
+ const byVertex = new Map();
46
+ clusters.forEach((ix, c) => {
47
+ for (const v of new Set(ix)) {
48
+ const l = byVertex.get(v);
49
+ if (l)
50
+ l.push(c);
51
+ else
52
+ byVertex.set(v, [c]);
53
+ }
54
+ });
55
+ const taken = new Uint8Array(clusters.length);
56
+ const groups = [];
57
+ for (let seed = 0; seed < clusters.length; seed++) {
58
+ if (taken[seed])
59
+ continue;
60
+ const group = [seed];
61
+ taken[seed] = 1;
62
+ while (group.length < GROUP) {
63
+ const shared = new Map();
64
+ for (const c of group)
65
+ for (const v of new Set(clusters[c]))
66
+ for (const o of byVertex.get(v))
67
+ if (!taken[o])
68
+ shared.set(o, (shared.get(o) ?? 0) + 1);
69
+ let best = -1;
70
+ let most = 0;
71
+ for (const [o, n] of shared)
72
+ if (n > most)
73
+ (most = n), (best = o);
74
+ if (best < 0)
75
+ break;
76
+ group.push(best);
77
+ taken[best] = 1;
78
+ }
79
+ groups.push(group);
80
+ }
81
+ return groups;
82
+ }
83
+ /**
84
+ * A mesh's cluster LOD hierarchy (ADR-0111; Nanite-style): level 0 is its own clusters; each next
85
+ * level groups the last level's clusters by shared vertices, simplifies each group to half its
86
+ * triangles with the group's border locked (neighbouring groups still meet), and clusters the
87
+ * result. A cluster's error is its group's simplification error (at least its children's), its
88
+ * parent's the group it went into, each measured from a sphere holding its children's. A group that
89
+ * will not halve, and the last level, are roots (parent error -1).
90
+ */
91
+ export function buildClusterLod(vertices, indices, maxLevels = 16) {
92
+ const all = [];
93
+ let level = clusterize(indices, vertices).map((ix) => ({ indices: ix, selfError: 0, selfSphere: sphereOf(ix, vertices), parentError: -1, parentSphere: [0, 0, 0, 0], level: 0, group: -1, madeFrom: -1 }));
94
+ all.push(...level);
95
+ let groups = 0;
96
+ for (let l = 1; l < maxLevels && level.length > 1; l++) {
97
+ const next = [];
98
+ for (const g of groupClusters(level.map((c) => c.indices))) {
99
+ const kids = g.map((k) => level[k]);
100
+ let n = 0;
101
+ for (const k of kids)
102
+ n += k.indices.length;
103
+ const merged = new Uint32Array(n);
104
+ let o = 0;
105
+ for (const k of kids) {
106
+ merged.set(k.indices, o);
107
+ o += k.indices.length;
108
+ }
109
+ const [simple, err] = MeshoptSimplifier.simplify(merged, vertices, 8, Math.floor(n / 6) * 3, 1e9, ['LockBorder', 'Sparse', 'ErrorAbsolute']);
110
+ if (g.length < 2 || simple.length > n * 0.85)
111
+ continue;
112
+ const error = Math.max(err, ...kids.map((k) => k.selfError));
113
+ const sphere = mergeSpheres(kids.map((k) => k.selfSphere));
114
+ const id = groups++;
115
+ for (const k of kids) {
116
+ k.parentError = error;
117
+ k.parentSphere = sphere;
118
+ k.group = id;
119
+ }
120
+ for (const ix of clusterize(simple, vertices))
121
+ next.push({ indices: ix, selfError: error, selfSphere: sphere, parentError: -1, parentSphere: [0, 0, 0, 0], level: l, group: -1, madeFrom: id });
122
+ }
123
+ if (next.length === 0)
124
+ break;
125
+ all.push(...next);
126
+ level = next;
127
+ }
128
+ return all;
129
+ }
130
+ /**
131
+ * Clusters a mesh (interleaved vertices, 8 floats each; its finest LOD's indices); with `lod`, its
132
+ * whole hierarchy (ADR-0111). Needs `MeshoptClusterizer.ready` (and the simplifier's for `lod`).
133
+ */
134
+ export function packClusters(vertices, indices, lod) {
135
+ const clusters = lod
136
+ ? buildClusterLod(vertices, indices)
137
+ : clusterize(indices, vertices).map((ix) => ({ indices: ix, selfError: 0, selfSphere: [0, 0, 0, 0], parentError: 0, parentSphere: [0, 0, 0, 0], level: 0 }));
138
+ const words = new Uint32Array(clusters.length * CLUSTER_WORDS);
139
+ const f = new Float32Array(words.buffer);
140
+ let nv = 0;
141
+ let nt = 0;
142
+ for (const c of clusters) {
143
+ nv += c.indices.length; // at most one local vertex per corner
144
+ nt += (c.indices.length + 3) & ~3;
145
+ }
146
+ let vertexOut = new Uint32Array(nv);
147
+ let triOut = new Uint8Array(nt);
148
+ let vCount = 0;
149
+ let tBytes = 0;
150
+ let corners = 0;
151
+ clusters.forEach((c, k) => {
152
+ // Local vertices in first-use order, and the triangles over them as bytes.
153
+ const local = new Map();
154
+ const vBase = vCount;
155
+ const t = tBytes;
156
+ c.indices.forEach((v, i) => {
157
+ let j = local.get(v);
158
+ if (j === undefined) {
159
+ j = vCount++ - vBase;
160
+ local.set(v, j);
161
+ vertexOut[vBase + j] = v;
162
+ }
163
+ triOut[t + i] = j;
164
+ });
165
+ tBytes = (t + c.indices.length + 3) & ~3;
166
+ const b = MeshoptClusterizer.computeClusterBounds(c.indices, vertices, 8);
167
+ const o = k * CLUSTER_WORDS;
168
+ f.set([b.centerX, b.centerY, b.centerZ, b.radius, b.coneApexX, b.coneApexY, b.coneApexZ, b.coneCutoff, b.coneAxisX, b.coneAxisY, b.coneAxisZ], o);
169
+ words[o + 12] = vBase;
170
+ words[o + 13] = t;
171
+ words[o + 14] = c.indices.length / 3;
172
+ f.set([...c.selfSphere, ...c.parentSphere, c.selfError, c.parentError, 0, 0, 0, 0, 0, 0], o + 16);
173
+ corners += c.indices.length;
174
+ });
175
+ vertexOut = vertexOut.slice(0, vCount);
176
+ triOut = triOut.slice(0, tBytes);
177
+ return { words, vertices: vertexOut, triangles: triOut, corners };
178
+ }
179
+ //# sourceMappingURL=cluster-build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-build.js","sourceRoot":"","sources":["../src/cluster-build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /** Words per page in a page table: first cluster, cluster count, vertex count, byte offset, byte length. */
2
+ export declare const PAGE_WORDS = 5;
3
+ /** Words before a page's data: vertex count, local id count, triangle bytes, vertex codec, vertex bytes. */
4
+ export declare const PAGE_HEADER_WORDS = 5;
5
+ /** A page's vertex block: 8 floats a vertex as written, or meshopt's vertex codec. */
6
+ export declare const PAGE_CODEC_RAW = 0;
7
+ export declare const PAGE_CODEC_MESHOPT = 1;
8
+ /** The cluster record's word holding its page (bits 2+) and its residency flags (bits 0–1). */
9
+ export declare const STREAM_WORD = 26;
10
+ /** The cluster record's word holding the page of the group it was simplified from, plus 1 (0: none, level 0). */
11
+ export declare const KIDS_WORD = 27;
12
+ /** Residency flags (`STREAM_WORD`): its page is not on the GPU (never drawn). */
13
+ export declare const STREAM_MISSING = 1;
14
+ /** Residency flags: its children's page is not on the GPU (drawn as a leaf of the cut). */
15
+ export declare const STREAM_LEAF = 2;
16
+ /** Encodes a page's vertices (`MeshoptEncoder.encodeVertexBuffer(bytes, count, 32)` from `meshoptimizer/encoder`). */
17
+ export type PageVertexEncoder = (bytes: Uint8Array, count: number, stride: number) => Uint8Array;
18
+ /** Decodes them (`MeshoptDecoder.decodeVertexBuffer(target, count, 32, source)` from `meshoptimizer/decoder`). */
19
+ export type PageVertexDecoder = (target: Uint8Array, count: number, stride: number, source: Uint8Array) => void;
20
+ export interface ClusterPageOptions {
21
+ /** The most GPU bytes a page holds (its local ids, triangle bytes and vertices); default 65536. A group bigger than that gets a page of its own. */
22
+ readonly pageBytes?: number;
23
+ /** Compresses each page's vertices; without it they are stored as written. */
24
+ readonly encode?: PageVertexEncoder;
25
+ }
26
+ /**
27
+ * A mesh's cluster hierarchy in pages (ADR-0134). The records are all in the file (128 bytes a
28
+ * cluster: what the cut needs); a page holds the topology and the vertices of whole hierarchy
29
+ * groups, coarse levels first. Pages `[0, roots)` hold the roots and stay resident; their
30
+ * vertices and triangles also form the primitive's own mesh (`rootVertices`, `rootIndices`), what
31
+ * a loader without streaming draws.
32
+ */
33
+ export interface ClusterPages {
34
+ /** `CLUSTER_WORDS` a cluster, in page order: base vertex 0 (set where the page lands), vertex and triangle offsets over the whole hierarchy, `STREAM_WORD` = page << 2, `KIDS_WORD` = the children's page + 1. */
35
+ readonly words: Uint32Array;
36
+ /** Local vertex ids and triangle bytes over every page: the room the records' offsets index. */
37
+ readonly localIds: number;
38
+ readonly triangleBytes: number;
39
+ /** Index count over every cluster (an instance's most). */
40
+ readonly corners: number;
41
+ /** `PAGE_WORDS` a page. */
42
+ readonly pages: Uint32Array;
43
+ /** Root pages (the first ones). */
44
+ readonly roots: number;
45
+ /** The most vertices any page past the roots holds (a page slot's size). */
46
+ readonly slotVertices: number;
47
+ /** Every page's bytes, one after another (each 4-aligned): the roots first. */
48
+ readonly data: Uint8Array;
49
+ /** The root pages' vertices (8 floats each, page after page) and their clusters' triangles over them. */
50
+ readonly rootVertices: Float32Array;
51
+ readonly rootIndices: Uint32Array;
52
+ }
53
+ /** One decoded page: its clusters' local ids (page vertex ids), their triangle bytes, its vertices. */
54
+ export interface DecodedPage {
55
+ readonly ids: Uint32Array;
56
+ readonly triangles: Uint8Array;
57
+ readonly vertices: Float32Array;
58
+ }
59
+ /**
60
+ * Builds a mesh's cluster LOD hierarchy (ADR-0111) and cuts it into pages (ADR-0134): the roots
61
+ * first, then each group's children (whole groups, so a page's arrival completes them), coarse
62
+ * levels before fine, packed greedily up to `pageBytes`. Needs `MeshoptClusterizer.ready` and
63
+ * the simplifier's.
64
+ */
65
+ export declare function buildClusterPages(vertices: Float32Array, indices: Uint32Array, o?: ClusterPageOptions): ClusterPages;
66
+ /**
67
+ * Decodes one page's bytes (`ClusterPages.data` from its table entry's offset and length, or what an
68
+ * HTTP `Range` fetch of `<name>.pages.bin` returned). A meshopt-coded page needs `decode`.
69
+ */
70
+ export declare function decodeClusterPage(bytes: Uint8Array, decode?: PageVertexDecoder): DecodedPage;
@@ -0,0 +1,203 @@
1
+ // Streaming cluster pages (ADR-0134, designed in ADR-0121): a mesh's cluster LOD hierarchy cut into
2
+ // pages that carry their own vertices, so a file downloads its coarse levels first and the rest as
3
+ // the view needs them. Pure: no GPU; `yali convert --clusters --stream` builds them in Node and the
4
+ // streamer (`@yali-engine/render/meshlets`) decodes them, so both import only this.
5
+ import { YaliError } from '@yali-engine/core';
6
+ import { MeshoptClusterizer } from 'meshoptimizer/clusterizer';
7
+ import { buildClusterLod, CLUSTER_WORDS } from "./cluster-build.js";
8
+ /** Words per page in a page table: first cluster, cluster count, vertex count, byte offset, byte length. */
9
+ export const PAGE_WORDS = 5;
10
+ /** Words before a page's data: vertex count, local id count, triangle bytes, vertex codec, vertex bytes. */
11
+ export const PAGE_HEADER_WORDS = 5;
12
+ /** A page's vertex block: 8 floats a vertex as written, or meshopt's vertex codec. */
13
+ export const PAGE_CODEC_RAW = 0;
14
+ export const PAGE_CODEC_MESHOPT = 1;
15
+ /** The cluster record's word holding its page (bits 2+) and its residency flags (bits 0–1). */
16
+ export const STREAM_WORD = 26;
17
+ /** The cluster record's word holding the page of the group it was simplified from, plus 1 (0: none, level 0). */
18
+ export const KIDS_WORD = 27;
19
+ /** Residency flags (`STREAM_WORD`): its page is not on the GPU (never drawn). */
20
+ export const STREAM_MISSING = 1;
21
+ /** Residency flags: its children's page is not on the GPU (drawn as a leaf of the cut). */
22
+ export const STREAM_LEAF = 2;
23
+ const VERTEX_FLOATS = 8;
24
+ const VERTEX_BYTES = VERTEX_FLOATS * 4;
25
+ /** GPU bytes a set of clusters takes in a page: local ids, triangle bytes (each cluster 4-aligned), deduplicated vertices. */
26
+ function unitBytes(cs, seen) {
27
+ let b = 0;
28
+ for (const c of cs) {
29
+ const own = new Set(c.indices);
30
+ b += own.size * 4 + ((c.indices.length + 3) & ~3);
31
+ for (const v of own)
32
+ if (!seen.has(v))
33
+ (seen.add(v), (b += VERTEX_BYTES));
34
+ }
35
+ return b;
36
+ }
37
+ /**
38
+ * Builds a mesh's cluster LOD hierarchy (ADR-0111) and cuts it into pages (ADR-0134): the roots
39
+ * first, then each group's children (whole groups, so a page's arrival completes them), coarse
40
+ * levels before fine, packed greedily up to `pageBytes`. Needs `MeshoptClusterizer.ready` and
41
+ * the simplifier's.
42
+ */
43
+ export function buildClusterPages(vertices, indices, o = {}) {
44
+ const limit = o.pageBytes ?? 65536;
45
+ const all = buildClusterLod(vertices, indices);
46
+ // Units: the roots, then each group's children, the coarsest groups first.
47
+ const roots = all.filter((c) => (c.group ?? -1) < 0);
48
+ const byGroup = new Map();
49
+ for (const c of all) {
50
+ const g = c.group ?? -1;
51
+ if (g < 0)
52
+ continue;
53
+ const l = byGroup.get(g);
54
+ if (l)
55
+ l.push(c);
56
+ else
57
+ byGroup.set(g, [c]);
58
+ }
59
+ const groups = [...byGroup.entries()].sort((a, b) => b[1][0].level - a[1][0].level || a[0] - b[0]);
60
+ const drafts = [];
61
+ const pack = (units) => {
62
+ const first = drafts.length;
63
+ let cur = null;
64
+ let seen = new Set();
65
+ for (const u of units) {
66
+ if (cur) {
67
+ const trial = new Set(seen);
68
+ const b = unitBytes(u, trial);
69
+ if (cur.bytes + b <= limit) {
70
+ cur.bytes += b;
71
+ cur.clusters.push(...u);
72
+ seen = trial;
73
+ continue;
74
+ }
75
+ }
76
+ seen = new Set();
77
+ cur = { clusters: [...u], bytes: unitBytes(u, seen) };
78
+ drafts.push(cur);
79
+ }
80
+ return drafts.length - first;
81
+ };
82
+ // Roots go a cluster at a time (they never leave, so any split is fine); groups whole.
83
+ const rootPages = pack(roots.map((c) => [c]));
84
+ pack(groups.map(([, cs]) => cs));
85
+ const pageOfGroup = new Map();
86
+ drafts.forEach((d, p) => {
87
+ for (const c of d.clusters)
88
+ if ((c.group ?? -1) >= 0)
89
+ pageOfGroup.set(c.group, p);
90
+ });
91
+ const n = all.length;
92
+ const words = new Uint32Array(n * CLUSTER_WORDS);
93
+ const f = new Float32Array(words.buffer);
94
+ const pages = new Uint32Array(drafts.length * PAGE_WORDS);
95
+ const chunks = [];
96
+ let dataBytes = 0;
97
+ let k = 0;
98
+ let idAt = 0;
99
+ let triAt = 0;
100
+ let corners = 0;
101
+ let slotVertices = 0;
102
+ const rootV = [];
103
+ const rootI = [];
104
+ let rootBase = 0;
105
+ drafts.forEach((d, p) => {
106
+ // The page's vertices in first-use order; each cluster's local ids over them.
107
+ const pageVertex = new Map();
108
+ const ids = [];
109
+ const tris = [];
110
+ const first = k;
111
+ for (const c of d.clusters) {
112
+ const local = new Map();
113
+ const o = k * CLUSTER_WORDS;
114
+ const vOff = idAt + ids.length;
115
+ const tOff = triAt + tris.length;
116
+ for (const v of c.indices) {
117
+ let j = local.get(v);
118
+ if (j === undefined) {
119
+ j = local.size;
120
+ local.set(v, j);
121
+ let pv = pageVertex.get(v);
122
+ if (pv === undefined)
123
+ pageVertex.set(v, (pv = pageVertex.size));
124
+ ids.push(pv);
125
+ }
126
+ tris.push(j);
127
+ }
128
+ while (tris.length & 3)
129
+ tris.push(0);
130
+ const b = MeshoptClusterizer.computeClusterBounds(c.indices, vertices, VERTEX_FLOATS);
131
+ f.set([b.centerX, b.centerY, b.centerZ, b.radius, b.coneApexX, b.coneApexY, b.coneApexZ, b.coneCutoff, b.coneAxisX, b.coneAxisY, b.coneAxisZ], o);
132
+ words[o + 12] = vOff;
133
+ words[o + 13] = tOff;
134
+ words[o + 14] = c.indices.length / 3;
135
+ f.set([...c.selfSphere, ...c.parentSphere, c.selfError, c.parentError], o + 16);
136
+ words[o + STREAM_WORD] = p << 2;
137
+ const from = c.madeFrom ?? -1;
138
+ words[o + KIDS_WORD] = from >= 0 ? pageOfGroup.get(from) + 1 : 0;
139
+ corners += c.indices.length;
140
+ // The root mesh: the page's vertices land after the earlier root pages'.
141
+ if (p < rootPages)
142
+ for (const v of c.indices)
143
+ rootI.push(rootBase + pageVertex.get(v));
144
+ k++;
145
+ }
146
+ const vcount = pageVertex.size;
147
+ const raw = new Float32Array(vcount * VERTEX_FLOATS);
148
+ for (const [v, pv] of pageVertex)
149
+ raw.set(vertices.subarray(v * VERTEX_FLOATS, v * VERTEX_FLOATS + VERTEX_FLOATS), pv * VERTEX_FLOATS);
150
+ if (p < rootPages) {
151
+ for (const x of raw)
152
+ rootV.push(x);
153
+ rootBase += vcount;
154
+ }
155
+ else
156
+ slotVertices = Math.max(slotVertices, vcount);
157
+ const rawBytes = new Uint8Array(raw.buffer);
158
+ const vbytes = o.encode ? o.encode(rawBytes, vcount, VERTEX_BYTES) : rawBytes;
159
+ const idBytes = (ids.length * 2 + 3) & ~3;
160
+ const size = PAGE_HEADER_WORDS * 4 + idBytes + tris.length + ((vbytes.length + 3) & ~3);
161
+ const page = new Uint8Array(size);
162
+ const head = new Uint32Array(page.buffer, 0, PAGE_HEADER_WORDS);
163
+ head.set([vcount, ids.length, tris.length, o.encode ? PAGE_CODEC_MESHOPT : PAGE_CODEC_RAW, vbytes.length]);
164
+ new Uint16Array(page.buffer, PAGE_HEADER_WORDS * 4, ids.length).set(ids);
165
+ page.set(tris, PAGE_HEADER_WORDS * 4 + idBytes);
166
+ page.set(vbytes, PAGE_HEADER_WORDS * 4 + idBytes + tris.length);
167
+ pages.set([first, k - first, vcount, dataBytes, size], p * PAGE_WORDS);
168
+ chunks.push(page);
169
+ dataBytes += size;
170
+ idAt += ids.length;
171
+ triAt += tris.length;
172
+ });
173
+ const data = new Uint8Array(dataBytes);
174
+ let at = 0;
175
+ for (const c of chunks)
176
+ (data.set(c, at), (at += c.length));
177
+ return { words, localIds: idAt, triangleBytes: triAt, corners, pages, roots: rootPages, slotVertices, data, rootVertices: new Float32Array(rootV), rootIndices: new Uint32Array(rootI) };
178
+ }
179
+ /**
180
+ * Decodes one page's bytes (`ClusterPages.data` from its table entry's offset and length, or what an
181
+ * HTTP `Range` fetch of `<name>.pages.bin` returned). A meshopt-coded page needs `decode`.
182
+ */
183
+ export function decodeClusterPage(bytes, decode) {
184
+ const aligned = bytes.byteOffset % 4 === 0 ? bytes : bytes.slice();
185
+ const head = new Uint32Array(aligned.buffer, aligned.byteOffset, PAGE_HEADER_WORDS);
186
+ const [vcount, nIds, triBytes, codec, vBytes] = head;
187
+ const idBytes = (nIds * 2 + 3) & ~3;
188
+ const at = aligned.byteOffset + PAGE_HEADER_WORDS * 4;
189
+ const ids = Uint32Array.from(new Uint16Array(aligned.buffer, at, nIds));
190
+ const triangles = aligned.slice(PAGE_HEADER_WORDS * 4 + idBytes, PAGE_HEADER_WORDS * 4 + idBytes + triBytes);
191
+ const vAt = PAGE_HEADER_WORDS * 4 + idBytes + triBytes;
192
+ const vertices = new Float32Array(vcount * VERTEX_FLOATS);
193
+ if (codec === PAGE_CODEC_RAW) {
194
+ new Uint8Array(vertices.buffer).set(aligned.subarray(vAt, vAt + vcount * VERTEX_BYTES));
195
+ }
196
+ else {
197
+ if (!decode)
198
+ throw new YaliError('PAGE_CODEC', 'This cluster page\'s vertices are meshopt-coded and no decoder was given.', 'Pass MeshoptDecoder.decodeVertexBuffer (meshoptimizer/decoder, after its ready) as decode.');
199
+ decode(new Uint8Array(vertices.buffer), vcount, VERTEX_BYTES, aligned.subarray(vAt, vAt + vBytes));
200
+ }
201
+ return { ids, triangles, vertices };
202
+ }
203
+ //# sourceMappingURL=cluster-pages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-pages.js","sourceRoot":"","sources":["../src/cluster-pages.ts"],"names":[],"mappings":"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"}