@onerjs/core 8.50.7 → 8.50.9

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 (44) hide show
  1. package/Collisions/gpuPicker.d.ts +12 -0
  2. package/Collisions/gpuPicker.js +51 -0
  3. package/Collisions/gpuPicker.js.map +1 -1
  4. package/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.js +10 -3
  5. package/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.js.map +1 -1
  6. package/FlowGraph/Blocks/Execution/flowGraphConsoleLogBlock.d.ts +1 -0
  7. package/FlowGraph/Blocks/Execution/flowGraphConsoleLogBlock.js +36 -3
  8. package/FlowGraph/Blocks/Execution/flowGraphConsoleLogBlock.js.map +1 -1
  9. package/FlowGraph/flowGraphEventBlock.d.ts +13 -0
  10. package/FlowGraph/flowGraphEventBlock.js +21 -2
  11. package/FlowGraph/flowGraphEventBlock.js.map +1 -1
  12. package/Materials/PBR/openpbrMaterial.js +3 -3
  13. package/Materials/PBR/openpbrMaterial.js.map +1 -1
  14. package/Meshes/Builders/polygonBuilder.d.ts +1 -0
  15. package/Meshes/Builders/polygonBuilder.js +27 -20
  16. package/Meshes/Builders/polygonBuilder.js.map +1 -1
  17. package/Misc/brdfTextureTools.d.ts +12 -0
  18. package/Misc/brdfTextureTools.js +22 -0
  19. package/Misc/brdfTextureTools.js.map +1 -1
  20. package/Misc/depthReducer.js +1 -1
  21. package/Misc/depthReducer.js.map +1 -1
  22. package/Rendering/depthRendererSceneComponent.js +7 -7
  23. package/Rendering/depthRendererSceneComponent.js.map +1 -1
  24. package/Shaders/ShadersInclude/openpbrBackgroundTransmission.js +1 -1
  25. package/Shaders/ShadersInclude/openpbrBackgroundTransmission.js.map +1 -1
  26. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js +3 -3
  27. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  28. package/Shaders/ShadersInclude/openpbrIblFunctions.js +8 -5
  29. package/Shaders/ShadersInclude/openpbrIblFunctions.js.map +1 -1
  30. package/Shaders/ShadersInclude/pbrBRDFFunctions.js +10 -6
  31. package/Shaders/ShadersInclude/pbrBRDFFunctions.js.map +1 -1
  32. package/Shaders/openpbr.fragment.js +4 -4
  33. package/Shaders/openpbr.fragment.js.map +1 -1
  34. package/ShadersWGSL/ShadersInclude/openpbrBackgroundTransmission.js +1 -1
  35. package/ShadersWGSL/ShadersInclude/openpbrBackgroundTransmission.js.map +1 -1
  36. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js +3 -3
  37. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  38. package/ShadersWGSL/ShadersInclude/openpbrIblFunctions.js +5 -3
  39. package/ShadersWGSL/ShadersInclude/openpbrIblFunctions.js.map +1 -1
  40. package/ShadersWGSL/ShadersInclude/pbrBRDFFunctions.js +5 -6
  41. package/ShadersWGSL/ShadersInclude/pbrBRDFFunctions.js.map +1 -1
  42. package/ShadersWGSL/openpbr.fragment.js +6 -6
  43. package/ShadersWGSL/openpbr.fragment.js.map +1 -1
  44. package/package.json +1 -1
