s3m-three 0.3.5 → 0.3.7

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 (69) hide show
  1. package/dist/browser/assets/s3mWorker-D7AV6O30.js +1 -0
  2. package/dist/browser/s3m-three.iife.ext-three.js +26 -20
  3. package/dist/browser/s3m-three.iife.js +26 -20
  4. package/dist/core/TextureDecode.d.ts +39 -0
  5. package/dist/core/TextureDecode.d.ts.map +1 -0
  6. package/dist/core/TextureDecode.js +174 -0
  7. package/dist/core/TextureDecode.js.map +1 -0
  8. package/dist/core/TextureFormat.d.ts +22 -2
  9. package/dist/core/TextureFormat.d.ts.map +1 -1
  10. package/dist/core/TextureFormat.js +22 -2
  11. package/dist/core/TextureFormat.js.map +1 -1
  12. package/dist/core/TileGeometry.d.ts +92 -0
  13. package/dist/core/TileGeometry.d.ts.map +1 -0
  14. package/dist/core/TileGeometry.js +607 -0
  15. package/dist/core/TileGeometry.js.map +1 -0
  16. package/dist/render/DatasetManager.d.ts +2 -0
  17. package/dist/render/DatasetManager.d.ts.map +1 -1
  18. package/dist/render/DatasetManager.js +1 -0
  19. package/dist/render/DatasetManager.js.map +1 -1
  20. package/dist/render/FeatureStyleManager.d.ts +4 -2
  21. package/dist/render/FeatureStyleManager.d.ts.map +1 -1
  22. package/dist/render/FeatureStyleManager.js +33 -1
  23. package/dist/render/FeatureStyleManager.js.map +1 -1
  24. package/dist/render/GeometryBuilder.d.ts +8 -10
  25. package/dist/render/GeometryBuilder.d.ts.map +1 -1
  26. package/dist/render/GeometryBuilder.js +77 -555
  27. package/dist/render/GeometryBuilder.js.map +1 -1
  28. package/dist/render/S3MViewer.d.ts +4 -0
  29. package/dist/render/S3MViewer.d.ts.map +1 -1
  30. package/dist/render/S3MViewer.js +13 -2
  31. package/dist/render/S3MViewer.js.map +1 -1
  32. package/dist/render/StyleMaterial.d.ts.map +1 -1
  33. package/dist/render/StyleMaterial.js +6 -0
  34. package/dist/render/StyleMaterial.js.map +1 -1
  35. package/dist/render/TextureFactory.d.ts +9 -19
  36. package/dist/render/TextureFactory.d.ts.map +1 -1
  37. package/dist/render/TextureFactory.js +62 -115
  38. package/dist/render/TextureFactory.js.map +1 -1
  39. package/dist/tileset/S3MTileset.d.ts +21 -0
  40. package/dist/tileset/S3MTileset.d.ts.map +1 -1
  41. package/dist/tileset/S3MTileset.js +41 -2
  42. package/dist/tileset/S3MTileset.js.map +1 -1
  43. package/dist/worker/S3MWorkerClient.d.ts +48 -0
  44. package/dist/worker/S3MWorkerClient.d.ts.map +1 -0
  45. package/dist/worker/S3MWorkerClient.js +124 -0
  46. package/dist/worker/S3MWorkerClient.js.map +1 -0
  47. package/dist/worker/s3mWorker.d.ts +2 -0
  48. package/dist/worker/s3mWorker.d.ts.map +1 -0
  49. package/dist/worker/s3mWorker.js +56 -0
  50. package/dist/worker/s3mWorker.js.map +1 -0
  51. package/dist/worker/transferables.d.ts +14 -0
  52. package/dist/worker/transferables.d.ts.map +1 -0
  53. package/dist/worker/transferables.js +61 -0
  54. package/dist/worker/transferables.js.map +1 -0
  55. package/docs/API.md +6 -0
  56. package/package.json +1 -1
  57. package/src/core/TextureDecode.ts +224 -0
  58. package/src/core/TextureFormat.ts +23 -2
  59. package/src/core/TileGeometry.ts +745 -0
  60. package/src/render/DatasetManager.ts +3 -0
  61. package/src/render/FeatureStyleManager.ts +31 -2
  62. package/src/render/GeometryBuilder.ts +91 -617
  63. package/src/render/S3MViewer.ts +18 -4
  64. package/src/render/StyleMaterial.ts +6 -0
  65. package/src/render/TextureFactory.ts +78 -123
  66. package/src/tileset/S3MTileset.ts +55 -3
  67. package/src/worker/S3MWorkerClient.ts +159 -0
  68. package/src/worker/s3mWorker.ts +76 -0
  69. package/src/worker/transferables.ts +58 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * S3M 解析 / 纹理解码 Worker 入口。
