From d63be7dd6227dad83c869db060f881d9a34cf2e0 Mon Sep 17 00:00:00 2001 From: duckietm Date: Fri, 3 Apr 2026 10:48:13 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=86=99=20=20more=20optimization=20mem?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camera/src/RoomCameraWidgetManager.ts | 7 +--- packages/room/src/RoomMessageHandler.ts | 6 +++ .../IsometricImageFurniVisualization.ts | 1 + packages/room/src/utils/RoomInstanceData.ts | 39 ++++++++++++++++++- packages/utils/src/TexturePool.ts | 13 ++++++- 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/packages/camera/src/RoomCameraWidgetManager.ts b/packages/camera/src/RoomCameraWidgetManager.ts index 85b7067..1d28a4c 100644 --- a/packages/camera/src/RoomCameraWidgetManager.ts +++ b/packages/camera/src/RoomCameraWidgetManager.ts @@ -117,12 +117,7 @@ export class RoomCameraWidgetManager implements IRoomCameraWidgetManager TextureUtils.writeToTexture(container, renderTexture); - const image = await TextureUtils.generateImage(renderTexture); - - container.destroy({ children: true }); - renderTexture.destroy(true); - - return image; + return await TextureUtils.generateImage(renderTexture); } public get effects(): Map diff --git a/packages/room/src/RoomMessageHandler.ts b/packages/room/src/RoomMessageHandler.ts index 706b3d8..b8a5b70 100644 --- a/packages/room/src/RoomMessageHandler.ts +++ b/packages/room/src/RoomMessageHandler.ts @@ -110,6 +110,12 @@ export class RoomMessageHandler this._latestEntryTileEvent = null; this._activeWiredUserMovements.clear(); this._activeRoomUserWalks.clear(); + + if(this._planeParser) + { + this._planeParser.dispose(); + this._planeParser = null; + } } public setRoomId(id: number): void diff --git a/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts b/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts index a5ee557..799fc68 100644 --- a/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts +++ b/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts @@ -105,6 +105,7 @@ export class IsometricImageFurniVisualization extends FurnitureAnimatedVisualiza const sprite = this.getSprite(layerId); if (sprite) { sprite.texture = this._thumbnailTexture; + sprite.offsetY -= 1; } } } diff --git a/packages/room/src/utils/RoomInstanceData.ts b/packages/room/src/utils/RoomInstanceData.ts index 37fd4cb..ab4a527 100644 --- a/packages/room/src/utils/RoomInstanceData.ts +++ b/packages/room/src/utils/RoomInstanceData.ts @@ -39,7 +39,44 @@ export class RoomInstanceData public dispose(): void { - return; + if(this._selectedObject) + { + this._selectedObject.dispose(); + this._selectedObject = null; + } + + if(this._placedObject) + { + this._placedObject.dispose(); + this._placedObject = null; + } + + if(this._furnitureStackingHeightMap) + { + this._furnitureStackingHeightMap.dispose(); + this._furnitureStackingHeightMap = null; + } + + if(this._tileObjectMap) + { + this._tileObjectMap.dispose(); + this._tileObjectMap = null; + } + + if(this._legacyGeometry) + { + this._legacyGeometry = null; + } + + if(this._roomCamera) + { + this._roomCamera = null; + } + + this._floorStack.clear(); + this._wallStack.clear(); + this._mouseButtonCursorOwners = []; + this._modelName = null; } public setModelName(name: string): void diff --git a/packages/utils/src/TexturePool.ts b/packages/utils/src/TexturePool.ts index 5e96234..701dc8b 100644 --- a/packages/utils/src/TexturePool.ts +++ b/packages/utils/src/TexturePool.ts @@ -3,7 +3,8 @@ import { Texture } from 'pixi.js'; export class TexturePool { - private static MAX_IDLE: number = 3600; + private static MAX_IDLE: number = 1800; + private static MAX_POOL_SIZE: number = 200; private _textures: { [index: string]: { [index: string]: Texture[] } } = {}; private _totalTextures: number = 0; @@ -51,6 +52,16 @@ export class TexturePool { if(!texture) return; + if(this._totalTextures >= TexturePool.MAX_POOL_SIZE) + { + //@ts-ignore + delete texture.source.hitMap; + + if(!texture.destroyed) texture.destroy(true); + + return; + } + if(!this._textures[texture.width]) this._textures[texture.width] = {}; if(!this._textures[texture.width][texture.height]) this._textures[texture.width][texture.height] = []; From 5b3c4ad0905e6b3138322b35377bacee85001563 Mon Sep 17 00:00:00 2001 From: duckietm Date: Fri, 3 Apr 2026 11:43:58 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=86=99=20Small=20updates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/avatar/src/AvatarImage.ts | 7 ++++ .../avatar/AvatarVisualization.ts | 35 +++++++++++-------- .../object/visualization/room/RoomPlane.ts | 13 ++++--- .../PlaneVisualizationAnimationLayer.ts | 1 + 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/packages/avatar/src/AvatarImage.ts b/packages/avatar/src/AvatarImage.ts index 4cc52cf..6f7e92b 100644 --- a/packages/avatar/src/AvatarImage.ts +++ b/packages/avatar/src/AvatarImage.ts @@ -293,6 +293,13 @@ export class AvatarImage implements IAvatarImage, IAvatarEffectListener clear: true }); + for(const child of container.children) + { + child.removeChildren(); + } + + container.destroy({ children: true }); + //@ts-ignore this._activeTexture.source.hitMap = null; diff --git a/packages/room/src/object/visualization/avatar/AvatarVisualization.ts b/packages/room/src/object/visualization/avatar/AvatarVisualization.ts index ff2323e..ff2cbf6 100644 --- a/packages/room/src/object/visualization/avatar/AvatarVisualization.ts +++ b/packages/room/src/object/visualization/avatar/AvatarVisualization.ts @@ -1101,14 +1101,19 @@ export class AvatarVisualization extends RoomObjectSpriteVisualization implement if(oppositeDirection !== currentDirection) { - const highlightEnabled = ((this.object.model.getValue(RoomObjectVariable.FIGURE_HIGHLIGHT_ENABLE) === 1) && (this.object.model.getValue(RoomObjectVariable.FIGURE_HIGHLIGHT) === 1)); - - this._avatarImage.setDirection(AvatarSetType.FULL, oppositeDirection); - - const renderedOpposite = (this._avatarImage.processAsTexture(AvatarSetType.FULL, highlightEnabled) || sprite.texture); - - if((this._reflectionOppositeDirection !== currentDirection) || (this._reflectionOppositeBaseTexture !== sprite.texture) || !this._reflectionOppositeTexture) + // Reuse the cached opposite texture if direction and base texture haven't changed + if(this._reflectionOppositeTexture && (this._reflectionOppositeDirection === currentDirection) && (this._reflectionOppositeBaseTexture === sprite.texture)) { + oppositeTexture = this._reflectionOppositeTexture; + } + else + { + const highlightEnabled = ((this.object.model.getValue(RoomObjectVariable.FIGURE_HIGHLIGHT_ENABLE) === 1) && (this.object.model.getValue(RoomObjectVariable.FIGURE_HIGHLIGHT) === 1)); + + this._avatarImage.setDirection(AvatarSetType.FULL, oppositeDirection); + + const renderedOpposite = (this._avatarImage.processAsTexture(AvatarSetType.FULL, highlightEnabled) || sprite.texture); + if(this._reflectionOppositeTexture) { this._reflectionOppositeTexture.destroy(true); @@ -1118,15 +1123,15 @@ export class AvatarVisualization extends RoomObjectSpriteVisualization implement this._reflectionOppositeTexture = this.cloneTexture(renderedOpposite); this._reflectionOppositeDirection = currentDirection; this._reflectionOppositeBaseTexture = sprite.texture; + + oppositeTexture = (this._reflectionOppositeTexture || renderedOpposite); + + // Restore the live avatar direction and refresh the current texture so + // movement updates do not keep showing the opposite-facing texture. + this._avatarImage.setDirection(AvatarSetType.FULL, currentDirection); + + sprite.texture = (this._avatarImage.processAsTexture(AvatarSetType.FULL, highlightEnabled) || sprite.texture); } - - oppositeTexture = (this._reflectionOppositeTexture || renderedOpposite); - - // Restore the live avatar direction and refresh the current texture so - // movement updates do not keep showing the opposite-facing texture. - this._avatarImage.setDirection(AvatarSetType.FULL, currentDirection); - - sprite.texture = (this._avatarImage.processAsTexture(AvatarSetType.FULL, highlightEnabled) || sprite.texture); } } diff --git a/packages/room/src/object/visualization/room/RoomPlane.ts b/packages/room/src/object/visualization/room/RoomPlane.ts index 3556447..116bdd4 100644 --- a/packages/room/src/object/visualization/room/RoomPlane.ts +++ b/packages/room/src/object/visualization/room/RoomPlane.ts @@ -741,6 +741,7 @@ export class RoomPlane implements IRoomPlane }); animationCanvas.destroy(true); + animContainer.destroy({ children: true }); } private renderLandscapeLayer(texture: Texture, tint: number, alignBottom: boolean): void @@ -798,7 +799,7 @@ export class RoomPlane implements IRoomPlane clear: false }); - layerSprite.destroy(); + layerContainer.destroy({ children: true }); } private renderBackgroundColor(): void @@ -826,7 +827,7 @@ export class RoomPlane implements IRoomPlane clear: true }); - colorGraphics.destroy(); + colorContainer.destroy({ children: true }); } private clearPlaneTexture(): void @@ -838,12 +839,16 @@ export class RoomPlane implements IRoomPlane if(canvasWidth <= 0 || canvasHeight <= 0) { + const emptyContainer = new Container(); + GetRenderer().render({ target: this._planeTexture, - container: new Container(), + container: emptyContainer, clear: true }); + emptyContainer.destroy(); + return; } @@ -863,7 +868,7 @@ export class RoomPlane implements IRoomPlane clear: true }); - colorGraphics.destroy(); + colorContainer.destroy({ children: true }); } private renderWindowReflections(): void diff --git a/packages/room/src/object/visualization/room/animated/PlaneVisualizationAnimationLayer.ts b/packages/room/src/object/visualization/room/animated/PlaneVisualizationAnimationLayer.ts index 169650e..aac9ee8 100644 --- a/packages/room/src/object/visualization/room/animated/PlaneVisualizationAnimationLayer.ts +++ b/packages/room/src/object/visualization/room/animated/PlaneVisualizationAnimationLayer.ts @@ -154,5 +154,6 @@ export class PlaneVisualizationAnimationLayer const sprite = new Sprite(item.bitmapData.texture); sprite.position.set(x, y); TextureUtils.writeToTexture(sprite, canvas, false); + sprite.destroy(); } }