@ifc-lite/pointcloud 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 (87) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +26 -0
  3. package/dist/formats/e57.d.ts +129 -0
  4. package/dist/formats/e57.d.ts.map +1 -0
  5. package/dist/formats/e57.js +495 -0
  6. package/dist/formats/e57.js.map +1 -0
  7. package/dist/formats/ifcx-points.d.ts +26 -0
  8. package/dist/formats/ifcx-points.d.ts.map +1 -0
  9. package/dist/formats/ifcx-points.js +134 -0
  10. package/dist/formats/ifcx-points.js.map +1 -0
  11. package/dist/formats/las.d.ts +54 -0
  12. package/dist/formats/las.d.ts.map +1 -0
  13. package/dist/formats/las.js +203 -0
  14. package/dist/formats/las.js.map +1 -0
  15. package/dist/formats/pcd.d.ts +3 -0
  16. package/dist/formats/pcd.d.ts.map +1 -0
  17. package/dist/formats/pcd.js +302 -0
  18. package/dist/formats/pcd.js.map +1 -0
  19. package/dist/formats/ply.d.ts +40 -0
  20. package/dist/formats/ply.d.ts.map +1 -0
  21. package/dist/formats/ply.js +250 -0
  22. package/dist/formats/ply.js.map +1 -0
  23. package/dist/from-ifcx-attributes.d.ts +10 -0
  24. package/dist/from-ifcx-attributes.d.ts.map +1 -0
  25. package/dist/from-ifcx-attributes.js +49 -0
  26. package/dist/from-ifcx-attributes.js.map +1 -0
  27. package/dist/index.d.ts +26 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +21 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/lzf.d.ts +10 -0
  32. package/dist/lzf.d.ts.map +1 -0
  33. package/dist/lzf.js +64 -0
  34. package/dist/lzf.js.map +1 -0
  35. package/dist/streaming/blob-source.d.ts +15 -0
  36. package/dist/streaming/blob-source.d.ts.map +1 -0
  37. package/dist/streaming/blob-source.js +30 -0
  38. package/dist/streaming/blob-source.js.map +1 -0
  39. package/dist/streaming/decode-worker.d.ts +2 -0
  40. package/dist/streaming/decode-worker.d.ts.map +1 -0
  41. package/dist/streaming/decode-worker.js +131 -0
  42. package/dist/streaming/decode-worker.js.map +1 -0
  43. package/dist/streaming/e57-source.d.ts +17 -0
  44. package/dist/streaming/e57-source.d.ts.map +1 -0
  45. package/dist/streaming/e57-source.js +83 -0
  46. package/dist/streaming/e57-source.js.map +1 -0
  47. package/dist/streaming/host.d.ts +54 -0
  48. package/dist/streaming/host.d.ts.map +1 -0
  49. package/dist/streaming/host.js +120 -0
  50. package/dist/streaming/host.js.map +1 -0
  51. package/dist/streaming/las-source.d.ts +28 -0
  52. package/dist/streaming/las-source.d.ts.map +1 -0
  53. package/dist/streaming/las-source.js +117 -0
  54. package/dist/streaming/las-source.js.map +1 -0
  55. package/dist/streaming/laz-source.d.ts +35 -0
  56. package/dist/streaming/laz-source.d.ts.map +1 -0
  57. package/dist/streaming/laz-source.js +205 -0
  58. package/dist/streaming/laz-source.js.map +1 -0
  59. package/dist/streaming/pcd-source.d.ts +25 -0
  60. package/dist/streaming/pcd-source.d.ts.map +1 -0
  61. package/dist/streaming/pcd-source.js +86 -0
  62. package/dist/streaming/pcd-source.js.map +1 -0
  63. package/dist/streaming/ply-source.d.ts +26 -0
  64. package/dist/streaming/ply-source.d.ts.map +1 -0
  65. package/dist/streaming/ply-source.js +98 -0
  66. package/dist/streaming/ply-source.js.map +1 -0
  67. package/dist/streaming/protocol.d.ts +62 -0
  68. package/dist/streaming/protocol.d.ts.map +1 -0
  69. package/dist/streaming/protocol.js +45 -0
  70. package/dist/streaming/protocol.js.map +1 -0
  71. package/dist/streaming/types.d.ts +41 -0
  72. package/dist/streaming/types.d.ts.map +1 -0
  73. package/dist/streaming/types.js +5 -0
  74. package/dist/streaming/types.js.map +1 -0
  75. package/dist/streaming/worker-client.d.ts +20 -0
  76. package/dist/streaming/worker-client.d.ts.map +1 -0
  77. package/dist/streaming/worker-client.js +152 -0
  78. package/dist/streaming/worker-client.js.map +1 -0
  79. package/dist/types.d.ts +36 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +5 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/xml-mini.d.ts +29 -0
  84. package/dist/xml-mini.d.ts.map +1 -0
  85. package/dist/xml-mini.js +181 -0
  86. package/dist/xml-mini.js.map +1 -0
  87. package/package.json +51 -0