3
+ *
4
+ * 职责:把 CPU 密集的解码搬离主线程——
5
+ * - parse:`.s3mb`(含 S3M 1.x / Draco / MeshOpt 内联 wasm 解码)整块解析;
6
+ * - tex: 纹理解码(DXT 解块 / CRN wasm 转码 / WEBP createImageBitmap),
7
+ * 与主线程共用 core/TextureDecode.ts 的同一份实现。
8
+ * 抓取(fetch)仍由 S3MTileset 在主线程做——重试、退避、content-type 检查这些
9
+ * 语义都留在原处不动,Worker 只收字节、吐纯数据结果。
10
+ *
11
+ * 协议:
12
+ * { type:'parse', id, buffer } → { id, ok:true, tile } | { id, ok:false, message, permanent }
13
+ * { type:'tex', id, tex } → { id, ok:true, data } | { id, ok:false, message }
14
+ *
15
+ * 线程安全:两个入口都无模块级可变状态;每次调用用独立的 reader / 解码器实例。
16
+ */
17
+ import { parseS3MB } from '../core/S3MBParser.js';
18
+ import { decodeTextureData } from '../core/TextureDecode.js';
19
+ import { assembleTileGeometry } from '../core/TileGeometry.js';
20
+ import type { ParsedTile, S3MTexture } from '../core/types.js';
21
+ import type { TileGeometryData } from '../core/TileGeometry.js';
22
+ import { collectTransferables } from './transferables.js';
23
+
24
+ type ParseRequest = {
25
+ type: 'parse';
26
+ id: number;
27
+ buffer: ArrayBuffer;
28
+ /** 解析后顺带做纯数据几何组装(解交错 / 法线 / 合批),一次往返带回 */
29
+ assemble?: boolean;
30
+ batching?: boolean;
31
+ };
32
+ type TexRequest = { type: 'tex'; id: number; tex: S3MTexture; compressed?: boolean };
33
+ type Request = ParseRequest | TexRequest;
34
+
35
+ type ParseResponse =
36
+ | { id: number; ok: true; tile: ParsedTile; geometry?: TileGeometryData }
37
+ | { id: number; ok: false; message: string; permanent: boolean };
38
+
39
+ type TexResponse = { id: number; ok: true; data: Awaited<ReturnType<typeof decodeTextureData>> };
40
+
41
+ const ctx = self as unknown as Worker;
42
+
43
+ /** 纹理解码响应的传输清单:RGBA 像素 buffer + WEBP 的 ImageBitmap 都走零拷贝 */
44
+ function texTransferList(data: Awaited<ReturnType<typeof decodeTextureData>>): ArrayBuffer[] {
45
+ const list = collectTransferables(data);
46
+ if (data.bitmap) list.push(data.bitmap as unknown as ArrayBuffer);
47
+ return list;
48
+ }
49
+
50
+ ctx.onmessage = async (e: MessageEvent<Request>) => {
51
+ const msg = e.data;
52
+ const { id } = msg;
53
+ try {
54
+ if (msg.type === 'parse') {
55
+ const tile = await parseS3MB(msg.buffer);
56
+ if (msg.assemble) {
57
+ // 解析 + 组装一起做,避免 tile 回主线程后再整块克隆回来一次
58
+ const geometry = assembleTileGeometry(tile, { batching: msg.batching });
59
+ ctx.postMessage(
60
+ { id, ok: true, tile, geometry } satisfies ParseResponse,
61
+ [...collectTransferables(tile), ...collectTransferables(geometry)]
62
+ );
63
+ } else {
64
+ // 响应整体过线(零拷贝);请求 buffer 是主线程 structured clone 过来的副本,无需回传
65
+ ctx.postMessage({ id, ok: true, tile } satisfies ParseResponse, collectTransferables(tile));
66
+ }
67
+ } else {
68
+ const data = await decodeTextureData(msg.tex, { compressed: msg.compressed });
69
+ ctx.postMessage({ id, ok: true, data } satisfies TexResponse, texTransferList(data));
70
+ }
71
+ } catch (err) {
72
+ const permanent = (err as { permanent?: boolean } | null)?.permanent === true;
73
+ const message = String((err as Error | null)?.message ?? err);
74
+ ctx.postMessage({ id, ok: false, message, permanent });
75
+ }
76
+ };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * 传输清单收集:递归扫出对象图里所有可 Transfer 的 ArrayBuffer(去重)。
3
+ *
4
+ * 用于 Worker 往返的零拷贝:postMessage 的 transferList 传这个清单后,
5
+ * 线程间共享同一块内存(structured clone 只拷贝「壳」,不拷字节)。
6
+ *
7
+ * 安全性约定:**要么全转,要么不转** —— 同一块 ArrayBuffer 上可能挂着多个视图
8
+ * (positions / normals 常是同一块顶点缓冲的 subarray),transferList 里出现它一次
9
+ * 之后所有视图共享的底层数据整体过线,视图本身仍然有效;但如果只转一半视图、
10
+ * 另一半留在原地,留在原地的会因 detach 变成空数据。所以只允许「把整个对象图
11
+ * 的 buffer 全部收集」或「完全不收集」两种用法,不支持挑着转。
12
+ */
13
+
14
+ /** 递归深度上限。ParsedTile 的层级是固定的(tile → geoPackage → geode → package),远用不到 12 层 */
15
+ const MAX_DEPTH = 12;
16
+
17
+ export function collectTransferables(root: unknown): ArrayBuffer[] {
18
+ const buffers = new Set<ArrayBuffer>();
19
+ const seen = new Set<object>();
20
+
21
+ const walk = (value: unknown, depth: number): void => {
22
+ if (value == null || depth > MAX_DEPTH) return;
23
+ if (ArrayBuffer.isView(value)) {
24
+ const b = (value as ArrayBufferView).buffer;
25
+ if (b instanceof ArrayBuffer) buffers.add(b);
26
+ return;
27
+ }
28
+ if (value instanceof ArrayBuffer) {
29
+ buffers.add(value);
30
+ return;
31
+ }
32
+ if (typeof value !== 'object') return;
33
+ const obj = value as object;
34
+ if (seen.has(obj)) return;
35
+ seen.add(obj);
36
+ if (Array.isArray(obj)) {
37
+ for (const item of obj) walk(item, depth + 1);
38
+ return;
39
+ }
40
+ if (obj instanceof Map) {
41
+ for (const [k, v] of obj) {
42
+ walk(k, depth + 1);
43
+ walk(v, depth + 1);
44
+ }
45
+ return;
46
+ }
47
+ if (obj instanceof Set) {
48
+ for (const item of obj) walk(item, depth + 1);
49
+ return;
50
+ }
51
+ for (const key of Object.keys(obj)) {
52
+ walk((obj as Record<string, unknown>)[key], depth + 1);
53
+ }
54
+ };
55
+
56
+ walk(root, 0);
57
+ return [...buffers];
58
+ }