@onerjs/core 8.51.6 → 8.51.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 (54) hide show
  1. package/Cameras/inputMapper.js +13 -9
  2. package/Cameras/inputMapper.js.map +1 -1
  3. package/Engines/AbstractEngine/abstractEngine.views.pure.js.map +1 -1
  4. package/Engines/AbstractEngine/abstractEngine.views.types.d.ts +2 -1
  5. package/Engines/AbstractEngine/abstractEngine.views.types.js.map +1 -1
  6. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.d.ts +5 -0
  7. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.js +8 -0
  8. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.js.map +1 -0
  9. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.d.ts +278 -0
  10. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js +718 -0
  11. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js.map +1 -0
  12. package/Materials/GaussianSplatting/pure.d.ts +1 -0
  13. package/Materials/GaussianSplatting/pure.js +1 -0
  14. package/Materials/GaussianSplatting/pure.js.map +1 -1
  15. package/Materials/Textures/internalTexture.js +7 -0
  16. package/Materials/Textures/internalTexture.js.map +1 -1
  17. package/Materials/index.d.ts +1 -0
  18. package/Materials/index.js +1 -0
  19. package/Materials/index.js.map +1 -1
  20. package/Materials/pure.d.ts +1 -0
  21. package/Materials/pure.js +1 -0
  22. package/Materials/pure.js.map +1 -1
  23. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.d.ts +7 -0
  24. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.js +8 -0
  25. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.js.map +1 -0
  26. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.d.ts +147 -0
  27. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.js +257 -0
  28. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.js.map +1 -0
  29. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +11 -0
  30. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +31 -0
  31. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
  32. package/Meshes/GaussianSplatting/pure.d.ts +1 -0
  33. package/Meshes/GaussianSplatting/pure.js +1 -0
  34. package/Meshes/GaussianSplatting/pure.js.map +1 -1
  35. package/Meshes/abstractMesh.pure.js +3 -0
  36. package/Meshes/abstractMesh.pure.js.map +1 -1
  37. package/Meshes/index.d.ts +1 -0
  38. package/Meshes/index.js +1 -0
  39. package/Meshes/index.js.map +1 -1
  40. package/Meshes/pure.d.ts +1 -0
  41. package/Meshes/pure.js +1 -0
  42. package/Meshes/pure.js.map +1 -1
  43. package/Shaders/ShadersInclude/gaussianSplatting.js +33 -10
  44. package/Shaders/ShadersInclude/gaussianSplatting.js.map +1 -1
  45. package/Shaders/gaussianSplatting.vertex.js +20 -1
  46. package/Shaders/gaussianSplatting.vertex.js.map +1 -1
  47. package/Shaders/picking.fragment.js +4 -1
  48. package/Shaders/picking.fragment.js.map +1 -1
  49. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js +33 -10
  50. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js.map +1 -1
  51. package/ShadersWGSL/gaussianSplatting.vertex.js +21 -2
  52. package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
  53. package/package.json +1 -1
  54. package/scene.pure.js.map +1 -1