@@ -0,0 +1,86 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { decodePcd } from '../formats/pcd.js';
5
+ export class PcdStreamingSource {
6
+ blob;
7
+ downsample;
8
+ label;
9
+ chunk = null;
10
+ served = false;
11
+ constructor(blob, options = {}) {
12
+ this.blob = blob;
13
+ this.downsample = options.downsample ?? { stride: 1 };
14
+ this.label = options.label;
15
+ }
16
+ async open(signal) {
17
+ abortIfAborted(signal);
18
+ const buf = await this.blob.arrayBuffer();
19
+ abortIfAborted(signal);
20
+ const decoded = decodePcd(new Uint8Array(buf));
21
+ this.chunk = applyStride(decoded, this.downsample.stride);
22
+ return {
23
+ totalPointCount: this.chunk.pointCount,
24
+ bbox: this.chunk.bbox,
25
+ hasColor: !!this.chunk.colors,
26
+ hasClassification: !!this.chunk.classifications,
27
+ hasIntensity: !!this.chunk.intensities,
28
+ label: this.label,
29
+ };
30
+ }
31
+ async next(maxPoints, signal) {
32
+ abortIfAborted(signal);
33
+ if (!this.chunk || this.served)
34
+ return null;
35
+ void maxPoints;
36
+ this.served = true;
37
+ return this.chunk;
38
+ }
39
+ close() {
40
+ this.chunk = null;
41
+ this.served = false;
42
+ }
43
+ }
44
+ function applyStride(chunk, stride) {
45
+ const s = Math.max(1, stride | 0);
46
+ if (s === 1)
47
+ return chunk;
48
+ const newCount = Math.ceil(chunk.pointCount / s);
49
+ const positions = new Float32Array(newCount * 3);
50
+ const colors = chunk.colors ? new Float32Array(newCount * 3) : undefined;
51
+ // Preserve classification + intensity through downsampling — without
52
+ // these, the classification / intensity color modes silently lose
53
+ // their per-point data the moment a file crosses the soft cap.
54
+ const classifications = chunk.classifications ? new Uint8Array(newCount) : undefined;
55
+ const intensities = chunk.intensities ? new Uint16Array(newCount) : undefined;
56
+ let dst = 0;
57
+ for (let i = 0; i < chunk.pointCount; i += s) {
58
+ positions[dst * 3] = chunk.positions[i * 3];
59
+ positions[dst * 3 + 1] = chunk.positions[i * 3 + 1];
60
+ positions[dst * 3 + 2] = chunk.positions[i * 3 + 2];
61
+ if (colors && chunk.colors) {
62
+ colors[dst * 3] = chunk.colors[i * 3];
63
+ colors[dst * 3 + 1] = chunk.colors[i * 3 + 1];
64
+ colors[dst * 3 + 2] = chunk.colors[i * 3 + 2];
65
+ }
66
+ if (classifications && chunk.classifications)
67
+ classifications[dst] = chunk.classifications[i];
68
+ if (intensities && chunk.intensities)
69
+ intensities[dst] = chunk.intensities[i];
70
+ dst++;
71
+ }
72
+ return {
73
+ positions,
74
+ colors,
75
+ classifications,
76
+ intensities,
77
+ pointCount: newCount,
78
+ bbox: chunk.bbox,
79
+ };
80
+ }
81
+ function abortIfAborted(signal) {
82
+ if (signal?.aborted) {
83
+ throw new DOMException('Aborted', 'AbortError');
84
+ }
85
+ }
86
+ //# sourceMappingURL=pcd-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pcd-source.js","sourceRoot":"","sources":["../../src/streaming/pcd-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * PLY streaming source — whole-file decode, single chunk.
3
+ *
4
+ * PLY isn't an octree format, so we don't get incremental visibility
5
+ * benefits from chunked decode. Reading the whole file once and emitting
6
+ * one chunk is simpler and correct. Memory is still bounded by
7
+ * `streamPointCloud`'s 25M-point cap — for files past that, the stride
8
+ * downsample applies on the way out.
9
+ */
10
+ import type { DecodedPointChunk } from '../types.js';
11
+ import type { DownsampleHint, PointSourceInfo, StreamingPointSource } from './types.js';
12
+ export declare class PlyStreamingSource implements StreamingPointSource {
13
+ private blob;
14
+ private downsample;
15
+ private label?;
16
+ private chunk;
17
+ private served;
18
+ constructor(blob: Blob, options?: {
19
+ label?: string;
20
+ downsample?: DownsampleHint;
21
+ });
22
+ open(signal?: AbortSignal): Promise<PointSourceInfo>;
23
+ next(maxPoints: number, signal?: AbortSignal): Promise<DecodedPointChunk | null>;
24
+ close(): void;
25
+ }
26
+ //# sourceMappingURL=ply-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ply-source.d.ts","sourceRoot":"","sources":["../../src/streaming/ply-source.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAEpB,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,MAAM,CAAS;gBAEX,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,cAAc,CAAA;KAAO;IAM/E,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;IAgCpD,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAQtF,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,98 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { decodePly, parsePlyHeader } from '../formats/ply.js';
5
+ export class PlyStreamingSource {
6
+ blob;
7
+ downsample;
8
+ label;
9
+ chunk = null;
10
+ served = false;
11
+ constructor(blob, options = {}) {
12
+ this.blob = blob;
13
+ this.downsample = options.downsample ?? { stride: 1 };
14
+ this.label = options.label;
15
+ }
16
+ async open(signal) {
17
+ abortIfAborted(signal);
18
+ const buf = await this.blob.arrayBuffer();
19
+ abortIfAborted(signal);
20
+ const bytes = new Uint8Array(buf);
21
+ // Header probe first — gives us the count + capabilities so the
22
+ // host can decide on downsampling stride before the full decode.
23
+ const header = parsePlyHeader(bytes);
24
+ const vertex = header.elements.find((e) => e.name === 'vertex');
25
+ if (!vertex)
26
+ throw new Error('PLY: no vertex element');
27
+ const hasRgb = !!vertex.properties.find((p) => p.name === 'red' || p.name === 'r')
28
+ && !!vertex.properties.find((p) => p.name === 'green' || p.name === 'g')
29
+ && !!vertex.properties.find((p) => p.name === 'blue' || p.name === 'b');
30
+ const hasIntensity = !!vertex.properties.find((p) => p.name === 'intensity' || p.name === 'scalar_Intensity');
31
+ // Decode now (we already have all bytes). The cost is amortised over
32
+ // the next() call — caller perceives no extra latency.
33
+ const fullChunk = decodePly(bytes);
34
+ this.chunk = applyStride(fullChunk, this.downsample.stride);
35
+ return {
36
+ totalPointCount: this.chunk.pointCount,
37
+ bbox: this.chunk.bbox,
38
+ hasColor: hasRgb,
39
+ hasClassification: false,
40
+ hasIntensity,
41
+ label: this.label,
42
+ };
43
+ }
44
+ async next(maxPoints, signal) {
45
+ abortIfAborted(signal);
46
+ if (!this.chunk || this.served)
47
+ return null;
48
+ void maxPoints; // Whole-file decode: ignore chunk-size hint.
49
+ this.served = true;
50
+ return this.chunk;
51
+ }
52
+ close() {
53
+ this.chunk = null;
54
+ this.served = false;
55
+ }
56
+ }
57
+ function applyStride(chunk, stride) {
58
+ const s = Math.max(1, stride | 0);
59
+ if (s === 1)
60
+ return chunk;
61
+ const newCount = Math.ceil(chunk.pointCount / s);
62
+ const positions = new Float32Array(newCount * 3);
63
+ const colors = chunk.colors ? new Float32Array(newCount * 3) : undefined;
64
+ const classifications = chunk.classifications ? new Uint8Array(newCount) : undefined;
65
+ const intensities = chunk.intensities ? new Uint16Array(newCount) : undefined;
66
+ let dst = 0;
67
+ for (let i = 0; i < chunk.pointCount; i += s) {
68
+ positions[dst * 3] = chunk.positions[i * 3];
69
+ positions[dst * 3 + 1] = chunk.positions[i * 3 + 1];
70
+ positions[dst * 3 + 2] = chunk.positions[i * 3 + 2];
71
+ if (colors && chunk.colors) {
72
+ colors[dst * 3] = chunk.colors[i * 3];
73
+ colors[dst * 3 + 1] = chunk.colors[i * 3 + 1];
74
+ colors[dst * 3 + 2] = chunk.colors[i * 3 + 2];
75
+ }
76
+ if (classifications && chunk.classifications) {
77
+ classifications[dst] = chunk.classifications[i];
78
+ }
79
+ if (intensities && chunk.intensities) {
80
+ intensities[dst] = chunk.intensities[i];
81
+ }
82
+ dst++;
83
+ }
84
+ return {
85
+ positions,
86
+ colors,
87
+ classifications,
88
+ intensities,
89
+ pointCount: newCount,
90
+ bbox: chunk.bbox,
91
+ };
92
+ }
93
+ function abortIfAborted(signal) {
94
+ if (signal?.aborted) {
95
+ throw new DOMException('Aborted', 'AbortError');
96
+ }
97
+ }
98
+ //# sourceMappingURL=ply-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ply-source.js","sourceRoot":"","sources":["../../src/streaming/ply-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * postMessage protocol shared between the main thread and decode-worker.
3
+ *
4
+ * Direction is encoded by message kind. Typed arrays are always carried
5
+ * in transferable buffers so we don't double-allocate.
6
+ */
7
+ import type { DecodedPointChunk, PointCloudBBox } from '../types.js';
8
+ import type { PointSourceInfo } from './types.js';
9
+ export type WorkerSourceFormat = 'las' | 'laz' | 'ply' | 'pcd' | 'e57';
10
+ /** main → worker */
11
+ export type WorkerRequest = {
12
+ kind: 'open';
13
+ requestId: number;
14
+ format: WorkerSourceFormat;
15
+ blob: Blob;
16
+ label?: string;
17
+ stride: number;
18
+ } | {
19
+ kind: 'next';
20
+ requestId: number;
21
+ sourceId: number;
22
+ maxPoints: number;
23
+ } | {
24
+ kind: 'close';
25
+ sourceId: number;
26
+ } | {
27
+ kind: 'abort';
28
+ sourceId: number;
29
+ };
30
+ /** worker → main */
31
+ export type WorkerResponse = {
32
+ kind: 'opened';
33
+ requestId: number;
34
+ sourceId: number;
35
+ info: PointSourceInfo;
36
+ } | {
37
+ kind: 'chunk';
38
+ requestId: number;
39
+ sourceId: number;
40
+ chunk: SerializedChunk | null;
41
+ } | {
42
+ kind: 'error';
43
+ requestId: number;
44
+ message: string;
45
+ };
46
+ /** Wire-friendly chunk: typed-array views replaced by their underlying buffers. */
47
+ export interface SerializedChunk {
48
+ positions: ArrayBuffer;
49
+ colors?: ArrayBuffer;
50
+ classifications?: ArrayBuffer;
51
+ intensities?: ArrayBuffer;
52
+ pointCount: number;
53
+ bbox: PointCloudBBox;
54
+ }
55
+ /** Convert a chunk into a transferable wire payload + transfer list. */
56
+ export declare function chunkToWire(chunk: DecodedPointChunk): {
57
+ payload: SerializedChunk;
58
+ transfer: ArrayBuffer[];
59
+ };
60
+ /** Inverse of `chunkToWire`. */
61
+ export declare function chunkFromWire(payload: SerializedChunk): DecodedPointChunk;
62
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/streaming/protocol.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEvE,oBAAoB;AACpB,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEN,oBAAoB;AACpB,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,eAAe,CAAC;CACvB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,WAAW,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG;IACrD,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB,CA4BA;AAED,gCAAgC;AAChC,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,iBAAiB,CASzE"}
@@ -0,0 +1,45 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /** Convert a chunk into a transferable wire payload + transfer list. */
5
+ export function chunkToWire(chunk) {
6
+ // We construct every typed array in this package via `new Float32Array(N)` /
7
+ // friends, so `.buffer` is always a plain `ArrayBuffer`. The `as ArrayBuffer`
8
+ // cast is safe and required because TS widens the type to `ArrayBufferLike`
9
+ // (which formally includes `SharedArrayBuffer`).
10
+ const positions = chunk.positions.buffer;
11
+ const transfer = [positions];
12
+ const payload = {
13
+ positions,
14
+ pointCount: chunk.pointCount,
15
+ bbox: chunk.bbox,
16
+ };
17
+ if (chunk.colors) {
18
+ const buf = chunk.colors.buffer;
19
+ payload.colors = buf;
20
+ transfer.push(buf);
21
+ }
22
+ if (chunk.classifications) {
23
+ const buf = chunk.classifications.buffer;
24
+ payload.classifications = buf;
25
+ transfer.push(buf);
26
+ }
27
+ if (chunk.intensities) {
28
+ const buf = chunk.intensities.buffer;
29
+ payload.intensities = buf;
30
+ transfer.push(buf);
31
+ }
32
+ return { payload, transfer };
33
+ }
34
+ /** Inverse of `chunkToWire`. */
35
+ export function chunkFromWire(payload) {
36
+ return {
37
+ positions: new Float32Array(payload.positions),
38
+ colors: payload.colors ? new Float32Array(payload.colors) : undefined,
39
+ classifications: payload.classifications ? new Uint8Array(payload.classifications) : undefined,
40
+ intensities: payload.intensities ? new Uint16Array(payload.intensities) : undefined,
41
+ pointCount: payload.pointCount,
42
+ bbox: payload.bbox,
43
+ };
44
+ }
45
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/streaming/protocol.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAqE/D,wEAAwE;AACxE,MAAM,UAAU,WAAW,CAAC,KAAwB;IAIlD,6EAA6E;IAC7E,8EAA8E;IAC9E,4EAA4E;IAC5E,iDAAiD;IACjD,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,MAAqB,CAAC;IACxD,MAAM,QAAQ,GAAkB,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAoB;QAC/B,SAAS;QACT,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC;IACF,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,MAAqB,CAAC;QAC/C,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,eAAe,CAAC,MAAqB,CAAC;QACxD,OAAO,CAAC,eAAe,GAAG,GAAG,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,MAAqB,CAAC;QACpD,OAAO,CAAC,WAAW,GAAG,GAAG,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC/B,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,aAAa,CAAC,OAAwB;IACpD,OAAO;QACL,SAAS,EAAE,IAAI,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC;QAC9C,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QACrE,eAAe,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS;QAC9F,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;QACnF,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { DecodedPointChunk, PointCloudBBox } from '../types.js';
2
+ /** Aggregate metadata returned from `StreamingPointSource.open()`. */
3
+ export interface PointSourceInfo {
4
+ /** Total points the source will emit if it streams to completion. */
5
+ totalPointCount: number;
6
+ /** Source-wide bbox in source-native coordinates. */
7
+ bbox: PointCloudBBox;
8
+ /** True if the source carries per-point RGB. */
9
+ hasColor: boolean;
10
+ /** True if the source carries per-point classification. */
11
+ hasClassification: boolean;
12
+ /** True if the source carries per-point intensity. */
13
+ hasIntensity: boolean;
14
+ /** Free-form display label (filename, URL, etc.). */
15
+ label?: string;
16
+ }
17
+ /**
18
+ * Renderer-agnostic streaming source.
19
+ *
20
+ * `open()` reads only enough bytes to discover header metadata.
21
+ * Callers then drive `next()` repeatedly until it returns null.
22
+ * Implementations should respect `signal` to abort cleanly between chunks.
23
+ */
24
+ export interface StreamingPointSource {
25
+ open(signal?: AbortSignal): Promise<PointSourceInfo>;
26
+ next(maxPoints: number, signal?: AbortSignal): Promise<DecodedPointChunk | null>;
27
+ close(): void;
28
+ }
29
+ /**
30
+ * Stride-based downsampling control.
31
+ *
32
+ * When the host applies a memory cap, it can request the source to skip
33
+ * every `stride` points (always > 0) so a large file produces a coarser,
34
+ * but still-valid, chunk stream. Sources that don't support this can
35
+ * decode normally and ignore the hint — the host will downsample on the
36
+ * receiving end.
37
+ */
38
+ export interface DownsampleHint {
39
+ stride: number;
40
+ }
41
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/streaming/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAErE,sEAAsE;AACtE,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,eAAe,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,IAAI,EAAE,cAAc,CAAC;IACrB,gDAAgD;IAChD,QAAQ,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,sDAAsD;IACtD,YAAY,EAAE,OAAO,CAAC;IACtB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACrD,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACjF,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,5 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/streaming/types.ts"],"names":[],"mappings":"AAAA;;+DAE+D"}
@@ -0,0 +1,20 @@
1
+ import type { StreamingPointSource } from './types.js';
2
+ export type DecodeWorkerFormat = 'las' | 'laz' | 'ply' | 'pcd' | 'e57';
3
+ export interface DecodeWorkerOptions {
4
+ /** Override the worker constructor — useful for tests or custom bundlers. */
5
+ spawn?: () => Worker;
6
+ }
7
+ export interface CreateDecodeWorkerSourceOptions extends DecodeWorkerOptions {
8
+ format: DecodeWorkerFormat;
9
+ blob: Blob;
10
+ label?: string;
11
+ /** stride>1 → drop every Nth point on decode for memory bounds. */
12
+ stride?: number;
13
+ }
14
+ /**
15
+ * Build a `StreamingPointSource` that runs decode work in the shared
16
+ * worker. The caller drives `open()` / `next()` / `close()` exactly
17
+ * like the in-process `LasStreamingSource`.
18
+ */
19
+ export declare function createDecodeWorkerSource(opts: CreateDecodeWorkerSourceOptions): StreamingPointSource;
20
+ //# sourceMappingURL=worker-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-client.d.ts","sourceRoot":"","sources":["../../src/streaming/worker-client.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAEV,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAqFD,MAAM,WAAW,+BAAgC,SAAQ,mBAAmB;IAC1E,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,+BAA+B,GACpC,oBAAoB,CAsEtB"}
@@ -0,0 +1,152 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { chunkFromWire, } from './protocol.js';
5
+ /** Pool a single worker per page; the host can spawn additional workers
6
+ * with `createDecodeWorkerSource({ spawn })` when concurrent decoding is
7
+ * desirable (e.g. multiple federated scans). */
8
+ let sharedWorker = null;
9
+ function defaultSpawn() {
10
+ // The bare-`.js` form works against the built dist but Vite's
11
+ // worker-import-meta-url plugin can't resolve it through the source
12
+ // alias used in the viewer dev build. Geometry uses `.worker.ts` for
13
+ // the same reason — Vite happily rewrites the suffix on dist builds.
14
+ return new Worker(new URL('./decode-worker.js', import.meta.url), {
15
+ type: 'module',
16
+ name: 'ifclite-pointcloud-decode',
17
+ });
18
+ }
19
+ function getSharedWorker(spawn) {
20
+ if (!sharedWorker) {
21
+ sharedWorker = spawn();
22
+ }
23
+ return sharedWorker;
24
+ }
25
+ class WorkerSession {
26
+ worker;
27
+ requests = new Map();
28
+ nextRequestId = 1;
29
+ listener;
30
+ constructor(worker) {
31
+ this.worker = worker;
32
+ this.listener = (event) => {
33
+ const msg = event.data;
34
+ if (!('requestId' in msg))
35
+ return;
36
+ const pending = this.requests.get(msg.requestId);
37
+ if (!pending)
38
+ return;
39
+ this.requests.delete(msg.requestId);
40
+ if (msg.kind === 'error') {
41
+ pending.reject(new Error(msg.message));
42
+ }
43
+ else {
44
+ pending.resolve(msg);
45
+ }
46
+ };
47
+ worker.addEventListener('message', this.listener);
48
+ }
49
+ /** Send a request that expects a single response by `requestId`. */
50
+ send(build, transfer = []) {
51
+ const requestId = this.nextRequestId++;
52
+ const req = build(requestId);
53
+ return new Promise((resolve, reject) => {
54
+ this.requests.set(requestId, {
55
+ resolve: (resp) => resolve(resp),
56
+ reject,
57
+ });
58
+ this.worker.postMessage(req, transfer);
59
+ });
60
+ }
61
+ /** Send a fire-and-forget message (close / abort). */
62
+ notify(req) {
63
+ this.worker.postMessage(req);
64
+ }
65
+ }
66
+ let sharedSession = null;
67
+ function getSharedSession(spawn) {
68
+ if (!sharedSession) {
69
+ sharedSession = new WorkerSession(getSharedWorker(spawn));
70
+ }
71
+ return sharedSession;
72
+ }
73
+ /**
74
+ * Build a `StreamingPointSource` that runs decode work in the shared
75
+ * worker. The caller drives `open()` / `next()` / `close()` exactly
76
+ * like the in-process `LasStreamingSource`.
77
+ */
78
+ export function createDecodeWorkerSource(opts) {
79
+ const session = getSharedSession(opts.spawn ?? defaultSpawn);
80
+ let sourceId = null;
81
+ let info = null;
82
+ return {
83
+ async open(signal) {
84
+ if (info)
85
+ return info;
86
+ abortIfAborted(signal);
87
+ const resp = await session.send((requestId) => ({
88
+ kind: 'open',
89
+ requestId,
90
+ format: opts.format,
91
+ blob: opts.blob,
92
+ label: opts.label,
93
+ stride: Math.max(1, opts.stride ?? 1),
94
+ }));
95
+ sourceId = resp.sourceId;
96
+ info = resp.info;
97
+ return info;
98
+ },
99
+ async next(maxPoints, signal) {
100
+ if (sourceId === null) {
101
+ throw new Error('decode-worker source not opened');
102
+ }
103
+ abortIfAborted(signal);
104
+ const id = sourceId;
105
+ // Propagate aborts that fire WHILE the worker is decoding —
106
+ // without this, cancel() returns immediately to the caller but
107
+ // the worker keeps grinding on a soon-to-be-discarded chunk.
108
+ const abortListener = () => {
109
+ session.notify({ kind: 'abort', sourceId: id });
110
+ };
111
+ signal?.addEventListener('abort', abortListener, { once: true });
112
+ try {
113
+ const resp = await session.send((requestId) => ({
114
+ kind: 'next',
115
+ requestId,
116
+ sourceId: id,
117
+ maxPoints,
118
+ }));
119
+ // Race: if the signal fired *while* the worker was finishing a
120
+ // chunk, the response can still arrive after the host has
121
+ // moved on. Treat a late completion as cancelled so the host's
122
+ // `onChunk` doesn't run after `cancel()` returned to the caller.
123
+ if (signal?.aborted) {
124
+ throw new DOMException('Aborted', 'AbortError');
125
+ }
126
+ if (!resp.chunk)
127
+ return null;
128
+ return chunkFromWire(resp.chunk);
129
+ }
130
+ finally {
131
+ signal?.removeEventListener('abort', abortListener);
132
+ }
133
+ },
134
+ close() {
135
+ if (sourceId !== null) {
136
+ session.notify({ kind: 'close', sourceId });
137
+ sourceId = null;
138
+ }
139
+ // Clear cached open()-result too so a subsequent open() actually
140
+ // re-opens the worker source instead of returning stale info
141
+ // alongside a now-null sourceId (which would make next() throw
142
+ // "decode-worker source not opened").
143
+ info = null;
144
+ },
145
+ };
146
+ }
147
+ function abortIfAborted(signal) {
148
+ if (signal?.aborted) {
149
+ throw new DOMException('Aborted', 'AbortError');
150
+ }
151
+ }
152
+ //# sourceMappingURL=worker-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-client.js","sourceRoot":"","sources":["../../src/streaming/worker-client.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAe/D,OAAO,EACL,aAAa,GAGd,MAAM,eAAe,CAAC;AAavB;;iDAEiD;AACjD,IAAI,YAAY,GAAkB,IAAI,CAAC;AAEvC,SAAS,YAAY;IACnB,8DAA8D;IAC9D,oEAAoE;IACpE,qEAAqE;IACrE,qEAAqE;IACrE,OAAO,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAChE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,2BAA2B;KAClC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,KAAmB;IAC1C,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,KAAK,EAAE,CAAC;IACzB,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAUD,MAAM,aAAa;IAKW;IAJpB,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC7C,aAAa,GAAG,CAAC,CAAC;IAClB,QAAQ,CAAgD;IAEhE,YAA4B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;QACxC,IAAI,CAAC,QAAQ,GAAG,CAAC,KAAK,EAAE,EAAE;YACxB,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC;YACvB,IAAI,CAAC,CAAC,WAAW,IAAI,GAAG,CAAC;gBAAE,OAAO;YAClC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACjD,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACpC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACzB,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACzC,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;QACH,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC;IAED,oEAAoE;IACpE,IAAI,CACF,KAA8C,EAC9C,WAA2B,EAAE;QAE7B,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;QAC7B,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE;gBAC3B,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAS,CAAC;gBACrC,MAAM;aACP,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,sDAAsD;IACtD,MAAM,CAAC,GAAkB;QACvB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,IAAI,aAAa,GAAyB,IAAI,CAAC;AAE/C,SAAS,gBAAgB,CAAC,KAAmB;IAC3C,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,aAAa,GAAG,IAAI,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAUD;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAqC;IAErC,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC,CAAC;IAC7D,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,IAAI,GAA2B,IAAI,CAAC;IAExC,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,MAAoB;YAC7B,IAAI,IAAI;gBAAE,OAAO,IAAI,CAAC;YACtB,cAAc,CAAC,MAAM,CAAC,CAAC;YACvB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAC7B,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;gBACd,IAAI,EAAE,MAAM;gBACZ,SAAS;gBACT,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;aACtC,CAAC,CACH,CAAC;YACF,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YACzB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,MAAoB;YAChD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACrD,CAAC;YACD,cAAc,CAAC,MAAM,CAAC,CAAC;YACvB,MAAM,EAAE,GAAG,QAAQ,CAAC;YACpB,4DAA4D;YAC5D,+DAA+D;YAC/D,6DAA6D;YAC7D,MAAM,aAAa,GAAG,GAAG,EAAE;gBACzB,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YAClD,CAAC,CAAC;YACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAC7B,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;oBACd,IAAI,EAAE,MAAM;oBACZ,SAAS;oBACT,QAAQ,EAAE,EAAE;oBACZ,SAAS;iBACV,CAAC,CACH,CAAC;gBACF,+DAA+D;gBAC/D,0DAA0D;gBAC1D,+DAA+D;gBAC/D,iEAAiE;gBACjE,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;oBACpB,MAAM,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;gBAClD,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,KAAK;oBAAE,OAAO,IAAI,CAAC;gBAC7B,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;oBAAS,CAAC;gBACT,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QACD,KAAK;YACH,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC5C,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;YACD,iEAAiE;YACjE,6DAA6D;YAC7D,+DAA+D;YAC/D,sCAAsC;YACtC,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,MAAoB;IAC1C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAClD,CAAC;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Renderer-agnostic point cloud types.
3
+ *
4
+ * Decoders in this package produce DecodedPointChunks; the renderer (and
5
+ * any other consumer) shapes them into GPU buffers. No WebGPU, no three.js.
6
+ */
7
+ export interface PointCloudBBox {
8
+ min: [number, number, number];
9
+ max: [number, number, number];
10
+ }
11
+ /**
12
+ * A decoded chunk of points ready for upload to a GPU buffer.
13
+ *
14
+ * Coordinates are in the source's native space. Any z-up→y-up swap and
15
+ * RTC offset is the renderer's responsibility (it already owns those for
16
+ * triangle meshes). Optional 4x4 transform on the asset is applied per-vertex
17
+ * in the vertex shader.
18
+ *
19
+ * Color channel layout: 0..1 floats per channel. RGB only — alpha is solid.
20
+ * Classification (LAS-style) is a per-point u8.
21
+ */
22
+ export interface DecodedPointChunk {
23
+ /** [x,y,z, x,y,z, ...] */
24
+ positions: Float32Array;
25
+ /** [r,g,b, r,g,b, ...] in 0..1 — undefined when source has no color */
26
+ colors?: Float32Array;
27
+ /** Per-point u8 classification — undefined when source has none */
28
+ classifications?: Uint8Array;
29
+ /** Per-point u16 intensity — undefined when source has none */
30
+ intensities?: Uint16Array;
31
+ /** Number of points in this chunk (positions.length / 3) */
32
+ pointCount: number;
33
+ /** Local bbox of this chunk's positions (pre-transform) */
34
+ bbox: PointCloudBBox;
35
+ }
36
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,SAAS,EAAE,YAAY,CAAC;IACxB,uEAAuE;IACvE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,mEAAmE;IACnE,eAAe,CAAC,EAAE,UAAU,CAAC;IAC7B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,IAAI,EAAE,cAAc,CAAC;CACtB"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;+DAE+D"}