@@ -136,6 +136,18 @@ export declare class GPUPicker {
136
136
  * @returns true if rendering if the picking texture has finished, otherwise false
137
137
  */
138
138
  private _checkRenderStatus;
139
+ /**
140
+ * Polls the picking material variant for every mesh in the render list until every
141
+ * variant is ready. Picking materials use parallel shader compilation, and a single
142
+ * ShaderMaterial may produce different effect variants per mesh (instances, thin
143
+ * instances, vertex colors, ...). If we render the picking texture before all variants
144
+ * are compiled, the renderer silently skips meshes whose effect is not yet ready, which
145
+ * can leave the click pixel cleared (0,0,0,0) and cause pickAsync to incorrectly return
146
+ * null. Once compiled, effects are cached by define string in the engine, so this
147
+ * polling only blocks on the very first pick (or whenever the render list changes to
148
+ * include meshes with new define combinations).
149
+ */
150
+ private _waitForPickingMaterialsReadyAsync;
139
151
  private _getMeshFromMultiplePoints;
140
152
  /**
141
153
  * Updates the render list with the current pickable meshes.
@@ -438,6 +438,7 @@ export class GPUPicker {
438
438
  // Invert Y
439
439
  const invertedY = rttSizeH - adjustedY - 1;
440
440
  this._preparePickingBuffer(this._engine, rttSizeW, rttSizeH, adjustedX, invertedY);
441
+ await this._waitForPickingMaterialsReadyAsync();
441
442
  return await this._executePickingAsync(adjustedX, invertedY, disposeWhenDone);
442
443
  }
443
444
  /**
@@ -486,6 +487,7 @@ export class GPUPicker {
486
487
  const h = Math.max(maxY - minY, 1);
487
488
  const partialCutH = rttSizeH - maxY - 1;
488
489
  this._preparePickingBuffer(this._engine, rttSizeW, rttSizeH, minX, partialCutH, w, h);
490
+ await this._waitForPickingMaterialsReadyAsync();
489
491
  return await this._executeMultiPickingAsync(processedXY, minX, maxY, rttSizeH, w, h, disposeWhenDone);
490
492
  }
491
493
  /**
@@ -520,6 +522,7 @@ export class GPUPicker {
520
522
  const h = Math.max(maxY - minY, 1);
521
523
  const partialCutH = rttSizeH - maxY - 1;
522
524
  this._preparePickingBuffer(this._engine, rttSizeW, rttSizeH, minX, partialCutH, w, h);
525
+ await this._waitForPickingMaterialsReadyAsync();
523
526
  return await this._executeBoxPickingAsync(minX, partialCutH, w, h, disposeWhenDone);
524
527
  }
525
528
  _getRenderInfo() {
@@ -706,6 +709,54 @@ export class GPUPicker {
706
709
  this._meshRenderingCount = 0;
707
710
  return false; // Wait for shaders to be ready
708
711
  }
712
+ /**
713
+ * Polls the picking material variant for every mesh in the render list until every
714
+ * variant is ready. Picking materials use parallel shader compilation, and a single
715
+ * ShaderMaterial may produce different effect variants per mesh (instances, thin
716
+ * instances, vertex colors, ...). If we render the picking texture before all variants
717
+ * are compiled, the renderer silently skips meshes whose effect is not yet ready, which
718
+ * can leave the click pixel cleared (0,0,0,0) and cause pickAsync to incorrectly return
719
+ * null. Once compiled, effects are cached by define string in the engine, so this
720
+ * polling only blocks on the very first pick (or whenever the render list changes to
721
+ * include meshes with new define combinations).
722
+ */
723
+ async _waitForPickingMaterialsReadyAsync() {
724
+ const renderList = this._pickingTexture?.renderList;
725
+ if (!renderList || renderList.length === 0) {
726
+ return;
727
+ }
728
+ // Cap the number of polling attempts to avoid hanging forever if a shader fails to compile.
729
+ const maxAttempts = 200;
730
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
731
+ let allReady = true;
732
+ // Iterate every mesh (do not break early): each isReady call kicks off compilation
733
+ // of that mesh's effect variant if not yet started, so visiting them all on the first
734
+ // attempt lets the compiles run in parallel (KHR_parallel_shader_compile) instead of
735
+ // being serialized one variant per render frame.
736
+ for (let i = 0; i < renderList.length; i++) {
737
+ const mesh = renderList[i];
738
+ const material = this._meshMaterialMap.get(mesh);
739
+ // Match the canonical "uses instanced shader variant" check used elsewhere in this file
740
+ // (see addPickingList) — InstancedMesh entries report isAnInstance=true while
741
+ // hasInstances=false, so omitting isAnInstance would validate the wrong shader variant.
742
+ const useInstances = mesh.hasInstances || mesh.isAnInstance || mesh.hasThinInstances;
743
+ if (material && !material.isReady(mesh, useInstances)) {
744
+ allReady = false;
745
+ }
746
+ }
747
+ if (allReady) {
748
+ return;
749
+ }
750
+ // Wait for the next scene render before re-checking. Effect compilation status
751
+ // (especially with KHR_parallel_shader_compile) is typically observed between
752
+ // frames, so tying the poll to the render loop is more efficient than a fixed timer.
753
+ // eslint-disable-next-line no-await-in-loop
754
+ await new Promise((resolve) => {
755
+ this._cachedScene.onAfterRenderObservable.addOnce(() => resolve());
756
+ });
757
+ }
758
+ Logger.Warn(`GPUPicker: gave up waiting for picking materials to compile after ${maxAttempts} attempts; picking results may be incorrect.`);
759
+ }
709
760
  _getMeshFromMultiplePoints(x, y, minX, maxY, w) {
710
761
  let offsetX = (x - minX - 1) * 4;
711
762
  let offsetY = (maxY - y - 1) * w * 4;
@@ -1 +1 @@
1
- {"version":3,"file":"gpuPicker.js","sourceRoot":"","sources":["../../../../dev/core/src/Collisions/gpuPicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type Engine } from \"core/Engines/engine\";\r\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { type Material } from \"core/Materials/material\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type IShaderMaterialOptions, ShaderMaterial } from \"core/Materials/shaderMaterial\";\r\nimport { GaussianSplattingMaterial } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial\";\r\nimport { GaussianSplattingGpuPickingMaterialPlugin } from \"core/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { type IVector2Like } from \"core/Maths/math.like\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"core/Meshes/buffer\";\r\nimport { type Mesh } from \"core/Meshes/mesh\";\r\nimport { type InstancedMesh } from \"core/Meshes/instancedMesh\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Observer } from \"core/Misc/observable\";\r\n\r\n/**\r\n * Class used to store the result of a GPU picking operation\r\n */\r\nexport interface IGPUPickingInfo {\r\n /**\r\n * Picked mesh\r\n */\r\n mesh: AbstractMesh;\r\n /**\r\n * Picked thin instance index\r\n */\r\n thinInstanceIndex?: number;\r\n}\r\n\r\n/**\r\n * Stores the result of a multi GPU piciking operation\r\n */\r\nexport interface IGPUMultiPickingInfo {\r\n /**\r\n * Picked mesh\r\n */\r\n meshes: Nullable<AbstractMesh>[];\r\n /**\r\n * Picked thin instance index\r\n */\r\n thinInstanceIndexes?: number[];\r\n}\r\n\r\n/**\r\n * Class used to perform a picking operation using GPU\r\n * GPUPIcker can pick meshes, instances and thin instances\r\n */\r\nexport class GPUPicker {\r\n private static readonly _AttributeName = \"instanceMeshID\";\r\n private static readonly _MaxPickingId = 0x00ffffff; // 24 bits unsigned integer max\r\n\r\n private _pickingTexture: Nullable<RenderTargetTexture> = null;\r\n\r\n private readonly _idMap: Array<number> = [];\r\n private readonly _thinIdMap: Array<{ meshId: number; thinId: number }> = [];\r\n private readonly _meshUniqueIdToPickerId: Array<number> = [];\r\n private _idWarningIssued = false;\r\n\r\n private _cachedScene: Nullable<Scene> = null;\r\n private _engine: Nullable<AbstractEngine> = null;\r\n\r\n private readonly _pickingMaterialCache: Nullable<ShaderMaterial>[] = new Array(9).fill(null);\r\n\r\n private _pickableMeshes: Array<AbstractMesh> = [];\r\n private readonly _meshMaterialMap: Map<AbstractMesh, Material> = new Map();\r\n private _readbuffer: Nullable<Uint8Array> = null;\r\n\r\n private _meshRenderingCount: number = 0;\r\n private _renderWarningIssued = false;\r\n private _renderPickingTexture = false;\r\n\r\n private _sceneBeforeRenderObserver: Nullable<Observer<Scene>> = null;\r\n private _pickingTextureAfterRenderObserver: Nullable<Observer<number>> = null;\r\n\r\n private _nextFreeId = 1;\r\n\r\n private readonly _gsPickingMaterials: Material[] = [];\r\n private readonly _gsCompoundRenderMeshes: AbstractMesh[] = [];\r\n\r\n /** Shader language used by the generator */\r\n protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n /**\r\n * Gets the shader language used in this generator.\r\n */\r\n public get shaderLanguage(): ShaderLanguage {\r\n return this._shaderLanguage;\r\n }\r\n\r\n private _pickingInProgress = false;\r\n\r\n /**\r\n * Gets a boolean indicating if the picking is in progress\r\n */\r\n public get pickingInProgress(): boolean {\r\n return this._pickingInProgress;\r\n }\r\n\r\n /**\r\n * Gets the default render materials used by the picker.\r\n *\r\n * index is Material filling mode\r\n */\r\n public get defaultRenderMaterials(): readonly Nullable<ShaderMaterial>[] {\r\n return this._pickingMaterialCache;\r\n }\r\n\r\n private _getColorIdFromReadBuffer(offset: number): number {\r\n const r = this._readbuffer![offset];\r\n const g = this._readbuffer![offset + 1];\r\n const b = this._readbuffer![offset + 2];\r\n return (r << 16) + (g << 8) + b;\r\n }\r\n\r\n private _createRenderTarget(scene: Scene, width: number, height: number): void {\r\n if (this._cachedScene && this._pickingTexture) {\r\n const index = this._cachedScene.customRenderTargets.indexOf(this._pickingTexture);\r\n if (index > -1) {\r\n this._cachedScene.customRenderTargets.splice(index, 1);\r\n this._renderPickingTexture = false;\r\n }\r\n }\r\n if (this._pickingTexture) {\r\n this._pickingTexture.dispose();\r\n }\r\n this._pickingTexture = new RenderTargetTexture(\"pickingTexure\", { width: width, height: height }, scene, {\r\n generateMipMaps: false,\r\n type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n samplingMode: Constants.TEXTURE_NEAREST_NEAREST,\r\n });\r\n }\r\n\r\n private _clearPickingMaterials(): void {\r\n for (let i = 0; i < this._pickingMaterialCache.length; i++) {\r\n const material = this._pickingMaterialCache[i];\r\n if (material !== null) {\r\n material.dispose();\r\n this._pickingMaterialCache[i] = null;\r\n }\r\n }\r\n }\r\n\r\n private _getPickingMaterial(scene: Scene, fillMode: number): ShaderMaterial {\r\n if (fillMode < 0 || 8 < fillMode) {\r\n fillMode = Constants.MATERIAL_TriangleFillMode;\r\n }\r\n\r\n const cachedMaterial = this._pickingMaterialCache[fillMode];\r\n if (cachedMaterial) {\r\n return cachedMaterial;\r\n }\r\n\r\n const engine = scene.getEngine();\r\n\r\n if (engine.isWebGPU) {\r\n this._shaderLanguage = ShaderLanguage.WGSL;\r\n }\r\n\r\n const defines: string[] = [];\r\n const options: Partial<IShaderMaterialOptions> = {\r\n attributes: [VertexBuffer.PositionKind, GPUPicker._AttributeName],\r\n uniforms: [\"world\", \"viewProjection\", \"meshID\"],\r\n needAlphaBlending: false,\r\n defines: defines,\r\n useClipPlane: null,\r\n shaderLanguage: this._shaderLanguage,\r\n extraInitializationsAsync: async () => {\r\n if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n await Promise.all([import(\"../ShadersWGSL/picking.fragment\"), import(\"../ShadersWGSL/picking.vertex\")]);\r\n } else {\r\n await Promise.all([import(\"../Shaders/picking.fragment\"), import(\"../Shaders/picking.vertex\")]);\r\n }\r\n },\r\n };\r\n\r\n const newMaterial = new ShaderMaterial(\"pickingShader\", scene, \"picking\", options, false);\r\n newMaterial.fillMode = fillMode;\r\n newMaterial.onBindObservable.add(this._materialBindCallback, undefined, undefined, this);\r\n\r\n this._pickingMaterialCache[fillMode] = newMaterial;\r\n return newMaterial;\r\n }\r\n\r\n private _materialBindCallback(mesh: AbstractMesh | undefined): void {\r\n if (!mesh) {\r\n return;\r\n }\r\n\r\n const material = this._meshMaterialMap.get(mesh)!;\r\n\r\n if (!material) {\r\n if (!this._renderWarningIssued) {\r\n this._renderWarningIssued = true;\r\n Logger.Warn(\"GPUPicker issue: Mesh not found in the material map. This may happen when the root mesh of an instance is not in the picking list.\");\r\n }\r\n return;\r\n }\r\n\r\n const effect = material.getEffect();\r\n if (!effect) {\r\n return;\r\n }\r\n\r\n if (!mesh.hasInstances && !mesh.isAnInstance && !mesh.hasThinInstances && this._meshUniqueIdToPickerId[mesh.uniqueId] !== undefined) {\r\n effect.setFloat(\"meshID\", this._meshUniqueIdToPickerId[mesh.uniqueId]);\r\n }\r\n\r\n this._meshRenderingCount++;\r\n }\r\n\r\n /**\r\n * Set the list of meshes to pick from\r\n * Set that value to null to clear the list (and avoid leaks)\r\n * The module will read and delete from the array provided by reference. Disposing the module or setting the value to null will clear the array.\r\n * @param list defines the list of meshes to pick from\r\n */\r\n public setPickingList(list: Nullable<Array<AbstractMesh | { mesh: AbstractMesh; material: ShaderMaterial }>>): void {\r\n this.clearPickingList();\r\n\r\n if (!list || list.length === 0) {\r\n return;\r\n }\r\n\r\n // Prepare target\r\n const scene = (\"mesh\" in list[0] ? list[0].mesh : list[0]).getScene();\r\n if (!this._cachedScene || this._cachedScene !== scene) {\r\n this._clearPickingMaterials();\r\n }\r\n\r\n this.addPickingList(list);\r\n }\r\n\r\n /**\r\n * Clear the current picking list and free resources\r\n */\r\n public clearPickingList(): void {\r\n if (this._pickableMeshes) {\r\n // Cleanup\r\n for (let index = 0; index < this._pickableMeshes.length; index++) {\r\n const mesh = this._pickableMeshes[index];\r\n const className = mesh.getClassName();\r\n\r\n // Skip GS part proxies - they don't have instance buffers or render list entries\r\n if (className === \"GaussianSplattingPartProxyMesh\") {\r\n continue;\r\n }\r\n\r\n // Skip thin instance cleanup for GaussianSplattingMesh (thin instances are for batching, not picking)\r\n if (className !== \"GaussianSplattingMesh\") {\r\n if (mesh.hasInstances) {\r\n (mesh as Mesh).removeVerticesData(GPUPicker._AttributeName);\r\n }\r\n if (mesh.hasThinInstances) {\r\n (mesh as Mesh).thinInstanceSetBuffer(GPUPicker._AttributeName, null);\r\n }\r\n }\r\n\r\n if (this._pickingTexture) {\r\n this._pickingTexture.setMaterialForRendering(mesh, undefined);\r\n }\r\n\r\n const material = this._meshMaterialMap.get(mesh);\r\n if (material && !this._pickingMaterialCache.includes(material as ShaderMaterial)) {\r\n material.onBindObservable.removeCallback(this._materialBindCallback);\r\n }\r\n }\r\n\r\n // Clean up GS compound meshes from render list\r\n for (const mesh of this._gsCompoundRenderMeshes) {\r\n if (this._pickingTexture) {\r\n this._pickingTexture.setMaterialForRendering(mesh, undefined);\r\n }\r\n }\r\n this._gsCompoundRenderMeshes.length = 0;\r\n\r\n // Dispose GS picking materials\r\n for (const material of this._gsPickingMaterials) {\r\n material.dispose();\r\n }\r\n this._gsPickingMaterials.length = 0;\r\n\r\n this._pickableMeshes.length = 0;\r\n this._meshMaterialMap.clear();\r\n this._idMap.length = 0;\r\n this._thinIdMap.length = 0;\r\n this._meshUniqueIdToPickerId.length = 0;\r\n if (this._pickingTexture) {\r\n this._pickingTexture.renderList = [];\r\n }\r\n }\r\n\r\n this._nextFreeId = 1;\r\n }\r\n\r\n /**\r\n * Add array of meshes to the current picking list\r\n * @param list defines the array of meshes to add to the current picking list\r\n */\r\n public addPickingList(list: Array<AbstractMesh | { mesh: AbstractMesh; material: ShaderMaterial }>): void {\r\n if (!list || list.length === 0) {\r\n return;\r\n }\r\n\r\n // Prepare target\r\n const scene = (\"mesh\" in list[0] ? list[0].mesh : list[0]).getScene();\r\n const engine = scene.getEngine();\r\n const rttSizeW = engine.getRenderWidth();\r\n const rttSizeH = engine.getRenderHeight();\r\n if (!this._pickingTexture) {\r\n this._createRenderTarget(scene, rttSizeW, rttSizeH);\r\n } else {\r\n const size = this._pickingTexture.getSize();\r\n\r\n if (size.width !== rttSizeW || size.height !== rttSizeH || this._cachedScene !== scene) {\r\n this._createRenderTarget(scene, rttSizeW, rttSizeH);\r\n }\r\n }\r\n\r\n this._sceneBeforeRenderObserver?.remove();\r\n this._sceneBeforeRenderObserver = scene.onBeforeRenderObservable.add(() => {\r\n if (scene.frameGraph && this._renderPickingTexture && this._cachedScene && this._pickingTexture) {\r\n this._cachedScene._renderRenderTarget(this._pickingTexture, this._cachedScene.cameras?.[0] ?? null);\r\n this._cachedScene.activeCamera = null;\r\n }\r\n });\r\n\r\n this._cachedScene = scene;\r\n this._engine = scene.getEngine();\r\n if (!this._pickingTexture!.renderList) {\r\n this._pickingTexture!.renderList = [];\r\n }\r\n\r\n const newPickableMeshes: AbstractMesh[] = new Array(list.length);\r\n const pickableMeshOffset = this._pickableMeshes?.length ?? 0;\r\n\r\n this._cachedScene = scene;\r\n this._engine = scene.getEngine();\r\n\r\n for (let i = 0; i < list.length; i++) {\r\n const item = list[i];\r\n if (\"mesh\" in item) {\r\n this._meshMaterialMap.set(item.mesh, item.material);\r\n newPickableMeshes[i] = item.mesh;\r\n } else {\r\n const className = item.getClassName();\r\n if (className === \"GaussianSplattingMesh\" || className === \"GaussianSplattingPartProxyMesh\") {\r\n // GS meshes get special picking materials - handled in the ID assignment loop below\r\n newPickableMeshes[i] = item;\r\n } else {\r\n const material = this._getPickingMaterial(scene, item.material?.fillMode ?? Constants.MATERIAL_TriangleFillMode);\r\n this._meshMaterialMap.set(item, material);\r\n newPickableMeshes[i] = item;\r\n }\r\n }\r\n }\r\n\r\n if (this._pickableMeshes !== null) {\r\n this._pickableMeshes = [...this._pickableMeshes, ...newPickableMeshes];\r\n } else {\r\n this._pickableMeshes = newPickableMeshes;\r\n }\r\n\r\n // We will affect colors and create vertex color buffers\r\n let nextFreeId = this._nextFreeId;\r\n\r\n // Collect GaussianSplatting part proxy groups for compound picking\r\n const gsCompoundGroups: { compound: AbstractMesh; partEntries: { proxy: AbstractMesh; globalIndex: number }[] }[] = [];\r\n\r\n for (let index = 0; index < newPickableMeshes.length; index++) {\r\n const mesh = newPickableMeshes[index];\r\n const className = mesh.getClassName();\r\n\r\n // Handle GaussianSplatting part proxy meshes - collect by compound for processing after the loop\r\n if (className === \"GaussianSplattingPartProxyMesh\") {\r\n const proxy = mesh as any; // GaussianSplattingPartProxyMesh\r\n const compound = proxy.compoundSplatMesh;\r\n const globalIndex = index + pickableMeshOffset;\r\n\r\n let group = gsCompoundGroups[compound.uniqueId];\r\n if (!group) {\r\n group = { compound, partEntries: [] };\r\n gsCompoundGroups[compound.uniqueId] = group;\r\n }\r\n group.partEntries.push({ proxy, globalIndex });\r\n continue; // Don't add to render list - the compound mesh will render for all parts\r\n }\r\n\r\n // Handle non-compound GaussianSplatting meshes\r\n if (className === \"GaussianSplattingMesh\") {\r\n const globalIndex = index + pickableMeshOffset;\r\n const pickId = nextFreeId;\r\n this._idMap[pickId] = globalIndex;\r\n this._meshUniqueIdToPickerId[mesh.uniqueId] = pickId;\r\n nextFreeId++;\r\n\r\n if (!mesh.isPickable || !mesh.isVisible) {\r\n continue;\r\n }\r\n\r\n // Create a GaussianSplattingMaterial with picking plugin for GPU picking\r\n const gsPickingMaterial = this._createGaussianSplattingPickingMaterial(scene, mesh);\r\n const plugin = gsPickingMaterial.pluginManager!.getPlugin<GaussianSplattingGpuPickingMaterialPlugin>(\"GaussianSplatGpuPicking\")!;\r\n plugin.meshId = pickId;\r\n\r\n gsPickingMaterial.onBindObservable.add(() => {\r\n this._meshRenderingCount++;\r\n });\r\n\r\n this._gsPickingMaterials.push(gsPickingMaterial);\r\n this._meshMaterialMap.set(mesh, gsPickingMaterial);\r\n this._pickingTexture!.setMaterialForRendering(mesh, gsPickingMaterial);\r\n this._pickingTexture!.renderList!.push(mesh);\r\n continue;\r\n }\r\n\r\n // Standard mesh processing\r\n const material = this._meshMaterialMap.get(mesh)!;\r\n\r\n if (!this._pickingMaterialCache.includes(material as ShaderMaterial)) {\r\n material.onBindObservable.add(this._materialBindCallback, undefined, undefined, this);\r\n }\r\n this._pickingTexture!.setMaterialForRendering(mesh, material);\r\n this._pickingTexture!.renderList!.push(mesh);\r\n\r\n if (mesh.isAnInstance) {\r\n continue; // This will be handled by the source mesh\r\n }\r\n\r\n const globalIndex = index + pickableMeshOffset;\r\n\r\n if (mesh.hasThinInstances) {\r\n const thinInstanceCount = (mesh as Mesh).thinInstanceCount;\r\n const instanceIdData = new Float32Array(thinInstanceCount);\r\n for (let i = 0; i < thinInstanceCount; i++) {\r\n instanceIdData[i] = nextFreeId;\r\n this._thinIdMap[nextFreeId] = { meshId: globalIndex, thinId: i };\r\n nextFreeId++;\r\n }\r\n (mesh as Mesh).thinInstanceSetBuffer(GPUPicker._AttributeName, instanceIdData, 1);\r\n } else {\r\n const currentMeshId = nextFreeId;\r\n this._idMap[currentMeshId] = globalIndex;\r\n nextFreeId++;\r\n\r\n if (mesh.hasInstances) {\r\n // find index of instances of that mesh\r\n const instancesForPick: number[] = [];\r\n for (let pickableMeshIndex = 0; pickableMeshIndex < newPickableMeshes.length; ++pickableMeshIndex) {\r\n const m = newPickableMeshes[pickableMeshIndex];\r\n if (m.isAnInstance && (m as InstancedMesh).sourceMesh === mesh) {\r\n instancesForPick.push(pickableMeshIndex);\r\n }\r\n }\r\n const instanceIdData = new Float32Array(instancesForPick.length + 1); // +1 for the source mesh\r\n\r\n instanceIdData[0] = currentMeshId;\r\n for (let i = 0; i < instancesForPick.length; i++) {\r\n instanceIdData[i + 1] = nextFreeId;\r\n const globalInstanceIndex = instancesForPick[i] + pickableMeshOffset;\r\n this._idMap[nextFreeId] = globalInstanceIndex;\r\n nextFreeId++;\r\n }\r\n\r\n const engine = mesh.getEngine();\r\n const buffer = new VertexBuffer(engine, instanceIdData, GPUPicker._AttributeName, false, false, 1, true);\r\n (mesh as Mesh).setVerticesBuffer(buffer, true);\r\n } else {\r\n this._meshUniqueIdToPickerId[mesh.uniqueId] = currentMeshId;\r\n }\r\n }\r\n }\r\n\r\n // Process GaussianSplatting compound groups (part proxy meshes)\r\n for (const group of gsCompoundGroups) {\r\n if (!group) {\r\n continue;\r\n }\r\n const compound = group.compound;\r\n\r\n // Assign picking IDs for each part\r\n const partMeshIds: number[] = new Array((compound as any).partCount || 1).fill(0);\r\n for (const entry of group.partEntries) {\r\n const pickId = nextFreeId;\r\n this._idMap[pickId] = entry.globalIndex;\r\n const partIndex = (entry.proxy as any).partIndex;\r\n if (partIndex < partMeshIds.length) {\r\n partMeshIds[partIndex] = pickId;\r\n }\r\n nextFreeId++;\r\n }\r\n\r\n // Create compound GS picking material with plugin\r\n const gsPickingMaterial = this._createGaussianSplattingPickingMaterial(scene, compound);\r\n const plugin = gsPickingMaterial.pluginManager!.getPlugin<GaussianSplattingGpuPickingMaterialPlugin>(\"GaussianSplatGpuPicking\")!;\r\n plugin.isCompound = true;\r\n plugin.partMeshIds = partMeshIds;\r\n // Only active (included, visible, and pickable) parts should contribute to the depth buffer.\r\n const activeParts = group.partEntries\r\n .filter((e) => (e.proxy as AbstractMesh).isPickable && (e.proxy as AbstractMesh).isVisible)\r\n .map((e) => (e.proxy as any).partIndex as number);\r\n plugin.setPartActive(activeParts);\r\n\r\n gsPickingMaterial.onBindObservable.add(() => {\r\n this._meshRenderingCount++;\r\n });\r\n\r\n this._gsPickingMaterials.push(gsPickingMaterial);\r\n this._meshMaterialMap.set(compound, gsPickingMaterial);\r\n this._pickingTexture!.setMaterialForRendering(compound, gsPickingMaterial);\r\n this._pickingTexture!.renderList!.push(compound);\r\n this._gsCompoundRenderMeshes.push(compound);\r\n }\r\n\r\n if (GPUPicker._MaxPickingId < nextFreeId - 1) {\r\n if (!this._idWarningIssued) {\r\n this._idWarningIssued = true;\r\n Logger.Warn(`GPUPicker maximum number of pickable meshes and instances is ${GPUPicker._MaxPickingId}. Some meshes or instances won't be pickable.`);\r\n }\r\n }\r\n\r\n this._nextFreeId = nextFreeId;\r\n }\r\n\r\n /**\r\n * Execute a picking operation\r\n * @param x defines the X coordinates where to run the pick\r\n * @param y defines the Y coordinates where to run the pick\r\n * @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)\r\n * @returns A promise with the picking results\r\n */\r\n public async pickAsync(x: number, y: number, disposeWhenDone = false): Promise<Nullable<IGPUPickingInfo>> {\r\n if (this._pickingInProgress) {\r\n return null;\r\n }\r\n\r\n if (!this._pickableMeshes || this._pickableMeshes.length === 0) {\r\n return null;\r\n }\r\n\r\n const { rttSizeW, rttSizeH, devicePixelRatio } = this._getRenderInfo();\r\n\r\n const { x: adjustedX, y: adjustedY } = this._prepareForPicking(x, y, devicePixelRatio);\r\n if (adjustedX < 0 || adjustedY < 0 || adjustedX >= rttSizeW || adjustedY >= rttSizeH) {\r\n return null;\r\n }\r\n\r\n this._pickingInProgress = true;\r\n\r\n // Invert Y\r\n const invertedY = rttSizeH - adjustedY - 1;\r\n this._preparePickingBuffer(this._engine!, rttSizeW, rttSizeH, adjustedX, invertedY);\r\n\r\n return await this._executePickingAsync(adjustedX, invertedY, disposeWhenDone);\r\n }\r\n\r\n /**\r\n * Execute a picking operation on multiple coordinates\r\n * @param xy defines the X,Y coordinates where to run the pick\r\n * @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)\r\n * @returns A promise with the picking results. Always returns an array with the same length as the number of coordinates. The mesh or null at the index where no mesh was picked.\r\n */\r\n public async multiPickAsync(xy: IVector2Like[], disposeWhenDone = false): Promise<Nullable<IGPUMultiPickingInfo>> {\r\n if (this._pickingInProgress) {\r\n return null;\r\n }\r\n\r\n if (!this._pickableMeshes || this._pickableMeshes.length === 0 || xy.length === 0) {\r\n return null;\r\n }\r\n\r\n if (xy.length === 1) {\r\n const pi = await this.pickAsync(xy[0].x, xy[0].y, disposeWhenDone);\r\n return {\r\n meshes: [pi?.mesh ?? null],\r\n thinInstanceIndexes: pi?.thinInstanceIndex ? [pi.thinInstanceIndex] : undefined,\r\n };\r\n }\r\n\r\n this._pickingInProgress = true;\r\n\r\n const processedXY = new Array(xy.length);\r\n\r\n let minX = Infinity;\r\n let maxX = -Infinity;\r\n let minY = Infinity;\r\n let maxY = -Infinity;\r\n\r\n const { rttSizeW, rttSizeH, devicePixelRatio } = this._getRenderInfo();\r\n\r\n // Process screen coordinates adjust to dpr\r\n for (let i = 0; i < xy.length; i++) {\r\n const item = xy[i];\r\n const { x, y } = item;\r\n\r\n const { x: adjustedX, y: adjustedY } = this._prepareForPicking(x, y, devicePixelRatio);\r\n\r\n processedXY[i] = {\r\n ...item,\r\n x: adjustedX,\r\n y: adjustedY,\r\n };\r\n\r\n minX = Math.min(minX, adjustedX);\r\n maxX = Math.max(maxX, adjustedX);\r\n minY = Math.min(minY, adjustedY);\r\n maxY = Math.max(maxY, adjustedY);\r\n }\r\n\r\n const w = Math.max(maxX - minX, 1);\r\n const h = Math.max(maxY - minY, 1);\r\n const partialCutH = rttSizeH - maxY - 1;\r\n\r\n this._preparePickingBuffer(this._engine!, rttSizeW, rttSizeH, minX, partialCutH, w, h);\r\n\r\n return await this._executeMultiPickingAsync(processedXY, minX, maxY, rttSizeH, w, h, disposeWhenDone);\r\n }\r\n\r\n /**\r\n * Execute a picking operation on box defined by two screen coordinates\r\n * @param x1 defines the X coordinate of the first corner of the box where to run the pick\r\n * @param y1 defines the Y coordinate of the first corner of the box where to run the pick\r\n * @param x2 defines the X coordinate of the opposite corner of the box where to run the pick\r\n * @param y2 defines the Y coordinate of the opposite corner of the box where to run the pick\r\n * @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)\r\n * @returns A promise with the picking results. Always returns an array with the same length as the number of coordinates. The mesh or null at the index where no mesh was picked.\r\n */\r\n public async boxPickAsync(x1: number, y1: number, x2: number, y2: number, disposeWhenDone = false): Promise<Nullable<IGPUMultiPickingInfo>> {\r\n if (this._pickingInProgress) {\r\n return null;\r\n }\r\n\r\n if (!this._pickableMeshes || this._pickableMeshes.length === 0) {\r\n return null;\r\n }\r\n\r\n this._pickingInProgress = true;\r\n\r\n const { rttSizeW, rttSizeH, devicePixelRatio } = this._getRenderInfo();\r\n\r\n const { x: adjustedX1, y: adjustedY1 } = this._prepareForPicking(x1, y1, devicePixelRatio);\r\n const { x: adjustedX2, y: adjustedY2 } = this._prepareForPicking(x2, y2, devicePixelRatio);\r\n\r\n const minX = Math.max(Math.min(adjustedX1, adjustedX2), 0);\r\n const maxX = Math.min(Math.max(adjustedX1, adjustedX2), rttSizeW - 1);\r\n const minY = Math.max(Math.min(adjustedY1, adjustedY2), 0);\r\n const maxY = Math.min(Math.max(adjustedY1, adjustedY2), rttSizeH - 1);\r\n\r\n if (minX >= rttSizeW || minY >= rttSizeH || maxX < 0 || maxY < 0) {\r\n this._pickingInProgress = false;\r\n return null;\r\n }\r\n\r\n const w = Math.max(maxX - minX, 1);\r\n const h = Math.max(maxY - minY, 1);\r\n const partialCutH = rttSizeH - maxY - 1;\r\n\r\n this._preparePickingBuffer(this._engine!, rttSizeW, rttSizeH, minX, partialCutH, w, h);\r\n\r\n return await this._executeBoxPickingAsync(minX, partialCutH, w, h, disposeWhenDone);\r\n }\r\n\r\n private _getRenderInfo(): { rttSizeW: number; rttSizeH: number; devicePixelRatio: number } {\r\n const engine = this._cachedScene!.getEngine();\r\n const rttSizeW = engine.getRenderWidth();\r\n const rttSizeH = engine.getRenderHeight();\r\n const devicePixelRatio = 1 / engine._hardwareScalingLevel;\r\n\r\n return {\r\n rttSizeW,\r\n rttSizeH,\r\n devicePixelRatio,\r\n };\r\n }\r\n\r\n private _prepareForPicking(x: number, y: number, devicePixelRatio: number): IVector2Like {\r\n return { x: (devicePixelRatio * x) >> 0, y: (devicePixelRatio * y) >> 0 };\r\n }\r\n\r\n private _preparePickingBuffer(engine: AbstractEngine, rttSizeW: number, rttSizeH: number, x: number, y: number, w = 1, h = 1): void {\r\n this._meshRenderingCount = 0;\r\n\r\n const requiredBufferSize = engine.isWebGPU ? (4 * w * h + 255) & ~255 : 4 * w * h;\r\n if (!this._readbuffer || this._readbuffer.length < requiredBufferSize) {\r\n this._readbuffer = new Uint8Array(requiredBufferSize);\r\n }\r\n\r\n // Do we need to rebuild the RTT?\r\n const size = this._pickingTexture!.getSize();\r\n if (size.width !== rttSizeW || size.height !== rttSizeH) {\r\n this._createRenderTarget(this._cachedScene!, rttSizeW, rttSizeH);\r\n this._updateRenderList();\r\n }\r\n\r\n this._pickingTexture!.clearColor = new Color4(0, 0, 0, 0);\r\n\r\n this._pickingTexture!.onBeforeRender = (): void => {\r\n this._enableScissor(x, y, w, h);\r\n };\r\n\r\n this._pickingTextureAfterRenderObserver?.remove();\r\n this._pickingTextureAfterRenderObserver = this._pickingTexture!.onAfterRenderObservable.add(() => {\r\n this._disableScissor();\r\n });\r\n\r\n this._cachedScene!.customRenderTargets.push(this._pickingTexture!);\r\n this._renderPickingTexture = true;\r\n }\r\n\r\n // pick one pixel\r\n private async _executePickingAsync(x: number, y: number, disposeWhenDone: boolean): Promise<Nullable<IGPUPickingInfo>> {\r\n return await new Promise((resolve, reject) => {\r\n if (!this._pickingTexture) {\r\n this._pickingInProgress = false;\r\n reject(new Error(\"Picking texture not created\"));\r\n return;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n this._pickingTexture.onAfterRender = async (): Promise<void> => {\r\n if (this._checkRenderStatus()) {\r\n this._pickingTexture!.onAfterRender = null as any;\r\n let pickedMesh: Nullable<AbstractMesh> = null;\r\n let thinInstanceIndex: number | undefined = undefined;\r\n\r\n // Remove from the active RTTs\r\n const index = this._cachedScene!.customRenderTargets.indexOf(this._pickingTexture!);\r\n if (index > -1) {\r\n this._cachedScene!.customRenderTargets.splice(index, 1);\r\n this._renderPickingTexture = false;\r\n }\r\n\r\n // Do the actual picking\r\n if (await this._readTexturePixelsAsync(x, y)) {\r\n const colorId = this._getColorIdFromReadBuffer(0);\r\n\r\n // Thin?\r\n if (this._thinIdMap[colorId]) {\r\n pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n } else {\r\n pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n }\r\n }\r\n\r\n if (disposeWhenDone) {\r\n this.dispose();\r\n }\r\n\r\n this._pickingInProgress = false;\r\n if (pickedMesh) {\r\n resolve({ mesh: pickedMesh, thinInstanceIndex: thinInstanceIndex });\r\n } else {\r\n resolve(null);\r\n }\r\n }\r\n };\r\n });\r\n }\r\n\r\n // pick multiple pixels\r\n private async _executeMultiPickingAsync(\r\n xy: IVector2Like[],\r\n minX: number,\r\n maxY: number,\r\n rttSizeH: number,\r\n w: number,\r\n h: number,\r\n disposeWhenDone: boolean\r\n ): Promise<Nullable<IGPUMultiPickingInfo>> {\r\n return await new Promise((resolve, reject) => {\r\n if (!this._pickingTexture) {\r\n this._pickingInProgress = false;\r\n reject(new Error(\"Picking texture not created\"));\r\n return;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n this._pickingTexture.onAfterRender = async (): Promise<void> => {\r\n if (this._checkRenderStatus()) {\r\n this._pickingTexture!.onAfterRender = null as any;\r\n const pickedMeshes: Nullable<AbstractMesh>[] = [];\r\n const thinInstanceIndexes: number[] = [];\r\n\r\n if (await this._readTexturePixelsAsync(minX, rttSizeH - maxY - 1, w, h)) {\r\n for (let i = 0; i < xy.length; i++) {\r\n const { pickedMesh, thinInstanceIndex } = this._getMeshFromMultiplePoints(xy[i].x, xy[i].y, minX, maxY, w);\r\n pickedMeshes.push(pickedMesh);\r\n thinInstanceIndexes.push(thinInstanceIndex ?? 0);\r\n }\r\n }\r\n\r\n if (disposeWhenDone) {\r\n this.dispose();\r\n }\r\n\r\n this._pickingInProgress = false;\r\n resolve({ meshes: pickedMeshes, thinInstanceIndexes: thinInstanceIndexes });\r\n }\r\n };\r\n });\r\n }\r\n\r\n // pick box area\r\n private async _executeBoxPickingAsync(x: number, y: number, w: number, h: number, disposeWhenDone: boolean): Promise<IGPUMultiPickingInfo> {\r\n return await new Promise((resolve, reject) => {\r\n if (!this._pickingTexture) {\r\n this._pickingInProgress = false;\r\n reject(new Error(\"Picking texture not created\"));\r\n return;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n this._pickingTexture.onAfterRender = async (): Promise<void> => {\r\n if (this._checkRenderStatus()) {\r\n this._pickingTexture!.onAfterRender = null as any;\r\n const pickedMeshes: Nullable<AbstractMesh>[] = [];\r\n const thinInstanceIndexes: number[] = [];\r\n\r\n if (await this._readTexturePixelsAsync(x, y, w, h)) {\r\n for (let offsetY = 0; offsetY < h; ++offsetY) {\r\n for (let offsetX = 0; offsetX < w; ++offsetX) {\r\n const colorId = this._getColorIdFromReadBuffer((offsetY * w + offsetX) * 4);\r\n if (colorId > 0) {\r\n // Thin?\r\n if (this._thinIdMap[colorId]) {\r\n const pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n const thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n pickedMeshes.push(pickedMesh);\r\n thinInstanceIndexes.push(thinInstanceIndex);\r\n } else {\r\n const pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n pickedMeshes.push(pickedMesh);\r\n thinInstanceIndexes.push(0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (disposeWhenDone) {\r\n this.dispose();\r\n }\r\n\r\n this._pickingInProgress = false;\r\n resolve({ meshes: pickedMeshes, thinInstanceIndexes: thinInstanceIndexes });\r\n }\r\n };\r\n });\r\n }\r\n\r\n private _enableScissor(x: number, y: number, w = 1, h = 1): void {\r\n if ((this._engine as WebGPUEngine | Engine).enableScissor) {\r\n (this._engine as WebGPUEngine | Engine).enableScissor(x, y, w, h);\r\n }\r\n }\r\n private _disableScissor(): void {\r\n if ((this._engine as WebGPUEngine | Engine).disableScissor) {\r\n (this._engine as WebGPUEngine | Engine).disableScissor();\r\n }\r\n }\r\n\r\n /**\r\n * @returns true if rendering if the picking texture has finished, otherwise false\r\n */\r\n private _checkRenderStatus(): boolean {\r\n const wasSuccessful = this._meshRenderingCount > 0;\r\n if (wasSuccessful) {\r\n // Remove from the active RTTs\r\n const index = this._cachedScene!.customRenderTargets.indexOf(this._pickingTexture!);\r\n if (index > -1) {\r\n this._cachedScene!.customRenderTargets.splice(index, 1);\r\n this._renderPickingTexture = false;\r\n }\r\n return true;\r\n }\r\n\r\n this._meshRenderingCount = 0;\r\n return false; // Wait for shaders to be ready\r\n }\r\n\r\n private _getMeshFromMultiplePoints(x: number, y: number, minX: number, maxY: number, w: number): { pickedMesh: Nullable<AbstractMesh>; thinInstanceIndex: number | undefined } {\r\n let offsetX = (x - minX - 1) * 4;\r\n let offsetY = (maxY - y - 1) * w * 4;\r\n\r\n offsetX = Math.max(offsetX, 0);\r\n offsetY = Math.max(offsetY, 0);\r\n\r\n const colorId = this._getColorIdFromReadBuffer(offsetX + offsetY);\r\n\r\n let pickedMesh: Nullable<AbstractMesh> = null;\r\n let thinInstanceIndex: number | undefined;\r\n\r\n if (colorId > 0) {\r\n if (this._thinIdMap[colorId]) {\r\n pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n } else {\r\n pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n }\r\n }\r\n\r\n return { pickedMesh, thinInstanceIndex };\r\n }\r\n\r\n /**\r\n * Updates the render list with the current pickable meshes.\r\n */\r\n private _updateRenderList(): void {\r\n this._pickingTexture!.renderList = [];\r\n for (const mesh of this._pickableMeshes) {\r\n const className = mesh.getClassName();\r\n // Part proxies don't render directly - their compound renders for them\r\n if (className === \"GaussianSplattingPartProxyMesh\") {\r\n continue;\r\n }\r\n this._pickingTexture!.setMaterialForRendering(mesh, this._meshMaterialMap.get(mesh));\r\n this._pickingTexture!.renderList.push(mesh);\r\n }\r\n // Also add compound GS meshes that render on behalf of part proxies\r\n for (const mesh of this._gsCompoundRenderMeshes) {\r\n this._pickingTexture!.setMaterialForRendering(mesh, this._meshMaterialMap.get(mesh));\r\n this._pickingTexture!.renderList.push(mesh);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a GaussianSplattingMaterial configured for GPU picking by attaching\r\n * a GaussianSplattingGpuPickingMaterialPlugin. The plugin injects picking ID\r\n * encoding into the existing Gaussian Splatting shaders via material plugin hooks.\r\n * @param scene The scene\r\n * @param gsMesh The Gaussian Splatting mesh (used to set the source mesh on the material)\r\n * @returns A GaussianSplattingMaterial with the picking plugin attached\r\n */\r\n private _createGaussianSplattingPickingMaterial(scene: Scene, gsMesh: AbstractMesh): GaussianSplattingMaterial {\r\n const gsPickingMaterial = new GaussianSplattingMaterial(\"gaussianSplattingGpuPicking\", scene);\r\n gsPickingMaterial.setSourceMesh(gsMesh as any);\r\n gsPickingMaterial.needAlphaBlending = () => false;\r\n gsPickingMaterial.backFaceCulling = false;\r\n\r\n // Attach the GPU picking plugin\r\n new GaussianSplattingGpuPickingMaterialPlugin(gsPickingMaterial);\r\n\r\n return gsPickingMaterial;\r\n }\r\n\r\n private async _readTexturePixelsAsync(x: number, y: number, w = 1, h = 1): Promise<boolean> {\r\n if (!this._cachedScene || !this._pickingTexture?._texture) {\r\n return false;\r\n }\r\n const engine = this._cachedScene.getEngine();\r\n await engine._readTexturePixels(this._pickingTexture._texture, w, h, -1, 0, this._readbuffer, true, true, x, y);\r\n\r\n return true;\r\n }\r\n\r\n /** Release the resources */\r\n public dispose(): void {\r\n this.setPickingList(null);\r\n this._cachedScene = null;\r\n\r\n // Cleaning up\r\n this._pickingTexture?.dispose();\r\n this._pickingTexture = null;\r\n this._clearPickingMaterials();\r\n this._sceneBeforeRenderObserver?.remove();\r\n this._sceneBeforeRenderObserver = null;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"gpuPicker.js","sourceRoot":"","sources":["../../../../dev/core/src/Collisions/gpuPicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type Engine } from \"core/Engines/engine\";\r\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { type Material } from \"core/Materials/material\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type IShaderMaterialOptions, ShaderMaterial } from \"core/Materials/shaderMaterial\";\r\nimport { GaussianSplattingMaterial } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial\";\r\nimport { GaussianSplattingGpuPickingMaterialPlugin } from \"core/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { type IVector2Like } from \"core/Maths/math.like\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"core/Meshes/buffer\";\r\nimport { type Mesh } from \"core/Meshes/mesh\";\r\nimport { type InstancedMesh } from \"core/Meshes/instancedMesh\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Observer } from \"core/Misc/observable\";\r\n\r\n/**\r\n * Class used to store the result of a GPU picking operation\r\n */\r\nexport interface IGPUPickingInfo {\r\n /**\r\n * Picked mesh\r\n */\r\n mesh: AbstractMesh;\r\n /**\r\n * Picked thin instance index\r\n */\r\n thinInstanceIndex?: number;\r\n}\r\n\r\n/**\r\n * Stores the result of a multi GPU piciking operation\r\n */\r\nexport interface IGPUMultiPickingInfo {\r\n /**\r\n * Picked mesh\r\n */\r\n meshes: Nullable<AbstractMesh>[];\r\n /**\r\n * Picked thin instance index\r\n */\r\n thinInstanceIndexes?: number[];\r\n}\r\n\r\n/**\r\n * Class used to perform a picking operation using GPU\r\n * GPUPIcker can pick meshes, instances and thin instances\r\n */\r\nexport class GPUPicker {\r\n private static readonly _AttributeName = \"instanceMeshID\";\r\n private static readonly _MaxPickingId = 0x00ffffff; // 24 bits unsigned integer max\r\n\r\n private _pickingTexture: Nullable<RenderTargetTexture> = null;\r\n\r\n private readonly _idMap: Array<number> = [];\r\n private readonly _thinIdMap: Array<{ meshId: number; thinId: number }> = [];\r\n private readonly _meshUniqueIdToPickerId: Array<number> = [];\r\n private _idWarningIssued = false;\r\n\r\n private _cachedScene: Nullable<Scene> = null;\r\n private _engine: Nullable<AbstractEngine> = null;\r\n\r\n private readonly _pickingMaterialCache: Nullable<ShaderMaterial>[] = new Array(9).fill(null);\r\n\r\n private _pickableMeshes: Array<AbstractMesh> = [];\r\n private readonly _meshMaterialMap: Map<AbstractMesh, Material> = new Map();\r\n private _readbuffer: Nullable<Uint8Array> = null;\r\n\r\n private _meshRenderingCount: number = 0;\r\n private _renderWarningIssued = false;\r\n private _renderPickingTexture = false;\r\n\r\n private _sceneBeforeRenderObserver: Nullable<Observer<Scene>> = null;\r\n private _pickingTextureAfterRenderObserver: Nullable<Observer<number>> = null;\r\n\r\n private _nextFreeId = 1;\r\n\r\n private readonly _gsPickingMaterials: Material[] = [];\r\n private readonly _gsCompoundRenderMeshes: AbstractMesh[] = [];\r\n\r\n /** Shader language used by the generator */\r\n protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n /**\r\n * Gets the shader language used in this generator.\r\n */\r\n public get shaderLanguage(): ShaderLanguage {\r\n return this._shaderLanguage;\r\n }\r\n\r\n private _pickingInProgress = false;\r\n\r\n /**\r\n * Gets a boolean indicating if the picking is in progress\r\n */\r\n public get pickingInProgress(): boolean {\r\n return this._pickingInProgress;\r\n }\r\n\r\n /**\r\n * Gets the default render materials used by the picker.\r\n *\r\n * index is Material filling mode\r\n */\r\n public get defaultRenderMaterials(): readonly Nullable<ShaderMaterial>[] {\r\n return this._pickingMaterialCache;\r\n }\r\n\r\n private _getColorIdFromReadBuffer(offset: number): number {\r\n const r = this._readbuffer![offset];\r\n const g = this._readbuffer![offset + 1];\r\n const b = this._readbuffer![offset + 2];\r\n return (r << 16) + (g << 8) + b;\r\n }\r\n\r\n private _createRenderTarget(scene: Scene, width: number, height: number): void {\r\n if (this._cachedScene && this._pickingTexture) {\r\n const index = this._cachedScene.customRenderTargets.indexOf(this._pickingTexture);\r\n if (index > -1) {\r\n this._cachedScene.customRenderTargets.splice(index, 1);\r\n this._renderPickingTexture = false;\r\n }\r\n }\r\n if (this._pickingTexture) {\r\n this._pickingTexture.dispose();\r\n }\r\n this._pickingTexture = new RenderTargetTexture(\"pickingTexure\", { width: width, height: height }, scene, {\r\n generateMipMaps: false,\r\n type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n samplingMode: Constants.TEXTURE_NEAREST_NEAREST,\r\n });\r\n }\r\n\r\n private _clearPickingMaterials(): void {\r\n for (let i = 0; i < this._pickingMaterialCache.length; i++) {\r\n const material = this._pickingMaterialCache[i];\r\n if (material !== null) {\r\n material.dispose();\r\n this._pickingMaterialCache[i] = null;\r\n }\r\n }\r\n }\r\n\r\n private _getPickingMaterial(scene: Scene, fillMode: number): ShaderMaterial {\r\n if (fillMode < 0 || 8 < fillMode) {\r\n fillMode = Constants.MATERIAL_TriangleFillMode;\r\n }\r\n\r\n const cachedMaterial = this._pickingMaterialCache[fillMode];\r\n if (cachedMaterial) {\r\n return cachedMaterial;\r\n }\r\n\r\n const engine = scene.getEngine();\r\n\r\n if (engine.isWebGPU) {\r\n this._shaderLanguage = ShaderLanguage.WGSL;\r\n }\r\n\r\n const defines: string[] = [];\r\n const options: Partial<IShaderMaterialOptions> = {\r\n attributes: [VertexBuffer.PositionKind, GPUPicker._AttributeName],\r\n uniforms: [\"world\", \"viewProjection\", \"meshID\"],\r\n needAlphaBlending: false,\r\n defines: defines,\r\n useClipPlane: null,\r\n shaderLanguage: this._shaderLanguage,\r\n extraInitializationsAsync: async () => {\r\n if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n await Promise.all([import(\"../ShadersWGSL/picking.fragment\"), import(\"../ShadersWGSL/picking.vertex\")]);\r\n } else {\r\n await Promise.all([import(\"../Shaders/picking.fragment\"), import(\"../Shaders/picking.vertex\")]);\r\n }\r\n },\r\n };\r\n\r\n const newMaterial = new ShaderMaterial(\"pickingShader\", scene, \"picking\", options, false);\r\n newMaterial.fillMode = fillMode;\r\n newMaterial.onBindObservable.add(this._materialBindCallback, undefined, undefined, this);\r\n\r\n this._pickingMaterialCache[fillMode] = newMaterial;\r\n return newMaterial;\r\n }\r\n\r\n private _materialBindCallback(mesh: AbstractMesh | undefined): void {\r\n if (!mesh) {\r\n return;\r\n }\r\n\r\n const material = this._meshMaterialMap.get(mesh)!;\r\n\r\n if (!material) {\r\n if (!this._renderWarningIssued) {\r\n this._renderWarningIssued = true;\r\n Logger.Warn(\"GPUPicker issue: Mesh not found in the material map. This may happen when the root mesh of an instance is not in the picking list.\");\r\n }\r\n return;\r\n }\r\n\r\n const effect = material.getEffect();\r\n if (!effect) {\r\n return;\r\n }\r\n\r\n if (!mesh.hasInstances && !mesh.isAnInstance && !mesh.hasThinInstances && this._meshUniqueIdToPickerId[mesh.uniqueId] !== undefined) {\r\n effect.setFloat(\"meshID\", this._meshUniqueIdToPickerId[mesh.uniqueId]);\r\n }\r\n\r\n this._meshRenderingCount++;\r\n }\r\n\r\n /**\r\n * Set the list of meshes to pick from\r\n * Set that value to null to clear the list (and avoid leaks)\r\n * The module will read and delete from the array provided by reference. Disposing the module or setting the value to null will clear the array.\r\n * @param list defines the list of meshes to pick from\r\n */\r\n public setPickingList(list: Nullable<Array<AbstractMesh | { mesh: AbstractMesh; material: ShaderMaterial }>>): void {\r\n this.clearPickingList();\r\n\r\n if (!list || list.length === 0) {\r\n return;\r\n }\r\n\r\n // Prepare target\r\n const scene = (\"mesh\" in list[0] ? list[0].mesh : list[0]).getScene();\r\n if (!this._cachedScene || this._cachedScene !== scene) {\r\n this._clearPickingMaterials();\r\n }\r\n\r\n this.addPickingList(list);\r\n }\r\n\r\n /**\r\n * Clear the current picking list and free resources\r\n */\r\n public clearPickingList(): void {\r\n if (this._pickableMeshes) {\r\n // Cleanup\r\n for (let index = 0; index < this._pickableMeshes.length; index++) {\r\n const mesh = this._pickableMeshes[index];\r\n const className = mesh.getClassName();\r\n\r\n // Skip GS part proxies - they don't have instance buffers or render list entries\r\n if (className === \"GaussianSplattingPartProxyMesh\") {\r\n continue;\r\n }\r\n\r\n // Skip thin instance cleanup for GaussianSplattingMesh (thin instances are for batching, not picking)\r\n if (className !== \"GaussianSplattingMesh\") {\r\n if (mesh.hasInstances) {\r\n (mesh as Mesh).removeVerticesData(GPUPicker._AttributeName);\r\n }\r\n if (mesh.hasThinInstances) {\r\n (mesh as Mesh).thinInstanceSetBuffer(GPUPicker._AttributeName, null);\r\n }\r\n }\r\n\r\n if (this._pickingTexture) {\r\n this._pickingTexture.setMaterialForRendering(mesh, undefined);\r\n }\r\n\r\n const material = this._meshMaterialMap.get(mesh);\r\n if (material && !this._pickingMaterialCache.includes(material as ShaderMaterial)) {\r\n material.onBindObservable.removeCallback(this._materialBindCallback);\r\n }\r\n }\r\n\r\n // Clean up GS compound meshes from render list\r\n for (const mesh of this._gsCompoundRenderMeshes) {\r\n if (this._pickingTexture) {\r\n this._pickingTexture.setMaterialForRendering(mesh, undefined);\r\n }\r\n }\r\n this._gsCompoundRenderMeshes.length = 0;\r\n\r\n // Dispose GS picking materials\r\n for (const material of this._gsPickingMaterials) {\r\n material.dispose();\r\n }\r\n this._gsPickingMaterials.length = 0;\r\n\r\n this._pickableMeshes.length = 0;\r\n this._meshMaterialMap.clear();\r\n this._idMap.length = 0;\r\n this._thinIdMap.length = 0;\r\n this._meshUniqueIdToPickerId.length = 0;\r\n if (this._pickingTexture) {\r\n this._pickingTexture.renderList = [];\r\n }\r\n }\r\n\r\n this._nextFreeId = 1;\r\n }\r\n\r\n /**\r\n * Add array of meshes to the current picking list\r\n * @param list defines the array of meshes to add to the current picking list\r\n */\r\n public addPickingList(list: Array<AbstractMesh | { mesh: AbstractMesh; material: ShaderMaterial }>): void {\r\n if (!list || list.length === 0) {\r\n return;\r\n }\r\n\r\n // Prepare target\r\n const scene = (\"mesh\" in list[0] ? list[0].mesh : list[0]).getScene();\r\n const engine = scene.getEngine();\r\n const rttSizeW = engine.getRenderWidth();\r\n const rttSizeH = engine.getRenderHeight();\r\n if (!this._pickingTexture) {\r\n this._createRenderTarget(scene, rttSizeW, rttSizeH);\r\n } else {\r\n const size = this._pickingTexture.getSize();\r\n\r\n if (size.width !== rttSizeW || size.height !== rttSizeH || this._cachedScene !== scene) {\r\n this._createRenderTarget(scene, rttSizeW, rttSizeH);\r\n }\r\n }\r\n\r\n this._sceneBeforeRenderObserver?.remove();\r\n this._sceneBeforeRenderObserver = scene.onBeforeRenderObservable.add(() => {\r\n if (scene.frameGraph && this._renderPickingTexture && this._cachedScene && this._pickingTexture) {\r\n this._cachedScene._renderRenderTarget(this._pickingTexture, this._cachedScene.cameras?.[0] ?? null);\r\n this._cachedScene.activeCamera = null;\r\n }\r\n });\r\n\r\n this._cachedScene = scene;\r\n this._engine = scene.getEngine();\r\n if (!this._pickingTexture!.renderList) {\r\n this._pickingTexture!.renderList = [];\r\n }\r\n\r\n const newPickableMeshes: AbstractMesh[] = new Array(list.length);\r\n const pickableMeshOffset = this._pickableMeshes?.length ?? 0;\r\n\r\n this._cachedScene = scene;\r\n this._engine = scene.getEngine();\r\n\r\n for (let i = 0; i < list.length; i++) {\r\n const item = list[i];\r\n if (\"mesh\" in item) {\r\n this._meshMaterialMap.set(item.mesh, item.material);\r\n newPickableMeshes[i] = item.mesh;\r\n } else {\r\n const className = item.getClassName();\r\n if (className === \"GaussianSplattingMesh\" || className === \"GaussianSplattingPartProxyMesh\") {\r\n // GS meshes get special picking materials - handled in the ID assignment loop below\r\n newPickableMeshes[i] = item;\r\n } else {\r\n const material = this._getPickingMaterial(scene, item.material?.fillMode ?? Constants.MATERIAL_TriangleFillMode);\r\n this._meshMaterialMap.set(item, material);\r\n newPickableMeshes[i] = item;\r\n }\r\n }\r\n }\r\n\r\n if (this._pickableMeshes !== null) {\r\n this._pickableMeshes = [...this._pickableMeshes, ...newPickableMeshes];\r\n } else {\r\n this._pickableMeshes = newPickableMeshes;\r\n }\r\n\r\n // We will affect colors and create vertex color buffers\r\n let nextFreeId = this._nextFreeId;\r\n\r\n // Collect GaussianSplatting part proxy groups for compound picking\r\n const gsCompoundGroups: { compound: AbstractMesh; partEntries: { proxy: AbstractMesh; globalIndex: number }[] }[] = [];\r\n\r\n for (let index = 0; index < newPickableMeshes.length; index++) {\r\n const mesh = newPickableMeshes[index];\r\n const className = mesh.getClassName();\r\n\r\n // Handle GaussianSplatting part proxy meshes - collect by compound for processing after the loop\r\n if (className === \"GaussianSplattingPartProxyMesh\") {\r\n const proxy = mesh as any; // GaussianSplattingPartProxyMesh\r\n const compound = proxy.compoundSplatMesh;\r\n const globalIndex = index + pickableMeshOffset;\r\n\r\n let group = gsCompoundGroups[compound.uniqueId];\r\n if (!group) {\r\n group = { compound, partEntries: [] };\r\n gsCompoundGroups[compound.uniqueId] = group;\r\n }\r\n group.partEntries.push({ proxy, globalIndex });\r\n continue; // Don't add to render list - the compound mesh will render for all parts\r\n }\r\n\r\n // Handle non-compound GaussianSplatting meshes\r\n if (className === \"GaussianSplattingMesh\") {\r\n const globalIndex = index + pickableMeshOffset;\r\n const pickId = nextFreeId;\r\n this._idMap[pickId] = globalIndex;\r\n this._meshUniqueIdToPickerId[mesh.uniqueId] = pickId;\r\n nextFreeId++;\r\n\r\n if (!mesh.isPickable || !mesh.isVisible) {\r\n continue;\r\n }\r\n\r\n // Create a GaussianSplattingMaterial with picking plugin for GPU picking\r\n const gsPickingMaterial = this._createGaussianSplattingPickingMaterial(scene, mesh);\r\n const plugin = gsPickingMaterial.pluginManager!.getPlugin<GaussianSplattingGpuPickingMaterialPlugin>(\"GaussianSplatGpuPicking\")!;\r\n plugin.meshId = pickId;\r\n\r\n gsPickingMaterial.onBindObservable.add(() => {\r\n this._meshRenderingCount++;\r\n });\r\n\r\n this._gsPickingMaterials.push(gsPickingMaterial);\r\n this._meshMaterialMap.set(mesh, gsPickingMaterial);\r\n this._pickingTexture!.setMaterialForRendering(mesh, gsPickingMaterial);\r\n this._pickingTexture!.renderList!.push(mesh);\r\n continue;\r\n }\r\n\r\n // Standard mesh processing\r\n const material = this._meshMaterialMap.get(mesh)!;\r\n\r\n if (!this._pickingMaterialCache.includes(material as ShaderMaterial)) {\r\n material.onBindObservable.add(this._materialBindCallback, undefined, undefined, this);\r\n }\r\n this._pickingTexture!.setMaterialForRendering(mesh, material);\r\n this._pickingTexture!.renderList!.push(mesh);\r\n\r\n if (mesh.isAnInstance) {\r\n continue; // This will be handled by the source mesh\r\n }\r\n\r\n const globalIndex = index + pickableMeshOffset;\r\n\r\n if (mesh.hasThinInstances) {\r\n const thinInstanceCount = (mesh as Mesh).thinInstanceCount;\r\n const instanceIdData = new Float32Array(thinInstanceCount);\r\n for (let i = 0; i < thinInstanceCount; i++) {\r\n instanceIdData[i] = nextFreeId;\r\n this._thinIdMap[nextFreeId] = { meshId: globalIndex, thinId: i };\r\n nextFreeId++;\r\n }\r\n (mesh as Mesh).thinInstanceSetBuffer(GPUPicker._AttributeName, instanceIdData, 1);\r\n } else {\r\n const currentMeshId = nextFreeId;\r\n this._idMap[currentMeshId] = globalIndex;\r\n nextFreeId++;\r\n\r\n if (mesh.hasInstances) {\r\n // find index of instances of that mesh\r\n const instancesForPick: number[] = [];\r\n for (let pickableMeshIndex = 0; pickableMeshIndex < newPickableMeshes.length; ++pickableMeshIndex) {\r\n const m = newPickableMeshes[pickableMeshIndex];\r\n if (m.isAnInstance && (m as InstancedMesh).sourceMesh === mesh) {\r\n instancesForPick.push(pickableMeshIndex);\r\n }\r\n }\r\n const instanceIdData = new Float32Array(instancesForPick.length + 1); // +1 for the source mesh\r\n\r\n instanceIdData[0] = currentMeshId;\r\n for (let i = 0; i < instancesForPick.length; i++) {\r\n instanceIdData[i + 1] = nextFreeId;\r\n const globalInstanceIndex = instancesForPick[i] + pickableMeshOffset;\r\n this._idMap[nextFreeId] = globalInstanceIndex;\r\n nextFreeId++;\r\n }\r\n\r\n const engine = mesh.getEngine();\r\n const buffer = new VertexBuffer(engine, instanceIdData, GPUPicker._AttributeName, false, false, 1, true);\r\n (mesh as Mesh).setVerticesBuffer(buffer, true);\r\n } else {\r\n this._meshUniqueIdToPickerId[mesh.uniqueId] = currentMeshId;\r\n }\r\n }\r\n }\r\n\r\n // Process GaussianSplatting compound groups (part proxy meshes)\r\n for (const group of gsCompoundGroups) {\r\n if (!group) {\r\n continue;\r\n }\r\n const compound = group.compound;\r\n\r\n // Assign picking IDs for each part\r\n const partMeshIds: number[] = new Array((compound as any).partCount || 1).fill(0);\r\n for (const entry of group.partEntries) {\r\n const pickId = nextFreeId;\r\n this._idMap[pickId] = entry.globalIndex;\r\n const partIndex = (entry.proxy as any).partIndex;\r\n if (partIndex < partMeshIds.length) {\r\n partMeshIds[partIndex] = pickId;\r\n }\r\n nextFreeId++;\r\n }\r\n\r\n // Create compound GS picking material with plugin\r\n const gsPickingMaterial = this._createGaussianSplattingPickingMaterial(scene, compound);\r\n const plugin = gsPickingMaterial.pluginManager!.getPlugin<GaussianSplattingGpuPickingMaterialPlugin>(\"GaussianSplatGpuPicking\")!;\r\n plugin.isCompound = true;\r\n plugin.partMeshIds = partMeshIds;\r\n // Only active (included, visible, and pickable) parts should contribute to the depth buffer.\r\n const activeParts = group.partEntries\r\n .filter((e) => (e.proxy as AbstractMesh).isPickable && (e.proxy as AbstractMesh).isVisible)\r\n .map((e) => (e.proxy as any).partIndex as number);\r\n plugin.setPartActive(activeParts);\r\n\r\n gsPickingMaterial.onBindObservable.add(() => {\r\n this._meshRenderingCount++;\r\n });\r\n\r\n this._gsPickingMaterials.push(gsPickingMaterial);\r\n this._meshMaterialMap.set(compound, gsPickingMaterial);\r\n this._pickingTexture!.setMaterialForRendering(compound, gsPickingMaterial);\r\n this._pickingTexture!.renderList!.push(compound);\r\n this._gsCompoundRenderMeshes.push(compound);\r\n }\r\n\r\n if (GPUPicker._MaxPickingId < nextFreeId - 1) {\r\n if (!this._idWarningIssued) {\r\n this._idWarningIssued = true;\r\n Logger.Warn(`GPUPicker maximum number of pickable meshes and instances is ${GPUPicker._MaxPickingId}. Some meshes or instances won't be pickable.`);\r\n }\r\n }\r\n\r\n this._nextFreeId = nextFreeId;\r\n }\r\n\r\n /**\r\n * Execute a picking operation\r\n * @param x defines the X coordinates where to run the pick\r\n * @param y defines the Y coordinates where to run the pick\r\n * @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)\r\n * @returns A promise with the picking results\r\n */\r\n public async pickAsync(x: number, y: number, disposeWhenDone = false): Promise<Nullable<IGPUPickingInfo>> {\r\n if (this._pickingInProgress) {\r\n return null;\r\n }\r\n\r\n if (!this._pickableMeshes || this._pickableMeshes.length === 0) {\r\n return null;\r\n }\r\n\r\n const { rttSizeW, rttSizeH, devicePixelRatio } = this._getRenderInfo();\r\n\r\n const { x: adjustedX, y: adjustedY } = this._prepareForPicking(x, y, devicePixelRatio);\r\n if (adjustedX < 0 || adjustedY < 0 || adjustedX >= rttSizeW || adjustedY >= rttSizeH) {\r\n return null;\r\n }\r\n\r\n this._pickingInProgress = true;\r\n\r\n // Invert Y\r\n const invertedY = rttSizeH - adjustedY - 1;\r\n this._preparePickingBuffer(this._engine!, rttSizeW, rttSizeH, adjustedX, invertedY);\r\n\r\n await this._waitForPickingMaterialsReadyAsync();\r\n\r\n return await this._executePickingAsync(adjustedX, invertedY, disposeWhenDone);\r\n }\r\n\r\n /**\r\n * Execute a picking operation on multiple coordinates\r\n * @param xy defines the X,Y coordinates where to run the pick\r\n * @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)\r\n * @returns A promise with the picking results. Always returns an array with the same length as the number of coordinates. The mesh or null at the index where no mesh was picked.\r\n */\r\n public async multiPickAsync(xy: IVector2Like[], disposeWhenDone = false): Promise<Nullable<IGPUMultiPickingInfo>> {\r\n if (this._pickingInProgress) {\r\n return null;\r\n }\r\n\r\n if (!this._pickableMeshes || this._pickableMeshes.length === 0 || xy.length === 0) {\r\n return null;\r\n }\r\n\r\n if (xy.length === 1) {\r\n const pi = await this.pickAsync(xy[0].x, xy[0].y, disposeWhenDone);\r\n return {\r\n meshes: [pi?.mesh ?? null],\r\n thinInstanceIndexes: pi?.thinInstanceIndex ? [pi.thinInstanceIndex] : undefined,\r\n };\r\n }\r\n\r\n this._pickingInProgress = true;\r\n\r\n const processedXY = new Array(xy.length);\r\n\r\n let minX = Infinity;\r\n let maxX = -Infinity;\r\n let minY = Infinity;\r\n let maxY = -Infinity;\r\n\r\n const { rttSizeW, rttSizeH, devicePixelRatio } = this._getRenderInfo();\r\n\r\n // Process screen coordinates adjust to dpr\r\n for (let i = 0; i < xy.length; i++) {\r\n const item = xy[i];\r\n const { x, y } = item;\r\n\r\n const { x: adjustedX, y: adjustedY } = this._prepareForPicking(x, y, devicePixelRatio);\r\n\r\n processedXY[i] = {\r\n ...item,\r\n x: adjustedX,\r\n y: adjustedY,\r\n };\r\n\r\n minX = Math.min(minX, adjustedX);\r\n maxX = Math.max(maxX, adjustedX);\r\n minY = Math.min(minY, adjustedY);\r\n maxY = Math.max(maxY, adjustedY);\r\n }\r\n\r\n const w = Math.max(maxX - minX, 1);\r\n const h = Math.max(maxY - minY, 1);\r\n const partialCutH = rttSizeH - maxY - 1;\r\n\r\n this._preparePickingBuffer(this._engine!, rttSizeW, rttSizeH, minX, partialCutH, w, h);\r\n\r\n await this._waitForPickingMaterialsReadyAsync();\r\n\r\n return await this._executeMultiPickingAsync(processedXY, minX, maxY, rttSizeH, w, h, disposeWhenDone);\r\n }\r\n\r\n /**\r\n * Execute a picking operation on box defined by two screen coordinates\r\n * @param x1 defines the X coordinate of the first corner of the box where to run the pick\r\n * @param y1 defines the Y coordinate of the first corner of the box where to run the pick\r\n * @param x2 defines the X coordinate of the opposite corner of the box where to run the pick\r\n * @param y2 defines the Y coordinate of the opposite corner of the box where to run the pick\r\n * @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)\r\n * @returns A promise with the picking results. Always returns an array with the same length as the number of coordinates. The mesh or null at the index where no mesh was picked.\r\n */\r\n public async boxPickAsync(x1: number, y1: number, x2: number, y2: number, disposeWhenDone = false): Promise<Nullable<IGPUMultiPickingInfo>> {\r\n if (this._pickingInProgress) {\r\n return null;\r\n }\r\n\r\n if (!this._pickableMeshes || this._pickableMeshes.length === 0) {\r\n return null;\r\n }\r\n\r\n this._pickingInProgress = true;\r\n\r\n const { rttSizeW, rttSizeH, devicePixelRatio } = this._getRenderInfo();\r\n\r\n const { x: adjustedX1, y: adjustedY1 } = this._prepareForPicking(x1, y1, devicePixelRatio);\r\n const { x: adjustedX2, y: adjustedY2 } = this._prepareForPicking(x2, y2, devicePixelRatio);\r\n\r\n const minX = Math.max(Math.min(adjustedX1, adjustedX2), 0);\r\n const maxX = Math.min(Math.max(adjustedX1, adjustedX2), rttSizeW - 1);\r\n const minY = Math.max(Math.min(adjustedY1, adjustedY2), 0);\r\n const maxY = Math.min(Math.max(adjustedY1, adjustedY2), rttSizeH - 1);\r\n\r\n if (minX >= rttSizeW || minY >= rttSizeH || maxX < 0 || maxY < 0) {\r\n this._pickingInProgress = false;\r\n return null;\r\n }\r\n\r\n const w = Math.max(maxX - minX, 1);\r\n const h = Math.max(maxY - minY, 1);\r\n const partialCutH = rttSizeH - maxY - 1;\r\n\r\n this._preparePickingBuffer(this._engine!, rttSizeW, rttSizeH, minX, partialCutH, w, h);\r\n\r\n await this._waitForPickingMaterialsReadyAsync();\r\n\r\n return await this._executeBoxPickingAsync(minX, partialCutH, w, h, disposeWhenDone);\r\n }\r\n\r\n private _getRenderInfo(): { rttSizeW: number; rttSizeH: number; devicePixelRatio: number } {\r\n const engine = this._cachedScene!.getEngine();\r\n const rttSizeW = engine.getRenderWidth();\r\n const rttSizeH = engine.getRenderHeight();\r\n const devicePixelRatio = 1 / engine._hardwareScalingLevel;\r\n\r\n return {\r\n rttSizeW,\r\n rttSizeH,\r\n devicePixelRatio,\r\n };\r\n }\r\n\r\n private _prepareForPicking(x: number, y: number, devicePixelRatio: number): IVector2Like {\r\n return { x: (devicePixelRatio * x) >> 0, y: (devicePixelRatio * y) >> 0 };\r\n }\r\n\r\n private _preparePickingBuffer(engine: AbstractEngine, rttSizeW: number, rttSizeH: number, x: number, y: number, w = 1, h = 1): void {\r\n this._meshRenderingCount = 0;\r\n\r\n const requiredBufferSize = engine.isWebGPU ? (4 * w * h + 255) & ~255 : 4 * w * h;\r\n if (!this._readbuffer || this._readbuffer.length < requiredBufferSize) {\r\n this._readbuffer = new Uint8Array(requiredBufferSize);\r\n }\r\n\r\n // Do we need to rebuild the RTT?\r\n const size = this._pickingTexture!.getSize();\r\n if (size.width !== rttSizeW || size.height !== rttSizeH) {\r\n this._createRenderTarget(this._cachedScene!, rttSizeW, rttSizeH);\r\n this._updateRenderList();\r\n }\r\n\r\n this._pickingTexture!.clearColor = new Color4(0, 0, 0, 0);\r\n\r\n this._pickingTexture!.onBeforeRender = (): void => {\r\n this._enableScissor(x, y, w, h);\r\n };\r\n\r\n this._pickingTextureAfterRenderObserver?.remove();\r\n this._pickingTextureAfterRenderObserver = this._pickingTexture!.onAfterRenderObservable.add(() => {\r\n this._disableScissor();\r\n });\r\n\r\n this._cachedScene!.customRenderTargets.push(this._pickingTexture!);\r\n this._renderPickingTexture = true;\r\n }\r\n\r\n // pick one pixel\r\n private async _executePickingAsync(x: number, y: number, disposeWhenDone: boolean): Promise<Nullable<IGPUPickingInfo>> {\r\n return await new Promise((resolve, reject) => {\r\n if (!this._pickingTexture) {\r\n this._pickingInProgress = false;\r\n reject(new Error(\"Picking texture not created\"));\r\n return;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n this._pickingTexture.onAfterRender = async (): Promise<void> => {\r\n if (this._checkRenderStatus()) {\r\n this._pickingTexture!.onAfterRender = null as any;\r\n let pickedMesh: Nullable<AbstractMesh> = null;\r\n let thinInstanceIndex: number | undefined = undefined;\r\n\r\n // Remove from the active RTTs\r\n const index = this._cachedScene!.customRenderTargets.indexOf(this._pickingTexture!);\r\n if (index > -1) {\r\n this._cachedScene!.customRenderTargets.splice(index, 1);\r\n this._renderPickingTexture = false;\r\n }\r\n\r\n // Do the actual picking\r\n if (await this._readTexturePixelsAsync(x, y)) {\r\n const colorId = this._getColorIdFromReadBuffer(0);\r\n\r\n // Thin?\r\n if (this._thinIdMap[colorId]) {\r\n pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n } else {\r\n pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n }\r\n }\r\n\r\n if (disposeWhenDone) {\r\n this.dispose();\r\n }\r\n\r\n this._pickingInProgress = false;\r\n if (pickedMesh) {\r\n resolve({ mesh: pickedMesh, thinInstanceIndex: thinInstanceIndex });\r\n } else {\r\n resolve(null);\r\n }\r\n }\r\n };\r\n });\r\n }\r\n\r\n // pick multiple pixels\r\n private async _executeMultiPickingAsync(\r\n xy: IVector2Like[],\r\n minX: number,\r\n maxY: number,\r\n rttSizeH: number,\r\n w: number,\r\n h: number,\r\n disposeWhenDone: boolean\r\n ): Promise<Nullable<IGPUMultiPickingInfo>> {\r\n return await new Promise((resolve, reject) => {\r\n if (!this._pickingTexture) {\r\n this._pickingInProgress = false;\r\n reject(new Error(\"Picking texture not created\"));\r\n return;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n this._pickingTexture.onAfterRender = async (): Promise<void> => {\r\n if (this._checkRenderStatus()) {\r\n this._pickingTexture!.onAfterRender = null as any;\r\n const pickedMeshes: Nullable<AbstractMesh>[] = [];\r\n const thinInstanceIndexes: number[] = [];\r\n\r\n if (await this._readTexturePixelsAsync(minX, rttSizeH - maxY - 1, w, h)) {\r\n for (let i = 0; i < xy.length; i++) {\r\n const { pickedMesh, thinInstanceIndex } = this._getMeshFromMultiplePoints(xy[i].x, xy[i].y, minX, maxY, w);\r\n pickedMeshes.push(pickedMesh);\r\n thinInstanceIndexes.push(thinInstanceIndex ?? 0);\r\n }\r\n }\r\n\r\n if (disposeWhenDone) {\r\n this.dispose();\r\n }\r\n\r\n this._pickingInProgress = false;\r\n resolve({ meshes: pickedMeshes, thinInstanceIndexes: thinInstanceIndexes });\r\n }\r\n };\r\n });\r\n }\r\n\r\n // pick box area\r\n private async _executeBoxPickingAsync(x: number, y: number, w: number, h: number, disposeWhenDone: boolean): Promise<IGPUMultiPickingInfo> {\r\n return await new Promise((resolve, reject) => {\r\n if (!this._pickingTexture) {\r\n this._pickingInProgress = false;\r\n reject(new Error(\"Picking texture not created\"));\r\n return;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n this._pickingTexture.onAfterRender = async (): Promise<void> => {\r\n if (this._checkRenderStatus()) {\r\n this._pickingTexture!.onAfterRender = null as any;\r\n const pickedMeshes: Nullable<AbstractMesh>[] = [];\r\n const thinInstanceIndexes: number[] = [];\r\n\r\n if (await this._readTexturePixelsAsync(x, y, w, h)) {\r\n for (let offsetY = 0; offsetY < h; ++offsetY) {\r\n for (let offsetX = 0; offsetX < w; ++offsetX) {\r\n const colorId = this._getColorIdFromReadBuffer((offsetY * w + offsetX) * 4);\r\n if (colorId > 0) {\r\n // Thin?\r\n if (this._thinIdMap[colorId]) {\r\n const pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n const thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n pickedMeshes.push(pickedMesh);\r\n thinInstanceIndexes.push(thinInstanceIndex);\r\n } else {\r\n const pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n pickedMeshes.push(pickedMesh);\r\n thinInstanceIndexes.push(0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (disposeWhenDone) {\r\n this.dispose();\r\n }\r\n\r\n this._pickingInProgress = false;\r\n resolve({ meshes: pickedMeshes, thinInstanceIndexes: thinInstanceIndexes });\r\n }\r\n };\r\n });\r\n }\r\n\r\n private _enableScissor(x: number, y: number, w = 1, h = 1): void {\r\n if ((this._engine as WebGPUEngine | Engine).enableScissor) {\r\n (this._engine as WebGPUEngine | Engine).enableScissor(x, y, w, h);\r\n }\r\n }\r\n private _disableScissor(): void {\r\n if ((this._engine as WebGPUEngine | Engine).disableScissor) {\r\n (this._engine as WebGPUEngine | Engine).disableScissor();\r\n }\r\n }\r\n\r\n /**\r\n * @returns true if rendering if the picking texture has finished, otherwise false\r\n */\r\n private _checkRenderStatus(): boolean {\r\n const wasSuccessful = this._meshRenderingCount > 0;\r\n if (wasSuccessful) {\r\n // Remove from the active RTTs\r\n const index = this._cachedScene!.customRenderTargets.indexOf(this._pickingTexture!);\r\n if (index > -1) {\r\n this._cachedScene!.customRenderTargets.splice(index, 1);\r\n this._renderPickingTexture = false;\r\n }\r\n return true;\r\n }\r\n\r\n this._meshRenderingCount = 0;\r\n return false; // Wait for shaders to be ready\r\n }\r\n\r\n /**\r\n * Polls the picking material variant for every mesh in the render list until every\r\n * variant is ready. Picking materials use parallel shader compilation, and a single\r\n * ShaderMaterial may produce different effect variants per mesh (instances, thin\r\n * instances, vertex colors, ...). If we render the picking texture before all variants\r\n * are compiled, the renderer silently skips meshes whose effect is not yet ready, which\r\n * can leave the click pixel cleared (0,0,0,0) and cause pickAsync to incorrectly return\r\n * null. Once compiled, effects are cached by define string in the engine, so this\r\n * polling only blocks on the very first pick (or whenever the render list changes to\r\n * include meshes with new define combinations).\r\n */\r\n private async _waitForPickingMaterialsReadyAsync(): Promise<void> {\r\n const renderList = this._pickingTexture?.renderList;\r\n if (!renderList || renderList.length === 0) {\r\n return;\r\n }\r\n\r\n // Cap the number of polling attempts to avoid hanging forever if a shader fails to compile.\r\n const maxAttempts = 200;\r\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\r\n let allReady = true;\r\n // Iterate every mesh (do not break early): each isReady call kicks off compilation\r\n // of that mesh's effect variant if not yet started, so visiting them all on the first\r\n // attempt lets the compiles run in parallel (KHR_parallel_shader_compile) instead of\r\n // being serialized one variant per render frame.\r\n for (let i = 0; i < renderList.length; i++) {\r\n const mesh = renderList[i];\r\n const material = this._meshMaterialMap.get(mesh);\r\n // Match the canonical \"uses instanced shader variant\" check used elsewhere in this file\r\n // (see addPickingList) — InstancedMesh entries report isAnInstance=true while\r\n // hasInstances=false, so omitting isAnInstance would validate the wrong shader variant.\r\n const useInstances = mesh.hasInstances || mesh.isAnInstance || mesh.hasThinInstances;\r\n if (material && !material.isReady(mesh, useInstances)) {\r\n allReady = false;\r\n }\r\n }\r\n if (allReady) {\r\n return;\r\n }\r\n // Wait for the next scene render before re-checking. Effect compilation status\r\n // (especially with KHR_parallel_shader_compile) is typically observed between\r\n // frames, so tying the poll to the render loop is more efficient than a fixed timer.\r\n // eslint-disable-next-line no-await-in-loop\r\n await new Promise<void>((resolve) => {\r\n this._cachedScene!.onAfterRenderObservable.addOnce(() => resolve());\r\n });\r\n }\r\n\r\n Logger.Warn(`GPUPicker: gave up waiting for picking materials to compile after ${maxAttempts} attempts; picking results may be incorrect.`);\r\n }\r\n\r\n private _getMeshFromMultiplePoints(x: number, y: number, minX: number, maxY: number, w: number): { pickedMesh: Nullable<AbstractMesh>; thinInstanceIndex: number | undefined } {\r\n let offsetX = (x - minX - 1) * 4;\r\n let offsetY = (maxY - y - 1) * w * 4;\r\n\r\n offsetX = Math.max(offsetX, 0);\r\n offsetY = Math.max(offsetY, 0);\r\n\r\n const colorId = this._getColorIdFromReadBuffer(offsetX + offsetY);\r\n\r\n let pickedMesh: Nullable<AbstractMesh> = null;\r\n let thinInstanceIndex: number | undefined;\r\n\r\n if (colorId > 0) {\r\n if (this._thinIdMap[colorId]) {\r\n pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n } else {\r\n pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n }\r\n }\r\n\r\n return { pickedMesh, thinInstanceIndex };\r\n }\r\n\r\n /**\r\n * Updates the render list with the current pickable meshes.\r\n */\r\n private _updateRenderList(): void {\r\n this._pickingTexture!.renderList = [];\r\n for (const mesh of this._pickableMeshes) {\r\n const className = mesh.getClassName();\r\n // Part proxies don't render directly - their compound renders for them\r\n if (className === \"GaussianSplattingPartProxyMesh\") {\r\n continue;\r\n }\r\n this._pickingTexture!.setMaterialForRendering(mesh, this._meshMaterialMap.get(mesh));\r\n this._pickingTexture!.renderList.push(mesh);\r\n }\r\n // Also add compound GS meshes that render on behalf of part proxies\r\n for (const mesh of this._gsCompoundRenderMeshes) {\r\n this._pickingTexture!.setMaterialForRendering(mesh, this._meshMaterialMap.get(mesh));\r\n this._pickingTexture!.renderList.push(mesh);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a GaussianSplattingMaterial configured for GPU picking by attaching\r\n * a GaussianSplattingGpuPickingMaterialPlugin. The plugin injects picking ID\r\n * encoding into the existing Gaussian Splatting shaders via material plugin hooks.\r\n * @param scene The scene\r\n * @param gsMesh The Gaussian Splatting mesh (used to set the source mesh on the material)\r\n * @returns A GaussianSplattingMaterial with the picking plugin attached\r\n */\r\n private _createGaussianSplattingPickingMaterial(scene: Scene, gsMesh: AbstractMesh): GaussianSplattingMaterial {\r\n const gsPickingMaterial = new GaussianSplattingMaterial(\"gaussianSplattingGpuPicking\", scene);\r\n gsPickingMaterial.setSourceMesh(gsMesh as any);\r\n gsPickingMaterial.needAlphaBlending = () => false;\r\n gsPickingMaterial.backFaceCulling = false;\r\n\r\n // Attach the GPU picking plugin\r\n new GaussianSplattingGpuPickingMaterialPlugin(gsPickingMaterial);\r\n\r\n return gsPickingMaterial;\r\n }\r\n\r\n private async _readTexturePixelsAsync(x: number, y: number, w = 1, h = 1): Promise<boolean> {\r\n if (!this._cachedScene || !this._pickingTexture?._texture) {\r\n return false;\r\n }\r\n const engine = this._cachedScene.getEngine();\r\n await engine._readTexturePixels(this._pickingTexture._texture, w, h, -1, 0, this._readbuffer, true, true, x, y);\r\n\r\n return true;\r\n }\r\n\r\n /** Release the resources */\r\n public dispose(): void {\r\n this.setPickingList(null);\r\n this._cachedScene = null;\r\n\r\n // Cleaning up\r\n this._pickingTexture?.dispose();\r\n this._pickingTexture = null;\r\n this._clearPickingMaterials();\r\n this._sceneBeforeRenderObserver?.remove();\r\n this._sceneBeforeRenderObserver = null;\r\n }\r\n}\r\n"]}
@@ -35,13 +35,20 @@ export class FlowGraphMeshPickEventBlock extends FlowGraphEventBlock {
35
35
  // returning true here to continue the propagation of the pointer event to the rest of the blocks
36
36
  return true;
37
37
  }
