@drawcall/lod 0.1.2 → 0.2.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 (144) hide show
  1. package/README.md +10 -69
  2. package/dist/at.d.ts +2 -0
  3. package/dist/at.js +8 -0
  4. package/dist/at.js.map +1 -0
  5. package/dist/baked/codec.d.ts +6 -3
  6. package/dist/baked/codec.js +22 -16
  7. package/dist/baked/codec.js.map +1 -1
  8. package/dist/baked/index.d.ts +4 -0
  9. package/dist/baked/index.js +2 -2
  10. package/dist/baked/index.js.map +1 -1
  11. package/dist/baked/low.d.ts +2 -2
  12. package/dist/baked/low.js +4 -4
  13. package/dist/baked/low.js.map +1 -1
  14. package/dist/bounds.d.ts +12 -2
  15. package/dist/bounds.js +72 -10
  16. package/dist/bounds.js.map +1 -1
  17. package/dist/compile.d.ts +4 -0
  18. package/dist/compile.js +100 -0
  19. package/dist/compile.js.map +1 -0
  20. package/dist/deferred.d.ts +12 -0
  21. package/dist/deferred.js +27 -0
  22. package/dist/deferred.js.map +1 -0
  23. package/dist/dispose.d.ts +7 -3
  24. package/dist/dispose.js +33 -4
  25. package/dist/dispose.js.map +1 -1
  26. package/dist/fade.d.ts +5 -13
  27. package/dist/fade.js +62 -28
  28. package/dist/fade.js.map +1 -1
  29. package/dist/impostor/bake/index.d.ts +1 -0
  30. package/dist/impostor/bake/index.js +1 -0
  31. package/dist/impostor/bake/index.js.map +1 -1
  32. package/dist/impostor/bake/materials.js +11 -1
  33. package/dist/impostor/bake/materials.js.map +1 -1
  34. package/dist/impostor/codec.d.ts +2 -7
  35. package/dist/impostor/codec.js +16 -27
  36. package/dist/impostor/codec.js.map +1 -1
  37. package/dist/impostor/mesh/card.js +4 -1
  38. package/dist/impostor/mesh/card.js.map +1 -1
  39. package/dist/impostor/mesh/index.d.ts +6 -4
  40. package/dist/impostor/mesh/index.js +8 -10
  41. package/dist/impostor/mesh/index.js.map +1 -1
  42. package/dist/impostor/mesh/material.d.ts +7 -5
  43. package/dist/impostor/mesh/material.js +29 -26
  44. package/dist/impostor/mesh/material.js.map +1 -1
  45. package/dist/impostor/mesh/surface.d.ts +20 -16
  46. package/dist/impostor/mesh/surface.js +74 -55
  47. package/dist/impostor/mesh/surface.js.map +1 -1
  48. package/dist/impostor/octahedral.d.ts +1 -8
  49. package/dist/impostor/octahedral.js +3 -18
  50. package/dist/impostor/octahedral.js.map +1 -1
  51. package/dist/index.d.ts +7 -6
  52. package/dist/index.js +5 -4
  53. package/dist/index.js.map +1 -1
  54. package/dist/instanced/args.js +2 -2
  55. package/dist/instanced/args.js.map +1 -1
  56. package/dist/instanced/{bounds.d.ts → blocks.d.ts} +25 -9
  57. package/dist/instanced/{bounds.js → blocks.js} +76 -53
  58. package/dist/instanced/blocks.js.map +1 -0
  59. package/dist/instanced/dirty.d.ts +3 -0
  60. package/dist/instanced/dirty.js +40 -5
  61. package/dist/instanced/dirty.js.map +1 -1
  62. package/dist/instanced/index.d.ts +25 -51
  63. package/dist/instanced/index.js +189 -413
  64. package/dist/instanced/index.js.map +1 -1
  65. package/dist/instanced/meshes.d.ts +54 -13
  66. package/dist/instanced/meshes.js +178 -41
  67. package/dist/instanced/meshes.js.map +1 -1
  68. package/dist/instanced/parts.d.ts +14 -0
  69. package/dist/instanced/parts.js +79 -0
  70. package/dist/instanced/parts.js.map +1 -0
  71. package/dist/instanced/raycast.d.ts +13 -0
  72. package/dist/instanced/raycast.js +53 -0
  73. package/dist/instanced/raycast.js.map +1 -0
  74. package/dist/instanced/select.d.ts +17 -9
  75. package/dist/instanced/select.js +114 -63
  76. package/dist/instanced/select.js.map +1 -1
  77. package/dist/instanced/store.d.ts +31 -0
  78. package/dist/instanced/store.js +96 -0
  79. package/dist/instanced/store.js.map +1 -0
  80. package/dist/levels.d.ts +71 -48
  81. package/dist/levels.js +99 -74
  82. package/dist/levels.js.map +1 -1
  83. package/dist/loader/bundle.d.ts +25 -0
  84. package/dist/loader/bundle.js +241 -0
  85. package/dist/loader/bundle.js.map +1 -0
  86. package/dist/loader/cache.d.ts +15 -15
  87. package/dist/loader/cache.js +71 -33
  88. package/dist/loader/cache.js.map +1 -1
  89. package/dist/loader/provenance.d.ts +30 -0
  90. package/dist/loader/provenance.js +105 -0
  91. package/dist/loader/provenance.js.map +1 -0
  92. package/dist/loader/url.d.ts +13 -0
  93. package/dist/loader/url.js +31 -0
  94. package/dist/loader/url.js.map +1 -0
  95. package/dist/loader.d.ts +30 -74
  96. package/dist/loader.js +191 -186
  97. package/dist/loader.js.map +1 -1
  98. package/dist/lod.d.ts +20 -31
  99. package/dist/lod.js +105 -96
  100. package/dist/lod.js.map +1 -1
  101. package/dist/material.js +9 -4
  102. package/dist/material.js.map +1 -1
  103. package/dist/mesh/codec.d.ts +4 -0
  104. package/dist/mesh/codec.js +192 -0
  105. package/dist/mesh/codec.js.map +1 -0
  106. package/dist/queue.d.ts +2 -0
  107. package/dist/queue.js +33 -0
  108. package/dist/queue.js.map +1 -0
  109. package/dist/residency.d.ts +44 -0
  110. package/dist/residency.js +205 -0
  111. package/dist/residency.js.map +1 -0
  112. package/dist/simplify.js +5 -3
  113. package/dist/simplify.js.map +1 -1
  114. package/dist/source/{error.d.ts → deviation.d.ts} +3 -3
  115. package/dist/source/{error.js → deviation.js} +6 -6
  116. package/dist/source/deviation.js.map +1 -0
  117. package/dist/source/source.d.ts +1 -1
  118. package/dist/source/source.js +1 -1
  119. package/dist/three.d.ts +17 -5
  120. package/dist/three.js +24 -3
  121. package/dist/three.js.map +1 -1
  122. package/dist/tsl.d.ts +5 -5
  123. package/dist/tsl.js +12 -19
  124. package/dist/tsl.js.map +1 -1
  125. package/dist/view.d.ts +16 -1
  126. package/dist/view.js +57 -1
  127. package/dist/view.js.map +1 -1
  128. package/dist/wind/index.d.ts +2 -2
  129. package/dist/wind/index.js +31 -28
  130. package/dist/wind/index.js.map +1 -1
  131. package/dist/wind/sway.d.ts +2 -1
  132. package/package.json +9 -3
  133. package/skills/lod/SKILL.md +71 -109
  134. package/dist/impostor/cache.d.ts +0 -15
  135. package/dist/impostor/cache.js +0 -44
  136. package/dist/impostor/cache.js.map +0 -1
  137. package/dist/instanced/bounds.js.map +0 -1
  138. package/dist/lazy.d.ts +0 -64
  139. package/dist/lazy.js +0 -187
  140. package/dist/lazy.js.map +0 -1
  141. package/dist/loader/dispose.d.ts +0 -3
  142. package/dist/loader/dispose.js +0 -25
  143. package/dist/loader/dispose.js.map +0 -1
  144. package/dist/source/error.js.map +0 -1
@@ -0,0 +1,241 @@
1
+ import { Box3, Group, Matrix4 } from "three/webgpu";
2
+ import { decodeBakedMeshAsync, encodeBakedMesh } from "../baked/codec.js";
3
+ import { boundingBox, measureLevels } from "../bounds.js";
4
+ import { loadOnce } from "../deferred.js";
5
+ import { disposeRejected } from "../dispose.js";
6
+ import { decodeImpostorAsync, encodeImpostor } from "../impostor/codec.js";
7
+ import { ImpostorMesh } from "../impostor/mesh/index.js";
8
+ import { measure, recordDeviation, resolveThresholds } from "../levels.js";
9
+ import { isImpostorMesh, isMesh } from "../three.js";
10
+ import { decodeMeshAsync, encodeMesh } from "../mesh/codec.js";
11
+ /** The coarsest drawable level, whose payload the index inlines unless it is the source, which loads from its URL. */
12
+ function coarsestOf(kinds) {
13
+ return kinds.reduce((last, kind, index) => (kind === "empty" ? last : index), -1);
14
+ }
15
+ /** The ladder indices whose payload is saved as its own entry: every derived drawable level except the inlined coarsest. */
16
+ export function separateLevels(kinds) {
17
+ const coarsest = coarsestOf(kinds);
18
+ return kinds.flatMap((kind, index) => (kind === "source" || kind === "empty" || index === coarsest ? [] : [index]));
19
+ }
20
+ /**
21
+ * Inline coarse derived payloads; a source-only request leaves its source deferred. The index
22
+ * keeps what thresholds are measured from, not thresholds or impostor draw options, so changing
23
+ * either reuses the cache. `levels` maps each deferred level index to its payload.
24
+ */
25
+ export async function encode(objects, kinds) {
26
+ const payloads = [];
27
+ const metadata = [];
28
+ const materials = materialsOf(objects[0]);
29
+ if (kinds.length !== objects.length)
30
+ throw new Error("LodLoader: level kinds do not match levels");
31
+ for (const [level, object] of objects.entries()) {
32
+ const kind = kinds[level];
33
+ if (!kind)
34
+ throw new Error("LodLoader: missing level kind");
35
+ const box = boundingBox(object);
36
+ if (box.isEmpty() && kind !== "empty")
37
+ throw new Error(`LodLoader: ${kind} level ${level} has an empty box`);
38
+ const bytes = await payload(object, kind, materials);
39
+ if (object.matrixAutoUpdate)
40
+ object.updateMatrix();
41
+ metadata.push({
42
+ kind,
43
+ name: object.name,
44
+ ...measure(object),
45
+ box: box.isEmpty() ? null : [...box.min.toArray(), ...box.max.toArray()],
46
+ matrix: object.matrix.toArray(),
47
+ matrixAutoUpdate: object.matrixAutoUpdate,
48
+ castShadow: object.castShadow,
49
+ receiveShadow: object.receiveShadow,
50
+ length: bytes.byteLength,
51
+ });
52
+ payloads.push(bytes);
53
+ }
54
+ const coarsest = coarsestOf(kinds);
55
+ if (coarsest < 0)
56
+ throw new Error("LodLoader: cache has no drawable level");
57
+ const coarse = coarsest > 0 ? payloads[coarsest] : new Uint8Array();
58
+ if (!coarse)
59
+ throw new Error("LodLoader: missing coarse payload");
60
+ const header = new TextEncoder().encode(JSON.stringify(metadata));
61
+ const index = new Uint8Array(8 + header.length + coarse.length);
62
+ const view = new DataView(index.buffer);
63
+ view.setUint32(0, 0x32444f4c, true);
64
+ view.setUint32(4, header.length, true);
65
+ index.set(header, 8);
66
+ index.set(coarse, 8 + header.length);
67
+ const levels = new Map(separateLevels(kinds).map((level) => {
68
+ const bytes = payloads[level];
69
+ if (!bytes)
70
+ throw new Error(`LodLoader: missing payload ${level}`);
71
+ return [level, bytes];
72
+ }));
73
+ return { index, levels };
74
+ }
75
+ async function payload(object, kind, materials) {
76
+ switch (kind) {
77
+ case "source":
78
+ case "empty":
79
+ return new Uint8Array();
80
+ case "simplify":
81
+ return encodeMesh(object, materials);
82
+ case "baked":
83
+ if (!isMesh(object))
84
+ throw new Error("LodLoader: baked level is not a mesh");
85
+ return encodeBakedMesh(object);
86
+ case "impostor":
87
+ if (!isImpostorMesh(object))
88
+ throw new Error("LodLoader: impostor level is not an ImpostorMesh");
89
+ return encodeImpostor(object.impostor);
90
+ }
91
+ }
92
+ /** The inverse of `payload`; `read` has checked that a source or empty level has no bytes. */
93
+ async function decodePayload(kind, bytes, loadSource, materials, draw) {
94
+ switch (kind) {
95
+ case "source":
96
+ return loadSource();
97
+ case "empty":
98
+ return new Group();
99
+ case "simplify":
100
+ return decodeMeshAsync(await bytes(), await materials());
101
+ case "baked":
102
+ return decodeBakedMeshAsync(await bytes());
103
+ case "impostor":
104
+ return new ImpostorMesh(await decodeImpostorAsync(await bytes()), 1, draw);
105
+ }
106
+ }
107
+ /** Index metadata exposes every drawable level without decoding its payload. `requested` holds level i's request at i. */
108
+ export function decode(bytes, requested, loadSource, loadLevel, onLevel, release = disposeRejected) {
109
+ const { metadata, coarsest, coarse } = read(bytes);
110
+ if (requested.length !== metadata.length)
111
+ fail("level count");
112
+ const diameter = measureLevels(metadata, "LodLoader").own.radius * 2;
113
+ const thresholds = resolveThresholds(metadata.map(({ deviation, texels }, index) => ({ maxPixels: requested[index]?.maxPixels, measured: { deviation, texels } })), diameter);
114
+ const materials = async () => {
115
+ const source = levels[0];
116
+ if (!source)
117
+ fail("missing source materials");
118
+ return materialsOf(source.object ?? (await loadOnce(source.load).promise));
119
+ };
120
+ const levels = metadata.map((level, index) => {
121
+ const load = async () => {
122
+ const levelBytes = async () => {
123
+ const payload = index === coarsest && coarsest > 0 ? coarse : await loadLevel(index);
124
+ if (payload.length !== level.length)
125
+ fail(`level ${index} payload length`);
126
+ return payload;
127
+ };
128
+ const loaded = await decodePayload(level.kind, levelBytes, loadSource, materials, requested[index]?.draw);
129
+ try {
130
+ place(loaded, level);
131
+ if (level.deviation !== undefined)
132
+ recordDeviation(loaded, level.deviation);
133
+ await onLevel?.(loaded, index);
134
+ return loaded;
135
+ }
136
+ catch (error) {
137
+ release(loaded);
138
+ throw error;
139
+ }
140
+ };
141
+ return {
142
+ load,
143
+ maxPixels: thresholds[index] ?? fail("missing threshold"),
144
+ box: level.box.clone().applyMatrix4(level.matrix),
145
+ };
146
+ });
147
+ return levels;
148
+ }
149
+ function materialsOf(object) {
150
+ const materials = [];
151
+ object?.traverse((node) => {
152
+ if (isMesh(node))
153
+ for (const material of [node.material].flat())
154
+ materials.push(material);
155
+ });
156
+ return materials;
157
+ }
158
+ function place(object, level) {
159
+ object.name = level.name;
160
+ level.matrix.decompose(object.position, object.quaternion, object.scale);
161
+ object.matrix.copy(level.matrix);
162
+ object.matrixAutoUpdate = level.matrixAutoUpdate;
163
+ object.castShadow = level.castShadow;
164
+ object.receiveShadow = level.receiveShadow;
165
+ }
166
+ function read(bytes) {
167
+ if (bytes.length < 8)
168
+ fail("missing header");
169
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
170
+ const length = view.getUint32(4, true);
171
+ if (view.getUint32(0, true) !== 0x32444f4c || length > bytes.length - 8)
172
+ fail("invalid header");
173
+ const parsed = JSON.parse(new TextDecoder().decode(bytes.subarray(8, 8 + length)));
174
+ if (!Array.isArray(parsed) || !parsed.length)
175
+ fail("missing levels");
176
+ const metadata = parsed.map((value) => {
177
+ const meta = object(value);
178
+ const kind = meta.kind;
179
+ if (kind !== "simplify" && kind !== "baked" && kind !== "impostor" && kind !== "empty" && kind !== "source")
180
+ fail("unknown level kind");
181
+ if (typeof meta.name !== "string" ||
182
+ typeof meta.castShadow !== "boolean" ||
183
+ typeof meta.receiveShadow !== "boolean" ||
184
+ typeof meta.matrixAutoUpdate !== "boolean")
185
+ fail("invalid level settings");
186
+ const size = finite(meta.length);
187
+ if (!Number.isSafeInteger(size) || size < 0)
188
+ fail("invalid payload length");
189
+ const box = meta.box === null ? new Box3() : new Box3().setFromArray(numbers(meta.box, 6));
190
+ if (box.isEmpty() && kind !== "empty")
191
+ fail("drawable level has an empty box");
192
+ if ((kind === "empty" || kind === "source") !== (size === 0))
193
+ fail("invalid level payload length");
194
+ const matrix = new Matrix4().fromArray(numbers(meta.matrix, 16));
195
+ const deviation = meta.deviation === undefined ? undefined : finite(meta.deviation);
196
+ if (deviation !== undefined && deviation < 0)
197
+ fail("negative deviation");
198
+ const texels = meta.texels === undefined ? undefined : finite(meta.texels);
199
+ if (texels !== undefined && texels <= 0)
200
+ fail("invalid texels");
201
+ const level = {
202
+ kind,
203
+ name: meta.name,
204
+ deviation,
205
+ texels,
206
+ box,
207
+ matrix,
208
+ matrixAutoUpdate: meta.matrixAutoUpdate,
209
+ castShadow: meta.castShadow,
210
+ receiveShadow: meta.receiveShadow,
211
+ length: size,
212
+ };
213
+ return level;
214
+ });
215
+ const coarsest = coarsestOf(metadata.map((level) => level.kind));
216
+ if (coarsest < 0)
217
+ fail("no drawable level");
218
+ const size = coarsest > 0 ? metadata[coarsest]?.length : 0;
219
+ if (size === undefined || bytes.length !== 8 + length + size)
220
+ fail("invalid coarse payload length");
221
+ return { metadata, coarsest, coarse: bytes.subarray(8 + length) };
222
+ }
223
+ function object(value) {
224
+ if (typeof value !== "object" || value === null || Array.isArray(value))
225
+ fail("expected metadata object");
226
+ return Object.fromEntries(Object.entries(value));
227
+ }
228
+ function finite(value) {
229
+ if (typeof value !== "number" || !Number.isFinite(value))
230
+ fail("expected finite number");
231
+ return value;
232
+ }
233
+ function numbers(value, count) {
234
+ if (!Array.isArray(value) || value.length !== count)
235
+ fail(`expected ${count} numbers`);
236
+ return value.map(finite);
237
+ }
238
+ function fail(reason) {
239
+ throw new Error(`LodLoader: invalid cache (${reason})`);
240
+ }
241
+ //# sourceMappingURL=bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/loader/bundle.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,15 @@
1
- import type { GLTSSource } from "@drawcall/glts";
2
- import type { Object3D } from "three/webgpu";
3
- import type { Dependencies } from "vitecache";
4
- import { type BakeImpostorOptions } from "../impostor/bake/index.js";
5
- import { type ImpostorCacheOptions } from "../impostor/cache.js";
6
- import type { Impostor } from "../impostor/impostor.js";
7
- /** Cache location and additional inputs that GLTS does not track, such as generator packages. */
8
- export interface LodCacheOptions extends ImpostorCacheOptions {
9
- /** Extra vitecache dependencies. Names beginning with glts: or lod: are reserved. */
10
- dependencies?: Dependencies;
11
- }
12
- /** Loaded GLTS scenes expose their run's source even outside an active script. */
13
- export declare function originOf(object: Object3D): GLTSSource | undefined;
14
- /** Capture dependencies when the bake starts, including files loaded since its request. */
15
- export declare function impostor(source: Object3D, options: BakeImpostorOptions, origin?: GLTSSource, excluded?: readonly Object3D[], cacheOptions?: LodCacheOptions): Promise<Impostor>;
1
+ import { CacheEntry, type CacheEntryOptions, type Dependencies } from "vitecache";
2
+ import type { LevelRequest } from "../loader.js";
3
+ /** Persistent cache location. Generator packages are discovered from GLTS source provenance. */
4
+ export type LodCacheOptions = Pick<CacheEntryOptions, "basePath" | "root">;
5
+ /**
6
+ * The index of a ladder: keyed by the requested URLs, levels and bundled modules, and saved with what loading the sources
7
+ * revealed, so vitecache rechecks those without loading the sources.
8
+ */
9
+ export declare function indexEntry(inputs: Dependencies, levels: readonly LevelRequest[], modules: Readonly<Record<string, string>>, options?: LodCacheOptions): CacheEntry;
10
+ /**
11
+ * A level payload saved apart from its index, addressed by the index's content: a valid index vouches for its payloads,
12
+ * and rebuilds write new ones rather than replacing those a live ladder or another build still reads.
13
+ */
14
+ export declare function payloadEntry(index: string, level: number, options?: LodCacheOptions): CacheEntry;
15
+ export declare function sha256(bytes: Uint8Array): Promise<string>;
@@ -1,37 +1,75 @@
1
- import { bake, bakeImpostor } from "../impostor/bake/index.js";
2
- import { cached } from "../impostor/cache.js";
3
- /** Loaded GLTS scenes expose their run's source even outside an active script. */
4
- export function originOf(object) {
5
- const source = Reflect.get(object, "source");
6
- if (source === undefined)
7
- return undefined;
8
- if (!isSource(source))
9
- throw new Error("LodLoader: invalid GLTS source metadata");
10
- return source;
1
+ import { CacheEntry } from "vitecache";
2
+ import { urlQuery } from "./url.js";
3
+ const version = "lod-levels@18";
4
+ /**
5
+ * The index of a ladder: keyed by the requested URLs, levels and bundled modules, and saved with what loading the sources
6
+ * revealed, so vitecache rechecks those without loading the sources.
7
+ */
8
+ export function indexEntry(inputs, levels, modules, options) {
9
+ // vitecache resolves URLs to file paths; keep generation parameters in the key.
10
+ const queries = {};
11
+ for (const [name, dependency] of Object.entries(inputs)) {
12
+ const query = dependency.url === undefined ? "" : urlQuery(dependency.url);
13
+ if (query)
14
+ queries[name] = query;
15
+ }
16
+ return new CacheEntry({
17
+ basePath: options?.basePath,
18
+ root: options?.root,
19
+ version,
20
+ dependencies: {
21
+ ...inputs,
22
+ "lod:levels": { value: levels.map(parameters) },
23
+ "lod:modules": { value: modules },
24
+ "lod:queries": { value: queries },
25
+ // Only packages the app installs resolve from its root; this package's own dependencies are covered by its version and `version` above.
26
+ "lod:package": { package: "@drawcall/lod" },
27
+ "lod:three": { package: "three" },
28
+ },
29
+ });
11
30
  }
12
- function isSource(source) {
13
- if (typeof source !== "object" || source === null)
14
- return false;
15
- const url = Reflect.get(source, "url");
16
- const dependencies = Reflect.get(source, "dependencyUrls");
17
- return typeof url === "string" && Array.isArray(dependencies) && dependencies.every((url) => typeof url === "string");
31
+ /**
32
+ * A level payload saved apart from its index, addressed by the index's content: a valid index vouches for its payloads,
33
+ * and rebuilds write new ones rather than replacing those a live ladder or another build still reads.
34
+ */
35
+ export function payloadEntry(index, level, options) {
36
+ return new CacheEntry({
37
+ basePath: options?.basePath,
38
+ root: options?.root,
39
+ version,
40
+ dependencies: { "lod:index": { value: index }, "lod:level": { value: level } },
41
+ });
18
42
  }
19
- /** Capture dependencies when the bake starts, including files loaded since its request. */
20
- export async function impostor(source, options, origin, excluded = [], cacheOptions) {
21
- const make = (settings) => (excluded.length > 0 ? bake(source, settings, excluded) : bakeImpostor(source, settings));
22
- if (!origin)
23
- return make(options);
24
- const urls = origin.dependencyUrls;
25
- const { dependencies = {}, ...location } = cacheOptions ?? {};
26
- if (Object.keys(dependencies).some((name) => name.startsWith("glts:")))
27
- throw new Error("LodLoader: dependency names beginning with glts: are reserved");
28
- return cached(options, {
29
- ...dependencies,
30
- "glts:source": { url: origin.url },
31
- // URL resolution tracks the file; retain its query parameters as inputs too.
32
- "glts:query": { value: new URL(origin.url).search },
33
- ...Object.fromEntries(urls.map((url, index) => [`glts:dependency:${index}`, { url }])),
34
- "glts:dependencyQueries": { value: urls.map((url) => new URL(url).search) },
35
- }, make, location);
43
+ export async function sha256(bytes) {
44
+ const hash = await crypto.subtle.digest("SHA-256", new Uint8Array(bytes));
45
+ return Array.from(new Uint8Array(hash), (byte) => byte.toString(16).padStart(2, "0")).join("");
46
+ }
47
+ /** What derives each level's content. Switch thresholds and impostor draw options apply at decode, so changing one reuses the cache. */
48
+ function parameters(level) {
49
+ switch (level.type) {
50
+ case "empty":
51
+ return { type: level.type };
52
+ case "simplify":
53
+ return { type: level.type, ratio: level.ratio ?? null };
54
+ case "baked":
55
+ return {
56
+ type: level.type,
57
+ ratio: level.ratio ?? null,
58
+ textureSize: level.textureSize ?? null,
59
+ low: level.low ?? null,
60
+ interior: level.interior ?? null,
61
+ };
62
+ case "impostor":
63
+ return {
64
+ type: level.type,
65
+ // The impostor bakes its top mip for this height too.
66
+ maxPixels: level.maxPixels ?? null,
67
+ layout: level.layout ?? null,
68
+ frames: level.frames ?? null,
69
+ resolution: level.resolution ?? null,
70
+ emissive: level.emissive ?? null,
71
+ supersample: level.supersample ?? null,
72
+ };
73
+ }
36
74
  }
37
75
  //# sourceMappingURL=cache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/loader/cache.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,YAAY,EAA4B,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,MAAM,EAA6B,MAAM,sBAAsB,CAAC;AASzE,kFAAkF;AAClF,MAAM,UAAU,QAAQ,CAAC,MAAgB;IACvC,MAAM,MAAM,GAAY,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAClF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,MAAe;IAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChE,MAAM,GAAG,GAAY,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAChD,MAAM,YAAY,GAAY,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACpE,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC;AACjI,CAAC;AAED,2FAA2F;AAC3F,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAgB,EAChB,OAA4B,EAC5B,MAAmB,EACnB,WAAgC,EAAE,EAClC,YAA8B;IAE9B,MAAM,IAAI,GAAG,CAAC,QAA6B,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1I,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,CAAC;IACnC,MAAM,EAAE,YAAY,GAAG,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,YAAY,IAAI,EAAE,CAAC;IAC9D,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACzJ,OAAO,MAAM,CACX,OAAO,EACP;QACE,GAAG,YAAY;QACf,aAAa,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE;QAClC,6EAA6E;QAC7E,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE;QACnD,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,mBAAmB,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACtF,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE;KAC5E,EACD,IAAI,EACJ,QAAQ,CACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/loader/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { LoadingManager, Object3D } from "three/webgpu";
2
+ import type { Dependencies, SavedDependencies } from "vitecache";
3
+ /** The requested assets, and the files and packages loading them revealed, for saving with the index built from them. */
4
+ export declare class Provenance {
5
+ private readonly manager;
6
+ readonly inputs: Dependencies;
7
+ private readonly resources;
8
+ /** Kept whole: a GLTS source reports what it has observed so far, so it is read when saving. */
9
+ private readonly scripts;
10
+ constructor(urls: Readonly<Record<string, string>>, manager: LoadingManager);
11
+ capture(url: string, object: Object3D, result: unknown): void;
12
+ /** The requested URLs, resolved as `inputs` holds them. */
13
+ get requested(): string[];
14
+ /**
15
+ * What the captured assets were built from so far, beyond the requested URLs, or why that cannot be validated later:
16
+ * a CDN module fetched at runtime, which bundled moduleSources cannot vouch for, or a cross-origin resource, which
17
+ * vitecache cannot hash.
18
+ */
19
+ dependencies(): {
20
+ dependencies: SavedDependencies;
21
+ } | {
22
+ reason: string;
23
+ };
24
+ }
25
+ /**
26
+ * Digests of the bundled modules each input script's GLTS loader links, by input name. They are known before a source runs,
27
+ * so they key its levels: a source's bundled module hashes come from these moduleSources. Any change to them, such as a new
28
+ * bare import in any .glts, therefore invalidates every GLTS-derived level.
29
+ */
30
+ export declare function bundledModules(urls: Readonly<Record<string, string>>, manager: LoadingManager): Promise<Record<string, string>>;
@@ -0,0 +1,105 @@
1
+ import { isGLTSLoader, isGLTSScene } from "../three.js";
2
+ import { sha256 } from "./cache.js";
3
+ import { assetPath, isLocal, localURL, sourceRelativeURL, urlPath } from "./url.js";
4
+ /** The requested assets, and the files and packages loading them revealed, for saving with the index built from them. */
5
+ export class Provenance {
6
+ manager;
7
+ inputs;
8
+ resources = new Set();
9
+ /** Kept whole: a GLTS source reports what it has observed so far, so it is read when saving. */
10
+ scripts = [];
11
+ constructor(urls, manager) {
12
+ this.manager = manager;
13
+ this.inputs = Object.fromEntries(Object.entries(urls).map(([name, url]) => [name, { url: localURL(manager.resolveURL(url)) }]));
14
+ }
15
+ capture(url, object, result) {
16
+ if (assetPath(url).extension !== "glts") {
17
+ for (const uri of gltfUrls(result, url))
18
+ this.resources.add(localURL(this.manager.resolveURL(uri)));
19
+ return;
20
+ }
21
+ if (!isGLTSScene(object))
22
+ throw new Error(`LodLoader: "${url}" did not load as a GLTS scene`);
23
+ this.scripts.push(object.source);
24
+ }
25
+ /** The requested URLs, resolved as `inputs` holds them. */
26
+ get requested() {
27
+ return Object.values(this.inputs).flatMap(({ url }) => (url === undefined ? [] : [url]));
28
+ }
29
+ /**
30
+ * What the captured assets were built from so far, beyond the requested URLs, or why that cannot be validated later:
31
+ * a CDN module fetched at runtime, which bundled moduleSources cannot vouch for, or a cross-origin resource, which
32
+ * vitecache cannot hash.
33
+ */
34
+ dependencies() {
35
+ if (this.scripts.some((source) => source.runtimeModules.length))
36
+ return { reason: "it imports CDN modules at runtime" };
37
+ const found = new Set(this.resources);
38
+ for (const source of this.scripts)
39
+ for (const url of [source.url, ...source.dependencyUrls])
40
+ found.add(localURL(url));
41
+ const inputs = this.requested;
42
+ // A script's provenance URL carries its execution's query, so any query of an input script is that input.
43
+ const scripts = new Set(inputs.filter((url) => assetPath(url).extension === "glts").map(urlPath));
44
+ const urls = [...found].filter((url) => !inputs.includes(url) && !scripts.has(urlPath(url))).sort();
45
+ const remote = urls.find((url) => !isLocal(url));
46
+ if (remote)
47
+ return { reason: `it loads the cross-origin resource "${remote}"` };
48
+ const packages = [...new Set(this.scripts.flatMap((source) => source.packages))].sort();
49
+ return {
50
+ dependencies: {
51
+ ...Object.fromEntries(urls.map((url, index) => [`resource:${index}`, { url }])),
52
+ ...Object.fromEntries(packages.map((name) => [`package:${name}`, { package: name }])),
53
+ },
54
+ };
55
+ }
56
+ }
57
+ const digests = new WeakMap();
58
+ /**
59
+ * Digests of the bundled modules each input script's GLTS loader links, by input name. They are known before a source runs,
60
+ * so they key its levels: a source's bundled module hashes come from these moduleSources. Any change to them, such as a new
61
+ * bare import in any .glts, therefore invalidates every GLTS-derived level.
62
+ */
63
+ export async function bundledModules(urls, manager) {
64
+ const found = {};
65
+ for (const [name, url] of Object.entries(urls)) {
66
+ const handler = manager.getHandler(urlPath(url));
67
+ if (!handler || !isGLTSLoader(handler))
68
+ continue;
69
+ let digest = digests.get(handler.moduleSources);
70
+ if (!digest) {
71
+ // Include namespace bindings: an unused namespace can retain an old module URL.
72
+ digest = sha256(new TextEncoder().encode(JSON.stringify(handler.moduleSources)));
73
+ digests.set(handler.moduleSources, digest);
74
+ }
75
+ found[name] = await digest;
76
+ }
77
+ return found;
78
+ }
79
+ function field(value, name) {
80
+ return typeof value === "object" && value !== null ? Reflect.get(value, name) : undefined;
81
+ }
82
+ function gltfUrls(result, url) {
83
+ const parser = field(result, "parser");
84
+ if (parser === undefined)
85
+ return [];
86
+ const json = field(parser, "json");
87
+ if (typeof json !== "object" || json === null)
88
+ throw new Error("LodLoader: glTF parser.json must provide source metadata");
89
+ return ["buffers", "images"].flatMap((name) => {
90
+ const resources = field(json, name);
91
+ if (resources === undefined)
92
+ return [];
93
+ if (!Array.isArray(resources))
94
+ throw new Error(`LodLoader: glTF ${name} must be an array`);
95
+ return resources.flatMap((resource) => {
96
+ const uri = field(resource, "uri");
97
+ if (uri === undefined)
98
+ return [];
99
+ if (typeof uri !== "string")
100
+ throw new Error("LodLoader: glTF resource URIs must be strings");
101
+ return /^data:/i.test(uri) ? [] : [sourceRelativeURL(uri, url)];
102
+ });
103
+ });
104
+ }
105
+ //# sourceMappingURL=provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../src/loader/provenance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** Resolve a relative asset path without changing absolute URLs or root-relative paths. */
2
+ export declare function loaderPathURL(url: string, base: string): string;
3
+ export declare const urlPath: (url: string) => string;
4
+ export declare const urlQuery: (url: string) => string;
5
+ export declare function assetPath(url: string): {
6
+ path: string;
7
+ extension: string;
8
+ };
9
+ export declare function sourceRelativeURL(value: string, source: string): string;
10
+ /** A same-origin path, as localURL leaves it: vitecache can resolve only these to project files. */
11
+ export declare const isLocal: (url: string) => boolean;
12
+ /** Keep same-origin dependencies portable between development and deployment. */
13
+ export declare function localURL(url: string): string;
@@ -0,0 +1,31 @@
1
+ import { LoaderUtils } from "three/webgpu";
2
+ const absolute = /^[a-z][a-z\d+.-]*:/i;
3
+ const fallbackBase = "https://lod.invalid";
4
+ /** Resolve a relative asset path without changing absolute URLs or root-relative paths. */
5
+ export function loaderPathURL(url, base) {
6
+ return absolute.test(url) || url.startsWith("/") ? url : LoaderUtils.resolveURL(url, base);
7
+ }
8
+ export const urlPath = (url) => url.replace(/[?#].*$/s, "");
9
+ export const urlQuery = (url) => new URL(url, fallbackBase).search;
10
+ export function assetPath(url) {
11
+ const path = urlPath(url);
12
+ const extension = /\.(glb|gltf|glts)$/i.exec(path)?.[1]?.toLowerCase();
13
+ if (!extension)
14
+ throw new Error(`LodLoader: cannot load "${url}": expected a .glb, .gltf or .glts file`);
15
+ return { path, extension };
16
+ }
17
+ export function sourceRelativeURL(value, source) {
18
+ const base = new URL(source, typeof document === "undefined" ? fallbackBase : document.baseURI);
19
+ const url = new URL(value, base);
20
+ return url.origin === base.origin && !absolute.test(source) ? url.pathname + url.search + url.hash : url.href;
21
+ }
22
+ /** A same-origin path, as localURL leaves it: vitecache can resolve only these to project files. */
23
+ export const isLocal = (url) => url.startsWith("/") && !url.startsWith("//");
24
+ /** Keep same-origin dependencies portable between development and deployment. */
25
+ export function localURL(url) {
26
+ if (typeof location === "undefined" || !/^https?:/i.test(url))
27
+ return url;
28
+ const parsed = new URL(url);
29
+ return parsed.origin === location.origin ? parsed.pathname + parsed.search + parsed.hash : url;
30
+ }
31
+ //# sourceMappingURL=url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/loader/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,QAAQ,GAAG,qBAAqB,CAAC;AACvC,MAAM,YAAY,GAAG,qBAAqB,CAAC;AAE3C,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,IAAY;IACrD,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC7F,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC5E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC;AAEnF,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IACvE,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,yCAAyC,CAAC,CAAC;IACzG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,MAAc;IAC7D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChG,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AAChH,CAAC;AAED,oGAAoG;AACpG,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAE9F,iFAAiF;AACjF,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,IAAI,OAAO,QAAQ,KAAK,WAAW,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC1E,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;AACjG,CAAC"}