From d864fe30180457353f99d4738de9573f3aeb33c8 Mon Sep 17 00:00:00 2001 From: DuckieTM Date: Sat, 15 Mar 2025 14:54:10 +0100 Subject: [PATCH] :up: Update Deps. + WiP --- package.json | 7 +- packages/api/package.json | 4 +- packages/assets/package.json | 4 +- packages/avatar/package.json | 2 +- packages/camera/package.json | 4 +- packages/communication/package.json | 2 +- packages/configuration/package.json | 2 +- packages/events/package.json | 2 +- packages/localization/package.json | 4 +- packages/room/package.json | 4 +- .../FurnitureDynamicThumbnailVisualization.ts | 124 ++----- .../FurnitureExternalImageVisualization.ts | 2 +- .../IsometricImageFurniVisualization.ts | 304 ++++++++++-------- packages/session/package.json | 4 +- packages/sound/package.json | 2 +- packages/utils/package.json | 2 +- packages/utils/src/TexturePool.ts | 4 +- 17 files changed, 215 insertions(+), 262 deletions(-) diff --git a/package.json b/package.json index 310d6ae..c5538c5 100644 --- a/package.json +++ b/package.json @@ -31,20 +31,19 @@ "howler": "^2.2.4", "pako": "^2.1.0", "pixi-filters": "^6.0.5", - "pixi.js": "^8.5.1", + "pixi.js": "^8.8.1", "clientjs": "^0.2.1" }, "devDependencies": { "@eslint/js": "^9.13.0", "@rollup/plugin-typescript": "^11.1.6", - "@types/eslint__js": "^8.42.3", "@types/howler": "^2.2.11", "@types/node": "^20.14.12", "@types/pako": "^2.0.3", "eslint": "^9.8.0", "tslib": "^2.6.3", - "typescript": "~5.5.4", - "typescript-eslint": "^7.17.0", + "typescript": "~5.8.2", + "typescript-eslint": "^8.26.1", "vite": "^5.4.9" } } diff --git a/packages/api/package.json b/packages/api/package.json index b8db477..ac5ffdb 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -12,9 +12,9 @@ }, "main": "./index", "dependencies": { - "pixi.js": "^8.5.1" + "pixi.js": "^8.8.1" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/assets/package.json b/packages/assets/package.json index 783d07d..00a013b 100644 --- a/packages/assets/package.json +++ b/packages/assets/package.json @@ -15,9 +15,9 @@ "@nitrots/api": "1.0.0", "@nitrots/utils": "1.0.0", "@pixi/gif": "^3.0.1", - "pixi.js": "^8.5.1" + "pixi.js": "^8.8.1" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/avatar/package.json b/packages/avatar/package.json index 6eaf15b..3f70573 100644 --- a/packages/avatar/package.json +++ b/packages/avatar/package.json @@ -15,6 +15,6 @@ "@nitrots/utils": "1.0.0" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/camera/package.json b/packages/camera/package.json index 4e2bca3..d189993 100644 --- a/packages/camera/package.json +++ b/packages/camera/package.json @@ -14,9 +14,9 @@ "@nitrots/configuration": "1.0.0", "@nitrots/events": "1.0.0", "@nitrots/utils": "1.0.0", - "pixi.js": "^8.5.1" + "pixi.js": "^8.8.1" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/communication/package.json b/packages/communication/package.json index e796bd7..146bc8d 100644 --- a/packages/communication/package.json +++ b/packages/communication/package.json @@ -14,6 +14,6 @@ "@nitrots/utils": "1.0.0" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/configuration/package.json b/packages/configuration/package.json index a708972..337c839 100644 --- a/packages/configuration/package.json +++ b/packages/configuration/package.json @@ -13,6 +13,6 @@ "@nitrots/utils": "1.0.0" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/events/package.json b/packages/events/package.json index 69a6032..85c4b86 100644 --- a/packages/events/package.json +++ b/packages/events/package.json @@ -13,6 +13,6 @@ "@nitrots/utils": "1.0.0" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/localization/package.json b/packages/localization/package.json index fad22bc..3dcfc43 100644 --- a/packages/localization/package.json +++ b/packages/localization/package.json @@ -13,9 +13,9 @@ "@nitrots/communication": "1.0.0", "@nitrots/configuration": "1.0.0", "@nitrots/events": "1.0.0", - "pixi.js": "^8.5.1" + "pixi.js": "^8.8.1" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/room/package.json b/packages/room/package.json index 9b7e497..71e36d4 100644 --- a/packages/room/package.json +++ b/packages/room/package.json @@ -16,9 +16,9 @@ "@nitrots/configuration": "1.0.0", "@nitrots/events": "1.0.0", "@nitrots/session": "1.0.0", - "pixi.js": "^8.5.1" + "pixi.js": "^8.8.1" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/room/src/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts index 8128baf..844c4ca 100644 --- a/packages/room/src/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts +++ b/packages/room/src/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts @@ -1,104 +1,40 @@ -import { Texture, Graphics } from 'pixi.js'; +import { Texture } from 'pixi.js'; import { IsometricImageFurniVisualization } from './IsometricImageFurniVisualization'; export class FurnitureDynamicThumbnailVisualization extends IsometricImageFurniVisualization { - private _cachedUrl: string | null; + private _cachedUrl: string; - constructor() { - super(); - this._cachedUrl = null; - this._hasOutline = false; // Disable outline to avoid borders - } + constructor() { + super(); + this._cachedUrl = null; + this._hasOutline = true; + } - protected updateModel(scale: number): boolean { - if (this.object) { - const thumbnailUrl = this.getThumbnailURL(); - - if (this._cachedUrl !== thumbnailUrl) { - this._cachedUrl = thumbnailUrl; - - if (this._cachedUrl && this._cachedUrl !== '') { - const image = new Image(); - image.crossOrigin = 'anonymous'; - - image.onload = () => { - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); - - const targetWidth = 32; - const targetHeight = 32; - - canvas.width = targetWidth; - canvas.height = targetHeight; - - context!.fillStyle = '#b0b0b0'; - context!.fillRect(0, 0, canvas.width, canvas.height); - - const aspectRatio = image.width / image.height; - let drawWidth = targetWidth; - let drawHeight = targetHeight; - - if (aspectRatio > 1) { - drawHeight = targetWidth / aspectRatio; - } else { - drawWidth = targetHeight * aspectRatio; - } - - const offsetX = (targetWidth - drawWidth) / 2; - const offsetY = (targetHeight - drawHeight) / 2; - - context!.drawImage(image, offsetX, offsetY, drawWidth, drawHeight); - const texture = Texture.from(canvas); - texture.source.scaleMode = 'linear'; - - this.setThumbnailImages(texture, scale); - }; - - image.onerror = () => { - console.error('Image load failed:', thumbnailUrl); - }; - - image.src = thumbnailUrl; - } else { - this.setThumbnailImages(null); - } - } + protected updateModel(scale: number): boolean { + if (this.object) { + const thumbnailUrl = this.getThumbnailURL(); + if (this._cachedUrl !== thumbnailUrl) { + this._cachedUrl = thumbnailUrl; + if (this._cachedUrl && this._cachedUrl !== '') { + const image = new Image(); + image.crossOrigin = '*'; + image.onload = this.onImageLoad.bind(this, image); + image.src = thumbnailUrl; + } else { + this.setThumbnailImages(null); } - return super.updateModel(scale); + } } + return super.updateModel(scale); + } - protected getThumbnailURL(): string { - return - } + private onImageLoad(image: HTMLImageElement): void { + const texture = Texture.from(image); + texture.source.scaleMode = 'linear'; + this.setThumbnailImages(texture); + } - protected setThumbnailImages(texture: Texture | null, scale: number = 1): void { - super.setThumbnailImages(texture); - - if (texture && this.sprite) { - this.sprite.texture = texture; - this.sprite.width = texture.width * scale; - this.sprite.height = texture.height * scale; - this.sprite.anchor.set(0.5, 0.5); - - if (this.sprite.mask) { - this.sprite.mask.destroy(); - this.sprite.mask = null; - } - - const mask = new Graphics() - .beginFill(0xffffff) - .drawRect(-texture.width / 2, -texture.height / 2, texture.width, texture.height) - .endFill(); - this.sprite.addChild(mask); - this.sprite.mask = mask; - - console.log('Sprite updated:', this.sprite.width, 'x', this.sprite.height); - } else if (!texture) { - if (this.sprite && this.sprite.mask) { - this.sprite.mask.destroy(); - this.sprite.mask = null; - } - console.log('Thumbnail cleared'); - } - } + protected getThumbnailURL(): string { + throw new Error('This method must be overridden!'); + } } \ No newline at end of file diff --git a/packages/room/src/object/visualization/furniture/FurnitureExternalImageVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureExternalImageVisualization.ts index 1261ff7..0961ba0 100644 --- a/packages/room/src/object/visualization/furniture/FurnitureExternalImageVisualization.ts +++ b/packages/room/src/object/visualization/furniture/FurnitureExternalImageVisualization.ts @@ -48,4 +48,4 @@ export class FurnitureExternalImageVisualization extends FurnitureDynamicThumbna return url; } -} +} \ No newline at end of file diff --git a/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts b/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts index 4564189..838cd10 100644 --- a/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts +++ b/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts @@ -1,173 +1,193 @@ import { IGraphicAsset } from '@nitrots/api'; import { TextureUtils } from '@nitrots/utils'; -import { Matrix, Sprite, Texture } from 'pixi.js'; +import { Container, Matrix, Sprite, Texture } from 'pixi.js'; import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; -export class IsometricImageFurniVisualization extends FurnitureAnimatedVisualization -{ - protected static THUMBNAIL: string = 'THUMBNAIL'; +export class IsometricImageFurniVisualization extends FurnitureAnimatedVisualization { + protected static THUMBNAIL: string = 'THUMBNAIL'; - private _thumbnailAssetNameNormal: string; - private _thumbnailImageNormal: Texture; - private _thumbnailDirection: number; - private _thumbnailChanged: boolean; - protected _hasOutline: boolean; + private _thumbnailAssetNameNormal: string; + private _thumbnailImageNormal: Texture; + private _thumbnailDirection: number; + private _thumbnailChanged: boolean; + protected _hasOutline: boolean; - constructor() - { - super(); + constructor() { + super(); - this._thumbnailAssetNameNormal = null; - this._thumbnailImageNormal = null; - this._thumbnailDirection = -1; - this._thumbnailChanged = false; - this._hasOutline = false; + this._thumbnailAssetNameNormal = null; + this._thumbnailImageNormal = null; + this._thumbnailDirection = -1; + this._thumbnailChanged = false; + this._hasOutline = false; + } + + public get hasThumbnailImage(): boolean { + return !!this._thumbnailImageNormal; + } + + public setThumbnailImages(k: Texture): void { + this._thumbnailImageNormal = k; + this._thumbnailChanged = true; + } + + protected updateModel(scale: number): boolean { + const flag = super.updateModel(scale); + + // Example: apply color tint for testing. + if (this.object && this.object.model) { + if (this.direction === 2) this.object.model.setValue('furniture_color', 0xFF0000); + else if (this.direction === 4) this.object.model.setValue('furniture_color', 0x0000FF); } - public get hasThumbnailImage(): boolean - { - return !(this._thumbnailImageNormal == null); + // Only refresh thumbnail if something changed or the direction changed. + if (!this._thumbnailChanged && (this._thumbnailDirection === this.direction)) + return flag; + + this.refreshThumbnail(); + + return true; + } + + private refreshThumbnail(): void { + if (!this.asset) return; + + if (this._thumbnailImageNormal) { + this.addThumbnailAsset(this._thumbnailImageNormal, 64); + } else { + this.asset.disposeAsset(this.getThumbnailAssetName(64)); } - public setThumbnailImages(k: Texture): void - { - this._thumbnailImageNormal = k; - this._thumbnailChanged = true; + this._thumbnailChanged = false; + this._thumbnailDirection = this.direction; + } + + private addThumbnailAsset(k: Texture, scale: number): void { + if (!k) { + console.warn('addThumbnailAsset called with null/undefined texture. Skipping.'); + return; } - protected updateModel(scale: number): boolean - { - const flag = super.updateModel(scale); + let layerId = 0; + while (layerId < this.totalSprites) { + if ( + this.getLayerTag(scale, this.direction, layerId) === + IsometricImageFurniVisualization.THUMBNAIL + ) { + const assetName = + this.cacheSpriteAssetName(scale, layerId, false) + this.getFrameNumber(scale, layerId); + const asset = this.getAsset(assetName, layerId); - if(!this._thumbnailChanged && (this._thumbnailDirection === this.direction)) return flag; + if (asset) { + const transformed = this.generateTransformedThumbnail(k, asset); + if (!transformed) return; - this.refreshThumbnail(); + const thumbAssetName = this.getThumbnailAssetName(scale); - return true; - } - - private refreshThumbnail(): void - { - if(this.asset == null) return; - - if(this._thumbnailImageNormal) - { - this.addThumbnailAsset(this._thumbnailImageNormal, 64); - } - else - { - this.asset.disposeAsset(this.getThumbnailAssetName(64)); + this.asset.disposeAsset(thumbAssetName); + this.asset.addAsset( + thumbAssetName, + transformed, + true, + asset.offsetX, + asset.offsetY, + false, + false + ); } + return; + } + layerId++; + } + } - this._thumbnailChanged = false; - this._thumbnailDirection = this.direction; + protected generateTransformedThumbnail(texture: Texture, asset: IGraphicAsset): Texture { + // 1) If an outline is needed, generate it. + if (this._hasOutline) { + const outlineContainer = new Container(); + const background = new Sprite(Texture.WHITE); + background.tint = 0x000000; + background.width = texture.width + 40; + background.height = texture.height + 40; + + const sprite = new Sprite(texture); + sprite.x = (background.width - sprite.width) / 2; + sprite.y = (background.height - sprite.height) / 2; + outlineContainer.addChild(background, sprite); + + // Generate a new texture that includes the outline. + texture = TextureUtils.generateTexture(outlineContainer); } - private addThumbnailAsset(k: Texture, scale: number): void - { - let layerId = 0; + // 2) Set the texture's intended dimensions. + texture.orig.width = asset.width; + texture.orig.height = asset.height; - while(layerId < this.totalSprites) - { - if(this.getLayerTag(scale, this.direction, layerId) === IsometricImageFurniVisualization.THUMBNAIL) - { - const assetName = (this.cacheSpriteAssetName(scale, layerId, false) + this.getFrameNumber(scale, layerId)); - const asset = this.getAsset(assetName, layerId); - - if(asset) - { - const _local_6 = this.generateTransformedThumbnail(k, asset); - const _local_7 = this.getThumbnailAssetName(scale); - - this.asset.disposeAsset(_local_7); - this.asset.addAsset(_local_7, _local_6, true, asset.offsetX, asset.offsetY, false, false); - } - - return; - } - - layerId++; - } + // 3) Build the matrix (same as your original logic). + // Default matrix: (a=1, b=0, c=0, d=1, tx=0, ty=0) + const matrix = new Matrix(); + switch (this.direction) { + case 2: + matrix.b = -0.5; // negative skew + matrix.d /= 1.6; // flatten vertically + matrix.ty = 0.5 * texture.width; // shift downward + break; + case 0: + case 4: + matrix.b = 0.5; // positive skew + matrix.d /= 1.6; + matrix.tx = -0.5; // shift left + break; } - protected generateTransformedThumbnail(texture: Texture, asset: IGraphicAsset): Texture - { - if(this._hasOutline) - { - const container = new Sprite(); - const background = new Sprite(Texture.WHITE); + // 4) Decompose the matrix. + const rotation = Math.atan2(matrix.b, matrix.a); + const scaleX = Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b); + const scaleY = matrix.d; + const tx = matrix.tx; + const ty = matrix.ty; - background.tint = 0x000000; - background.width = (texture.width + 40); - background.height = (texture.height + 40); + // 5) Create a sprite from the texture. + const finalSprite = new Sprite(texture); + // Set the anchor to center to ease flipping. + finalSprite.anchor.set(0.5, 0.5); - const sprite = new Sprite(texture); - const offsetX = ((background.width - sprite.width) / 2); - const offsetY = ((background.height - sprite.height) / 2); + // 6) Apply the decomposed transform. + // Since our anchor is center, add half of the texture's width/height. + finalSprite.x = tx + texture.width / 2; + finalSprite.y = ty + texture.height / 2; + finalSprite.rotation = rotation; + finalSprite.scale.set(scaleX, scaleY); - sprite.x = Math.floor(offsetX); - sprite.y = Math.floor(offsetY); + console.log( + 'Manual override: direction', this.direction, + 'rotation =', finalSprite.rotation, + 'scale =', finalSprite.scale.x, finalSprite.scale.y, + 'position =', finalSprite.x, finalSprite.y + ); - container.addChild(background, sprite); + // 8) Wrap the sprite in a container and generate the final texture. + const container = new Container(); + container.addChild(finalSprite); + return TextureUtils.generateTexture(container); + } - texture = TextureUtils.generateTexture(container); - } - - const scale = 1.1; - const matrix = new Matrix(); - const difference = (asset.width / texture.width); - - switch(this.direction) - { - case 2: - matrix.a = difference; - matrix.b = (-0.5 * difference); - matrix.c = 0; - matrix.d = (difference * scale); - matrix.tx = 0; - matrix.ty = ((0.5 * difference) * texture.width); - break; - case 0: - case 4: - matrix.a = difference; - matrix.b = (0.5 * difference); - matrix.c = 0; - matrix.d = (difference * scale); - matrix.tx = 0; - matrix.ty = 0; - break; - default: - matrix.a = difference; - matrix.b = 0; - matrix.c = 0; - matrix.d = difference; - matrix.tx = 0; - matrix.ty = 0; - } - - const sprite = new Sprite(texture); - - sprite.setFromMatrix(matrix); - - return TextureUtils.generateTexture(sprite); + protected getSpriteAssetName(scale: number, layerId: number): string { + if ( + this._thumbnailImageNormal && + this.getLayerTag(scale, this.direction, layerId) === IsometricImageFurniVisualization.THUMBNAIL + ) { + return this.getThumbnailAssetName(scale); } + return super.getSpriteAssetName(scale, layerId); + } - protected getSpriteAssetName(scale: number, layerId: number): string - { - if(this._thumbnailImageNormal && (this.getLayerTag(scale, this.direction, layerId) === IsometricImageFurniVisualization.THUMBNAIL)) return this.getThumbnailAssetName(scale); + protected getThumbnailAssetName(scale: number): string { + this._thumbnailAssetNameNormal = [this._type, this.object.id, 'thumb', 64, this.direction].join('_'); + return this._thumbnailAssetNameNormal; + } - return super.getSpriteAssetName(scale, layerId); - } - - protected getThumbnailAssetName(scale: number): string - { - this._thumbnailAssetNameNormal = this.getFullThumbnailAssetName(this.object.id, 64); - - return this._thumbnailAssetNameNormal; - } - - protected getFullThumbnailAssetName(k: number, _arg_2: number): string - { - return [this._type, k, 'thumb', _arg_2].join('_'); - } -} + protected getFullThumbnailAssetName(k: number, _arg_2: number): string { + return [this._type, k, 'thumb', _arg_2, this.direction].join('_'); + } +} \ No newline at end of file diff --git a/packages/session/package.json b/packages/session/package.json index 462c60c..699adc4 100644 --- a/packages/session/package.json +++ b/packages/session/package.json @@ -15,9 +15,9 @@ "@nitrots/configuration": "1.0.0", "@nitrots/events": "1.0.0", "@nitrots/localization": "1.0.0", - "pixi.js": "^8.5.1" + "pixi.js": "^8.8.1" }, "devDependencies": { - "typescript": "~5.5.4" + "typescript": "~5.8.2" } } diff --git a/packages/sound/package.json b/packages/sound/package.json index fca6085..53bbf1b 100644 --- a/packages/sound/package.json +++ b/packages/sound/package.json @@ -11,7 +11,7 @@ "dependencies": { "@nitrots/api": "1.0.0", "@nitrots/communication": "1.0.0", - "pixi.js": "^8.5.1" + "pixi.js": "^8.8.1" }, "devDependencies": { "typescript": "~5.5.4" diff --git a/packages/utils/package.json b/packages/utils/package.json index 7743567..4c99424 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -11,7 +11,7 @@ "dependencies": { "@nitrots/api": "1.0.0", "pako": "^2.1.0", - "pixi.js": "^8.5.1" + "pixi.js": "^8.8.1" }, "devDependencies": { "@types/pako": "^2.0.3", diff --git a/packages/utils/src/TexturePool.ts b/packages/utils/src/TexturePool.ts index 128679c..5e96234 100644 --- a/packages/utils/src/TexturePool.ts +++ b/packages/utils/src/TexturePool.ts @@ -89,9 +89,7 @@ export class TexturePool this._textures[texture.width][texture.height].splice(i, 1); - this._totalTextures--; - - NitroLogger.log(`[TexturePool] Texture disposed: ${texture.width}x${texture.height}`); + this._totalTextures--; } } }