Skip to content

Commit 330c718

Browse files
authored
Merge pull request #783 from goyalpalak18/fix/gpu-memory-leak-event-switching
fix(scene-manager): dispose GPU resources on event switch
2 parents 284e898 + ae6df4a commit 330c718

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

packages/phoenix-event-display/src/managers/three-manager/scene-manager.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,15 +458,81 @@ export class SceneManager {
458458

459459
/**
460460
* Clears event data of the scene.
461+
* Properly disposes of all GPU resources (geometries, materials, textures)
462+
* to prevent memory leaks during event switching.
461463
*/
462464
public clearEventData() {
463465
const eventData = this.getEventData();
464466
if (eventData != null) {
467+
this.disposeObject3D(eventData);
465468
this.scene.remove(eventData);
466469
}
467470
this.getEventData();
468471
}
469472

473+
/**
474+
* Recursively disposes of all GPU resources in an Object3D hierarchy.
475+
* @param object The Object3D to dispose.
476+
*/
477+
private disposeObject3D(object: Object3D) {
478+
object.traverse((child: Object3D) => {
479+
const mesh = child as Mesh | LineSegments | Line;
480+
481+
// Dispose geometry
482+
if (mesh.geometry) {
483+
mesh.geometry.dispose();
484+
}
485+
486+
// Dispose material(s)
487+
if (mesh.material) {
488+
const materials = Array.isArray(mesh.material)
489+
? mesh.material
490+
: [mesh.material];
491+
492+
for (const material of materials) {
493+
// Dispose any textures attached to the material
494+
if ((material as any).map) {
495+
(material as any).map.dispose();
496+
}
497+
if ((material as any).alphaMap) {
498+
(material as any).alphaMap.dispose();
499+
}
500+
if ((material as any).aoMap) {
501+
(material as any).aoMap.dispose();
502+
}
503+
if ((material as any).bumpMap) {
504+
(material as any).bumpMap.dispose();
505+
}
506+
if ((material as any).displacementMap) {
507+
(material as any).displacementMap.dispose();
508+
}
509+
if ((material as any).emissiveMap) {
510+
(material as any).emissiveMap.dispose();
511+
}
512+
if ((material as any).envMap) {
513+
(material as any).envMap.dispose();
514+
}
515+
if ((material as any).lightMap) {
516+
(material as any).lightMap.dispose();
517+
}
518+
if ((material as any).metalnessMap) {
519+
(material as any).metalnessMap.dispose();
520+
}
521+
if ((material as any).normalMap) {
522+
(material as any).normalMap.dispose();
523+
}
524+
if ((material as any).roughnessMap) {
525+
(material as any).roughnessMap.dispose();
526+
}
527+
if ((material as any).specularMap) {
528+
(material as any).specularMap.dispose();
529+
}
530+
material.dispose();
531+
}
532+
}
533+
});
534+
}
535+
470536
/** Returns a mesh representing the passed text. It will use this.textFont. */
471537
public getText(text: string, colour: Color): Mesh {
472538
const textGeometry = new TextGeometry(text, {

0 commit comments

Comments
 (0)