@@ -0,0 +1,257 @@
1
+ /** This file must only contain pure code and pure imports */
2
+ import { GaussianSplattingMaterial } from "../../Materials/GaussianSplatting/gaussianSplattingMaterial.pure.js";
3
+ import { GaussianSplattingDebugMaterialPlugin } from "../../Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js";
4
+ /**
5
+ * Manages debug rendering options across a set of Gaussian splat meshes.
6
+ * Create one instance, add meshes via addMesh(), then set options to apply
7
+ * them to every registered mesh simultaneously.
8
+ *
9
+ * All options default to their "off" states so there is no rendering cost
10
+ * until a feature is explicitly enabled.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // Global options — applied to every registered mesh
15
+ * const gsDebugger = new GaussianSplattingDebugger();
16
+ * gsDebugger.addMesh(mesh1);
17
+ * gsDebugger.addMesh(compoundMesh); // compound mesh with multiple parts
18
+ * gsDebugger.clippingBox = { min: new Vector3(-2, -2, -2), max: new Vector3(2, 2, 2) };
19
+ * gsDebugger.shOrder1 = false;
20
+ *
21
+ * // Per-part override — saturate opacity on part 0 of the compound mesh only,
22
+ * // leaving all other parts (and mesh1) unaffected
23
+ * gsDebugger.setPartOptions(compoundMesh, 0, { opacitySaturate: true });
24
+ * // Later, restore part 0 to the global setting
25
+ * gsDebugger.clearPartOptions(compoundMesh, 0);
26
+ * ```
27
+ */
28
+ export class GaussianSplattingDebugger {
29
+ constructor() {
30
+ this._plugins = [];
31
+ this._meshes = [];
32
+ this._disposeObservers = [];
33
+ // Cached option state so newly added meshes inherit current settings
34
+ this._clippingBox = null;
35
+ this._opacityCulling = null;
36
+ this._sizeCulling = null;
37
+ this._opacityScale = 1.0;
38
+ this._opacitySaturate = false;
39
+ this._shDc = true;
40
+ this._shOrder1 = true;
41
+ this._shOrder2 = true;
42
+ this._shOrder3 = true;
43
+ this._shOrder4 = true;
44
+ }
45
+ /**
46
+ * Adds a mesh to the debugger, attaching a debug plugin to its material.
47
+ * The mesh must already have a GaussianSplattingMaterial assigned (i.e., data
48
+ * must have been loaded at least once). Current option values are applied immediately.
49
+ * The mesh is automatically unregistered if it is disposed.
50
+ * @param mesh The mesh to register.
51
+ */
52
+ addMesh(mesh) {
53
+ if (this._meshes.indexOf(mesh) !== -1) {
54
+ return;
55
+ }
56
+ const mat = mesh.material;
57
+ if (!(mat instanceof GaussianSplattingMaterial)) {
58
+ throw new Error("GaussianSplattingDebugger.addMesh: mesh must have a GaussianSplattingMaterial.");
59
+ }
60
+ const plugin = new GaussianSplattingDebugMaterialPlugin(mat);
61
+ plugin.partCount = mesh.partCount ?? 0;
62
+ this._applyAllTo(plugin);
63
+ this._meshes.push(mesh);
64
+ this._plugins.push(plugin);
65
+ this._disposeObservers.push(mesh.onDisposeObservable.add(() => this.removeMesh(mesh)));
66
+ }
67
+ /**
68
+ * Removes a mesh and disposes its debug plugin.
69
+ * @param mesh The mesh to unregister.
70
+ */
71
+ removeMesh(mesh) {
72
+ const idx = this._meshes.indexOf(mesh);
73
+ if (idx === -1) {
74
+ return;
75
+ }
76
+ mesh.onDisposeObservable.remove(this._disposeObservers[idx]);
77
+ this._plugins[idx].dispose();
78
+ this._meshes.splice(idx, 1);
79
+ this._plugins.splice(idx, 1);
80
+ this._disposeObservers.splice(idx, 1);
81
+ }
82
+ /** Disposes all debug plugins and clears the mesh list. */
83
+ dispose() {
84
+ for (let i = 0; i < this._meshes.length; i++) {
85
+ this._meshes[i].onDisposeObservable.remove(this._disposeObservers[i]);
86
+ this._plugins[i].dispose();
87
+ }
88
+ this._meshes.length = 0;
89
+ this._plugins.length = 0;
90
+ this._disposeObservers.length = 0;
91
+ }
92
+ /**
93
+ * Returns the min/max size range of splats in a mesh.
94
+ * Convenience wrapper for GaussianSplattingMeshBase.splatSizeRange.
95
+ * @param mesh The mesh to query.
96
+ * @returns the splat size range, or null if not yet computed.
97
+ */
98
+ static GetSplatSizeRange(mesh) {
99
+ return mesh.splatSizeRange;
100
+ }
101
+ // ----- Option setters (broadcast to all plugins) -----
102
+ _applyAllTo(plugin) {
103
+ plugin.clippingBox = this._clippingBox;
104
+ plugin.opacityCulling = this._opacityCulling;
105
+ plugin.sizeCulling = this._sizeCulling;
106
+ plugin.opacityScale = this._opacityScale;
107
+ plugin.opacitySaturate = this._opacitySaturate;
108
+ plugin.shDc = this._shDc;
109
+ plugin.shOrder1 = this._shOrder1;
110
+ plugin.shOrder2 = this._shOrder2;
111
+ plugin.shOrder3 = this._shOrder3;
112
+ plugin.shOrder4 = this._shOrder4;
113
+ }
114
+ /**
115
+ * World-space axis-aligned clipping box. Splats outside are not rendered.
116
+ * Set to null to disable.
117
+ */
118
+ get clippingBox() {
119
+ return this._clippingBox;
120
+ }
121
+ set clippingBox(value) {
122
+ this._clippingBox = value;
123
+ for (const p of this._plugins) {
124
+ p.clippingBox = value;
125
+ }
126
+ }
127
+ /**
128
+ * Opacity culling range [0..1]. Splats outside this range are not rendered.
129
+ * Set to null to disable.
130
+ */
131
+ get opacityCulling() {
132
+ return this._opacityCulling;
133
+ }
134
+ set opacityCulling(value) {
135
+ this._opacityCulling = value;
136
+ for (const p of this._plugins) {
137
+ p.opacityCulling = value;
138
+ }
139
+ }
140
+ /**
141
+ * Size culling range. Size is pow(|det(Σ)|, 1/6) of the 3D covariance matrix,
142
+ * equal to the geometric mean of the principal radii. Splats outside this range are not rendered.
143
+ * Use GaussianSplattingDebugger.GetSplatSizeRange(mesh) to find an asset's range.
144
+ * Set to null to disable.
145
+ */
146
+ get sizeCulling() {
147
+ return this._sizeCulling;
148
+ }
149
+ set sizeCulling(value) {
150
+ this._sizeCulling = value;
151
+ for (const p of this._plugins) {
152
+ p.sizeCulling = value;
153
+ }
154
+ }
155
+ /** Scalar multiplier applied to every splat's opacity. 1.0 = no change. */
156
+ get opacityScale() {
157
+ return this._opacityScale;
158
+ }
159
+ set opacityScale(value) {
160
+ this._opacityScale = value;
161
+ for (const p of this._plugins) {
162
+ p.opacityScale = value;
163
+ }
164
+ }
165
+ /**
166
+ * When true, replaces the Gaussian spatial falloff with a flat uniform opacity,
167
+ * showing each splat as a solid disk.
168
+ */
169
+ get opacitySaturate() {
170
+ return this._opacitySaturate;
171
+ }
172
+ set opacitySaturate(value) {
173
+ this._opacitySaturate = value;
174
+ for (const p of this._plugins) {
175
+ p.opacitySaturate = value;
176
+ }
177
+ }
178
+ /** Include the DC (base) color from colorsTexture. Default: true. */
179
+ get shDc() {
180
+ return this._shDc;
181
+ }
182
+ set shDc(value) {
183
+ this._shDc = value;
184
+ for (const p of this._plugins) {
185
+ p.shDc = value;
186
+ }
187
+ }
188
+ /** Include SH band 1 contribution. Default: true. */
189
+ get shOrder1() {
190
+ return this._shOrder1;
191
+ }
192
+ set shOrder1(value) {
193
+ this._shOrder1 = value;
194
+ for (const p of this._plugins) {
195
+ p.shOrder1 = value;
196
+ }
197
+ }
198
+ /** Include SH band 2 contribution. Default: true. */
199
+ get shOrder2() {
200
+ return this._shOrder2;
201
+ }
202
+ set shOrder2(value) {
203
+ this._shOrder2 = value;
204
+ for (const p of this._plugins) {
205
+ p.shOrder2 = value;
206
+ }
207
+ }
208
+ /** Include SH band 3 contribution. Default: true. */
209
+ get shOrder3() {
210
+ return this._shOrder3;
211
+ }
212
+ set shOrder3(value) {
213
+ this._shOrder3 = value;
214
+ for (const p of this._plugins) {
215
+ p.shOrder3 = value;
216
+ }
217
+ }
218
+ /** Include SH band 4 contribution. Default: true. */
219
+ get shOrder4() {
220
+ return this._shOrder4;
221
+ }
222
+ set shOrder4(value) {
223
+ this._shOrder4 = value;
224
+ for (const p of this._plugins) {
225
+ p.shOrder4 = value;
226
+ }
227
+ }
228
+ // ----- Per-part API (compound meshes only) -----
229
+ /**
230
+ * Sets per-part debug overrides for a specific part of a compound mesh.
231
+ * The mesh must already be registered via addMesh(). Logs an error if the mesh
232
+ * is not compound (partCount is 0).
233
+ * @param mesh The compound mesh.
234
+ * @param partIndex The zero-based part index.
235
+ * @param options Partial set of debug options to override for this part.
236
+ */
237
+ setPartOptions(mesh, partIndex, options) {
238
+ const idx = this._meshes.indexOf(mesh);
239
+ if (idx < 0) {
240
+ return;
241
+ }
242
+ this._plugins[idx].setPartOptions(partIndex, options);
243
+ }
244
+ /**
245
+ * Clears all per-part debug overrides for a specific part, falling back to global settings.
246
+ * @param mesh The compound mesh.
247
+ * @param partIndex The zero-based part index.
248
+ */
249
+ clearPartOptions(mesh, partIndex) {
250
+ const idx = this._meshes.indexOf(mesh);
251
+ if (idx < 0) {
252
+ return;
253
+ }
254
+ this._plugins[idx].clearPartOptions(partIndex);
255
+ }
256
+ }
257
+ //# sourceMappingURL=gaussianSplattingDebugger.pure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gaussianSplattingDebugger.pure.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\n\nimport { type Nullable } from \"../../types\";\nimport { type Observer } from \"../../Misc/observable\";\nimport { type Node } from \"../../node\";\nimport { type Vector3 } from \"../../Maths/math.vector\";\nimport { GaussianSplattingMaterial } from \"../../Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\nimport { GaussianSplattingDebugMaterialPlugin, type IGaussianSplattingDebugOptions } from \"../../Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure\";\nimport { type GaussianSplattingMeshBase } from \"./gaussianSplattingMeshBase.pure\";\n\n/**\n * Manages debug rendering options across a set of Gaussian splat meshes.\n * Create one instance, add meshes via addMesh(), then set options to apply\n * them to every registered mesh simultaneously.\n *\n * All options default to their \"off\" states so there is no rendering cost\n * until a feature is explicitly enabled.\n *\n * @example\n * ```ts\n * // Global options — applied to every registered mesh\n * const gsDebugger = new GaussianSplattingDebugger();\n * gsDebugger.addMesh(mesh1);\n * gsDebugger.addMesh(compoundMesh); // compound mesh with multiple parts\n * gsDebugger.clippingBox = { min: new Vector3(-2, -2, -2), max: new Vector3(2, 2, 2) };\n * gsDebugger.shOrder1 = false;\n *\n * // Per-part override — saturate opacity on part 0 of the compound mesh only,\n * // leaving all other parts (and mesh1) unaffected\n * gsDebugger.setPartOptions(compoundMesh, 0, { opacitySaturate: true });\n * // Later, restore part 0 to the global setting\n * gsDebugger.clearPartOptions(compoundMesh, 0);\n * ```\n */\nexport class GaussianSplattingDebugger {\n private _plugins: GaussianSplattingDebugMaterialPlugin[] = [];\n private _meshes: GaussianSplattingMeshBase[] = [];\n private _disposeObservers: Observer<Node>[] = [];\n\n // Cached option state so newly added meshes inherit current settings\n private _clippingBox: Nullable<{ min: Vector3; max: Vector3 }> = null;\n private _opacityCulling: Nullable<{ min: number; max: number }> = null;\n private _sizeCulling: Nullable<{ min: number; max: number }> = null;\n private _opacityScale: number = 1.0;\n private _opacitySaturate: boolean = false;\n private _shDc: boolean = true;\n private _shOrder1: boolean = true;\n private _shOrder2: boolean = true;\n private _shOrder3: boolean = true;\n private _shOrder4: boolean = true;\n\n /**\n * Adds a mesh to the debugger, attaching a debug plugin to its material.\n * The mesh must already have a GaussianSplattingMaterial assigned (i.e., data\n * must have been loaded at least once). Current option values are applied immediately.\n * The mesh is automatically unregistered if it is disposed.\n * @param mesh The mesh to register.\n */\n public addMesh(mesh: GaussianSplattingMeshBase): void {\n if (this._meshes.indexOf(mesh) !== -1) {\n return;\n }\n const mat = mesh.material;\n if (!(mat instanceof GaussianSplattingMaterial)) {\n throw new Error(\"GaussianSplattingDebugger.addMesh: mesh must have a GaussianSplattingMaterial.\");\n }\n const plugin = new GaussianSplattingDebugMaterialPlugin(mat);\n plugin.partCount = (mesh as unknown as { partCount?: number }).partCount ?? 0;\n this._applyAllTo(plugin);\n this._meshes.push(mesh);\n this._plugins.push(plugin);\n this._disposeObservers.push(mesh.onDisposeObservable.add(() => this.removeMesh(mesh))!);\n }\n\n /**\n * Removes a mesh and disposes its debug plugin.\n * @param mesh The mesh to unregister.\n */\n public removeMesh(mesh: GaussianSplattingMeshBase): void {\n const idx = this._meshes.indexOf(mesh);\n if (idx === -1) {\n return;\n }\n mesh.onDisposeObservable.remove(this._disposeObservers[idx]);\n this._plugins[idx].dispose();\n this._meshes.splice(idx, 1);\n this._plugins.splice(idx, 1);\n this._disposeObservers.splice(idx, 1);\n }\n\n /** Disposes all debug plugins and clears the mesh list. */\n public dispose(): void {\n for (let i = 0; i < this._meshes.length; i++) {\n this._meshes[i].onDisposeObservable.remove(this._disposeObservers[i]);\n this._plugins[i].dispose();\n }\n this._meshes.length = 0;\n this._plugins.length = 0;\n this._disposeObservers.length = 0;\n }\n\n /**\n * Returns the min/max size range of splats in a mesh.\n * Convenience wrapper for GaussianSplattingMeshBase.splatSizeRange.\n * @param mesh The mesh to query.\n * @returns the splat size range, or null if not yet computed.\n */\n public static GetSplatSizeRange(mesh: GaussianSplattingMeshBase): Nullable<{ min: number; max: number }> {\n return mesh.splatSizeRange;\n }\n\n // ----- Option setters (broadcast to all plugins) -----\n\n private _applyAllTo(plugin: GaussianSplattingDebugMaterialPlugin): void {\n plugin.clippingBox = this._clippingBox;\n plugin.opacityCulling = this._opacityCulling;\n plugin.sizeCulling = this._sizeCulling;\n plugin.opacityScale = this._opacityScale;\n plugin.opacitySaturate = this._opacitySaturate;\n plugin.shDc = this._shDc;\n plugin.shOrder1 = this._shOrder1;\n plugin.shOrder2 = this._shOrder2;\n plugin.shOrder3 = this._shOrder3;\n plugin.shOrder4 = this._shOrder4;\n }\n\n /**\n * World-space axis-aligned clipping box. Splats outside are not rendered.\n * Set to null to disable.\n */\n public get clippingBox(): Nullable<{ min: Vector3; max: Vector3 }> {\n return this._clippingBox;\n }\n public set clippingBox(value: Nullable<{ min: Vector3; max: Vector3 }>) {\n this._clippingBox = value;\n for (const p of this._plugins) {\n p.clippingBox = value;\n }\n }\n\n /**\n * Opacity culling range [0..1]. Splats outside this range are not rendered.\n * Set to null to disable.\n */\n public get opacityCulling(): Nullable<{ min: number; max: number }> {\n return this._opacityCulling;\n }\n public set opacityCulling(value: Nullable<{ min: number; max: number }>) {\n this._opacityCulling = value;\n for (const p of this._plugins) {\n p.opacityCulling = value;\n }\n }\n\n /**\n * Size culling range. Size is pow(|det(Σ)|, 1/6) of the 3D covariance matrix,\n * equal to the geometric mean of the principal radii. Splats outside this range are not rendered.\n * Use GaussianSplattingDebugger.GetSplatSizeRange(mesh) to find an asset's range.\n * Set to null to disable.\n */\n public get sizeCulling(): Nullable<{ min: number; max: number }> {\n return this._sizeCulling;\n }\n public set sizeCulling(value: Nullable<{ min: number; max: number }>) {\n this._sizeCulling = value;\n for (const p of this._plugins) {\n p.sizeCulling = value;\n }\n }\n\n /** Scalar multiplier applied to every splat's opacity. 1.0 = no change. */\n public get opacityScale(): number {\n return this._opacityScale;\n }\n public set opacityScale(value: number) {\n this._opacityScale = value;\n for (const p of this._plugins) {\n p.opacityScale = value;\n }\n }\n\n /**\n * When true, replaces the Gaussian spatial falloff with a flat uniform opacity,\n * showing each splat as a solid disk.\n */\n public get opacitySaturate(): boolean {\n return this._opacitySaturate;\n }\n public set opacitySaturate(value: boolean) {\n this._opacitySaturate = value;\n for (const p of this._plugins) {\n p.opacitySaturate = value;\n }\n }\n\n /** Include the DC (base) color from colorsTexture. Default: true. */\n public get shDc(): boolean {\n return this._shDc;\n }\n public set shDc(value: boolean) {\n this._shDc = value;\n for (const p of this._plugins) {\n p.shDc = value;\n }\n }\n\n /** Include SH band 1 contribution. Default: true. */\n public get shOrder1(): boolean {\n return this._shOrder1;\n }\n public set shOrder1(value: boolean) {\n this._shOrder1 = value;\n for (const p of this._plugins) {\n p.shOrder1 = value;\n }\n }\n\n /** Include SH band 2 contribution. Default: true. */\n public get shOrder2(): boolean {\n return this._shOrder2;\n }\n public set shOrder2(value: boolean) {\n this._shOrder2 = value;\n for (const p of this._plugins) {\n p.shOrder2 = value;\n }\n }\n\n /** Include SH band 3 contribution. Default: true. */\n public get shOrder3(): boolean {\n return this._shOrder3;\n }\n public set shOrder3(value: boolean) {\n this._shOrder3 = value;\n for (const p of this._plugins) {\n p.shOrder3 = value;\n }\n }\n\n /** Include SH band 4 contribution. Default: true. */\n public get shOrder4(): boolean {\n return this._shOrder4;\n }\n public set shOrder4(value: boolean) {\n this._shOrder4 = value;\n for (const p of this._plugins) {\n p.shOrder4 = value;\n }\n }\n\n // ----- Per-part API (compound meshes only) -----\n\n /**\n * Sets per-part debug overrides for a specific part of a compound mesh.\n * The mesh must already be registered via addMesh(). Logs an error if the mesh\n * is not compound (partCount is 0).\n * @param mesh The compound mesh.\n * @param partIndex The zero-based part index.\n * @param options Partial set of debug options to override for this part.\n */\n public setPartOptions(mesh: GaussianSplattingMeshBase, partIndex: number, options: Partial<IGaussianSplattingDebugOptions>): void {\n const idx = this._meshes.indexOf(mesh);\n if (idx < 0) {\n return;\n }\n this._plugins[idx].setPartOptions(partIndex, options);\n }\n\n /**\n * Clears all per-part debug overrides for a specific part, falling back to global settings.\n * @param mesh The compound mesh.\n * @param partIndex The zero-based part index.\n */\n public clearPartOptions(mesh: GaussianSplattingMeshBase, partIndex: number): void {\n const idx = this._meshes.indexOf(mesh);\n if (idx < 0) {\n return;\n }\n this._plugins[idx].clearPartOptions(partIndex);\n }\n}\n"]}
@@ -256,6 +256,8 @@ export declare class GaussianSplattingMeshBase extends Mesh {
256
256
  protected _useRGBACovariants: boolean;
257
257
  private _material;
258
258
  private _tmpCovariances;
259
+ private _splatSizeMin;
260
+ private _splatSizeMax;
259
261
  private _sortIsDirty;
260
262
  protected _cachedBoundingMin: Nullable<Vector3>;
261
263
  protected _cachedBoundingMax: Nullable<Vector3>;
@@ -322,6 +324,15 @@ export declare class GaussianSplattingMeshBase extends Mesh {
322
324
  * Only available if the mesh was created with keepInRam: true
323
325
  */
324
326
  get shData(): Nullable<Uint8Array<ArrayBufferLike>[]>;
327
+ /**
328
+ * Returns the min/max size range of splats in this mesh, where size is pow(|det(Σ)|, 1/6)
329
+ * of the 3D covariance matrix — equivalent to the geometric mean of the principal radii.
330
+ * Computed automatically during updateData(). Returns null before any data has been loaded.
331
+ */
332
+ get splatSizeRange(): Nullable<{
333
+ min: number;
334
+ max: number;
335
+ }>;
325
336
  /**
326
337
  * Set the number of batch (a batch is 16384 splats) after which a display update is performed
327
338
  * A value of 0 (default) means display update will not happens before splat is ready.
@@ -286,6 +286,17 @@ export class GaussianSplattingMeshBase extends Mesh {
286
286
  get shData() {
287
287
  return this._keepInRam ? this._shData : null;
288
288
  }
289
+ /**
290
+ * Returns the min/max size range of splats in this mesh, where size is pow(|det(Σ)|, 1/6)
291
+ * of the 3D covariance matrix — equivalent to the geometric mean of the principal radii.
292
+ * Computed automatically during updateData(). Returns null before any data has been loaded.
293
+ */
294
+ get splatSizeRange() {
295
+ if (!isFinite(this._splatSizeMin) || !isFinite(this._splatSizeMax)) {
296
+ return null;
297
+ }
298
+ return { min: this._splatSizeMin, max: this._splatSizeMax };
299
+ }
289
300
  /**
290
301
  * Gets the covariancesA texture
291
302
  */
@@ -449,6 +460,8 @@ export class GaussianSplattingMeshBase extends Mesh {
449
460
  this._useRGBACovariants = false;
450
461
  this._material = null;
451
462
  this._tmpCovariances = [0, 0, 0, 0, 0, 0];
463
+ this._splatSizeMin = Infinity;
464
+ this._splatSizeMax = -Infinity;
452
465
  this._sortIsDirty = false;
453
466
  // Cached bounding box for incremental addPart updates (O(1) vs O(N) scan of positions)
454
467
  this._cachedBoundingMin = null;
@@ -1712,6 +1725,20 @@ export class GaussianSplattingMeshBase extends Mesh {
1712
1725
  covA[dstIndex * 4 + 3] = ToHalfFloat(covariances[3] / transform);
1713
1726
  covB[dstIndex * covBSItemSize + 0] = ToHalfFloat(covariances[4] / transform);
1714
1727
  covB[dstIndex * covBSItemSize + 1] = ToHalfFloat(covariances[5] / transform);
1728
+ const c0 = covariances[0];
1729
+ const c1 = covariances[1];
1730
+ const c2 = covariances[2];
1731
+ const c3 = covariances[3];
1732
+ const c4 = covariances[4];
1733
+ const c5 = covariances[5];
1734
+ const det3d = c0 * (c3 * c5 - c4 * c4) - c1 * (c1 * c5 - c4 * c2) + c2 * (c1 * c4 - c3 * c2);
1735
+ const splatSize = Math.pow(Math.abs(det3d), 1.0 / 6.0);
1736
+ if (splatSize < this._splatSizeMin) {
1737
+ this._splatSizeMin = splatSize;
1738
+ }
1739
+ if (splatSize > this._splatSizeMax) {
1740
+ this._splatSizeMax = splatSize;
1741
+ }
1715
1742
  // colors
1716
1743
  colorArray[dstIndex * 4 + 0] = uBuffer[32 * srcIndex + 24 + 0];
1717
1744
  colorArray[dstIndex * 4 + 1] = uBuffer[32 * srcIndex + 24 + 1];
@@ -1932,6 +1959,10 @@ export class GaussianSplattingMeshBase extends Mesh {
1932
1959
  // GPU region untouched. Falls through to the full-rebuild path when textures don't exist yet
1933
1960
  // or the texture height needs to grow.
1934
1961
  const incremental = this._canReuseCachedData(previousVertexCount, vertexCount);
1962
+ if (!incremental) {
1963
+ this._splatSizeMin = Infinity;
1964
+ this._splatSizeMax = -Infinity;
1965
+ }
1935
1966
  // The first texture line/texel that must be (re-)processed and uploaded.
1936
1967
  // For a full rebuild this is 0. For an incremental update it is the row boundary just before
1937
1968
  // previousVertexCount so that any partial old row is re-processed as a complete row.