@@ -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