@ifc-lite/renderer 6.0.1 → 6.3.1

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 (206) hide show
  1. package/README.md +23 -0
  2. package/dist/ao-pass.d.ts +0 -16
  3. package/dist/ao-pass.d.ts.map +1 -1
  4. package/dist/ao-pass.js +2 -0
  5. package/dist/ao-pass.js.map +1 -1
  6. package/dist/camera-animation.d.ts +1 -1
  7. package/dist/camera-animation.d.ts.map +1 -1
  8. package/dist/camera-animation.js +11 -11
  9. package/dist/camera-animation.js.map +1 -1
  10. package/dist/camera-controls.d.ts +0 -21
  11. package/dist/camera-controls.d.ts.map +1 -1
  12. package/dist/camera-controls.js +8 -90
  13. package/dist/camera-controls.js.map +1 -1
  14. package/dist/camera-inertia.d.ts +27 -0
  15. package/dist/camera-inertia.d.ts.map +1 -0
  16. package/dist/camera-inertia.js +33 -0
  17. package/dist/camera-inertia.js.map +1 -0
  18. package/dist/camera-surface-zoom.d.ts +1 -1
  19. package/dist/camera-zoom.d.ts +55 -0
  20. package/dist/camera-zoom.d.ts.map +1 -0
  21. package/dist/camera-zoom.js +138 -0
  22. package/dist/camera-zoom.js.map +1 -0
  23. package/dist/camera.d.ts.map +1 -1
  24. package/dist/camera.js +8 -0
  25. package/dist/camera.js.map +1 -1
  26. package/dist/deviation/deviation-computer.d.ts +5 -1
  27. package/dist/deviation/deviation-computer.d.ts.map +1 -1
  28. package/dist/deviation/deviation-computer.js +13 -6
  29. package/dist/deviation/deviation-computer.js.map +1 -1
  30. package/dist/deviation/deviation-readback.d.ts +16 -3
  31. package/dist/deviation/deviation-readback.d.ts.map +1 -1
  32. package/dist/deviation/deviation-readback.js +46 -36
  33. package/dist/deviation/deviation-readback.js.map +1 -1
  34. package/dist/deviation/deviation-statistics-kernel.d.ts +111 -0
  35. package/dist/deviation/deviation-statistics-kernel.d.ts.map +1 -0
  36. package/dist/deviation/deviation-statistics-kernel.js +303 -0
  37. package/dist/deviation/deviation-statistics-kernel.js.map +1 -0
  38. package/dist/deviation/deviation-statistics.d.ts +100 -0
  39. package/dist/deviation/deviation-statistics.d.ts.map +1 -0
  40. package/dist/deviation/deviation-statistics.js +100 -0
  41. package/dist/deviation/deviation-statistics.js.map +1 -0
  42. package/dist/device-recovery.d.ts.map +1 -1
  43. package/dist/device-recovery.js +5 -0
  44. package/dist/device-recovery.js.map +1 -1
  45. package/dist/device.d.ts +0 -3
  46. package/dist/device.d.ts.map +1 -1
  47. package/dist/device.js +5 -1
  48. package/dist/device.js.map +1 -1
  49. package/dist/edge-pass.d.ts +0 -12
  50. package/dist/edge-pass.d.ts.map +1 -1
  51. package/dist/edge-pass.js +3 -0
  52. package/dist/edge-pass.js.map +1 -1
  53. package/dist/edl-pass.d.ts +0 -21
  54. package/dist/edl-pass.d.ts.map +1 -1
  55. package/dist/edl-pass.js +23 -0
  56. package/dist/edl-pass.js.map +1 -1
  57. package/dist/frame-timing-gpu.d.ts +11 -15
  58. package/dist/frame-timing-gpu.d.ts.map +1 -1
  59. package/dist/frame-timing-gpu.js +57 -26
  60. package/dist/frame-timing-gpu.js.map +1 -1
  61. package/dist/gpu-counters.d.ts +30 -0
  62. package/dist/gpu-counters.d.ts.map +1 -0
  63. package/dist/gpu-counters.js +84 -0
  64. package/dist/gpu-counters.js.map +1 -0
  65. package/dist/gpu-static-upload.d.ts.map +1 -1
  66. package/dist/gpu-static-upload.js +2 -0
  67. package/dist/gpu-static-upload.js.map +1 -1
  68. package/dist/index.d.ts +33 -21
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +71 -60
  71. package/dist/index.js.map +1 -1
  72. package/dist/pick-rte-snapshot.d.ts +4 -0
  73. package/dist/pick-rte-snapshot.d.ts.map +1 -1
  74. package/dist/pick-rte-snapshot.js +10 -0
  75. package/dist/pick-rte-snapshot.js.map +1 -1
  76. package/dist/picker-depth-sample.d.ts +9 -0
  77. package/dist/picker-depth-sample.d.ts.map +1 -0
  78. package/dist/picker-depth-sample.js +63 -0
  79. package/dist/picker-depth-sample.js.map +1 -0
  80. package/dist/picker-readbacks.d.ts +10 -1
  81. package/dist/picker-readbacks.d.ts.map +1 -1
  82. package/dist/picker-readbacks.js +30 -1
  83. package/dist/picker-readbacks.js.map +1 -1
  84. package/dist/picker.d.ts +4 -4
  85. package/dist/picker.d.ts.map +1 -1
  86. package/dist/picker.js +77 -102
  87. package/dist/picker.js.map +1 -1
  88. package/dist/picking-manager.d.ts +5 -2
  89. package/dist/picking-manager.d.ts.map +1 -1
  90. package/dist/picking-manager.js +32 -11
  91. package/dist/picking-manager.js.map +1 -1
  92. package/dist/pipeline.d.ts +8 -0
  93. package/dist/pipeline.d.ts.map +1 -1
  94. package/dist/pipeline.js +22 -0
  95. package/dist/pipeline.js.map +1 -1
  96. package/dist/pointcloud/point-cloud-keyed-chunks.d.ts +23 -0
  97. package/dist/pointcloud/point-cloud-keyed-chunks.d.ts.map +1 -0
  98. package/dist/pointcloud/point-cloud-keyed-chunks.js +44 -0
  99. package/dist/pointcloud/point-cloud-keyed-chunks.js.map +1 -0
  100. package/dist/pointcloud/point-cloud-node.d.ts +5 -1
  101. package/dist/pointcloud/point-cloud-node.d.ts.map +1 -1
  102. package/dist/pointcloud/point-cloud-node.js +8 -4
  103. package/dist/pointcloud/point-cloud-node.js.map +1 -1
  104. package/dist/pointcloud/point-cloud-placement.d.ts +6 -0
  105. package/dist/pointcloud/point-cloud-placement.d.ts.map +1 -1
  106. package/dist/pointcloud/point-cloud-placement.js +8 -0
  107. package/dist/pointcloud/point-cloud-placement.js.map +1 -1
  108. package/dist/pointcloud/point-cloud-ray-transform.d.ts +17 -8
  109. package/dist/pointcloud/point-cloud-ray-transform.d.ts.map +1 -1
  110. package/dist/pointcloud/point-cloud-ray-transform.js +17 -13
  111. package/dist/pointcloud/point-cloud-ray-transform.js.map +1 -1
  112. package/dist/pointcloud/point-cloud-renderer.d.ts +10 -8
  113. package/dist/pointcloud/point-cloud-renderer.d.ts.map +1 -1
  114. package/dist/pointcloud/point-cloud-renderer.js +20 -31
  115. package/dist/pointcloud/point-cloud-renderer.js.map +1 -1
  116. package/dist/pointcloud/point-cloud-stream-lifecycle.d.ts +8 -1
  117. package/dist/pointcloud/point-cloud-stream-lifecycle.d.ts.map +1 -1
  118. package/dist/pointcloud/point-cloud-stream-lifecycle.js +17 -2
  119. package/dist/pointcloud/point-cloud-stream-lifecycle.js.map +1 -1
  120. package/dist/pointcloud/point-cloud-uniforms.d.ts +11 -0
  121. package/dist/pointcloud/point-cloud-uniforms.d.ts.map +1 -1
  122. package/dist/pointcloud/point-cloud-uniforms.js +8 -0
  123. package/dist/pointcloud/point-cloud-uniforms.js.map +1 -1
  124. package/dist/post-pass-chain.d.ts +2 -0
  125. package/dist/post-pass-chain.d.ts.map +1 -1
  126. package/dist/post-pass-chain.js +1 -1
  127. package/dist/post-pass-chain.js.map +1 -1
  128. package/dist/raycast-point-cloud-query.d.ts.map +1 -1
  129. package/dist/raycast-point-cloud-query.js +11 -1
  130. package/dist/raycast-point-cloud-query.js.map +1 -1
  131. package/dist/relative-to-eye.d.ts +3 -0
  132. package/dist/relative-to-eye.d.ts.map +1 -1
  133. package/dist/relative-to-eye.js +4 -1
  134. package/dist/relative-to-eye.js.map +1 -1
  135. package/dist/renderer-frame-timing.d.ts +21 -0
  136. package/dist/renderer-frame-timing.d.ts.map +1 -0
  137. package/dist/renderer-frame-timing.js +104 -0
  138. package/dist/renderer-frame-timing.js.map +1 -0
  139. package/dist/renderer-viewport.d.ts +13 -7
  140. package/dist/renderer-viewport.d.ts.map +1 -1
  141. package/dist/renderer-viewport.js +15 -7
  142. package/dist/renderer-viewport.js.map +1 -1
  143. package/dist/scene-batch-rebuild.d.ts +7 -0
  144. package/dist/scene-batch-rebuild.d.ts.map +1 -1
  145. package/dist/scene-batch-rebuild.js +12 -0
  146. package/dist/scene-batch-rebuild.js.map +1 -1
  147. package/dist/scene-contents.d.ts +3 -2
  148. package/dist/scene-contents.d.ts.map +1 -1
  149. package/dist/scene-flush.d.ts +43 -0
  150. package/dist/scene-flush.d.ts.map +1 -0
  151. package/dist/scene-flush.js +103 -0
  152. package/dist/scene-flush.js.map +1 -0
  153. package/dist/scene-geometry.d.ts.map +1 -1
  154. package/dist/scene-geometry.js +2 -0
  155. package/dist/scene-geometry.js.map +1 -1
  156. package/dist/scene.d.ts +26 -27
  157. package/dist/scene.d.ts.map +1 -1
  158. package/dist/scene.js +66 -109
  159. package/dist/scene.js.map +1 -1
  160. package/dist/selection-mask-pass.d.ts +2 -27
  161. package/dist/selection-mask-pass.d.ts.map +1 -1
  162. package/dist/selection-mask-pass.js +44 -39
  163. package/dist/selection-mask-pass.js.map +1 -1
  164. package/dist/selection-mask-pipelines.d.ts +3 -3
  165. package/dist/selection-mask-pipelines.d.ts.map +1 -1
  166. package/dist/selection-mask-pipelines.js +11 -8
  167. package/dist/selection-mask-pipelines.js.map +1 -1
  168. package/dist/shaders/depth-nudge.wgsl.d.ts +67 -0
  169. package/dist/shaders/depth-nudge.wgsl.d.ts.map +1 -0
  170. package/dist/shaders/depth-nudge.wgsl.js +130 -0
  171. package/dist/shaders/depth-nudge.wgsl.js.map +1 -0
  172. package/dist/shaders/ghost.wgsl.d.ts +2 -0
  173. package/dist/shaders/ghost.wgsl.d.ts.map +1 -0
  174. package/dist/shaders/ghost.wgsl.js +46 -0
  175. package/dist/shaders/ghost.wgsl.js.map +1 -0
  176. package/dist/shaders/main.wgsl.d.ts +1 -1
  177. package/dist/shaders/main.wgsl.d.ts.map +1 -1
  178. package/dist/shaders/main.wgsl.js +6 -4
  179. package/dist/shaders/main.wgsl.js.map +1 -1
  180. package/dist/shaders/section-2d-overlay.wgsl.d.ts +1 -16
  181. package/dist/shaders/section-2d-overlay.wgsl.d.ts.map +1 -1
  182. package/dist/shaders/section-2d-overlay.wgsl.js +6 -6
  183. package/dist/shaders/section-2d-overlay.wgsl.js.map +1 -1
  184. package/dist/shaders/selection-mask.wgsl.d.ts +2 -10
  185. package/dist/shaders/selection-mask.wgsl.d.ts.map +1 -1
  186. package/dist/shaders/selection-mask.wgsl.js +9 -42
  187. package/dist/shaders/selection-mask.wgsl.js.map +1 -1
  188. package/dist/shaders/symbolic-overlay.wgsl.d.ts +1 -1
  189. package/dist/shaders/symbolic-overlay.wgsl.d.ts.map +1 -1
  190. package/dist/shaders/symbolic-overlay.wgsl.js +5 -4
  191. package/dist/shaders/symbolic-overlay.wgsl.js.map +1 -1
  192. package/dist/shadow-pass.d.ts +0 -19
  193. package/dist/shadow-pass.d.ts.map +1 -1
  194. package/dist/shadow-pass.js +19 -0
  195. package/dist/shadow-pass.js.map +1 -1
  196. package/dist/test/frame-timing-device.d.ts +17 -0
  197. package/dist/test/frame-timing-device.d.ts.map +1 -0
  198. package/dist/test/frame-timing-device.js +70 -0
  199. package/dist/test/frame-timing-device.js.map +1 -0
  200. package/dist/types.d.ts +2 -0
  201. package/dist/types.d.ts.map +1 -1
  202. package/dist/xray-alpha.d.ts +8 -0
  203. package/dist/xray-alpha.d.ts.map +1 -1
  204. package/dist/xray-alpha.js +23 -0
  205. package/dist/xray-alpha.js.map +1 -1
  206. package/package.json +3 -2
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Linear passes behind the deviation summary statistics (#6872).
3
+ *
4
+ * Every figure is built from at most two O(n) passes over the readback, each
5
+ * of which can run in one call or in time-boxed slices that yield to the
6
+ * event loop, so a 25M-point cloud never blocks the main thread in one task.
7
+ *
8
+ * Exact percentiles without a copy: for a non-negative float32, the IEEE bit
9
+ * pattern read as an unsigned integer is monotone in the value. So |d|'s
10
+ * order statistics are the order statistics of `bits & 0x7fffffff`, found by
11
+ * a two-level radix select: pass 1 counts the high 16 bits (65,536 bins), the
12
+ * cumulative counts name the bucket holding each wanted rank, and pass 2
13
+ * counts the low 16 bits of the values in just those (at most three)
14
+ * buckets. Memory is four 256 KiB count tables, independent of n, and the
15
+ * input is never reordered or copied.
16
+ */
17
+ import type { DeviationHistogram, DeviationHistogramRange } from './deviation-statistics.js';
18
+ /** A pass over `[start, end)`, then an optional step once the pass is done. */
19
+ export interface Phase {
20
+ scan(start: number, end: number): void;
21
+ done?(): void;
22
+ }
23
+ export declare function runPhases(length: number, phases: readonly Phase[]): void;
24
+ /**
25
+ * Run the phases in slices of at most ~{@link SLICE_BUDGET_MS} ms. Always
26
+ * yields once before starting, so the caller's task (a click, a render)
27
+ * finishes first and an abort raised in it is seen before any work.
28
+ */
29
+ export declare function runPhasesSliced(length: number, phases: readonly Phase[], signal?: AbortSignal): Promise<void>;
30
+ export declare function checkMask(values: Float32Array, valid: ArrayLike<number> | undefined): void;
31
+ export declare function checkTolerance(tolerance: number): void;
32
+ /** Valid points with |d| ≤ tolerance. */
33
+ export declare class ToleranceCount implements Phase {
34
+ private readonly values;
35
+ private readonly tolerance;
36
+ private readonly valid?;
37
+ count: number;
38
+ constructor(values: Float32Array, tolerance: number, valid?: ArrayLike<number> | undefined);
39
+ scan(start: number, end: number): void;
40
+ }
41
+ /** Fixed bins over [center − h, center + h], the colour ramp's own range. */
42
+ export declare class HistogramBinner {
43
+ readonly histogram: DeviationHistogram;
44
+ private readonly last;
45
+ constructor(range: DeviationHistogramRange);
46
+ /** `v` must be finite. */
47
+ add(v: number): void;
48
+ }
49
+ /** Histogram as a standalone pass. */
50
+ export declare class HistogramPass implements Phase {
51
+ private readonly values;
52
+ private readonly valid?;
53
+ readonly binner: HistogramBinner;
54
+ constructor(values: Float32Array, range: DeviationHistogramRange, valid?: ArrayLike<number> | undefined);
55
+ scan(start: number, end: number): void;
56
+ }
57
+ /** Neumaier compensated sum: exact-to-rounding for mixed magnitudes. */
58
+ declare class CompensatedSum {
59
+ private sum;
60
+ private compensation;
61
+ add(x: number): void;
62
+ value(): number;
63
+ }
64
+ /** Nearest-rank index (0-based) of the `percent`-th percentile of n values. */
65
+ export declare function nearestRank(percent: number, n: number): number;
66
+ /** Percentiles of |d| reported, in percent. */
67
+ export declare const PERCENTILES: readonly [50, 95, 99];
68
+ export interface MomentOptions {
69
+ valid?: ArrayLike<number>;
70
+ tolerance?: number;
71
+ /** Compared against `Math.fround(clipRange)`: the shader pegs in float32. */
72
+ clipRange?: number;
73
+ histogram?: DeviationHistogramRange;
74
+ }
75
+ /**
76
+ * The two passes of a full summary: moments, extremes, counts and the
77
+ * high-bits table first; then σ about the now-known mean, and the low bits
78
+ * of the percentile buckets.
79
+ */
80
+ export declare class StatisticsPasses {
81
+ private readonly values;
82
+ private readonly options;
83
+ readonly phases: readonly Phase[];
84
+ n: number;
85
+ within: number;
86
+ clipped: number;
87
+ min: number;
88
+ max: number;
89
+ maxAbs: number;
90
+ mean: number;
91
+ readonly sum: CompensatedSum;
92
+ readonly sumAbs: CompensatedSum;
93
+ readonly sumSq: CompensatedSum;
94
+ readonly residual: CompensatedSum;
95
+ readonly binner: HistogramBinner | null;
96
+ /** |d| for each of {@link PERCENTILES}, set after the second pass. */
97
+ readonly percentiles: number[];
98
+ private readonly bits;
99
+ private readonly high;
100
+ private readonly clipAt;
101
+ /** Per wanted rank: its high-bits bucket and the rank within that bucket. */
102
+ private targets;
103
+ constructor(values: Float32Array, options: MomentOptions);
104
+ private scanMoments;
105
+ /** Locate each wanted rank's high-bits bucket from the cumulative counts. */
106
+ private plan;
107
+ private scanResiduals;
108
+ private resolve;
109
+ }
110
+ export {};
111
+ //# sourceMappingURL=deviation-statistics-kernel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviation-statistics-kernel.d.ts","sourceRoot":"","sources":["../../src/deviation/deviation-statistics-kernel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,303 @@
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
+ const ABS_MASK = 0x7fffffff;
5
+ /** |d| bit patterns at or above this are ±Infinity or NaN. */
6
+ const NON_FINITE = 0x7f800000;
7
+ const RADIX = 1 << 16;
8
+ const LOW_MASK = RADIX - 1;
9
+ /** Elements per slice between clock checks. */
10
+ const SLICE = 1 << 16;
11
+ /** Longest stretch of work before yielding, ms. */
12
+ const SLICE_BUDGET_MS = 8;
13
+ export function runPhases(length, phases) {
14
+ for (const phase of phases) {
15
+ phase.scan(0, length);
16
+ phase.done?.();
17
+ }
18
+ }
19
+ /**
20
+ * Yield through a MessageChannel task, not `scheduler.yield()`: that
21
+ * continuation runs ahead of already-queued normal tasks, React renders
22
+ * included, so a loop yielding through it still starves the UI (the same
23
+ * reasoning as the IDS validator's yield).
24
+ */
25
+ function yieldToEventLoop() {
26
+ return new Promise((resolve) => {
27
+ const channel = new MessageChannel();
28
+ channel.port1.onmessage = () => {
29
+ // An open port keeps a Node process alive.
30
+ channel.port1.close();
31
+ channel.port2.close();
32
+ resolve();
33
+ };
34
+ channel.port2.postMessage(null);
35
+ });
36
+ }
37
+ /**
38
+ * Run the phases in slices of at most ~{@link SLICE_BUDGET_MS} ms. Always
39
+ * yields once before starting, so the caller's task (a click, a render)
40
+ * finishes first and an abort raised in it is seen before any work.
41
+ */
42
+ export async function runPhasesSliced(length, phases, signal) {
43
+ await yieldToEventLoop();
44
+ signal?.throwIfAborted();
45
+ let sliceStart = performance.now();
46
+ for (const phase of phases) {
47
+ for (let start = 0; start < length;) {
48
+ const end = Math.min(length, start + SLICE);
49
+ phase.scan(start, end);
50
+ start = end;
51
+ if (performance.now() - sliceStart >= SLICE_BUDGET_MS) {
52
+ await yieldToEventLoop();
53
+ signal?.throwIfAborted();
54
+ sliceStart = performance.now();
55
+ }
56
+ }
57
+ phase.done?.();
58
+ }
59
+ }
60
+ export function checkMask(values, valid) {
61
+ if (valid && valid.length !== values.length) {
62
+ throw new RangeError(`deviation statistics: mask length ${valid.length} != values length ${values.length}`);
63
+ }
64
+ }
65
+ export function checkTolerance(tolerance) {
66
+ if (!(tolerance >= 0) || !Number.isFinite(tolerance)) {
67
+ throw new RangeError(`deviation statistics: tolerance must be a finite value ≥ 0, got ${tolerance}`);
68
+ }
69
+ }
70
+ function bitsOf(values) {
71
+ return new Uint32Array(values.buffer, values.byteOffset, values.length);
72
+ }
73
+ const bitCast = new Uint32Array(1);
74
+ const floatCast = new Float32Array(bitCast.buffer);
75
+ function floatFromBits(bits) {
76
+ bitCast[0] = bits;
77
+ return floatCast[0];
78
+ }
79
+ /** Valid points with |d| ≤ tolerance. */
80
+ export class ToleranceCount {
81
+ values;
82
+ tolerance;
83
+ valid;
84
+ count = 0;
85
+ constructor(values, tolerance, valid) {
86
+ this.values = values;
87
+ this.tolerance = tolerance;
88
+ this.valid = valid;
89
+ checkMask(values, valid);
90
+ checkTolerance(tolerance);
91
+ }
92
+ scan(start, end) {
93
+ const { values, tolerance, valid } = this;
94
+ let count = 0;
95
+ for (let i = start; i < end; i++) {
96
+ // NaN and ±Infinity fail the comparison on their own.
97
+ if (Math.abs(values[i]) <= tolerance && (!valid || valid[i] !== 0))
98
+ count++;
99
+ }
100
+ this.count += count;
101
+ }
102
+ }
103
+ /** Fixed bins over [center − h, center + h], the colour ramp's own range. */
104
+ export class HistogramBinner {
105
+ histogram;
106
+ last;
107
+ constructor(range) {
108
+ const { center, halfRange, bins } = range;
109
+ if (!(halfRange > 0) || !Number.isFinite(halfRange) || !Number.isFinite(center)) {
110
+ throw new RangeError(`deviation histogram: halfRange must be finite and > 0, got ${halfRange}`);
111
+ }
112
+ if (!Number.isInteger(bins) || bins < 1) {
113
+ throw new RangeError(`deviation histogram: bins must be a positive integer, got ${bins}`);
114
+ }
115
+ this.histogram = {
116
+ min: center - halfRange, max: center + halfRange, binWidth: (2 * halfRange) / bins,
117
+ counts: new Array(bins).fill(0), below: 0, above: 0,
118
+ };
119
+ this.last = bins - 1;
120
+ }
121
+ /** `v` must be finite. */
122
+ add(v) {
123
+ const h = this.histogram;
124
+ if (v < h.min)
125
+ h.below++;
126
+ else if (v > h.max)
127
+ h.above++;
128
+ else
129
+ h.counts[Math.min(this.last, Math.floor((v - h.min) / h.binWidth))]++;
130
+ }
131
+ }
132
+ /** Histogram as a standalone pass. */
133
+ export class HistogramPass {
134
+ values;
135
+ valid;
136
+ binner;
137
+ constructor(values, range, valid) {
138
+ this.values = values;
139
+ this.valid = valid;
140
+ checkMask(values, valid);
141
+ this.binner = new HistogramBinner(range);
142
+ }
143
+ scan(start, end) {
144
+ const { values, valid, binner } = this;
145
+ for (let i = start; i < end; i++) {
146
+ const v = values[i];
147
+ if (Number.isFinite(v) && (!valid || valid[i] !== 0))
148
+ binner.add(v);
149
+ }
150
+ }
151
+ }
152
+ /** Neumaier compensated sum: exact-to-rounding for mixed magnitudes. */
153
+ class CompensatedSum {
154
+ sum = 0;
155
+ compensation = 0;
156
+ add(x) {
157
+ const t = this.sum + x;
158
+ if (Math.abs(this.sum) >= Math.abs(x))
159
+ this.compensation += (this.sum - t) + x;
160
+ else
161
+ this.compensation += (x - t) + this.sum;
162
+ this.sum = t;
163
+ }
164
+ value() {
165
+ return this.sum + this.compensation;
166
+ }
167
+ }
168
+ /** Nearest-rank index (0-based) of the `percent`-th percentile of n values. */
169
+ export function nearestRank(percent, n) {
170
+ return Math.min(n - 1, Math.max(0, Math.ceil((percent * n) / 100) - 1));
171
+ }
172
+ /** Percentiles of |d| reported, in percent. */
173
+ export const PERCENTILES = [50, 95, 99];
174
+ /**
175
+ * The two passes of a full summary: moments, extremes, counts and the
176
+ * high-bits table first; then σ about the now-known mean, and the low bits
177
+ * of the percentile buckets.
178
+ */
179
+ export class StatisticsPasses {
180
+ values;
181
+ options;
182
+ phases;
183
+ n = 0;
184
+ within = 0;
185
+ clipped = 0;
186
+ min = Infinity;
187
+ max = -Infinity;
188
+ maxAbs = 0;
189
+ mean = 0;
190
+ sum = new CompensatedSum();
191
+ sumAbs = new CompensatedSum();
192
+ sumSq = new CompensatedSum();
193
+ residual = new CompensatedSum();
194
+ binner;
195
+ /** |d| for each of {@link PERCENTILES}, set after the second pass. */
196
+ percentiles = [];
197
+ bits;
198
+ high = new Uint32Array(RADIX);
199
+ clipAt;
200
+ /** Per wanted rank: its high-bits bucket and the rank within that bucket. */
201
+ targets = [];
202
+ constructor(values, options) {
203
+ this.values = values;
204
+ this.options = options;
205
+ checkMask(values, options.valid);
206
+ if (options.tolerance !== undefined)
207
+ checkTolerance(options.tolerance);
208
+ this.binner = options.histogram ? new HistogramBinner(options.histogram) : null;
209
+ this.clipAt = options.clipRange === undefined ? undefined : Math.fround(options.clipRange);
210
+ this.bits = bitsOf(values);
211
+ this.phases = [
212
+ { scan: (s, e) => this.scanMoments(s, e), done: () => this.plan() },
213
+ { scan: (s, e) => this.scanResiduals(s, e), done: () => this.resolve() },
214
+ ];
215
+ }
216
+ scanMoments(start, end) {
217
+ const { values, bits, high, binner, sum, sumAbs, sumSq, clipAt } = this;
218
+ const { valid } = this.options;
219
+ // Absent options compare against NaN / +Infinity, so they never count.
220
+ const tolerance = this.options.tolerance ?? Number.NaN;
221
+ const clip = clipAt ?? Number.POSITIVE_INFINITY;
222
+ let { n, min, max, maxAbs, within, clipped } = this;
223
+ for (let i = start; i < end; i++) {
224
+ const b = bits[i] & ABS_MASK;
225
+ if (b >= NON_FINITE || (valid && valid[i] === 0))
226
+ continue;
227
+ const v = values[i];
228
+ const abs = Math.abs(v);
229
+ n++;
230
+ high[b >>> 16]++;
231
+ sum.add(v);
232
+ sumAbs.add(abs);
233
+ sumSq.add(v * v);
234
+ if (v < min)
235
+ min = v;
236
+ if (v > max)
237
+ max = v;
238
+ if (abs > maxAbs)
239
+ maxAbs = abs;
240
+ if (abs <= tolerance)
241
+ within++;
242
+ if (abs >= clip)
243
+ clipped++;
244
+ binner?.add(v);
245
+ }
246
+ Object.assign(this, { n, min, max, maxAbs, within, clipped });
247
+ }
248
+ /** Locate each wanted rank's high-bits bucket from the cumulative counts. */
249
+ plan() {
250
+ const n = this.n;
251
+ if (n === 0)
252
+ return;
253
+ this.mean = this.sum.value() / n;
254
+ const lows = new Map();
255
+ let bucket = 0;
256
+ let below = 0;
257
+ // Ranks ascend with the percentiles, so one forward walk serves all.
258
+ for (const percent of PERCENTILES) {
259
+ const rank = nearestRank(percent, n);
260
+ while (below + this.high[bucket] <= rank)
261
+ below += this.high[bucket++];
262
+ let low = lows.get(bucket);
263
+ if (!low)
264
+ lows.set(bucket, low = new Uint32Array(RADIX));
265
+ this.targets.push({ bucket, rank: rank - below, low });
266
+ }
267
+ }
268
+ scanResiduals(start, end) {
269
+ if (this.n === 0)
270
+ return;
271
+ const { values, bits, residual, mean } = this;
272
+ const { valid } = this.options;
273
+ // At most three distinct buckets; unused slots never match (> 0xffff).
274
+ const [t0, t1, t2] = [0, 1, 2].map((k) => this.targets[k]);
275
+ const b0 = t0.bucket, b1 = t1.bucket === b0 ? -1 : t1.bucket;
276
+ const b2 = t2.bucket === b0 || t2.bucket === t1.bucket ? -1 : t2.bucket;
277
+ const l0 = t0.low, l1 = t1.low, l2 = t2.low;
278
+ for (let i = start; i < end; i++) {
279
+ const b = bits[i] & ABS_MASK;
280
+ if (b >= NON_FINITE || (valid && valid[i] === 0))
281
+ continue;
282
+ const d = values[i] - mean;
283
+ residual.add(d * d);
284
+ const h = b >>> 16;
285
+ if (h === b0)
286
+ l0[b & LOW_MASK]++;
287
+ else if (h === b1)
288
+ l1[b & LOW_MASK]++;
289
+ else if (h === b2)
290
+ l2[b & LOW_MASK]++;
291
+ }
292
+ }
293
+ resolve() {
294
+ for (const { bucket, rank, low } of this.targets) {
295
+ let below = 0;
296
+ let l = 0;
297
+ while (below + low[l] <= rank)
298
+ below += low[l++];
299
+ this.percentiles.push(floatFromBits((bucket << 16) | l));
300
+ }
301
+ }
302
+ }
303
+ //# sourceMappingURL=deviation-statistics-kernel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviation-statistics-kernel.js","sourceRoot":"","sources":["../../src/deviation/deviation-statistics-kernel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /** A bin layout that lines up with the deviation colour ramp. */
2
+ export interface DeviationHistogramRange {
3
+ /** Ramp centre in metres (`deviationRange.centerOffset`). */
4
+ center: number;
5
+ /** Ramp half-width in metres; bins span [center − h, center + h]. */
6
+ halfRange: number;
7
+ /** Number of equal-width bins. */
8
+ bins: number;
9
+ }
10
+ export interface DeviationHistogram {
11
+ /** Lower edge of the first bin, metres. */
12
+ min: number;
13
+ /** Upper edge of the last bin (inclusive), metres. */
14
+ max: number;
15
+ binWidth: number;
16
+ /** Valid points per bin, low → high. */
17
+ counts: number[];
18
+ /** Valid points below `min` / above `max` (the ramp's saturated ends). */
19
+ below: number;
20
+ above: number;
21
+ }
22
+ export interface DeviationToleranceShare {
23
+ tolerance: number;
24
+ /** Valid points with |d| ≤ tolerance. */
25
+ count: number;
26
+ /** `count / validCount`; null when no point is valid. */
27
+ share: number | null;
28
+ }
29
+ export interface DeviationStatistics {
30
+ /** Every input point, valid or not. */
31
+ count: number;
32
+ /** Points that are unmasked and finite; every other figure is over these. */
33
+ validCount: number;
34
+ /** Valid points with |d| ≥ `clipRange` (pegged by the compute clip). */
35
+ clippedCount: number;
36
+ min: number | null;
37
+ max: number | null;
38
+ /** Signed mean. */
39
+ mean: number | null;
40
+ meanAbs: number | null;
41
+ rms: number | null;
42
+ /** Population standard deviation of the signed values. */
43
+ stdDev: number | null;
44
+ p50Abs: number | null;
45
+ p95Abs: number | null;
46
+ p99Abs: number | null;
47
+ maxAbs: number | null;
48
+ withinTolerance: DeviationToleranceShare | null;
49
+ histogram: DeviationHistogram | null;
50
+ }
51
+ export interface DeviationStatisticsOptions {
52
+ /** Per-point validity; zero excludes the point. Must match `values.length`. */
53
+ valid?: ArrayLike<number>;
54
+ /** Report the share of points with |d| ≤ tolerance (metres, ≥ 0). */
55
+ tolerance?: number;
56
+ /**
57
+ * The `maxRange` the compute pass clamped to, to count pegged points. The
58
+ * shader pegs at the float32 value, so the comparison is against
59
+ * `Math.fround(clipRange)`: 0.7 m pegs at 0.699999988 m.
60
+ */
61
+ clipRange?: number;
62
+ histogram?: DeviationHistogramRange;
63
+ }
64
+ /** One scan asset's slice of a shared readback array. */
65
+ export interface DeviationAssetRange {
66
+ expressId: number;
67
+ modelIndex: number;
68
+ offset: number;
69
+ count: number;
70
+ }
71
+ /** Every computed point's signed distance, grouped by scan asset. */
72
+ export interface DeviationDistances {
73
+ values: Float32Array;
74
+ assets: DeviationAssetRange[];
75
+ }
76
+ /** Cancellation for the sliced `…Async` variants. */
77
+ export interface DeviationAsyncOptions {
78
+ /** Aborting rejects with the signal's reason at the next slice boundary. */
79
+ signal?: AbortSignal;
80
+ }
81
+ export interface DeviationAssetSummary {
82
+ expressId: number;
83
+ modelIndex: number;
84
+ statistics: DeviationStatistics;
85
+ }
86
+ /** Full summary in one synchronous call: two O(n) passes, no copy. */
87
+ export declare function computeDeviationStatistics(values: Float32Array, options?: DeviationStatisticsOptions): DeviationStatistics;
88
+ /** {@link computeDeviationStatistics} in time-boxed slices that yield to the event loop. */
89
+ export declare function computeDeviationStatisticsAsync(values: Float32Array, options?: DeviationStatisticsOptions & DeviationAsyncOptions): Promise<DeviationStatistics>;
90
+ /** Valid points with |d| ≤ tolerance: one O(n) pass in yielding slices, no allocation. */
91
+ export declare function countWithinToleranceAsync(values: Float32Array, tolerance: number, options?: {
92
+ valid?: ArrayLike<number>;
93
+ } & DeviationAsyncOptions): Promise<number>;
94
+ /** Fixed-bin histogram over the ramp range: one O(n) pass in yielding slices. */
95
+ export declare function deviationHistogramAsync(values: Float32Array, range: DeviationHistogramRange, options?: {
96
+ valid?: ArrayLike<number>;
97
+ } & DeviationAsyncOptions): Promise<DeviationHistogram>;
98
+ /** Per-asset statistics over each asset's slice of one readback array, in yielding slices. */
99
+ export declare function summarizeDeviationAssetsAsync(distances: DeviationDistances, options?: Omit<DeviationStatisticsOptions, 'valid'> & DeviationAsyncOptions): Promise<DeviationAssetSummary[]>;
100
+ //# sourceMappingURL=deviation-statistics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviation-statistics.d.ts","sourceRoot":"","sources":["../../src/deviation/deviation-statistics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
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
+ /**
5
+ * Summary statistics over a BIM ↔ scan deviation readback (#6872).
6
+ *
7
+ * Pure functions of a `Float32Array` of signed distances in metres (one per
8
+ * scan point, positive = outside the surface), plus an optional validity
9
+ * mask. A value is VALID when the mask (if any) is non-zero AND the value is
10
+ * finite: NaN and ±Infinity never enter a moment, a percentile or a count.
11
+ *
12
+ * Accuracy:
13
+ * - Sums use Neumaier (improved Kahan) compensated summation in float64, and
14
+ * the standard deviation is a second pass over (d − mean)², so neither the
15
+ * mean nor σ loses digits to cancellation on large clouds.
16
+ * - Percentiles of |d| are EXACT nearest-rank order statistics
17
+ * (rank ⌈p·n⌉, the convention `frame-timing-stats.ts` uses), found by a
18
+ * two-pass radix select on the float32 bit patterns
19
+ * (`deviation-statistics-kernel.ts`): O(n) worst case, a fixed 1 MiB of
20
+ * count tables whatever n is, and the input is never copied or reordered.
21
+ *
22
+ * Main thread: every figure is at most two linear passes. The `…Async`
23
+ * variants run those passes in slices of a few milliseconds that yield to
24
+ * the event loop, so a 25M-point summary never blocks one task for long, and
25
+ * take an `AbortSignal` so a superseded request stops early. The viewer only
26
+ * uses those; the synchronous {@link computeDeviationStatistics} suits a
27
+ * worker, a CLI or a test.
28
+ */
29
+ import { HistogramPass, StatisticsPasses, ToleranceCount, runPhases, runPhasesSliced, } from './deviation-statistics-kernel.js';
30
+ function statisticsOf(passes, count, tolerance) {
31
+ const { n } = passes;
32
+ const withinTolerance = tolerance === undefined
33
+ ? null
34
+ : { tolerance, count: passes.within, share: n > 0 ? passes.within / n : null };
35
+ const histogram = passes.binner?.histogram ?? null;
36
+ if (n === 0) {
37
+ return {
38
+ count, validCount: 0, clippedCount: 0,
39
+ min: null, max: null, mean: null, meanAbs: null, rms: null, stdDev: null,
40
+ p50Abs: null, p95Abs: null, p99Abs: null, maxAbs: null,
41
+ withinTolerance, histogram,
42
+ };
43
+ }
44
+ const [p50Abs, p95Abs, p99Abs] = passes.percentiles;
45
+ return {
46
+ count,
47
+ validCount: n,
48
+ clippedCount: passes.clipped,
49
+ min: passes.min,
50
+ max: passes.max,
51
+ mean: passes.mean,
52
+ meanAbs: passes.sumAbs.value() / n,
53
+ rms: Math.sqrt(passes.sumSq.value() / n),
54
+ // σ from squared residuals about the mean, not E[d²] − mean², which cancels.
55
+ stdDev: Math.sqrt(passes.residual.value() / n),
56
+ p50Abs,
57
+ p95Abs,
58
+ p99Abs,
59
+ maxAbs: passes.maxAbs,
60
+ withinTolerance,
61
+ histogram,
62
+ };
63
+ }
64
+ /** Full summary in one synchronous call: two O(n) passes, no copy. */
65
+ export function computeDeviationStatistics(values, options = {}) {
66
+ const passes = new StatisticsPasses(values, options);
67
+ runPhases(values.length, passes.phases);
68
+ return statisticsOf(passes, values.length, options.tolerance);
69
+ }
70
+ /** {@link computeDeviationStatistics} in time-boxed slices that yield to the event loop. */
71
+ export async function computeDeviationStatisticsAsync(values, options = {}) {
72
+ const passes = new StatisticsPasses(values, options);
73
+ await runPhasesSliced(values.length, passes.phases, options.signal);
74
+ return statisticsOf(passes, values.length, options.tolerance);
75
+ }
76
+ /** Valid points with |d| ≤ tolerance: one O(n) pass in yielding slices, no allocation. */
77
+ export async function countWithinToleranceAsync(values, tolerance, options = {}) {
78
+ const pass = new ToleranceCount(values, tolerance, options.valid);
79
+ await runPhasesSliced(values.length, [pass], options.signal);
80
+ return pass.count;
81
+ }
82
+ /** Fixed-bin histogram over the ramp range: one O(n) pass in yielding slices. */
83
+ export async function deviationHistogramAsync(values, range, options = {}) {
84
+ const pass = new HistogramPass(values, range, options.valid);
85
+ await runPhasesSliced(values.length, [pass], options.signal);
86
+ return pass.binner.histogram;
87
+ }
88
+ /** Per-asset statistics over each asset's slice of one readback array, in yielding slices. */
89
+ export async function summarizeDeviationAssetsAsync(distances, options = {}) {
90
+ const summaries = [];
91
+ for (const asset of distances.assets) {
92
+ summaries.push({
93
+ expressId: asset.expressId,
94
+ modelIndex: asset.modelIndex,
95
+ statistics: await computeDeviationStatisticsAsync(distances.values.subarray(asset.offset, asset.offset + asset.count), options),
96
+ });
97
+ }
98
+ return summaries;
99
+ }
100
+ //# sourceMappingURL=deviation-statistics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviation-statistics.js","sourceRoot":"","sources":["../../src/deviation/deviation-statistics.ts"],"names":[],"mappings":"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"}