Skip to content

SelectionOutlineLayer: Fix clearSelection crash with instanced meshes#18235

Merged
sebavan merged 5 commits intoBabylonJS:masterfrom
marns:fix-instanced-outlines
Apr 8, 2026
Merged

SelectionOutlineLayer: Fix clearSelection crash with instanced meshes#18235
sebavan merged 5 commits intoBabylonJS:masterfrom
marns:fix-instanced-outlines

Conversation

@marns
Copy link
Copy Markdown
Contributor

@marns marns commented Apr 4, 2026

Summary

  • addSelection calls registerInstancedBuffer('instanceSelectionId') on the source mesh, but only adds the instance to _selection
  • clearSelection iterates _selection — cleans up the instance but never touches the source
  • The source retains a stale instanceSelectionId key in instancedBuffers with deleted backing storage
  • On the next render, _processInstancedBuffers iterates that key and crashes: Cannot read properties of undefined (reading 'instanceSelectionId')

Fix

  • Track source meshes that had registerInstancedBuffer called in _instancedBufferSources
  • Clean them up in clearSelection

Repro

Select a node whose descendants include instanced meshes (e.g. multiple GLB instances from the same container), then trigger a re-selection. The outline layer's clearSelection + addSelection cycle leaves stale state on the source mesh.

Test plan

  • Added unit test that directly calls _processInstancedBuffers to reproduce the crash
  • All 2402 existing tests pass

@Popov72
Copy link
Copy Markdown
Contributor

Popov72 commented Apr 5, 2026

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 5, 2026

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

Copy link
Copy Markdown
Contributor

@Popov72 Popov72 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bug diagnosis is solid and the fix direction (tracking source meshes in a Set) is correct. However there are three issues that should be addressed before merging.

Comment thread packages/dev/core/src/Layers/thinSelectionOutlineLayer.ts
Comment thread packages/dev/core/src/Layers/thinSelectionOutlineLayer.ts
@marns marns requested a review from Popov72 April 5, 2026 22:54
@Popov72
Copy link
Copy Markdown
Contributor

Popov72 commented Apr 6, 2026

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 6, 2026

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

Copy link
Copy Markdown
Contributor

@Popov72 Popov72 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All three concerns from the previous review have been addressed well. The shared cleanup method is clean, the tests now exercise the real API, and _disposeMesh handles the tracking Set.

One minor edge case to be aware of (non-blocking): if multiple instances from the same source are selected and one is disposed, _disposeMesh removes the source from _instancedBufferSources immediately. When clearSelection is later called for the remaining instances, the source won't be cleaned up because it's no longer in the Set. This leaves stale (but valid) instanceSelectionId data on the source — not a crash (the storage data is still intact), but a GPU resource leak until the next addSelection or mesh disposal. A possible refinement would be to only remove the source from the Set when no more selected instances from that source remain, but this is unlikely to matter in practice.

Comment thread packages/dev/core/src/Layers/thinSelectionOutlineLayer.ts
@Popov72
Copy link
Copy Markdown
Contributor

Popov72 commented Apr 7, 2026

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 7, 2026

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

Copy link
Copy Markdown
Contributor

@Popov72 Popov72 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The edge case is now properly handled -- _disposeMesh only removes the source from tracking when no other selected instance shares it, and the new test validates this scenario. LGTM.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 7, 2026

Snapshot stored with reference name:
refs/pull/18235/merge

Test environment:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18235/merge/index.html

To test a playground add it to the URL, for example:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18235/merge/index.html#WGZLGJ#4600

Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves):

https://playground.babylonjs.com/?snapshot=refs/pull/18235/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18235/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18235/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18235/merge

To test the snapshot in the playground with a playground ID add it after the snapshot query string:

https://playground.babylonjs.com/?snapshot=refs/pull/18235/merge#BCU1XR#0

If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 7, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 7, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 7, 2026

@sebavan
Copy link
Copy Markdown
Member

sebavan commented Apr 8, 2026

@marns any chance you can update and merge master back in ?

…lines

# Conflicts:
#	packages/dev/core/src/Layers/thinSelectionOutlineLayer.ts
@sebavan
Copy link
Copy Markdown
Member

sebavan commented Apr 8, 2026

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@sebavan sebavan enabled auto-merge (squash) April 8, 2026 17:43
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 8, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 8, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 8, 2026

@sebavan sebavan merged commit 21c8f71 into BabylonJS:master Apr 8, 2026
21 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants