mirror of
https://github.com/duckietm/Nitro-Cool-UI-Renderer.git
synced 2025-06-21 15:06:58 +00:00
Wip
This commit is contained in:
parent
00790c0789
commit
8acd0c7de4
@ -37,7 +37,7 @@ export class FurnitureChangeStateWhenStepOnLogic extends FurnitureLogic
|
|||||||
let sizeX = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_SIZE_X);
|
let sizeX = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_SIZE_X);
|
||||||
let sizeY = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_SIZE_Y);
|
let sizeY = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_SIZE_Y);
|
||||||
|
|
||||||
const direction = (((Math.floor(this.object.getDirection().x) + 45) % 360) / 90);
|
const direction = Math.floor(((this.object.getDirection().x + 45) % 360) / 90);
|
||||||
|
|
||||||
if((direction === 1) || (direction === 3)) [sizeX, sizeY] = [sizeY, sizeX];
|
if((direction === 1) || (direction === 3)) [sizeX, sizeY] = [sizeY, sizeX];
|
||||||
|
|
||||||
|
@ -2,39 +2,47 @@ import { Texture } from 'pixi.js';
|
|||||||
import { IsometricImageFurniVisualization } from './IsometricImageFurniVisualization';
|
import { IsometricImageFurniVisualization } from './IsometricImageFurniVisualization';
|
||||||
|
|
||||||
export class FurnitureDynamicThumbnailVisualization extends IsometricImageFurniVisualization {
|
export class FurnitureDynamicThumbnailVisualization extends IsometricImageFurniVisualization {
|
||||||
private _cachedUrl: string;
|
private _cachedUrl: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._cachedUrl = null;
|
|
||||||
this._hasOutline = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected updateModel(scale: number): boolean {
|
this._cachedUrl = null;
|
||||||
if (this.object) {
|
this._hasOutline = true;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private onImageLoad(image: HTMLImageElement): void {
|
protected updateModel(scale: number): boolean {
|
||||||
const texture = Texture.from(image);
|
if (this.object) {
|
||||||
texture.source.scaleMode = 'linear';
|
const thumbnailUrl = this.getThumbnailURL();
|
||||||
this.setThumbnailImages(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getThumbnailURL(): string {
|
if (this._cachedUrl !== thumbnailUrl) {
|
||||||
throw new Error('This method must be overridden!');
|
this._cachedUrl = thumbnailUrl;
|
||||||
}
|
|
||||||
|
if (this._cachedUrl && this._cachedUrl !== '') {
|
||||||
|
const image = new Image();
|
||||||
|
|
||||||
|
image.src = thumbnailUrl;
|
||||||
|
image.crossOrigin = '*';
|
||||||
|
|
||||||
|
image.onload = () => {
|
||||||
|
if (image.complete && image.width > 0 && image.height > 0) {
|
||||||
|
const texture = Texture.from(image);
|
||||||
|
texture.source.scaleMode = 'linear';
|
||||||
|
this.setThumbnailImages(texture, thumbnailUrl); // Pass URL here
|
||||||
|
} else {
|
||||||
|
console.error("Image failed to load properly:", thumbnailUrl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.setThumbnailImages(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.updateModel(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getThumbnailURL(): string {
|
||||||
|
throw new Error('This method must be overridden!');
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,206 +1,154 @@
|
|||||||
import { IGraphicAsset } from '@nitrots/api';
|
import { IGraphicAsset } from '@nitrots/api';
|
||||||
import { TextureUtils } from '@nitrots/utils';
|
import { GetRenderer, TextureUtils } from '@nitrots/utils';
|
||||||
import * as PIXI from 'pixi.js';
|
import { Matrix, Sprite, Texture, RenderTexture } from 'pixi.js';
|
||||||
import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization';
|
import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization';
|
||||||
|
|
||||||
console.log('Pixi.js Version at import:', PIXI.VERSION);
|
|
||||||
|
|
||||||
export class IsometricImageFurniVisualization extends FurnitureAnimatedVisualization {
|
export class IsometricImageFurniVisualization extends FurnitureAnimatedVisualization {
|
||||||
protected static THUMBNAIL: string = 'THUMBNAIL';
|
protected static THUMBNAIL: string = 'THUMBNAIL';
|
||||||
|
|
||||||
private _thumbnailAssetNameNormal: string;
|
private _thumbnailAssetNameNormal: string;
|
||||||
private _thumbnailImageNormal: PIXI.Texture;
|
private _thumbnailImageNormal: Texture;
|
||||||
private _thumbnailDirection: number;
|
private _thumbnailDirection: number;
|
||||||
private _thumbnailChanged: boolean;
|
private _thumbnailChanged: boolean;
|
||||||
protected _hasOutline: boolean;
|
private _uniqueId: string;
|
||||||
|
private _photoUrl: string; // Store the photo URL or ID
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this._thumbnailAssetNameNormal = null;
|
this._thumbnailAssetNameNormal = null;
|
||||||
this._thumbnailImageNormal = null;
|
this._thumbnailImageNormal = null;
|
||||||
this._thumbnailDirection = -1;
|
this._thumbnailDirection = -1;
|
||||||
this._thumbnailChanged = false;
|
this._thumbnailChanged = false;
|
||||||
this._hasOutline = false; // Disable outline for simplicity
|
this._uniqueId = `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
||||||
}
|
this._photoUrl = null;
|
||||||
|
|
||||||
public get hasThumbnailImage(): boolean {
|
|
||||||
return !!this._thumbnailImageNormal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setThumbnailImages(k: PIXI.Texture): void {
|
|
||||||
this._thumbnailImageNormal = k;
|
|
||||||
this._thumbnailChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected updateModel(scale: number): boolean {
|
|
||||||
const flag = super.updateModel(scale);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._thumbnailChanged && (this._thumbnailDirection === this.direction))
|
public get hasThumbnailImage(): boolean {
|
||||||
return flag;
|
return !(this._thumbnailImageNormal == null);
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._thumbnailChanged = false;
|
public setThumbnailImages(k: Texture, url?: string): void {
|
||||||
this._thumbnailDirection = this.direction;
|
this._thumbnailImageNormal = k;
|
||||||
}
|
this._photoUrl = url || null; // Store the URL or ID passed with the texture
|
||||||
|
this._thumbnailChanged = true;
|
||||||
private addThumbnailAsset(k: PIXI.Texture, scale: number): void {
|
|
||||||
if (!k) {
|
|
||||||
console.warn('addThumbnailAsset called with null/undefined texture. Skipping.');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let layerId = 0;
|
public getPhotoUrl(): string {
|
||||||
while (layerId < this.totalSprites) {
|
return this._photoUrl; // Expose the URL for the click handler
|
||||||
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) {
|
protected updateModel(scale: number): boolean {
|
||||||
const transformed = this.generateTransformedThumbnail(k, asset);
|
const flag = super.updateModel(scale);
|
||||||
if (!transformed) return;
|
|
||||||
|
|
||||||
const thumbAssetName = this.getThumbnailAssetName(scale);
|
if (!this._thumbnailChanged && (this._thumbnailDirection === this.direction)) {
|
||||||
|
return flag;
|
||||||
this.asset.disposeAsset(thumbAssetName);
|
|
||||||
this.asset.addAsset(
|
|
||||||
thumbAssetName,
|
|
||||||
transformed,
|
|
||||||
true,
|
|
||||||
asset.offsetX,
|
|
||||||
asset.offsetY,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
layerId++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected generateTransformedThumbnail(texture: PIXI.Texture, asset: IGraphicAsset): PIXI.Texture {
|
this.refreshThumbnail();
|
||||||
console.log('Entering generateTransformedThumbnail');
|
|
||||||
console.log('Initial texture dimensions:', texture.width, 'x', texture.height);
|
|
||||||
console.log('Asset dimensions:', asset.width, 'x', asset.height);
|
|
||||||
|
|
||||||
// 1) Scale the texture to 320x320, then to 64x64
|
return true;
|
||||||
const targetWidth = 64;
|
|
||||||
const targetHeight = 64;
|
|
||||||
let workingTexture = texture;
|
|
||||||
|
|
||||||
// Ensure texture is 320x320
|
|
||||||
if (texture.width !== 320 || texture.height !== 320) {
|
|
||||||
const scaleContainer = new PIXI.Container();
|
|
||||||
const scaleSprite = new PIXI.Sprite(texture);
|
|
||||||
scaleSprite.width = 320;
|
|
||||||
scaleSprite.height = 320;
|
|
||||||
scaleContainer.addChild(scaleSprite);
|
|
||||||
workingTexture = TextureUtils.generateTexture(scaleContainer, 320, 320);
|
|
||||||
console.log('Scaled texture to 320x320:', workingTexture.width, 'x', workingTexture.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale to 64x64
|
|
||||||
const scaleFactor = targetWidth / workingTexture.width; // 64/320 = 0.2
|
|
||||||
const scaledContainer = new PIXI.Container();
|
|
||||||
const scaledSprite = new PIXI.Sprite(workingTexture);
|
|
||||||
scaledSprite.scale.set(scaleFactor, scaleFactor); // Scale to 64x64
|
|
||||||
scaledContainer.addChild(scaledSprite);
|
|
||||||
workingTexture = TextureUtils.generateTexture(scaledContainer, targetWidth, targetHeight);
|
|
||||||
console.log('Scaled texture to 64x64:', workingTexture.width, 'x', workingTexture.height);
|
|
||||||
|
|
||||||
// 2) Apply trapezoid transformation: (0,0), (64,30), (64,64), (0,34)
|
|
||||||
if (this.direction === 4) {
|
|
||||||
const sprite = new PIXI.Sprite(workingTexture);
|
|
||||||
const container = new PIXI.Container();
|
|
||||||
container.addChild(sprite);
|
|
||||||
|
|
||||||
// Apply the trapezoid transformation
|
|
||||||
const points = [
|
|
||||||
new PIXI.Point(0, 0),
|
|
||||||
new PIXI.Point(64, 30),
|
|
||||||
new PIXI.Point(64, 64),
|
|
||||||
new PIXI.Point(0, 34),
|
|
||||||
];
|
|
||||||
|
|
||||||
const graphics = new PIXI.Graphics();
|
|
||||||
graphics.beginFill(0xFFFFFF);
|
|
||||||
graphics.drawPolygon(points);
|
|
||||||
graphics.endFill();
|
|
||||||
|
|
||||||
container.addChild(graphics);
|
|
||||||
container.mask = graphics;
|
|
||||||
|
|
||||||
const bounds = container.getBounds();
|
|
||||||
console.log('Container bounds before render:', bounds.width, 'x', bounds.height);
|
|
||||||
|
|
||||||
const finalTexture = TextureUtils.generateTexture(container, targetWidth, targetHeight);
|
|
||||||
console.log('Final texture dimensions:', finalTexture.width, 'x', finalTexture.height);
|
|
||||||
return finalTexture;
|
|
||||||
} else {
|
|
||||||
// Original matrix transformation for cases 0 and 2
|
|
||||||
const matrix = new PIXI.Matrix();
|
|
||||||
switch (this.direction) {
|
|
||||||
case 0:
|
|
||||||
case 2:
|
|
||||||
matrix.b = 0.5; // Positive skew
|
|
||||||
matrix.d /= 1.6;
|
|
||||||
matrix.tx = -0.5; // Shift left
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sprite = new PIXI.Sprite(workingTexture);
|
private refreshThumbnail(): void {
|
||||||
sprite.position.set(matrix.tx, matrix.ty);
|
if (this.asset == null) {
|
||||||
sprite.scale.set(matrix.a, matrix.d);
|
return;
|
||||||
sprite.skew.set(matrix.b, matrix.c);
|
}
|
||||||
|
|
||||||
const container = new PIXI.Container();
|
const thumbnailAssetName = this.getThumbnailAssetName(64);
|
||||||
container.addChild(sprite);
|
|
||||||
return TextureUtils.generateTexture(container);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (this._thumbnailImageNormal) {
|
||||||
|
this.addThumbnailAsset(this._thumbnailImageNormal, 64);
|
||||||
|
} else {
|
||||||
|
const layerId = 2;
|
||||||
|
const sprite = this.getSprite(layerId);
|
||||||
|
}
|
||||||
|
|
||||||
protected getSpriteAssetName(scale: number, layerId: number): string {
|
this._thumbnailChanged = false;
|
||||||
if (
|
this._thumbnailDirection = this.direction;
|
||||||
this._thumbnailImageNormal &&
|
|
||||||
this.getLayerTag(scale, this.direction, layerId) === IsometricImageFurniVisualization.THUMBNAIL
|
|
||||||
) {
|
|
||||||
return this.getThumbnailAssetName(scale);
|
|
||||||
}
|
}
|
||||||
return super.getSpriteAssetName(scale, layerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getThumbnailAssetName(scale: number): string {
|
private addThumbnailAsset(k: Texture, scale: number): void {
|
||||||
this._thumbnailAssetNameNormal = [this._type, this.object.id, 'thumb', 64, this.direction].join('_');
|
let layerId = 0;
|
||||||
return this._thumbnailAssetNameNormal;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getFullThumbnailAssetName(k: number, _arg_2: number): string {
|
while (layerId < this.totalSprites) {
|
||||||
return [this._type, k, 'thumb', _arg_2, this.direction].join('_');
|
const layerTag = this.getLayerTag(scale, this.direction, layerId);
|
||||||
}
|
|
||||||
}
|
if (layerTag === IsometricImageFurniVisualization.THUMBNAIL) {
|
||||||
|
const assetName = (this.cacheSpriteAssetName(scale, layerId, false) + this.getFrameNumber(scale, layerId));
|
||||||
|
const asset = this.getAsset(assetName, layerId);
|
||||||
|
const thumbnailAssetName = `${this.getThumbnailAssetName(scale)}-${this._uniqueId}`;
|
||||||
|
const transformedTexture = this.generateTransformedThumbnail(k, asset || { width: 64, height: 64, offsetX: -34, offsetY: -30 });
|
||||||
|
|
||||||
|
this.asset.addAsset(thumbnailAssetName, transformedTexture, true, asset?.offsetX || -34, asset?.offsetY || -30, false, false);
|
||||||
|
|
||||||
|
const sprite = this.getSprite(layerId);
|
||||||
|
if (sprite) {
|
||||||
|
sprite.texture = transformedTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
layerId++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected generateTransformedThumbnail(texture: Texture, asset: IGraphicAsset): Texture {
|
||||||
|
const sprite = new Sprite(texture);
|
||||||
|
const scaleFactor = (asset?.width || 64) / texture.width;
|
||||||
|
const matrix = new Matrix();
|
||||||
|
|
||||||
|
switch (this.direction) {
|
||||||
|
case 2:
|
||||||
|
matrix.a = scaleFactor;
|
||||||
|
matrix.b = (-0.5 * scaleFactor);
|
||||||
|
matrix.c = 0;
|
||||||
|
matrix.d = scaleFactor;
|
||||||
|
matrix.tx = 0;
|
||||||
|
matrix.ty = (0.5 * scaleFactor * texture.width);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
case 4:
|
||||||
|
matrix.a = scaleFactor;
|
||||||
|
matrix.b = (0.5 * scaleFactor);
|
||||||
|
matrix.c = 0;
|
||||||
|
matrix.d = scaleFactor;
|
||||||
|
matrix.tx = 0;
|
||||||
|
matrix.ty = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
matrix.a = scaleFactor;
|
||||||
|
matrix.b = 0;
|
||||||
|
matrix.c = 0;
|
||||||
|
matrix.d = scaleFactor;
|
||||||
|
matrix.tx = 0;
|
||||||
|
matrix.ty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprite.setFromMatrix(matrix);
|
||||||
|
|
||||||
|
const width = 64;
|
||||||
|
const height = 64;
|
||||||
|
const renderTexture = RenderTexture.create({ width, height, resolution: 1 });
|
||||||
|
GetRenderer().render({ container: sprite, target: renderTexture });
|
||||||
|
|
||||||
|
return renderTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getSpriteAssetName(scale: number, layerId: number): string {
|
||||||
|
if (this._thumbnailImageNormal && (this.getLayerTag(scale, this.direction, layerId) === IsometricImageFurniVisualization.THUMBNAIL)) {
|
||||||
|
return `${this.getThumbnailAssetName(scale)}-${this._uniqueId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getSpriteAssetName(scale, layerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getThumbnailAssetName(scale: number): string {
|
||||||
|
return this.cacheSpriteAssetName(scale, 2, false) + this.getFrameNumber(scale, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getFullThumbnailAssetName(k: number, _arg_2: number): string {
|
||||||
|
return [this._type, k, 'thumb', _arg_2].join('_');
|
||||||
|
}
|
||||||
|
}
|
@ -89,11 +89,24 @@ export class RoomObjectCache
|
|||||||
data.height = sprite.sprite.height;
|
data.height = sprite.sprite.height;
|
||||||
data.type = sprite.sprite.type;
|
data.type = sprite.sprite.type;
|
||||||
data.posture = sprite.sprite.posture;
|
data.posture = sprite.sprite.posture;
|
||||||
|
|
||||||
|
console.log("Sprite data before processing:", {
|
||||||
|
name: data.name,
|
||||||
|
type: data.type,
|
||||||
|
tag: sprite.sprite.tag, // Add this line to log the tag
|
||||||
|
width: data.width,
|
||||||
|
height: data.height,
|
||||||
|
frame: data.frame,
|
||||||
|
color: data.color
|
||||||
|
});
|
||||||
|
|
||||||
const isSkewed = this.isSkewedSprite(sprite.sprite);
|
const isSkewed = this.isSkewedSprite(sprite.sprite);
|
||||||
|
|
||||||
if(isSkewed) data.skew = (((sprite.sprite.direction % 4) === 0) ? -0.5 : 0.5);
|
if(isSkewed)
|
||||||
|
{
|
||||||
|
data.skew = (((sprite.sprite.direction % 4) === 0) ? -0.5 : 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
if(((((isSkewed || (sprite.name.indexOf('%image.library.url%') >= 0)) || (sprite.name.indexOf('%group.badge.url%') >= 0)) && (data.width <= RoomObjectCache.MAX_SIZE_FOR_AVG_COLOR)) && (data.height <= RoomObjectCache.MAX_SIZE_FOR_AVG_COLOR)))
|
if(((((isSkewed || (sprite.name.indexOf('%image.library.url%') >= 0)) || (sprite.name.indexOf('%group.badge.url%') >= 0)) && (data.width <= RoomObjectCache.MAX_SIZE_FOR_AVG_COLOR)) && (data.height <= RoomObjectCache.MAX_SIZE_FOR_AVG_COLOR)))
|
||||||
{
|
{
|
||||||
//data.color = Canvas._Str_23439(sprite.sprite.texture).toString();
|
//data.color = Canvas._Str_23439(sprite.sprite.texture).toString();
|
||||||
@ -117,6 +130,11 @@ export class RoomObjectCache
|
|||||||
private isSkewedSprite(k: IRoomObjectSprite): boolean
|
private isSkewedSprite(k: IRoomObjectSprite): boolean
|
||||||
{
|
{
|
||||||
if(!k.type) return false;
|
if(!k.type) return false;
|
||||||
|
|
||||||
|
console.log("Checking if sprite is skewed:", {
|
||||||
|
type: k.type,
|
||||||
|
tag: k.tag
|
||||||
|
});
|
||||||
|
|
||||||
if((k.type.indexOf('external_image_wallitem') === 0) && (k.tag === 'THUMBNAIL')) return true;
|
if((k.type.indexOf('external_image_wallitem') === 0) && (k.tag === 'THUMBNAIL')) return true;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user