@onerjs/core 8.54.4 → 8.54.5
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.
- package/Engines/WebGPU/Extensions/engine.cubeTexture.pure.js +1 -1
- package/Engines/WebGPU/Extensions/engine.cubeTexture.pure.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.rawTexture.pure.js +2 -2
- package/Engines/WebGPU/Extensions/engine.rawTexture.pure.js.map +1 -1
- package/Engines/WebGPU/webgpuCacheRenderPipeline.d.ts +1 -0
- package/Engines/WebGPU/webgpuCacheRenderPipeline.js +18 -4
- package/Engines/WebGPU/webgpuCacheRenderPipeline.js.map +1 -1
- package/Engines/WebGPU/webgpuCacheTextureView.d.ts +13 -0
- package/Engines/WebGPU/webgpuCacheTextureView.js +32 -0
- package/Engines/WebGPU/webgpuCacheTextureView.js.map +1 -0
- package/Engines/WebGPU/webgpuRenderTargetWrapper.d.ts +10 -0
- package/Engines/WebGPU/webgpuRenderTargetWrapper.js +10 -0
- package/Engines/WebGPU/webgpuRenderTargetWrapper.js.map +1 -1
- package/Engines/WebGPU/webgpuShaderProcessorsWGSL.pure.js +57 -4
- package/Engines/WebGPU/webgpuShaderProcessorsWGSL.pure.js.map +1 -1
- package/Engines/WebGPU/webgpuTextureManager.d.ts +1 -1
- package/Engines/WebGPU/webgpuTextureManager.js +4 -2
- package/Engines/WebGPU/webgpuTextureManager.js.map +1 -1
- package/Engines/abstractEngine.pure.js +2 -2
- package/Engines/abstractEngine.pure.js.map +1 -1
- package/Engines/thinNativeEngine.pure.d.ts +5 -0
- package/Engines/thinNativeEngine.pure.js +29 -6
- package/Engines/thinNativeEngine.pure.js.map +1 -1
- package/Engines/webgpuEngine.pure.d.ts +1 -0
- package/Engines/webgpuEngine.pure.js +21 -8
- package/Engines/webgpuEngine.pure.js.map +1 -1
- package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.d.ts +95 -1
- package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.js +169 -4
- package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.js.map +1 -1
- package/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.d.ts +21 -6
- package/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.js +28 -26
- package/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.js.map +1 -1
- package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.d.ts +30 -2
- package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.js +111 -29
- package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.js.map +1 -1
- package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.d.ts +56 -2
- package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.js +99 -14
- package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.js.map +1 -1
- package/FlowGraph/Blocks/Data/Transformers/flowGraphJsonPointerParserBlock.pure.js +10 -2
- package/FlowGraph/Blocks/Data/Transformers/flowGraphJsonPointerParserBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.js +21 -1
- package/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.d.ts +18 -0
- package/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.js +29 -2
- package/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.d.ts +15 -0
- package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.js +44 -7
- package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.d.ts +9 -0
- package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.js +9 -1
- package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.d.ts +7 -0
- package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.js +8 -1
- package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.d.ts +5 -0
- package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.js +8 -0
- package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.js.map +1 -0
- package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.d.ts +37 -0
- package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.js +44 -0
- package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.js.map +1 -0
- package/FlowGraph/Blocks/Event/index.d.ts +1 -0
- package/FlowGraph/Blocks/Event/index.js +1 -0
- package/FlowGraph/Blocks/Event/index.js.map +1 -1
- package/FlowGraph/Blocks/Event/pure.d.ts +1 -0
- package/FlowGraph/Blocks/Event/pure.js +1 -0
- package/FlowGraph/Blocks/Event/pure.js.map +1 -1
- package/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.d.ts +4 -1
- package/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.js +67 -2
- package/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.d.ts +13 -0
- package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.js +102 -7
- package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.js +5 -1
- package/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCancelDelayBlock.pure.js +5 -1
- package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCancelDelayBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.d.ts +11 -2
- package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.js +21 -3
- package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphSetDelayBlock.pure.js +25 -4
- package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphSetDelayBlock.pure.js.map +1 -1
- package/FlowGraph/Blocks/flowGraphBlockFactory.js +18 -0
- package/FlowGraph/Blocks/flowGraphBlockFactory.js.map +1 -1
- package/FlowGraph/Blocks/flowGraphBlockNames.d.ts +9 -0
- package/FlowGraph/Blocks/flowGraphBlockNames.js +9 -0
- package/FlowGraph/Blocks/flowGraphBlockNames.js.map +1 -1
- package/FlowGraph/CustomTypes/flowGraphMatrix.d.ts +17 -3
- package/FlowGraph/CustomTypes/flowGraphMatrix.js +27 -21
- package/FlowGraph/CustomTypes/flowGraphMatrix.js.map +1 -1
- package/FlowGraph/flowGraphContext.d.ts +23 -0
- package/FlowGraph/flowGraphContext.js +29 -0
- package/FlowGraph/flowGraphContext.js.map +1 -1
- package/FlowGraph/flowGraphCoordinator.d.ts +58 -1
- package/FlowGraph/flowGraphCoordinator.js +72 -0
- package/FlowGraph/flowGraphCoordinator.js.map +1 -1
- package/FlowGraph/flowGraphDelayRegistry.d.ts +31 -0
- package/FlowGraph/flowGraphDelayRegistry.js +50 -0
- package/FlowGraph/flowGraphDelayRegistry.js.map +1 -0
- package/FlowGraph/flowGraphHostResolver.d.ts +69 -0
- package/FlowGraph/flowGraphHostResolver.js +25 -0
- package/FlowGraph/flowGraphHostResolver.js.map +1 -0
- package/FlowGraph/flowGraphMath.d.ts +48 -1
- package/FlowGraph/flowGraphMath.js +169 -4
- package/FlowGraph/flowGraphMath.js.map +1 -1
- package/FlowGraph/flowGraphPathConverterComponent.d.ts +14 -3
- package/FlowGraph/flowGraphPathConverterComponent.js +110 -18
- package/FlowGraph/flowGraphPathConverterComponent.js.map +1 -1
- package/FlowGraph/flowGraphSignalConnection.pure.js +7 -1
- package/FlowGraph/flowGraphSignalConnection.pure.js.map +1 -1
- package/FlowGraph/index.d.ts +2 -0
- package/FlowGraph/index.js +2 -0
- package/FlowGraph/index.js.map +1 -1
- package/FlowGraph/pure.d.ts +2 -0
- package/FlowGraph/pure.js +2 -0
- package/FlowGraph/pure.js.map +1 -1
- package/Maths/math.vector.pure.d.ts +10 -0
- package/Maths/math.vector.pure.js +13 -0
- package/Maths/math.vector.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.d.ts +216 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js +714 -67
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +81 -4
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +466 -52
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.d.ts +19 -0
- package/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.js +24 -0
- package/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js +31 -6
- package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js.map +1 -1
- package/Meshes/GreasedLine/greasedLineRibbonMesh.pure.js +5 -1
- package/Meshes/GreasedLine/greasedLineRibbonMesh.pure.js.map +1 -1
- package/Misc/greasedLineTools.js +1 -1
- package/Misc/greasedLineTools.js.map +1 -1
- package/Misc/tools.pure.js +14 -2
- package/Misc/tools.pure.js.map +1 -1
- package/Particles/gpuParticleSystem.pure.d.ts +66 -1
- package/Particles/gpuParticleSystem.pure.js +189 -49
- package/Particles/gpuParticleSystem.pure.js.map +1 -1
- package/Physics/v2/characterController.js +69 -17
- package/Physics/v2/characterController.js.map +1 -1
- package/XR/features/Layers/WebXRWebGPUCompositionLayer.d.ts +3 -9
- package/XR/features/Layers/WebXRWebGPUCompositionLayer.js +4 -11
- package/XR/features/Layers/WebXRWebGPUCompositionLayer.js.map +1 -1
- package/XR/features/WebXRAbstractFeature.d.ts +9 -0
- package/XR/features/WebXRAbstractFeature.js +16 -0
- package/XR/features/WebXRAbstractFeature.js.map +1 -1
- package/XR/features/WebXRDepthSensing.pure.d.ts +7 -0
- package/XR/features/WebXRDepthSensing.pure.js +350 -39
- package/XR/features/WebXRDepthSensing.pure.js.map +1 -1
- package/XR/features/WebXRImageTracking.pure.js.map +1 -1
- package/XR/features/WebXRLayers.pure.d.ts +6 -5
- package/XR/features/WebXRLayers.pure.js +65 -8
- package/XR/features/WebXRLayers.pure.js.map +1 -1
- package/XR/features/WebXRRawCameraAccess.pure.js +9 -2
- package/XR/features/WebXRRawCameraAccess.pure.js.map +1 -1
- package/XR/features/WebXRSpaceWarp.pure.d.ts +0 -1
- package/XR/features/WebXRSpaceWarp.pure.js +13 -4
- package/XR/features/WebXRSpaceWarp.pure.js.map +1 -1
- package/XR/features/WebXRWalkingLocomotion.pure.js.map +1 -1
- package/XR/webXRCamera.js +27 -0
- package/XR/webXRCamera.js.map +1 -1
- package/XR/webXRFeatureWarningRegistry.d.ts +14 -0
- package/XR/webXRFeatureWarningRegistry.js +19 -0
- package/XR/webXRFeatureWarningRegistry.js.map +1 -0
- package/XR/webXRFeaturesManager.d.ts +5 -0
- package/XR/webXRFeaturesManager.js +23 -4
- package/XR/webXRFeaturesManager.js.map +1 -1
- package/XR/webXRGraphicsBinding.d.ts +17 -10
- package/XR/webXRGraphicsBinding.js +8 -5
- package/XR/webXRGraphicsBinding.js.map +1 -1
- package/XR/webXRSessionManager.d.ts +3 -5
- package/XR/webXRSessionManager.js +1 -3
- package/XR/webXRSessionManager.js.map +1 -1
- package/XR/webXRWebGPURenderTargetTextureProvider.d.ts +21 -5
- package/XR/webXRWebGPURenderTargetTextureProvider.js +38 -10
- package/XR/webXRWebGPURenderTargetTextureProvider.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/** This file must only contain pure code and pure imports */
|
|
2
2
|
import { type Nullable } from "../../types.js";
|
|
3
3
|
import { type Scene } from "../../scene.pure.js";
|
|
4
|
+
import { type AbstractMesh } from "../abstractMesh.pure.js";
|
|
4
5
|
import { Mesh } from "../mesh.pure.js";
|
|
5
6
|
import { BoundingInfo } from "../../Culling/boundingInfo.js";
|
|
6
7
|
import { type GaussianSplattingMesh } from "./gaussianSplattingMesh.pure.js";
|
|
7
8
|
import { type Ray } from "../../Culling/ray.core.js";
|
|
8
9
|
import { PickingInfo } from "../../Collisions/pickingInfo.js";
|
|
10
|
+
import { Vector3 } from "../../Maths/math.vector.pure.js";
|
|
9
11
|
/**
|
|
10
12
|
* Class used as a proxy mesh for a part of a compound Gaussian Splatting mesh
|
|
11
13
|
*/
|
|
@@ -75,6 +77,23 @@ export declare class GaussianSplattingPartProxyMesh extends Mesh {
|
|
|
75
77
|
* @returns "GaussianSplattingPartProxyMesh"
|
|
76
78
|
*/
|
|
77
79
|
getClassName(): string;
|
|
80
|
+
/**
|
|
81
|
+
* Returns the world-space bounding vectors spanning this part (and any descendants).
|
|
82
|
+
*
|
|
83
|
+
* A part proxy carries real bounds (set via {@link setBoundingInfo}) but owns NO geometry — the compound
|
|
84
|
+
* holds the splats. The base {@link Node.getHierarchyBoundingVectors} only folds in a mesh's own bounds
|
|
85
|
+
* when it has a `subMeshes` array (a geometry-less mesh's is `undefined`) and skips zero-vertex descendants,
|
|
86
|
+
* so for a bare proxy it returns a degenerate ±MAX_VALUE box. Callers that treat the proxy as a normal mesh
|
|
87
|
+
* (camera framing, grounding, picking) would then derive NaN / astronomically large offsets. This override
|
|
88
|
+
* folds the proxy's own world-space box into whatever the base returns for descendants.
|
|
89
|
+
* @param includeDescendants include bounding vectors from descendant meshes
|
|
90
|
+
* @param predicate optional filter applied to each descendant mesh
|
|
91
|
+
* @returns the world-space min/max spanning this part (and any descendants)
|
|
92
|
+
*/
|
|
93
|
+
getHierarchyBoundingVectors(includeDescendants?: boolean, predicate?: Nullable<(abstractMesh: AbstractMesh) => boolean>): {
|
|
94
|
+
min: Vector3;
|
|
95
|
+
max: Vector3;
|
|
96
|
+
};
|
|
78
97
|
/**
|
|
79
98
|
* Updates the part index for this proxy mesh.
|
|
80
99
|
* This should only be called internally when parts are removed from the compound mesh.
|
|
@@ -69,6 +69,30 @@ export class GaussianSplattingPartProxyMesh extends Mesh {
|
|
|
69
69
|
getClassName() {
|
|
70
70
|
return "GaussianSplattingPartProxyMesh";
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns the world-space bounding vectors spanning this part (and any descendants).
|
|
74
|
+
*
|
|
75
|
+
* A part proxy carries real bounds (set via {@link setBoundingInfo}) but owns NO geometry — the compound
|
|
76
|
+
* holds the splats. The base {@link Node.getHierarchyBoundingVectors} only folds in a mesh's own bounds
|
|
77
|
+
* when it has a `subMeshes` array (a geometry-less mesh's is `undefined`) and skips zero-vertex descendants,
|
|
78
|
+
* so for a bare proxy it returns a degenerate ±MAX_VALUE box. Callers that treat the proxy as a normal mesh
|
|
79
|
+
* (camera framing, grounding, picking) would then derive NaN / astronomically large offsets. This override
|
|
80
|
+
* folds the proxy's own world-space box into whatever the base returns for descendants.
|
|
81
|
+
* @param includeDescendants include bounding vectors from descendant meshes
|
|
82
|
+
* @param predicate optional filter applied to each descendant mesh
|
|
83
|
+
* @returns the world-space min/max spanning this part (and any descendants)
|
|
84
|
+
*/
|
|
85
|
+
getHierarchyBoundingVectors(includeDescendants = true, predicate = null) {
|
|
86
|
+
// Base recomputes this proxy's world matrix but skips its (geometry-less) own bounds.
|
|
87
|
+
const result = super.getHierarchyBoundingVectors(includeDescendants, predicate);
|
|
88
|
+
// Refresh the world-space corners against the just-computed world matrix, then extend the result:
|
|
89
|
+
// CheckExtends turns the base's ±MAX_VALUE sentinel seed into this part's real box.
|
|
90
|
+
const info = this.getBoundingInfo();
|
|
91
|
+
info.update(this.getWorldMatrix());
|
|
92
|
+
Vector3.CheckExtends(info.boundingBox.minimumWorld, result.min, result.max);
|
|
93
|
+
Vector3.CheckExtends(info.boundingBox.maximumWorld, result.min, result.max);
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
72
96
|
/**
|
|
73
97
|
* Updates the part index for this proxy mesh.
|
|
74
98
|
* This should only be called internally when parts are removed from the compound mesh.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gaussianSplattingPartProxyMesh.pure.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type GaussianSplattingMesh } from \"./gaussianSplattingMesh.pure\";\r\nimport { type Ray } from \"../../Culling/ray.core\";\r\nimport { PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Class used as a proxy mesh for a part of a compound Gaussian Splatting mesh\r\n */\r\nexport class GaussianSplattingPartProxyMesh extends Mesh {\r\n /**\r\n * Local-space bounds for this part, stored directly on the proxy so it does not\r\n * need to retain a reference to the original source mesh.\r\n */\r\n private _minimum: Vector3;\r\n private _maximum: Vector3;\r\n\r\n /**\r\n * The index of the part in the compound mesh (internal storage)\r\n */\r\n private _partIndex: number;\r\n\r\n /**\r\n * Number of splats owned by this part.\r\n * @internal\r\n */\r\n public _vertexCount: number;\r\n\r\n /**\r\n * Offset of this part in the compound splat ordering.\r\n * @internal\r\n */\r\n public _splatsDataOffset: number;\r\n\r\n /**\r\n * Texel offset of this part inside the compound SH textures.\r\n * This matches the splat offset because SH data is stored one texel per splat.\r\n * @internal\r\n */\r\n public _shDataOffset: number;\r\n\r\n /**\r\n * Gets the index of the part in the compound mesh\r\n */\r\n public get partIndex(): number {\r\n return this._partIndex;\r\n }\r\n\r\n /**\r\n * The compound mesh that owns this part proxy\r\n */\r\n public readonly compoundSplatMesh: GaussianSplattingMesh;\r\n\r\n /**\r\n * Backward-compatible alias for the owning compound mesh.\r\n * @deprecated Use `compoundSplatMesh` instead.\r\n */\r\n public get proxiedMesh(): GaussianSplattingMesh {\r\n return this.compoundSplatMesh;\r\n }\r\n\r\n /**\r\n * Creates a new Gaussian Splatting part proxy mesh\r\n * @param name The name of the proxy mesh\r\n * @param scene The scene the proxy mesh belongs to\r\n * @param compoundSplatMesh The compound mesh that owns this part proxy\r\n * @param partIndex The index of the part in the compound mesh\r\n * @param boundingInfo Local-space bounds of the part inside the compound mesh\r\n * @param vertexCount Number of splats owned by the part\r\n * @param splatsDataOffset Offset of the part in the compound splat ordering\r\n * @param shDataOffset Offset of the part in the compound SH textures\r\n */\r\n constructor(\r\n name: string,\r\n scene: Nullable<Scene>,\r\n compoundSplatMesh: GaussianSplattingMesh,\r\n partIndex: number,\r\n boundingInfo: BoundingInfo,\r\n vertexCount: number,\r\n splatsDataOffset: number,\r\n shDataOffset: number = splatsDataOffset\r\n ) {\r\n super(name, scene);\r\n this._partIndex = partIndex;\r\n this._vertexCount = vertexCount;\r\n this._splatsDataOffset = splatsDataOffset;\r\n this._shDataOffset = shDataOffset;\r\n this._minimum = boundingInfo.minimum.clone();\r\n this._maximum = boundingInfo.maximum.clone();\r\n this.compoundSplatMesh = compoundSplatMesh;\r\n\r\n this._applyBoundingInfo();\r\n this.compoundSplatMesh.setWorldMatrixForPart(this.partIndex, this.getWorldMatrix());\r\n\r\n // Update the compound mesh's part matrix when this proxy's world matrix changes.\r\n this.onAfterWorldMatrixUpdateObservable.add(() => {\r\n this.compoundSplatMesh.setWorldMatrixForPart(this.partIndex, this.getWorldMatrix());\r\n });\r\n }\r\n\r\n /**\r\n * Updates the bounding info of this proxy mesh from its stored part metadata.\r\n */\r\n public updateBoundingInfoFromPartData(): void {\r\n this._applyBoundingInfo();\r\n }\r\n\r\n /**\r\n * Backward-compatible alias retained while callers move away from source-mesh based semantics.\r\n */\r\n public updateBoundingInfoFromProxiedMesh(): void {\r\n this.updateBoundingInfoFromPartData();\r\n }\r\n\r\n private _applyBoundingInfo(): void {\r\n this.setBoundingInfo(new BoundingInfo(this._minimum.clone(), this._maximum.clone()));\r\n }\r\n\r\n /**\r\n * Returns the class name\r\n * @returns \"GaussianSplattingPartProxyMesh\"\r\n */\r\n public override getClassName(): string {\r\n return \"GaussianSplattingPartProxyMesh\";\r\n }\r\n\r\n /**\r\n * Updates the part index for this proxy mesh.\r\n * This should only be called internally when parts are removed from the compound mesh.\r\n * @param newPartIndex the new part index\r\n * @internal\r\n */\r\n public updatePartIndex(newPartIndex: number): void {\r\n this._partIndex = newPartIndex;\r\n }\r\n\r\n /**\r\n * Updates the per-part metadata for this proxy mesh.\r\n * This is used internally when compound parts are rebuilt and re-indexed.\r\n * @param vertexCount the number of splats owned by the part\r\n * @param splatsDataOffset the new splat offset in the compound\r\n * @param shDataOffset the new SH texel offset in the compound\r\n * @internal\r\n */\r\n public updatePartMetadata(vertexCount: number, splatsDataOffset: number, shDataOffset: number = splatsDataOffset): void {\r\n this._vertexCount = vertexCount;\r\n this._splatsDataOffset = splatsDataOffset;\r\n this._shDataOffset = shDataOffset;\r\n }\r\n\r\n /**\r\n * Gets whether the part is visible\r\n */\r\n public override get isVisible(): boolean {\r\n return this.compoundSplatMesh.getPartVisibility(this.partIndex) > 0;\r\n }\r\n\r\n /**\r\n * Sets whether the part is visible\r\n */\r\n public override set isVisible(value: boolean) {\r\n this.compoundSplatMesh.setPartVisibility(this.partIndex, value ? 1.0 : 0.0);\r\n }\r\n\r\n /**\r\n * Gets the visibility of the part (0.0 to 1.0)\r\n */\r\n public override get visibility(): number {\r\n return this.compoundSplatMesh.getPartVisibility(this.partIndex);\r\n }\r\n\r\n /**\r\n * Sets the visibility of the part (0.0 to 1.0)\r\n */\r\n public override set visibility(value: number) {\r\n this.compoundSplatMesh.setPartVisibility(this.partIndex, value);\r\n }\r\n\r\n /**\r\n * Checks if a ray intersects with this proxy mesh using only bounding info\r\n * @param ray defines the ray to test\r\n * @returns the picking info with this mesh set as pickedMesh if hit\r\n */\r\n public override intersects(ray: Ray): PickingInfo {\r\n const pickingInfo = new PickingInfo();\r\n const boundingInfo = this.getBoundingInfo();\r\n\r\n if (!boundingInfo) {\r\n return pickingInfo;\r\n }\r\n\r\n // Always check against bounding info for proxy meshes\r\n if (!ray.intersectsSphere(boundingInfo.boundingSphere) || !ray.intersectsBox(boundingInfo.boundingBox)) {\r\n return pickingInfo;\r\n }\r\n\r\n // If we hit the bounding volume, report this mesh as picked\r\n pickingInfo.hit = true;\r\n pickingInfo.pickedMesh = this;\r\n pickingInfo.distance = Vector3.Distance(ray.origin, boundingInfo.boundingSphere.center);\r\n pickingInfo.subMeshId = 0;\r\n\r\n return pickingInfo;\r\n }\r\n\r\n /**\r\n * Serialize current GaussianSplattingPartProxyMesh\r\n * @param serializationObject defines the object which will receive the serialization data\r\n * @returns the serialized object\r\n */\r\n public override serialize(serializationObject: any = {}): any {\r\n serializationObject = super.serialize(serializationObject);\r\n // GaussianSplattingPartProxyMesh needs no SubMesh, Geometry, or Material\r\n serializationObject.subMeshes = [];\r\n serializationObject.geometryUniqueId = undefined;\r\n serializationObject.geometryId = undefined;\r\n serializationObject.materialUniqueId = undefined;\r\n serializationObject.materialId = undefined;\r\n serializationObject.instances = [];\r\n serializationObject.actions = undefined;\r\n serializationObject.type = this.getClassName();\r\n serializationObject.compoundSplatMeshId = this.compoundSplatMesh.id;\r\n // Part metadata is needed to reconnect the proxy to the correct compound segment.\r\n serializationObject.partIndex = this._partIndex;\r\n serializationObject.vertexCount = this._vertexCount;\r\n serializationObject.splatsDataOffset = this._splatsDataOffset;\r\n serializationObject.shDataOffset = this._shDataOffset;\r\n const boundingInfo = this.getBoundingInfo();\r\n serializationObject.boundingInfo = {\r\n minimum: boundingInfo.minimum.asArray(),\r\n maximum: boundingInfo.maximum.asArray(),\r\n };\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Parses a serialized GaussianSplattingPartProxyMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingPartProxyMesh in\r\n * @returns the created GaussianSplattingPartProxyMesh\r\n */\r\n public static override Parse(parsedMesh: any, scene: Scene): GaussianSplattingPartProxyMesh {\r\n const partIndex = parsedMesh.partIndex;\r\n const compoundSplatMesh =\r\n (parsedMesh.compoundSplatMesh as GaussianSplattingMesh | undefined) ?? (scene.getLastMeshById(parsedMesh.compoundSplatMeshId) as GaussianSplattingMesh | null);\r\n if (!compoundSplatMesh) {\r\n throw new Error(`GaussianSplattingPartProxyMesh: compound mesh not found with ID ${parsedMesh.compoundSplatMeshId}`);\r\n }\r\n const minimum = Vector3.FromArray(parsedMesh.boundingInfo.minimum);\r\n const maximum = Vector3.FromArray(parsedMesh.boundingInfo.maximum);\r\n const boundingInfo = new BoundingInfo(minimum, maximum);\r\n const vertexCount = parsedMesh.vertexCount ?? 0;\r\n const splatsDataOffset = parsedMesh.splatsDataOffset ?? 0;\r\n const shDataOffset = parsedMesh.shDataOffset ?? splatsDataOffset;\r\n return new GaussianSplattingPartProxyMesh(parsedMesh.name, scene, compoundSplatMesh, partIndex, boundingInfo, vertexCount, splatsDataOffset, shDataOffset);\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingPartProxyMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingPartProxyMesh(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n Mesh._GaussianSplattingPartProxyMeshParser = GaussianSplattingPartProxyMesh.Parse;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"gaussianSplattingPartProxyMesh.pure.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { type AbstractMesh } from \"../abstractMesh.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type GaussianSplattingMesh } from \"./gaussianSplattingMesh.pure\";\r\nimport { type Ray } from \"../../Culling/ray.core\";\r\nimport { PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Class used as a proxy mesh for a part of a compound Gaussian Splatting mesh\r\n */\r\nexport class GaussianSplattingPartProxyMesh extends Mesh {\r\n /**\r\n * Local-space bounds for this part, stored directly on the proxy so it does not\r\n * need to retain a reference to the original source mesh.\r\n */\r\n private _minimum: Vector3;\r\n private _maximum: Vector3;\r\n\r\n /**\r\n * The index of the part in the compound mesh (internal storage)\r\n */\r\n private _partIndex: number;\r\n\r\n /**\r\n * Number of splats owned by this part.\r\n * @internal\r\n */\r\n public _vertexCount: number;\r\n\r\n /**\r\n * Offset of this part in the compound splat ordering.\r\n * @internal\r\n */\r\n public _splatsDataOffset: number;\r\n\r\n /**\r\n * Texel offset of this part inside the compound SH textures.\r\n * This matches the splat offset because SH data is stored one texel per splat.\r\n * @internal\r\n */\r\n public _shDataOffset: number;\r\n\r\n /**\r\n * Gets the index of the part in the compound mesh\r\n */\r\n public get partIndex(): number {\r\n return this._partIndex;\r\n }\r\n\r\n /**\r\n * The compound mesh that owns this part proxy\r\n */\r\n public readonly compoundSplatMesh: GaussianSplattingMesh;\r\n\r\n /**\r\n * Backward-compatible alias for the owning compound mesh.\r\n * @deprecated Use `compoundSplatMesh` instead.\r\n */\r\n public get proxiedMesh(): GaussianSplattingMesh {\r\n return this.compoundSplatMesh;\r\n }\r\n\r\n /**\r\n * Creates a new Gaussian Splatting part proxy mesh\r\n * @param name The name of the proxy mesh\r\n * @param scene The scene the proxy mesh belongs to\r\n * @param compoundSplatMesh The compound mesh that owns this part proxy\r\n * @param partIndex The index of the part in the compound mesh\r\n * @param boundingInfo Local-space bounds of the part inside the compound mesh\r\n * @param vertexCount Number of splats owned by the part\r\n * @param splatsDataOffset Offset of the part in the compound splat ordering\r\n * @param shDataOffset Offset of the part in the compound SH textures\r\n */\r\n constructor(\r\n name: string,\r\n scene: Nullable<Scene>,\r\n compoundSplatMesh: GaussianSplattingMesh,\r\n partIndex: number,\r\n boundingInfo: BoundingInfo,\r\n vertexCount: number,\r\n splatsDataOffset: number,\r\n shDataOffset: number = splatsDataOffset\r\n ) {\r\n super(name, scene);\r\n this._partIndex = partIndex;\r\n this._vertexCount = vertexCount;\r\n this._splatsDataOffset = splatsDataOffset;\r\n this._shDataOffset = shDataOffset;\r\n this._minimum = boundingInfo.minimum.clone();\r\n this._maximum = boundingInfo.maximum.clone();\r\n this.compoundSplatMesh = compoundSplatMesh;\r\n\r\n this._applyBoundingInfo();\r\n this.compoundSplatMesh.setWorldMatrixForPart(this.partIndex, this.getWorldMatrix());\r\n\r\n // Update the compound mesh's part matrix when this proxy's world matrix changes.\r\n this.onAfterWorldMatrixUpdateObservable.add(() => {\r\n this.compoundSplatMesh.setWorldMatrixForPart(this.partIndex, this.getWorldMatrix());\r\n });\r\n }\r\n\r\n /**\r\n * Updates the bounding info of this proxy mesh from its stored part metadata.\r\n */\r\n public updateBoundingInfoFromPartData(): void {\r\n this._applyBoundingInfo();\r\n }\r\n\r\n /**\r\n * Backward-compatible alias retained while callers move away from source-mesh based semantics.\r\n */\r\n public updateBoundingInfoFromProxiedMesh(): void {\r\n this.updateBoundingInfoFromPartData();\r\n }\r\n\r\n private _applyBoundingInfo(): void {\r\n this.setBoundingInfo(new BoundingInfo(this._minimum.clone(), this._maximum.clone()));\r\n }\r\n\r\n /**\r\n * Returns the class name\r\n * @returns \"GaussianSplattingPartProxyMesh\"\r\n */\r\n public override getClassName(): string {\r\n return \"GaussianSplattingPartProxyMesh\";\r\n }\r\n\r\n /**\r\n * Returns the world-space bounding vectors spanning this part (and any descendants).\r\n *\r\n * A part proxy carries real bounds (set via {@link setBoundingInfo}) but owns NO geometry — the compound\r\n * holds the splats. The base {@link Node.getHierarchyBoundingVectors} only folds in a mesh's own bounds\r\n * when it has a `subMeshes` array (a geometry-less mesh's is `undefined`) and skips zero-vertex descendants,\r\n * so for a bare proxy it returns a degenerate ±MAX_VALUE box. Callers that treat the proxy as a normal mesh\r\n * (camera framing, grounding, picking) would then derive NaN / astronomically large offsets. This override\r\n * folds the proxy's own world-space box into whatever the base returns for descendants.\r\n * @param includeDescendants include bounding vectors from descendant meshes\r\n * @param predicate optional filter applied to each descendant mesh\r\n * @returns the world-space min/max spanning this part (and any descendants)\r\n */\r\n public override getHierarchyBoundingVectors(\r\n includeDescendants: boolean = true,\r\n predicate: Nullable<(abstractMesh: AbstractMesh) => boolean> = null\r\n ): { min: Vector3; max: Vector3 } {\r\n // Base recomputes this proxy's world matrix but skips its (geometry-less) own bounds.\r\n const result = super.getHierarchyBoundingVectors(includeDescendants, predicate);\r\n // Refresh the world-space corners against the just-computed world matrix, then extend the result:\r\n // CheckExtends turns the base's ±MAX_VALUE sentinel seed into this part's real box.\r\n const info = this.getBoundingInfo();\r\n info.update(this.getWorldMatrix());\r\n Vector3.CheckExtends(info.boundingBox.minimumWorld, result.min, result.max);\r\n Vector3.CheckExtends(info.boundingBox.maximumWorld, result.min, result.max);\r\n return result;\r\n }\r\n\r\n /**\r\n * Updates the part index for this proxy mesh.\r\n * This should only be called internally when parts are removed from the compound mesh.\r\n * @param newPartIndex the new part index\r\n * @internal\r\n */\r\n public updatePartIndex(newPartIndex: number): void {\r\n this._partIndex = newPartIndex;\r\n }\r\n\r\n /**\r\n * Updates the per-part metadata for this proxy mesh.\r\n * This is used internally when compound parts are rebuilt and re-indexed.\r\n * @param vertexCount the number of splats owned by the part\r\n * @param splatsDataOffset the new splat offset in the compound\r\n * @param shDataOffset the new SH texel offset in the compound\r\n * @internal\r\n */\r\n public updatePartMetadata(vertexCount: number, splatsDataOffset: number, shDataOffset: number = splatsDataOffset): void {\r\n this._vertexCount = vertexCount;\r\n this._splatsDataOffset = splatsDataOffset;\r\n this._shDataOffset = shDataOffset;\r\n }\r\n\r\n /**\r\n * Gets whether the part is visible\r\n */\r\n public override get isVisible(): boolean {\r\n return this.compoundSplatMesh.getPartVisibility(this.partIndex) > 0;\r\n }\r\n\r\n /**\r\n * Sets whether the part is visible\r\n */\r\n public override set isVisible(value: boolean) {\r\n this.compoundSplatMesh.setPartVisibility(this.partIndex, value ? 1.0 : 0.0);\r\n }\r\n\r\n /**\r\n * Gets the visibility of the part (0.0 to 1.0)\r\n */\r\n public override get visibility(): number {\r\n return this.compoundSplatMesh.getPartVisibility(this.partIndex);\r\n }\r\n\r\n /**\r\n * Sets the visibility of the part (0.0 to 1.0)\r\n */\r\n public override set visibility(value: number) {\r\n this.compoundSplatMesh.setPartVisibility(this.partIndex, value);\r\n }\r\n\r\n /**\r\n * Checks if a ray intersects with this proxy mesh using only bounding info\r\n * @param ray defines the ray to test\r\n * @returns the picking info with this mesh set as pickedMesh if hit\r\n */\r\n public override intersects(ray: Ray): PickingInfo {\r\n const pickingInfo = new PickingInfo();\r\n const boundingInfo = this.getBoundingInfo();\r\n\r\n if (!boundingInfo) {\r\n return pickingInfo;\r\n }\r\n\r\n // Always check against bounding info for proxy meshes\r\n if (!ray.intersectsSphere(boundingInfo.boundingSphere) || !ray.intersectsBox(boundingInfo.boundingBox)) {\r\n return pickingInfo;\r\n }\r\n\r\n // If we hit the bounding volume, report this mesh as picked\r\n pickingInfo.hit = true;\r\n pickingInfo.pickedMesh = this;\r\n pickingInfo.distance = Vector3.Distance(ray.origin, boundingInfo.boundingSphere.center);\r\n pickingInfo.subMeshId = 0;\r\n\r\n return pickingInfo;\r\n }\r\n\r\n /**\r\n * Serialize current GaussianSplattingPartProxyMesh\r\n * @param serializationObject defines the object which will receive the serialization data\r\n * @returns the serialized object\r\n */\r\n public override serialize(serializationObject: any = {}): any {\r\n serializationObject = super.serialize(serializationObject);\r\n // GaussianSplattingPartProxyMesh needs no SubMesh, Geometry, or Material\r\n serializationObject.subMeshes = [];\r\n serializationObject.geometryUniqueId = undefined;\r\n serializationObject.geometryId = undefined;\r\n serializationObject.materialUniqueId = undefined;\r\n serializationObject.materialId = undefined;\r\n serializationObject.instances = [];\r\n serializationObject.actions = undefined;\r\n serializationObject.type = this.getClassName();\r\n serializationObject.compoundSplatMeshId = this.compoundSplatMesh.id;\r\n // Part metadata is needed to reconnect the proxy to the correct compound segment.\r\n serializationObject.partIndex = this._partIndex;\r\n serializationObject.vertexCount = this._vertexCount;\r\n serializationObject.splatsDataOffset = this._splatsDataOffset;\r\n serializationObject.shDataOffset = this._shDataOffset;\r\n const boundingInfo = this.getBoundingInfo();\r\n serializationObject.boundingInfo = {\r\n minimum: boundingInfo.minimum.asArray(),\r\n maximum: boundingInfo.maximum.asArray(),\r\n };\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Parses a serialized GaussianSplattingPartProxyMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingPartProxyMesh in\r\n * @returns the created GaussianSplattingPartProxyMesh\r\n */\r\n public static override Parse(parsedMesh: any, scene: Scene): GaussianSplattingPartProxyMesh {\r\n const partIndex = parsedMesh.partIndex;\r\n const compoundSplatMesh =\r\n (parsedMesh.compoundSplatMesh as GaussianSplattingMesh | undefined) ?? (scene.getLastMeshById(parsedMesh.compoundSplatMeshId) as GaussianSplattingMesh | null);\r\n if (!compoundSplatMesh) {\r\n throw new Error(`GaussianSplattingPartProxyMesh: compound mesh not found with ID ${parsedMesh.compoundSplatMeshId}`);\r\n }\r\n const minimum = Vector3.FromArray(parsedMesh.boundingInfo.minimum);\r\n const maximum = Vector3.FromArray(parsedMesh.boundingInfo.maximum);\r\n const boundingInfo = new BoundingInfo(minimum, maximum);\r\n const vertexCount = parsedMesh.vertexCount ?? 0;\r\n const splatsDataOffset = parsedMesh.splatsDataOffset ?? 0;\r\n const shDataOffset = parsedMesh.shDataOffset ?? splatsDataOffset;\r\n return new GaussianSplattingPartProxyMesh(parsedMesh.name, scene, compoundSplatMesh, partIndex, boundingInfo, vertexCount, splatsDataOffset, shDataOffset);\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingPartProxyMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingPartProxyMesh(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n Mesh._GaussianSplattingPartProxyMeshParser = GaussianSplattingPartProxyMesh.Parse;\r\n}\r\n"]}
|
|
@@ -147,7 +147,8 @@ export const GaussianSplattingSortWorker = function (self) {
|
|
|
147
147
|
// Compound (rig) meshes give each splat its own world transform via its part: depth uses the
|
|
148
148
|
// splat's part coefficients. Single meshes use the one global world matrix. Both produce
|
|
149
149
|
// depths in the same camera-forward space, so all active splats sort together correctly.
|
|
150
|
-
|
|
150
|
+
// Require a non-empty partIndices: an empty one (length 0) would make partLen-1 index -1 below.
|
|
151
|
+
const compound = !!(partMatrices && partMatrices.length > 0 && partIndices && partIndices.length > 0);
|
|
151
152
|
let depthCoeffs = [];
|
|
152
153
|
let partLen = 0;
|
|
153
154
|
let a = 0;
|
|
@@ -178,14 +179,26 @@ export const GaussianSplattingSortWorker = function (self) {
|
|
|
178
179
|
let writeIndex = 0;
|
|
179
180
|
let minDepth = Infinity;
|
|
180
181
|
let maxDepth = -Infinity;
|
|
182
|
+
// A partIndices entry >= partCount means partIndices and partMatrices disagree — an inconsistent
|
|
183
|
+
// snapshot posted mid-rebuild.
|
|
184
|
+
const partCount = depthCoeffs.length;
|
|
185
|
+
let inconsistentSnapshot = false;
|
|
181
186
|
const rangeWords = activeIntervals ? activeIntervals.length : 2;
|
|
182
|
-
for (let r = 0; r < rangeWords; r += 2) {
|
|
187
|
+
gather: for (let r = 0; r < rangeWords; r += 2) {
|
|
183
188
|
const start = activeIntervals ? activeIntervals[r] : 0;
|
|
184
189
|
const end = start + (activeIntervals ? activeIntervals[r + 1] : totalSplats);
|
|
185
190
|
if (compound) {
|
|
186
191
|
for (let sourceIndex = start; sourceIndex < end; sourceIndex++) {
|
|
187
192
|
const o = 4 * sourceIndex;
|
|
188
|
-
const
|
|
193
|
+
const rawPart = partIndices[sourceIndex < partLen ? sourceIndex : partLen - 1];
|
|
194
|
+
if (rawPart >= partCount) {
|
|
195
|
+
// Reject rather than sort with the wrong transform: the output buffer is untouched
|
|
196
|
+
// until the scatter pass below, so returning it as-is keeps the last good order and
|
|
197
|
+
// the next frame retries once the snapshot is consistent.
|
|
198
|
+
inconsistentSnapshot = true;
|
|
199
|
+
break gather;
|
|
200
|
+
}
|
|
201
|
+
const coeff = depthCoeffs[rawPart];
|
|
189
202
|
const depth = coeff[0] * positions[o] + coeff[1] * positions[o + 1] + coeff[2] * positions[o + 2] + coeff[3];
|
|
190
203
|
sortSourceIndices[writeIndex] = sourceIndex;
|
|
191
204
|
sortDepths[writeIndex] = depth;
|
|
@@ -214,6 +227,10 @@ export const GaussianSplattingSortWorker = function (self) {
|
|
|
214
227
|
}
|
|
215
228
|
}
|
|
216
229
|
}
|
|
230
|
+
if (inconsistentSnapshot) {
|
|
231
|
+
self.postMessage({ command: "sorted", depthMix, cameraId, sortRequestId, rangeVersion }, [depthMix.buffer]);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
217
234
|
// Counting (radix) sort by a depth-derived integer key — O(n) vs the legacy comparison sort.
|
|
218
235
|
// Bucket bit depth follows PlayCanvas: round(log2(n/4)) clamped to [10, 20]. The farthest splat
|
|
219
236
|
// gets key 0 so the ascending counting sort yields back-to-front order for alpha blending.
|
|
@@ -290,15 +307,21 @@ export const GaussianSplattingSortWorker = function (self) {
|
|
|
290
307
|
indices[2 * j] = j;
|
|
291
308
|
}
|
|
292
309
|
}
|
|
293
|
-
|
|
310
|
+
let inconsistentSnapshot = false;
|
|
311
|
+
if (partMatrices && partMatrices.length > 0 && partIndices && partIndices.length > 0) {
|
|
294
312
|
// Precompute depth coefficients for each rig node.
|
|
295
313
|
const depthCoeffs = partMatrices.map((m) => computeDepthCoeffs(m));
|
|
296
|
-
// NB: For performance reasons, we assume that part indices are valid.
|
|
297
314
|
const length = partIndices.length;
|
|
298
315
|
for (let j = 0; j < vertexCountPadded; j++) {
|
|
299
316
|
const sourceIndex = indices[2 * j];
|
|
300
317
|
// NB: We need this 'min' because the vertex array is padded, not partIndices.
|
|
301
318
|
const partIndex = partIndices[Math.min(sourceIndex, length - 1)];
|
|
319
|
+
if (partIndex >= depthCoeffs.length) {
|
|
320
|
+
// Inconsistent snapshot (see the counting-sort branch): skip the sort rather than depth
|
|
321
|
+
// splats with the wrong transform; the unsorted indices render for one frame, then retry.
|
|
322
|
+
inconsistentSnapshot = true;
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
302
325
|
const coeff = depthCoeffs[partIndex];
|
|
303
326
|
floatMix[2 * j + 1] =
|
|
304
327
|
coeff[0] * positions[4 * sourceIndex + 0] + coeff[1] * positions[4 * sourceIndex + 1] + coeff[2] * positions[4 * sourceIndex + 2] + coeff[3];
|
|
@@ -314,7 +337,9 @@ export const GaussianSplattingSortWorker = function (self) {
|
|
|
314
337
|
indices[2 * j + 1] = ~indices[2 * j + 1];
|
|
315
338
|
}
|
|
316
339
|
}
|
|
317
|
-
|
|
340
|
+
if (!inconsistentSnapshot) {
|
|
341
|
+
depthMix.sort();
|
|
342
|
+
}
|
|
318
343
|
}
|
|
319
344
|
}
|
|
320
345
|
catch (sortError) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gaussianSplattingSortWorker.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingSortWorker.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\n\r\n/**\r\n * Message commands exchanged with the Gaussian Splatting depth-sort worker. Every message carries a\r\n * `command` field naming the intended work, instead of inferring it from which payload is present.\r\n */\r\nexport const GaussianSplattingSortWorkerCommand = {\r\n /** Main -> worker: set the source splat centers (stride 4: xyz + 1). */\r\n POSITIONS: \"positions\",\r\n /** Main -> worker: patch a contiguous sub-range of the existing source splat centers in place. */\r\n POSITIONS_UPDATE: \"positionsUpdate\",\r\n /** Main -> worker: set the compound-mesh rig node matrices. */\r\n PART_MATRICES: \"partMatrices\",\r\n /** Main -> worker: set the compound-mesh per-splat rig node indices. */\r\n PART_INDICES: \"partIndices\",\r\n /** Main -> worker: set the active source-splat ranges (flat [start0, count0, ...]). */\r\n INTERVALS: \"intervals\",\r\n /** Main -> worker: sort the active splats for a camera view. */\r\n SORT: \"sort\",\r\n /** Worker -> main: a completed sort result. */\r\n SORTED: \"sorted\",\r\n} as const;\r\n\r\n/**\r\n * Depth-sort web worker body for Gaussian Splatting meshes.\r\n *\r\n * The function is self-contained: it is serialized with `Function.prototype.toString()` and run\r\n * inside a `Blob`-backed `Worker`, so it must not reference anything from its enclosing module\r\n * (including {@link GaussianSplattingSortWorkerCommand} — the command literals are duplicated here).\r\n *\r\n * The intended work for each message is selected explicitly via its `command` field:\r\n * - `positions` set source splat centers (stride 4: xyz + 1).\r\n * - `partMatrices` set compound-mesh rig node matrices.\r\n * - `partIndices` set compound-mesh per-splat rig node indices.\r\n * - `intervals` set active source-splat ranges (flat [start0, count0, ...]); persisted across sorts.\r\n * - `sort` sort the active splats for `{ worldMatrix, cameraForward, cameraPosition, depthMix,\r\n * cameraId, sortRequestId, rightHanded }` and post back a `sorted` result.\r\n *\r\n * @param self - the worker global scope\r\n */\r\nexport const GaussianSplattingSortWorker = function (self: Worker) {\r\n let positions: Float32Array;\r\n // Real (unpadded) splat count backing `positions` — see emptySplatIndex below for why this matters.\r\n let vertexCount = 0;\r\n let depthMix: BigInt64Array;\r\n let partIndices: Uint8Array;\r\n let partMatrices: Float32Array[];\r\n // Active source-splat intervals as flat [start0, count0, start1, count1, ...]. Persisted between\r\n // sort requests and refreshed by the main thread via the `intervals` message.\r\n let intervals: Nullable<Uint32Array> = null;\r\n // Reusable counting-sort scratch buffers (grown on demand, never per-sort allocations).\r\n let sortSourceIndices: Uint32Array; // active source splat index for each compact slot\r\n let sortDepths: Float32Array; // view-space depth for each compact slot\r\n let sortKeys: Uint32Array; // depth-derived integer bucket key for each compact slot\r\n let sortCounts: Uint32Array; // counting-sort histogram (one entry per bucket)\r\n\r\n self.onmessage = (e: any) => {\r\n // The intended work is selected explicitly via the message `command` field. These string\r\n // literals must match GaussianSplattingSortWorkerCommand above (this body is serialized in\r\n // isolation and cannot reference the shared constant).\r\n const command = e.data.command;\r\n if (command === \"positions\") {\r\n positions = e.data.positions;\r\n vertexCount = e.data.vertexCount;\r\n } else if (command === \"positionsUpdate\") {\r\n // Patch only the changed sub-range in place, avoiding a full re-copy/transfer of the entire\r\n // (potentially hundreds-of-MB) position buffer on every streamed LOD decode.\r\n if (positions && e.data.data) {\r\n positions.set(e.data.data, e.data.offset);\r\n }\r\n } else if (command === \"partMatrices\") {\r\n partMatrices = e.data.partMatrices;\r\n } else if (command === \"partIndices\") {\r\n partIndices = e.data.partIndices;\r\n } else if (command === \"intervals\") {\r\n intervals = e.data.intervals;\r\n } else if (command === \"sort\") {\r\n const cameraId = e.data.cameraId;\r\n const sortRequestId = e.data.sortRequestId;\r\n const rangeVersion = e.data.rangeVersion;\r\n const globalWorldMatrix = e.data.worldMatrix;\r\n const cameraForward = e.data.cameraForward;\r\n const cameraPosition = e.data.cameraPosition;\r\n\r\n depthMix = e.data.depthMix;\r\n\r\n if (!positions || !cameraForward) {\r\n // Sort request arrived before positions were initialized — return the buffer unchanged so the main thread can unlock _canPostToWorker.\r\n self.postMessage({ command: \"sorted\", depthMix, cameraId, sortRequestId, rangeVersion }, [depthMix.buffer]);\r\n return;\r\n }\r\n\r\n // Feature flags are forwarded by the main thread on each sort request (the worker body is\r\n // serialized in isolation and cannot read shared statics directly). useCountingSort defaults to\r\n // true; set it false to fall back to the legacy comparison sort.\r\n const useCountingSort = e.data.useCountingSort !== false;\r\n const logSortPerformance = !!e.data.logSortPerformance;\r\n\r\n // `cameraForward` is the view matrix's third row [m[2], m[6], m[10]], which points into the scene\r\n // in a left-handed scene but back toward the viewer in a right-handed one. As a result the signed\r\n // `depth = dot(cameraForward, worldPos - cameraPos)` increases with distance in left-handed scenes\r\n // but decreases with distance in right-handed ones. The counting sort below relies on \"larger depth\r\n // = farther\", so negate the depth in right-handed scenes to keep that invariant and preserve correct\r\n // back-to-front ordering. (The legacy comparison sort handles either sign naturally and is untouched.)\r\n const depthSign = e.data.rightHanded ? -1 : 1;\r\n\r\n // Resolve the active interval set. The main thread always sends an `intervals` message,\r\n // but fall back to \"all source splats\" if a sort somehow arrives before it.\r\n const activeIntervals = intervals;\r\n const totalSplats = positions.length / 4;\r\n // Index to use when 16-aligning the sorted output needs extra filler entries. Real data never\r\n // lives at or past `vertexCount` — with or without range filtering — and `_getTextureSize`\r\n // (gaussianSplattingMeshBase.pure.ts) always reserves at least one empty slot there, even when\r\n // `vertexCount` would otherwise exactly fill every texture row.\r\n const emptySplatIndex = vertexCount;\r\n let renderSplatCount = totalSplats;\r\n if (activeIntervals) {\r\n renderSplatCount = 0;\r\n for (let rangeIndex = 1; rangeIndex < activeIntervals.length; rangeIndex += 2) {\r\n renderSplatCount += activeIntervals[rangeIndex];\r\n }\r\n }\r\n const vertexCountPadded = Math.max((renderSplatCount + 15) & ~0xf, 16);\r\n\r\n // depth = dot(cameraForward, worldPos - cameraPos)\r\n const camDot = cameraForward[0] * cameraPosition[0] + cameraForward[1] * cameraPosition[1] + cameraForward[2] * cameraPosition[2];\r\n\r\n const computeDepthCoeffs = (m: Float32Array): number[] => {\r\n return [\r\n cameraForward[0] * m[0] + cameraForward[1] * m[1] + cameraForward[2] * m[2],\r\n cameraForward[0] * m[4] + cameraForward[1] * m[5] + cameraForward[2] * m[6],\r\n cameraForward[0] * m[8] + cameraForward[1] * m[9] + cameraForward[2] * m[10],\r\n cameraForward[0] * m[12] + cameraForward[1] * m[13] + cameraForward[2] * m[14] - camDot,\r\n ];\r\n };\r\n\r\n // Optional, flag-gated sort timing (a simple wall-clock delta logged to the worker console).\r\n const perf = (globalThis as { performance?: { now(): number } }).performance;\r\n const sortStart = logSortPerformance && perf ? perf.now() : 0;\r\n\r\n try {\r\n if (useCountingSort) {\r\n // ===== Fast O(n) counting (radix) sort =====\r\n // Output view: the even 32-bit words of the depthMix buffer hold the sorted source indices\r\n // (the main thread reads indexMix[2*j]); the odd words are left unused.\r\n const outIndices = new Uint32Array(depthMix.buffer);\r\n\r\n // Grow the reusable scratch buffers when the active count increases (kept across sorts).\r\n if (!sortSourceIndices || sortSourceIndices.length < renderSplatCount) {\r\n const capacity = Math.max(renderSplatCount, 16);\r\n sortSourceIndices = new Uint32Array(capacity);\r\n sortDepths = new Float32Array(capacity);\r\n sortKeys = new Uint32Array(capacity);\r\n }\r\n\r\n // Compound (rig) meshes give each splat its own world transform via its part: depth uses the\r\n // splat's part coefficients. Single meshes use the one global world matrix. Both produce\r\n // depths in the same camera-forward space, so all active splats sort together correctly.\r\n const compound = !!(partMatrices && partIndices);\r\n let depthCoeffs: number[][] = [];\r\n let partLen = 0;\r\n let a = 0;\r\n let b = 0;\r\n let c = 0;\r\n let d = 0;\r\n if (compound) {\r\n depthCoeffs = partMatrices.map((m) => {\r\n const co = computeDepthCoeffs(m);\r\n co[0] *= depthSign;\r\n co[1] *= depthSign;\r\n co[2] *= depthSign;\r\n co[3] *= depthSign;\r\n return co;\r\n });\r\n partLen = partIndices.length;\r\n } else {\r\n const coeff = computeDepthCoeffs(globalWorldMatrix);\r\n a = coeff[0] * depthSign;\r\n b = coeff[1] * depthSign;\r\n c = coeff[2] * depthSign;\r\n d = coeff[3] * depthSign;\r\n }\r\n\r\n // Pass 1: gather the active source indices, compute each splat's view-space depth (signed\r\n // distance from the camera along the forward axis), and track the depth range. The compound\r\n // branch is hoisted out of the inner loop so the hot path stays straight-line.\r\n let writeIndex = 0;\r\n let minDepth = Infinity;\r\n let maxDepth = -Infinity;\r\n const rangeWords = activeIntervals ? activeIntervals.length : 2;\r\n for (let r = 0; r < rangeWords; r += 2) {\r\n const start = activeIntervals ? activeIntervals[r] : 0;\r\n const end = start + (activeIntervals ? activeIntervals[r + 1] : totalSplats);\r\n if (compound) {\r\n for (let sourceIndex = start; sourceIndex < end; sourceIndex++) {\r\n const o = 4 * sourceIndex;\r\n const coeff = depthCoeffs[partIndices[sourceIndex < partLen ? sourceIndex : partLen - 1]];\r\n const depth = coeff[0] * positions[o] + coeff[1] * positions[o + 1] + coeff[2] * positions[o + 2] + coeff[3];\r\n sortSourceIndices[writeIndex] = sourceIndex;\r\n sortDepths[writeIndex] = depth;\r\n writeIndex++;\r\n if (depth < minDepth) {\r\n minDepth = depth;\r\n }\r\n if (depth > maxDepth) {\r\n maxDepth = depth;\r\n }\r\n }\r\n } else {\r\n for (let sourceIndex = start; sourceIndex < end; sourceIndex++) {\r\n const o = 4 * sourceIndex;\r\n const depth = a * positions[o] + b * positions[o + 1] + c * positions[o + 2] + d;\r\n sortSourceIndices[writeIndex] = sourceIndex;\r\n sortDepths[writeIndex] = depth;\r\n writeIndex++;\r\n if (depth < minDepth) {\r\n minDepth = depth;\r\n }\r\n if (depth > maxDepth) {\r\n maxDepth = depth;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Counting (radix) sort by a depth-derived integer key — O(n) vs the legacy comparison sort.\r\n // Bucket bit depth follows PlayCanvas: round(log2(n/4)) clamped to [10, 20]. The farthest splat\r\n // gets key 0 so the ascending counting sort yields back-to-front order for alpha blending.\r\n const compareBits = Math.max(10, Math.min(20, Math.round(Math.log2(Math.max(1, renderSplatCount) / 4))));\r\n const bucketCount = 2 ** compareBits + 1;\r\n if (!sortCounts || sortCounts.length !== bucketCount) {\r\n sortCounts = new Uint32Array(bucketCount);\r\n } else {\r\n sortCounts.fill(0);\r\n }\r\n\r\n const range = maxDepth - minDepth;\r\n if (!(range > 1e-12)) {\r\n // All active splats share a depth (or none are active): identity order, single bucket.\r\n for (let k = 0; k < renderSplatCount; k++) {\r\n sortKeys[k] = 0;\r\n }\r\n sortCounts[0] = renderSplatCount;\r\n } else {\r\n const scale = (bucketCount - 1) / range;\r\n const maxKey = bucketCount - 1;\r\n for (let k = 0; k < renderSplatCount; k++) {\r\n // maxDepth -> 0 (rendered first), minDepth -> bucketCount-1 (rendered last). Clamp\r\n // against float rounding (a tiny `range` makes `scale` huge), which could otherwise\r\n // produce key >= bucketCount and corrupt the histogram with out-of-bounds writes.\r\n let key = ((maxDepth - sortDepths[k]) * scale) >>> 0;\r\n if (key > maxKey) {\r\n key = maxKey;\r\n }\r\n sortKeys[k] = key;\r\n sortCounts[key]++;\r\n }\r\n }\r\n\r\n // Prefix-sum the histogram into bucket end offsets, then scatter source indices into place.\r\n for (let i = 1; i < bucketCount; i++) {\r\n sortCounts[i] += sortCounts[i - 1];\r\n }\r\n for (let k = 0; k < renderSplatCount; k++) {\r\n const dest = --sortCounts[sortKeys[k]];\r\n outIndices[2 * dest] = sortSourceIndices[k];\r\n }\r\n\r\n // Pad the remainder up to the 16-multiple with a guaranteed-empty index (see\r\n // emptySplatIndex above) — NOT splat index 0, which is just the first real splat of\r\n // whatever source data was loaded. Padding with a real, opaque splat draws it an extra\r\n // 15 times at the very end of the (back-to-front) draw order — i.e. always on top,\r\n // regardless of camera.\r\n for (let dest = renderSplatCount; dest < vertexCountPadded; dest++) {\r\n outIndices[2 * dest] = emptySplatIndex;\r\n }\r\n } else {\r\n // ===== Legacy comparison sort: pack (index, ~depthBits) into each 64-bit lane and sort it =====\r\n const indices = new Uint32Array(depthMix.buffer);\r\n const floatMix = new Float32Array(depthMix.buffer);\r\n\r\n // Build the compact list of source-splat indices to sort.\r\n if (activeIntervals) {\r\n let writeIndex = 0;\r\n for (let rangeIndex = 0; rangeIndex < activeIntervals.length; rangeIndex += 2) {\r\n const start = activeIntervals[rangeIndex];\r\n const count = activeIntervals[rangeIndex + 1];\r\n for (let sourceIndex = start; sourceIndex < start + count; sourceIndex++) {\r\n indices[2 * writeIndex++] = sourceIndex;\r\n }\r\n }\r\n // Pad up to a multiple of 16. Splat index 0 isn't guaranteed invisible (see the\r\n // counting-sort branch above) — use the same guaranteed-empty index instead.\r\n for (; writeIndex < vertexCountPadded; writeIndex++) {\r\n indices[2 * writeIndex] = emptySplatIndex;\r\n }\r\n } else {\r\n for (let j = 0; j < vertexCountPadded; j++) {\r\n indices[2 * j] = j;\r\n }\r\n }\r\n\r\n if (partMatrices && partIndices) {\r\n // Precompute depth coefficients for each rig node.\r\n const depthCoeffs = partMatrices.map((m) => computeDepthCoeffs(m));\r\n // NB: For performance reasons, we assume that part indices are valid.\r\n const length = partIndices.length;\r\n for (let j = 0; j < vertexCountPadded; j++) {\r\n const sourceIndex = indices[2 * j];\r\n // NB: We need this 'min' because the vertex array is padded, not partIndices.\r\n const partIndex = partIndices[Math.min(sourceIndex, length - 1)];\r\n const coeff = depthCoeffs[partIndex];\r\n floatMix[2 * j + 1] =\r\n coeff[0] * positions[4 * sourceIndex + 0] + coeff[1] * positions[4 * sourceIndex + 1] + coeff[2] * positions[4 * sourceIndex + 2] + coeff[3];\r\n // Invert the depth bits (bitwise not) so the ascending sort renders back to front.\r\n indices[2 * j + 1] = ~indices[2 * j + 1];\r\n }\r\n } else {\r\n const [a, b, c, d] = computeDepthCoeffs(globalWorldMatrix);\r\n for (let j = 0; j < vertexCountPadded; j++) {\r\n const sourceIndex = indices[2 * j];\r\n floatMix[2 * j + 1] = a * positions[4 * sourceIndex + 0] + b * positions[4 * sourceIndex + 1] + c * positions[4 * sourceIndex + 2] + d;\r\n indices[2 * j + 1] = ~indices[2 * j + 1];\r\n }\r\n }\r\n\r\n depthMix.sort();\r\n }\r\n } catch (sortError) {\r\n // Transient data inconsistency (e.g. partIndices/partMatrices mismatch during addPart/removePart rebuild).\r\n // Return the buffer unsorted so the main thread can unlock _canPostToWorker and retry next frame.\r\n // Logger is unavailable inside the worker — console is the only option.\r\n // eslint-disable-next-line no-console\r\n console.error(\"Gaussian splat sort worker encountered an error (will retry next frame):\", sortError);\r\n }\r\n\r\n if (logSortPerformance && perf) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[GaussianSplatting] ${useCountingSort ? \"counting\" : \"legacy\"} sort: ${renderSplatCount} splats in ${(perf.now() - sortStart).toFixed(2)}ms`);\r\n }\r\n\r\n self.postMessage({ command: \"sorted\", depthMix, cameraId, sortRequestId, rangeVersion }, [depthMix.buffer]);\r\n }\r\n };\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"gaussianSplattingSortWorker.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingSortWorker.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\n\r\n/**\r\n * Message commands exchanged with the Gaussian Splatting depth-sort worker. Every message carries a\r\n * `command` field naming the intended work, instead of inferring it from which payload is present.\r\n */\r\nexport const GaussianSplattingSortWorkerCommand = {\r\n /** Main -> worker: set the source splat centers (stride 4: xyz + 1). */\r\n POSITIONS: \"positions\",\r\n /** Main -> worker: patch a contiguous sub-range of the existing source splat centers in place. */\r\n POSITIONS_UPDATE: \"positionsUpdate\",\r\n /** Main -> worker: set the compound-mesh rig node matrices. */\r\n PART_MATRICES: \"partMatrices\",\r\n /** Main -> worker: set the compound-mesh per-splat rig node indices. */\r\n PART_INDICES: \"partIndices\",\r\n /** Main -> worker: set the active source-splat ranges (flat [start0, count0, ...]). */\r\n INTERVALS: \"intervals\",\r\n /** Main -> worker: sort the active splats for a camera view. */\r\n SORT: \"sort\",\r\n /** Worker -> main: a completed sort result. */\r\n SORTED: \"sorted\",\r\n} as const;\r\n\r\n/**\r\n * Depth-sort web worker body for Gaussian Splatting meshes.\r\n *\r\n * The function is self-contained: it is serialized with `Function.prototype.toString()` and run\r\n * inside a `Blob`-backed `Worker`, so it must not reference anything from its enclosing module\r\n * (including {@link GaussianSplattingSortWorkerCommand} — the command literals are duplicated here).\r\n *\r\n * The intended work for each message is selected explicitly via its `command` field:\r\n * - `positions` set source splat centers (stride 4: xyz + 1).\r\n * - `partMatrices` set compound-mesh rig node matrices.\r\n * - `partIndices` set compound-mesh per-splat rig node indices.\r\n * - `intervals` set active source-splat ranges (flat [start0, count0, ...]); persisted across sorts.\r\n * - `sort` sort the active splats for `{ worldMatrix, cameraForward, cameraPosition, depthMix,\r\n * cameraId, sortRequestId, rightHanded }` and post back a `sorted` result.\r\n *\r\n * @param self - the worker global scope\r\n */\r\nexport const GaussianSplattingSortWorker = function (self: Worker) {\r\n let positions: Float32Array;\r\n // Real (unpadded) splat count backing `positions` — see emptySplatIndex below for why this matters.\r\n let vertexCount = 0;\r\n let depthMix: BigInt64Array;\r\n let partIndices: Uint8Array;\r\n let partMatrices: Float32Array[];\r\n // Active source-splat intervals as flat [start0, count0, start1, count1, ...]. Persisted between\r\n // sort requests and refreshed by the main thread via the `intervals` message.\r\n let intervals: Nullable<Uint32Array> = null;\r\n // Reusable counting-sort scratch buffers (grown on demand, never per-sort allocations).\r\n let sortSourceIndices: Uint32Array; // active source splat index for each compact slot\r\n let sortDepths: Float32Array; // view-space depth for each compact slot\r\n let sortKeys: Uint32Array; // depth-derived integer bucket key for each compact slot\r\n let sortCounts: Uint32Array; // counting-sort histogram (one entry per bucket)\r\n\r\n self.onmessage = (e: any) => {\r\n // The intended work is selected explicitly via the message `command` field. These string\r\n // literals must match GaussianSplattingSortWorkerCommand above (this body is serialized in\r\n // isolation and cannot reference the shared constant).\r\n const command = e.data.command;\r\n if (command === \"positions\") {\r\n positions = e.data.positions;\r\n vertexCount = e.data.vertexCount;\r\n } else if (command === \"positionsUpdate\") {\r\n // Patch only the changed sub-range in place, avoiding a full re-copy/transfer of the entire\r\n // (potentially hundreds-of-MB) position buffer on every streamed LOD decode.\r\n if (positions && e.data.data) {\r\n positions.set(e.data.data, e.data.offset);\r\n }\r\n } else if (command === \"partMatrices\") {\r\n partMatrices = e.data.partMatrices;\r\n } else if (command === \"partIndices\") {\r\n partIndices = e.data.partIndices;\r\n } else if (command === \"intervals\") {\r\n intervals = e.data.intervals;\r\n } else if (command === \"sort\") {\r\n const cameraId = e.data.cameraId;\r\n const sortRequestId = e.data.sortRequestId;\r\n const rangeVersion = e.data.rangeVersion;\r\n const globalWorldMatrix = e.data.worldMatrix;\r\n const cameraForward = e.data.cameraForward;\r\n const cameraPosition = e.data.cameraPosition;\r\n\r\n depthMix = e.data.depthMix;\r\n\r\n if (!positions || !cameraForward) {\r\n // Sort request arrived before positions were initialized — return the buffer unchanged so the main thread can unlock _canPostToWorker.\r\n self.postMessage({ command: \"sorted\", depthMix, cameraId, sortRequestId, rangeVersion }, [depthMix.buffer]);\r\n return;\r\n }\r\n\r\n // Feature flags are forwarded by the main thread on each sort request (the worker body is\r\n // serialized in isolation and cannot read shared statics directly). useCountingSort defaults to\r\n // true; set it false to fall back to the legacy comparison sort.\r\n const useCountingSort = e.data.useCountingSort !== false;\r\n const logSortPerformance = !!e.data.logSortPerformance;\r\n\r\n // `cameraForward` is the view matrix's third row [m[2], m[6], m[10]], which points into the scene\r\n // in a left-handed scene but back toward the viewer in a right-handed one. As a result the signed\r\n // `depth = dot(cameraForward, worldPos - cameraPos)` increases with distance in left-handed scenes\r\n // but decreases with distance in right-handed ones. The counting sort below relies on \"larger depth\r\n // = farther\", so negate the depth in right-handed scenes to keep that invariant and preserve correct\r\n // back-to-front ordering. (The legacy comparison sort handles either sign naturally and is untouched.)\r\n const depthSign = e.data.rightHanded ? -1 : 1;\r\n\r\n // Resolve the active interval set. The main thread always sends an `intervals` message,\r\n // but fall back to \"all source splats\" if a sort somehow arrives before it.\r\n const activeIntervals = intervals;\r\n const totalSplats = positions.length / 4;\r\n // Index to use when 16-aligning the sorted output needs extra filler entries. Real data never\r\n // lives at or past `vertexCount` — with or without range filtering — and `_getTextureSize`\r\n // (gaussianSplattingMeshBase.pure.ts) always reserves at least one empty slot there, even when\r\n // `vertexCount` would otherwise exactly fill every texture row.\r\n const emptySplatIndex = vertexCount;\r\n let renderSplatCount = totalSplats;\r\n if (activeIntervals) {\r\n renderSplatCount = 0;\r\n for (let rangeIndex = 1; rangeIndex < activeIntervals.length; rangeIndex += 2) {\r\n renderSplatCount += activeIntervals[rangeIndex];\r\n }\r\n }\r\n const vertexCountPadded = Math.max((renderSplatCount + 15) & ~0xf, 16);\r\n\r\n // depth = dot(cameraForward, worldPos - cameraPos)\r\n const camDot = cameraForward[0] * cameraPosition[0] + cameraForward[1] * cameraPosition[1] + cameraForward[2] * cameraPosition[2];\r\n\r\n const computeDepthCoeffs = (m: Float32Array): number[] => {\r\n return [\r\n cameraForward[0] * m[0] + cameraForward[1] * m[1] + cameraForward[2] * m[2],\r\n cameraForward[0] * m[4] + cameraForward[1] * m[5] + cameraForward[2] * m[6],\r\n cameraForward[0] * m[8] + cameraForward[1] * m[9] + cameraForward[2] * m[10],\r\n cameraForward[0] * m[12] + cameraForward[1] * m[13] + cameraForward[2] * m[14] - camDot,\r\n ];\r\n };\r\n\r\n // Optional, flag-gated sort timing (a simple wall-clock delta logged to the worker console).\r\n const perf = (globalThis as { performance?: { now(): number } }).performance;\r\n const sortStart = logSortPerformance && perf ? perf.now() : 0;\r\n\r\n try {\r\n if (useCountingSort) {\r\n // ===== Fast O(n) counting (radix) sort =====\r\n // Output view: the even 32-bit words of the depthMix buffer hold the sorted source indices\r\n // (the main thread reads indexMix[2*j]); the odd words are left unused.\r\n const outIndices = new Uint32Array(depthMix.buffer);\r\n\r\n // Grow the reusable scratch buffers when the active count increases (kept across sorts).\r\n if (!sortSourceIndices || sortSourceIndices.length < renderSplatCount) {\r\n const capacity = Math.max(renderSplatCount, 16);\r\n sortSourceIndices = new Uint32Array(capacity);\r\n sortDepths = new Float32Array(capacity);\r\n sortKeys = new Uint32Array(capacity);\r\n }\r\n\r\n // Compound (rig) meshes give each splat its own world transform via its part: depth uses the\r\n // splat's part coefficients. Single meshes use the one global world matrix. Both produce\r\n // depths in the same camera-forward space, so all active splats sort together correctly.\r\n // Require a non-empty partIndices: an empty one (length 0) would make partLen-1 index -1 below.\r\n const compound = !!(partMatrices && partMatrices.length > 0 && partIndices && partIndices.length > 0);\r\n let depthCoeffs: number[][] = [];\r\n let partLen = 0;\r\n let a = 0;\r\n let b = 0;\r\n let c = 0;\r\n let d = 0;\r\n if (compound) {\r\n depthCoeffs = partMatrices.map((m) => {\r\n const co = computeDepthCoeffs(m);\r\n co[0] *= depthSign;\r\n co[1] *= depthSign;\r\n co[2] *= depthSign;\r\n co[3] *= depthSign;\r\n return co;\r\n });\r\n partLen = partIndices.length;\r\n } else {\r\n const coeff = computeDepthCoeffs(globalWorldMatrix);\r\n a = coeff[0] * depthSign;\r\n b = coeff[1] * depthSign;\r\n c = coeff[2] * depthSign;\r\n d = coeff[3] * depthSign;\r\n }\r\n\r\n // Pass 1: gather the active source indices, compute each splat's view-space depth (signed\r\n // distance from the camera along the forward axis), and track the depth range. The compound\r\n // branch is hoisted out of the inner loop so the hot path stays straight-line.\r\n let writeIndex = 0;\r\n let minDepth = Infinity;\r\n let maxDepth = -Infinity;\r\n // A partIndices entry >= partCount means partIndices and partMatrices disagree — an inconsistent\r\n // snapshot posted mid-rebuild.\r\n const partCount = depthCoeffs.length;\r\n let inconsistentSnapshot = false;\r\n const rangeWords = activeIntervals ? activeIntervals.length : 2;\r\n gather: for (let r = 0; r < rangeWords; r += 2) {\r\n const start = activeIntervals ? activeIntervals[r] : 0;\r\n const end = start + (activeIntervals ? activeIntervals[r + 1] : totalSplats);\r\n if (compound) {\r\n for (let sourceIndex = start; sourceIndex < end; sourceIndex++) {\r\n const o = 4 * sourceIndex;\r\n const rawPart = partIndices[sourceIndex < partLen ? sourceIndex : partLen - 1];\r\n if (rawPart >= partCount) {\r\n // Reject rather than sort with the wrong transform: the output buffer is untouched\r\n // until the scatter pass below, so returning it as-is keeps the last good order and\r\n // the next frame retries once the snapshot is consistent.\r\n inconsistentSnapshot = true;\r\n break gather;\r\n }\r\n const coeff = depthCoeffs[rawPart];\r\n const depth = coeff[0] * positions[o] + coeff[1] * positions[o + 1] + coeff[2] * positions[o + 2] + coeff[3];\r\n sortSourceIndices[writeIndex] = sourceIndex;\r\n sortDepths[writeIndex] = depth;\r\n writeIndex++;\r\n if (depth < minDepth) {\r\n minDepth = depth;\r\n }\r\n if (depth > maxDepth) {\r\n maxDepth = depth;\r\n }\r\n }\r\n } else {\r\n for (let sourceIndex = start; sourceIndex < end; sourceIndex++) {\r\n const o = 4 * sourceIndex;\r\n const depth = a * positions[o] + b * positions[o + 1] + c * positions[o + 2] + d;\r\n sortSourceIndices[writeIndex] = sourceIndex;\r\n sortDepths[writeIndex] = depth;\r\n writeIndex++;\r\n if (depth < minDepth) {\r\n minDepth = depth;\r\n }\r\n if (depth > maxDepth) {\r\n maxDepth = depth;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (inconsistentSnapshot) {\r\n self.postMessage({ command: \"sorted\", depthMix, cameraId, sortRequestId, rangeVersion }, [depthMix.buffer]);\r\n return;\r\n }\r\n\r\n // Counting (radix) sort by a depth-derived integer key — O(n) vs the legacy comparison sort.\r\n // Bucket bit depth follows PlayCanvas: round(log2(n/4)) clamped to [10, 20]. The farthest splat\r\n // gets key 0 so the ascending counting sort yields back-to-front order for alpha blending.\r\n const compareBits = Math.max(10, Math.min(20, Math.round(Math.log2(Math.max(1, renderSplatCount) / 4))));\r\n const bucketCount = 2 ** compareBits + 1;\r\n if (!sortCounts || sortCounts.length !== bucketCount) {\r\n sortCounts = new Uint32Array(bucketCount);\r\n } else {\r\n sortCounts.fill(0);\r\n }\r\n\r\n const range = maxDepth - minDepth;\r\n if (!(range > 1e-12)) {\r\n // All active splats share a depth (or none are active): identity order, single bucket.\r\n for (let k = 0; k < renderSplatCount; k++) {\r\n sortKeys[k] = 0;\r\n }\r\n sortCounts[0] = renderSplatCount;\r\n } else {\r\n const scale = (bucketCount - 1) / range;\r\n const maxKey = bucketCount - 1;\r\n for (let k = 0; k < renderSplatCount; k++) {\r\n // maxDepth -> 0 (rendered first), minDepth -> bucketCount-1 (rendered last). Clamp\r\n // against float rounding (a tiny `range` makes `scale` huge), which could otherwise\r\n // produce key >= bucketCount and corrupt the histogram with out-of-bounds writes.\r\n let key = ((maxDepth - sortDepths[k]) * scale) >>> 0;\r\n if (key > maxKey) {\r\n key = maxKey;\r\n }\r\n sortKeys[k] = key;\r\n sortCounts[key]++;\r\n }\r\n }\r\n\r\n // Prefix-sum the histogram into bucket end offsets, then scatter source indices into place.\r\n for (let i = 1; i < bucketCount; i++) {\r\n sortCounts[i] += sortCounts[i - 1];\r\n }\r\n for (let k = 0; k < renderSplatCount; k++) {\r\n const dest = --sortCounts[sortKeys[k]];\r\n outIndices[2 * dest] = sortSourceIndices[k];\r\n }\r\n\r\n // Pad the remainder up to the 16-multiple with a guaranteed-empty index (see\r\n // emptySplatIndex above) — NOT splat index 0, which is just the first real splat of\r\n // whatever source data was loaded. Padding with a real, opaque splat draws it an extra\r\n // 15 times at the very end of the (back-to-front) draw order — i.e. always on top,\r\n // regardless of camera.\r\n for (let dest = renderSplatCount; dest < vertexCountPadded; dest++) {\r\n outIndices[2 * dest] = emptySplatIndex;\r\n }\r\n } else {\r\n // ===== Legacy comparison sort: pack (index, ~depthBits) into each 64-bit lane and sort it =====\r\n const indices = new Uint32Array(depthMix.buffer);\r\n const floatMix = new Float32Array(depthMix.buffer);\r\n\r\n // Build the compact list of source-splat indices to sort.\r\n if (activeIntervals) {\r\n let writeIndex = 0;\r\n for (let rangeIndex = 0; rangeIndex < activeIntervals.length; rangeIndex += 2) {\r\n const start = activeIntervals[rangeIndex];\r\n const count = activeIntervals[rangeIndex + 1];\r\n for (let sourceIndex = start; sourceIndex < start + count; sourceIndex++) {\r\n indices[2 * writeIndex++] = sourceIndex;\r\n }\r\n }\r\n // Pad up to a multiple of 16. Splat index 0 isn't guaranteed invisible (see the\r\n // counting-sort branch above) — use the same guaranteed-empty index instead.\r\n for (; writeIndex < vertexCountPadded; writeIndex++) {\r\n indices[2 * writeIndex] = emptySplatIndex;\r\n }\r\n } else {\r\n for (let j = 0; j < vertexCountPadded; j++) {\r\n indices[2 * j] = j;\r\n }\r\n }\r\n\r\n let inconsistentSnapshot = false;\r\n if (partMatrices && partMatrices.length > 0 && partIndices && partIndices.length > 0) {\r\n // Precompute depth coefficients for each rig node.\r\n const depthCoeffs = partMatrices.map((m) => computeDepthCoeffs(m));\r\n const length = partIndices.length;\r\n for (let j = 0; j < vertexCountPadded; j++) {\r\n const sourceIndex = indices[2 * j];\r\n // NB: We need this 'min' because the vertex array is padded, not partIndices.\r\n const partIndex = partIndices[Math.min(sourceIndex, length - 1)];\r\n if (partIndex >= depthCoeffs.length) {\r\n // Inconsistent snapshot (see the counting-sort branch): skip the sort rather than depth\r\n // splats with the wrong transform; the unsorted indices render for one frame, then retry.\r\n inconsistentSnapshot = true;\r\n break;\r\n }\r\n const coeff = depthCoeffs[partIndex];\r\n floatMix[2 * j + 1] =\r\n coeff[0] * positions[4 * sourceIndex + 0] + coeff[1] * positions[4 * sourceIndex + 1] + coeff[2] * positions[4 * sourceIndex + 2] + coeff[3];\r\n // Invert the depth bits (bitwise not) so the ascending sort renders back to front.\r\n indices[2 * j + 1] = ~indices[2 * j + 1];\r\n }\r\n } else {\r\n const [a, b, c, d] = computeDepthCoeffs(globalWorldMatrix);\r\n for (let j = 0; j < vertexCountPadded; j++) {\r\n const sourceIndex = indices[2 * j];\r\n floatMix[2 * j + 1] = a * positions[4 * sourceIndex + 0] + b * positions[4 * sourceIndex + 1] + c * positions[4 * sourceIndex + 2] + d;\r\n indices[2 * j + 1] = ~indices[2 * j + 1];\r\n }\r\n }\r\n\r\n if (!inconsistentSnapshot) {\r\n depthMix.sort();\r\n }\r\n }\r\n } catch (sortError) {\r\n // Transient data inconsistency (e.g. partIndices/partMatrices mismatch during addPart/removePart rebuild).\r\n // Return the buffer unsorted so the main thread can unlock _canPostToWorker and retry next frame.\r\n // Logger is unavailable inside the worker — console is the only option.\r\n // eslint-disable-next-line no-console\r\n console.error(\"Gaussian splat sort worker encountered an error (will retry next frame):\", sortError);\r\n }\r\n\r\n if (logSortPerformance && perf) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[GaussianSplatting] ${useCountingSort ? \"counting\" : \"legacy\"} sort: ${renderSplatCount} splats in ${(perf.now() - sortStart).toFixed(2)}ms`);\r\n }\r\n\r\n self.postMessage({ command: \"sorted\", depthMix, cameraId, sortRequestId, rangeVersion }, [depthMix.buffer]);\r\n }\r\n };\r\n};\r\n"]}
|
|
@@ -288,7 +288,11 @@ export class GreasedLineRibbonMesh extends GreasedLineBaseMesh {
|
|
|
288
288
|
if (ribbonInfo.directionsAutoMode === 3 /* GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_FACE_TO */ && !(ribbonInfo.directions instanceof Vector3)) {
|
|
289
289
|
throw "In GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_FACE_TO 'GreasedLineMeshOptions.ribbonOptions.directions' must be a Vector3.";
|
|
290
290
|
}
|
|
291
|
-
|
|
291
|
+
// Copy into the scratch vector instead of rebinding the slot. Assigning would make
|
|
292
|
+
// TmpVectors.Vector3[1] alias either the caller's vector or one of the DIRECTION_*
|
|
293
|
+
// constants (which are themselves Vector3.UpReadOnly / LeftReadOnly / ...), so the next
|
|
294
|
+
// write to that shared scratch slot anywhere in the engine would silently corrupt them.
|
|
295
|
+
TmpVectors.Vector3[1].copyFrom(ribbonInfo.directions instanceof Vector3 ? ribbonInfo.directions : GreasedLineRibbonMesh.DIRECTION_XZ);
|
|
292
296
|
for (let i = 0; i < pointVectors.length - (directionPlane ? 0 : 1); i++) {
|
|
293
297
|
const p1 = pointVectors[i];
|
|
294
298
|
const p2 = pointVectors[i + 1];
|