38
- // check if the mesh is the picked mesh or a descendant
39
38
  const mesh = this._getReferencedMesh(context);
40
- if (mesh && pickedInfo.pickInfo?.pickedMesh && (pickedInfo.pickInfo?.pickedMesh === mesh || _IsDescendantOf(pickedInfo.pickInfo?.pickedMesh, mesh))) {
39
+ const pickedMesh = pickedInfo.pickInfo?.pickedMesh;
40
+ // When no target mesh is configured, fire for any picked mesh.
41
+ // When a target is configured, require an exact match or descendant match.
42
+ // Match by reference first, then by descendant, then by stable name/id as a
43
+ // fallback for scene reloads where the object reference changes but the mesh
44
+ // identity (name) is preserved (uniqueId increments monotonically and is NOT
45
+ // stable across reloads).
46
+ const meshMatches = !mesh ? !!pickedMesh : !!(pickedMesh && (pickedMesh === mesh || _IsDescendantOf(pickedMesh, mesh) || pickedMesh.name === mesh.name));
47
+ if (meshMatches && pickedMesh) {
41
48
  this.pointerId.setValue(pickedInfo.event.pointerId, context);
42
49
  this.pickOrigin.setValue(pickedInfo.pickInfo.ray?.origin, context);
43
50
  this.pickedPoint.setValue(pickedInfo.pickInfo.pickedPoint, context);
44
- this.pickedMesh.setValue(pickedInfo.pickInfo.pickedMesh, context);
51
+ this.pickedMesh.setValue(pickedMesh, context);
45
52
  this._execute(context);
46
53
  // stop the propagation if the configuration says so
47
54
  return !this.config?.stopPropagation;
@@ -1 +1 @@
1
- {"version":3,"file":"flowGraphMeshPickEventBlock.js","sourceRoot":"","sources":["../../../../../../dev/core/src/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.ts"],"names":[],"mappings":"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","sourcesContent":["import { type AbstractMesh } from \"../../../Meshes/abstractMesh\";\r\nimport { FlowGraphEventBlock } from \"../../flowGraphEventBlock\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../../Events/pointerEvents\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\nimport { _IsDescendantOf } from \"../../utils\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection\";\r\nimport { RichTypeAny, RichTypeNumber, RichTypeVector3 } from \"core/FlowGraph/flowGraphRichTypes\";\r\nimport { type Vector3 } from \"core/Maths/math.vector\";\r\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\r\n/**\r\n * Configuration for the mesh pick event block.\r\n */\r\nexport interface IFlowGraphMeshPickEventBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n /**\r\n * Should this mesh block propagation of the event.\r\n */\r\n stopPropagation?: boolean;\r\n\r\n /**\r\n * The mesh to listen to. Can also be set by the asset input.\r\n */\r\n targetMesh?: AbstractMesh;\r\n}\r\n/**\r\n * A block that activates when a mesh is picked.\r\n */\r\nexport class FlowGraphMeshPickEventBlock extends FlowGraphEventBlock {\r\n /**\r\n * Input connection: The mesh to listen to.\r\n */\r\n public readonly asset: FlowGraphDataConnection<AbstractMesh>;\r\n\r\n /**\r\n * Output connection: The picked point.\r\n */\r\n public readonly pickedPoint: FlowGraphDataConnection<Vector3>;\r\n\r\n /**\r\n * Output connection: The picked origin.\r\n */\r\n public readonly pickOrigin: FlowGraphDataConnection<Vector3>;\r\n\r\n /**\r\n * Output connection: The pointer id.\r\n */\r\n public readonly pointerId: FlowGraphDataConnection<number>;\r\n\r\n /**\r\n * Output connection: The picked mesh. Possibly NOT the same as the asset (could be a descendant).\r\n */\r\n public readonly pickedMesh: FlowGraphDataConnection<AbstractMesh>;\r\n\r\n /**\r\n * Input connection: The type of the pointer event.\r\n */\r\n public readonly pointerType: FlowGraphDataConnection<PointerEventTypes>;\r\n\r\n /**\r\n * the type of the event this block reacts to\r\n */\r\n public override readonly type: FlowGraphEventType = FlowGraphEventType.MeshPick;\r\n\r\n public constructor(\r\n /**\r\n * the configuration of the block\r\n */\r\n public override config?: IFlowGraphMeshPickEventBlockConfiguration\r\n ) {\r\n super(config);\r\n this.asset = this.registerDataInput(\"asset\", RichTypeAny, config?.targetMesh);\r\n this.pickedPoint = this.registerDataOutput(\"pickedPoint\", RichTypeVector3);\r\n this.pickOrigin = this.registerDataOutput(\"pickOrigin\", RichTypeVector3);\r\n this.pointerId = this.registerDataOutput(\"pointerId\", RichTypeNumber);\r\n this.pickedMesh = this.registerDataOutput(\"pickedMesh\", RichTypeAny);\r\n this.pointerType = this.registerDataInput(\"pointerType\", RichTypeAny, PointerEventTypes.POINTERPICK);\r\n }\r\n\r\n public _getReferencedMesh(context: FlowGraphContext): AbstractMesh {\r\n return this.asset.getValue(context);\r\n }\r\n\r\n public override _executeEvent(context: FlowGraphContext, pickedInfo: PointerInfo): boolean {\r\n // get the pointer type\r\n const pointerType = this.pointerType.getValue(context);\r\n if (pointerType !== pickedInfo.type) {\r\n // returning true here to continue the propagation of the pointer event to the rest of the blocks\r\n return true;\r\n }\r\n // check if the mesh is the picked mesh or a descendant\r\n const mesh = this._getReferencedMesh(context);\r\n if (mesh && pickedInfo.pickInfo?.pickedMesh && (pickedInfo.pickInfo?.pickedMesh === mesh || _IsDescendantOf(pickedInfo.pickInfo?.pickedMesh, mesh))) {\r\n this.pointerId.setValue((pickedInfo.event as PointerEvent).pointerId, context);\r\n this.pickOrigin.setValue(pickedInfo.pickInfo.ray?.origin!, context);\r\n this.pickedPoint.setValue(pickedInfo.pickInfo.pickedPoint!, context);\r\n this.pickedMesh.setValue(pickedInfo.pickInfo.pickedMesh, context);\r\n this._execute(context);\r\n // stop the propagation if the configuration says so\r\n return !this.config?.stopPropagation;\r\n } else {\r\n // reset the outputs\r\n this.pointerId.resetToDefaultValue(context);\r\n this.pickOrigin.resetToDefaultValue(context);\r\n this.pickedPoint.resetToDefaultValue(context);\r\n this.pickedMesh.resetToDefaultValue(context);\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public override _preparePendingTasks(_context: FlowGraphContext): void {\r\n // no-op\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public override _cancelPendingTasks(_context: FlowGraphContext): void {\r\n // no-op\r\n }\r\n\r\n /**\r\n * @returns class name of the block.\r\n */\r\n public override getClassName(): string {\r\n return FlowGraphBlockNames.MeshPickEvent;\r\n }\r\n}\r\nRegisterClass(FlowGraphBlockNames.MeshPickEvent, FlowGraphMeshPickEventBlock);\r\n"]}
1
+ {"version":3,"file":"flowGraphMeshPickEventBlock.js","sourceRoot":"","sources":["../../../../../../dev/core/src/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.ts"],"names":[],"mappings":"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","sourcesContent":["import { type AbstractMesh } from \"../../../Meshes/abstractMesh\";\r\nimport { FlowGraphEventBlock } from \"../../flowGraphEventBlock\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../../Events/pointerEvents\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\nimport { _IsDescendantOf } from \"../../utils\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection\";\r\nimport { RichTypeAny, RichTypeNumber, RichTypeVector3 } from \"core/FlowGraph/flowGraphRichTypes\";\r\nimport { type Vector3 } from \"core/Maths/math.vector\";\r\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\r\n/**\r\n * Configuration for the mesh pick event block.\r\n */\r\nexport interface IFlowGraphMeshPickEventBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n /**\r\n * Should this mesh block propagation of the event.\r\n */\r\n stopPropagation?: boolean;\r\n\r\n /**\r\n * The mesh to listen to. Can also be set by the asset input.\r\n */\r\n targetMesh?: AbstractMesh;\r\n}\r\n/**\r\n * A block that activates when a mesh is picked.\r\n */\r\nexport class FlowGraphMeshPickEventBlock extends FlowGraphEventBlock {\r\n /**\r\n * Input connection: The mesh to listen to.\r\n */\r\n public readonly asset: FlowGraphDataConnection<AbstractMesh>;\r\n\r\n /**\r\n * Output connection: The picked point.\r\n */\r\n public readonly pickedPoint: FlowGraphDataConnection<Vector3>;\r\n\r\n /**\r\n * Output connection: The picked origin.\r\n */\r\n public readonly pickOrigin: FlowGraphDataConnection<Vector3>;\r\n\r\n /**\r\n * Output connection: The pointer id.\r\n */\r\n public readonly pointerId: FlowGraphDataConnection<number>;\r\n\r\n /**\r\n * Output connection: The picked mesh. Possibly NOT the same as the asset (could be a descendant).\r\n */\r\n public readonly pickedMesh: FlowGraphDataConnection<AbstractMesh>;\r\n\r\n /**\r\n * Input connection: The type of the pointer event.\r\n */\r\n public readonly pointerType: FlowGraphDataConnection<PointerEventTypes>;\r\n\r\n /**\r\n * the type of the event this block reacts to\r\n */\r\n public override readonly type: FlowGraphEventType = FlowGraphEventType.MeshPick;\r\n\r\n public constructor(\r\n /**\r\n * the configuration of the block\r\n */\r\n public override config?: IFlowGraphMeshPickEventBlockConfiguration\r\n ) {\r\n super(config);\r\n this.asset = this.registerDataInput(\"asset\", RichTypeAny, config?.targetMesh);\r\n this.pickedPoint = this.registerDataOutput(\"pickedPoint\", RichTypeVector3);\r\n this.pickOrigin = this.registerDataOutput(\"pickOrigin\", RichTypeVector3);\r\n this.pointerId = this.registerDataOutput(\"pointerId\", RichTypeNumber);\r\n this.pickedMesh = this.registerDataOutput(\"pickedMesh\", RichTypeAny);\r\n this.pointerType = this.registerDataInput(\"pointerType\", RichTypeAny, PointerEventTypes.POINTERPICK);\r\n }\r\n\r\n public _getReferencedMesh(context: FlowGraphContext): AbstractMesh {\r\n return this.asset.getValue(context);\r\n }\r\n\r\n public override _executeEvent(context: FlowGraphContext, pickedInfo: PointerInfo): boolean {\r\n // get the pointer type\r\n const pointerType = this.pointerType.getValue(context);\r\n if (pointerType !== pickedInfo.type) {\r\n // returning true here to continue the propagation of the pointer event to the rest of the blocks\r\n return true;\r\n }\r\n const mesh = this._getReferencedMesh(context);\r\n const pickedMesh = pickedInfo.pickInfo?.pickedMesh;\r\n // When no target mesh is configured, fire for any picked mesh.\r\n // When a target is configured, require an exact match or descendant match.\r\n // Match by reference first, then by descendant, then by stable name/id as a\r\n // fallback for scene reloads where the object reference changes but the mesh\r\n // identity (name) is preserved (uniqueId increments monotonically and is NOT\r\n // stable across reloads).\r\n const meshMatches = !mesh ? !!pickedMesh : !!(pickedMesh && (pickedMesh === mesh || _IsDescendantOf(pickedMesh, mesh) || pickedMesh.name === mesh.name));\r\n if (meshMatches && pickedMesh) {\r\n this.pointerId.setValue((pickedInfo.event as PointerEvent).pointerId, context);\r\n this.pickOrigin.setValue(pickedInfo.pickInfo!.ray?.origin!, context);\r\n this.pickedPoint.setValue(pickedInfo.pickInfo!.pickedPoint!, context);\r\n this.pickedMesh.setValue(pickedMesh, context);\r\n this._execute(context);\r\n // stop the propagation if the configuration says so\r\n return !this.config?.stopPropagation;\r\n } else {\r\n // reset the outputs\r\n this.pointerId.resetToDefaultValue(context);\r\n this.pickOrigin.resetToDefaultValue(context);\r\n this.pickedPoint.resetToDefaultValue(context);\r\n this.pickedMesh.resetToDefaultValue(context);\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public override _preparePendingTasks(_context: FlowGraphContext): void {\r\n // no-op\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public override _cancelPendingTasks(_context: FlowGraphContext): void {\r\n // no-op\r\n }\r\n\r\n /**\r\n * @returns class name of the block.\r\n */\r\n public override getClassName(): string {\r\n return FlowGraphBlockNames.MeshPickEvent;\r\n }\r\n}\r\nRegisterClass(FlowGraphBlockNames.MeshPickEvent, FlowGraphMeshPickEventBlock);\r\n"]}
@@ -40,6 +40,7 @@ export declare class FlowGraphConsoleLogBlock extends FlowGraphExecutionBlockWit
40
40
  * @returns class name of the block.
41
41
  */
42
42
  getClassName(): string;
43
+ private _serializeValue;
43
44
  private _getMessageValue;
44
45
  private _getTemplateMatches;
45
46
  }
@@ -45,20 +45,53 @@ export class FlowGraphConsoleLogBlock extends FlowGraphExecutionBlockWithOutSign
45
45
  getClassName() {
46
46
  return "FlowGraphConsoleLogBlock" /* FlowGraphBlockNames.ConsoleLog */;
47
47
  }
48
+ _serializeValue(value) {
49
+ if (value === null || value === undefined) {
50
+ return String(value);
51
+ }
52
+ if (typeof value === "object") {
53
+ // Prefer the object's own toString() (e.g. Vector3 → "{X:1 Y:2 Z:3}").
54
+ // Only fall back to JSON.stringify when toString() is the unhelpful default.
55
+ const str = value.toString();
56
+ if (str === "[object Object]") {
57
+ try {
58
+ return JSON.stringify(value);
59
+ }
60
+ catch {
61
+ return str;
62
+ }
63
+ }
64
+ return str;
65
+ }
66
+ return String(value);
67
+ }
48
68
  _getMessageValue(context) {
49
69
  if (this.config?.messageTemplate) {
50
70
  let template = this.config.messageTemplate;
51
71
  const matches = this._getTemplateMatches(template);
72
+ // If the message input is an object, use its keys as the primary
73
+ // source for template placeholders, falling back to named data inputs.
74
+ const messageValue = this.message.getValue(context);
75
+ const messageObj = messageValue !== null && messageValue !== undefined && typeof messageValue === "object" ? messageValue : null;
52
76
  for (const match of matches) {
53
- const value = this.getDataInput(match)?.getValue(context);
77
+ let value;
78
+ if (messageObj !== null && match in messageObj) {
79
+ value = messageObj[match];
80
+ }
81
+ else {
82
+ value = this.getDataInput(match)?.getValue(context);
83
+ }
54
84
  if (value !== undefined) {
55
- // replace all
56
- template = template.replace(new RegExp(`\\{${match}\\}`, "g"), value.toString());
85
+ // Escape regex metacharacters in the placeholder name before building the pattern.
86
+ const escapedMatch = match.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
87
+ template = template.replace(new RegExp(`\\{${escapedMatch}\\}`, "g"), this._serializeValue(value));
57
88
  }
58
89
  }
59
90
  return template;
60
91
  }
61
92
  else {
93
+ // No template — pass the raw value directly so Logger receives the original
94
+ // object (e.g. Vector3) rather than a stringified representation.
62
95
  return this.message.getValue(context);
63
96
  }
64
97
  }