mirror of
https://github.com/billsonnn/nitro-renderer.git
synced 2025-01-19 06:46:28 +01:00
Start gif support
This commit is contained in:
parent
4b3f4b9548
commit
29c2ee2282
@ -1,4 +1,4 @@
|
||||
import { Resource, Texture } from '@pixi/core';
|
||||
import { BaseTexture, Resource, Texture } from '@pixi/core';
|
||||
import { Loader, LoaderResource } from '@pixi/loaders';
|
||||
import { Spritesheet } from '@pixi/spritesheet';
|
||||
import { IGraphicAsset } from '../../room';
|
||||
@ -94,158 +94,119 @@ export class AssetManager extends Disposable implements IAssetManager
|
||||
return collection;
|
||||
}
|
||||
|
||||
public downloadAsset(assetUrl: string, cb: Function): boolean
|
||||
public downloadAsset(assetUrl: string, cb: (status: boolean) => void): void
|
||||
{
|
||||
return this.downloadAssets([ assetUrl ], cb);
|
||||
this.downloadAssets([ assetUrl ], cb);
|
||||
}
|
||||
|
||||
public downloadAssets(assetUrls: string[], cb: Function): boolean
|
||||
public downloadAssets(assetUrls: string[], cb: (status: boolean) => void): void
|
||||
{
|
||||
if(!assetUrls || !assetUrls.length)
|
||||
{
|
||||
cb(true);
|
||||
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
const totalToDownload = assetUrls.length;
|
||||
|
||||
let totalDownloaded = 0;
|
||||
|
||||
const onDownloaded = (loader: Loader, resource: LoaderResource, flag: boolean) =>
|
||||
{
|
||||
if(loader) loader.destroy();
|
||||
|
||||
if(!flag)
|
||||
{
|
||||
this._logger.error('Failed to download asset: ' + resource.url);
|
||||
|
||||
cb(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
totalDownloaded++;
|
||||
|
||||
if(totalDownloaded === totalToDownload) cb(true);
|
||||
};
|
||||
const loader = new Loader();
|
||||
|
||||
for(const url of assetUrls)
|
||||
{
|
||||
if(!url) continue;
|
||||
|
||||
const loader = new Loader();
|
||||
|
||||
loader
|
||||
.add({
|
||||
url,
|
||||
crossOrigin: 'anonymous',
|
||||
xhrType: url.endsWith('.nitro') ? LoaderResource.XHR_RESPONSE_TYPE.BUFFER : LoaderResource.XHR_RESPONSE_TYPE.JSON
|
||||
})
|
||||
.use((resource: LoaderResource, next: Function) =>
|
||||
{
|
||||
this.assetLoader(loader, resource, onDownloaded);
|
||||
|
||||
next();
|
||||
})
|
||||
.load();
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
let remaining = assetUrls.length;
|
||||
|
||||
private assetLoader(loader: Loader, resource: LoaderResource, onDownloaded: Function): void
|
||||
{
|
||||
if(!resource || resource.error)
|
||||
const onDownloaded = (status: boolean, url: string) =>
|
||||
{
|
||||
if(resource && resource.texture) resource.texture.destroy(true);
|
||||
|
||||
onDownloaded(loader, resource, false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(resource.extension === 'nitro')
|
||||
{
|
||||
const nitroBundle = new NitroBundle(resource.data);
|
||||
const assetData = (nitroBundle.jsonFile as IAssetData);
|
||||
|
||||
if(!assetData)
|
||||
if(!status)
|
||||
{
|
||||
onDownloaded(loader, resource, false);
|
||||
this._logger.error('Failed to download asset: ' + url);
|
||||
|
||||
loader.destroy();
|
||||
|
||||
cb(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(assetData.spritesheet && Object.keys(assetData.spritesheet).length)
|
||||
{
|
||||
const baseTexture = nitroBundle.baseTexture;
|
||||
remaining--;
|
||||
|
||||
if(!baseTexture)
|
||||
if(!remaining)
|
||||
{
|
||||
loader.destroy();
|
||||
|
||||
cb(true);
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
loader.load((loader, resources) =>
|
||||
{
|
||||
for(const key in resources)
|
||||
{
|
||||
const resource = resources[key];
|
||||
|
||||
if(!resource || resource.error)
|
||||
{
|
||||
onDownloaded(loader, resource, false);
|
||||
onDownloaded(false, resource.url);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(baseTexture.valid)
|
||||
if(resource.extension === 'nitro')
|
||||
{
|
||||
const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet);
|
||||
const nitroBundle = new NitroBundle(resource.data);
|
||||
|
||||
spritesheet.parse(() =>
|
||||
this.processAsset(nitroBundle.baseTexture, (nitroBundle.jsonFile as IAssetData), status =>
|
||||
{
|
||||
this.createCollection(assetData, spritesheet);
|
||||
|
||||
onDownloaded(loader, resource, true);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
baseTexture.once('loaded', () =>
|
||||
{
|
||||
baseTexture.removeAllListeners();
|
||||
|
||||
const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet);
|
||||
|
||||
spritesheet.parse(() =>
|
||||
{
|
||||
this.createCollection(assetData, spritesheet);
|
||||
|
||||
onDownloaded(loader, resource, true);
|
||||
});
|
||||
onDownloaded(true, resource.url);
|
||||
});
|
||||
|
||||
baseTexture.once('error', () =>
|
||||
{
|
||||
baseTexture.removeAllListeners();
|
||||
|
||||
onDownloaded(loader, resource, false);
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
return;
|
||||
if(resource.type === LoaderResource.TYPE.IMAGE)
|
||||
{
|
||||
if(resource.texture) this.setTexture(resource.name, resource.texture);
|
||||
|
||||
onDownloaded(true, resource.url);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.createCollection(assetData, null);
|
||||
private processAsset(baseTexture: BaseTexture, data: IAssetData, onDownloaded: (status: boolean) => void): void
|
||||
{
|
||||
const spritesheetData = data.spritesheet;
|
||||
|
||||
onDownloaded(loader, resource, true);
|
||||
}
|
||||
|
||||
else if(resource.type === LoaderResource.TYPE.IMAGE)
|
||||
if(spritesheetData && Object.keys(spritesheetData).length)
|
||||
{
|
||||
if(resource.texture.valid)
|
||||
{
|
||||
this.setTexture(resource.name, resource.texture);
|
||||
const spritesheet = new Spritesheet(baseTexture, spritesheetData);
|
||||
|
||||
onDownloaded(loader, resource, true);
|
||||
}
|
||||
else
|
||||
spritesheet.parse(() =>
|
||||
{
|
||||
onDownloaded(loader, resource, false);
|
||||
}
|
||||
this.createCollection(data, spritesheet);
|
||||
|
||||
onDownloaded(true);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.createCollection(data, null);
|
||||
|
||||
onDownloaded(true);
|
||||
}
|
||||
|
||||
public get collections(): Map<string, IGraphicAssetCollection>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Resource, Texture } from '@pixi/core';
|
||||
import { BaseTexture, Resource, Texture } from '@pixi/core';
|
||||
import { Loader, LoaderResource } from '@pixi/loaders';
|
||||
import { Spritesheet } from '@pixi/spritesheet';
|
||||
import { IAssetData } from '../../core/asset/interfaces';
|
||||
@ -10,6 +10,7 @@ import { NitroEvent } from '../../core/events/NitroEvent';
|
||||
import { RoomContentLoadedEvent } from '../../room/events/RoomContentLoadedEvent';
|
||||
import { IRoomObject } from '../../room/object/IRoomObject';
|
||||
import { GraphicAssetCollection } from '../../room/object/visualization/utils/GraphicAssetCollection';
|
||||
import { GraphicAssetGifCollection } from '../../room/object/visualization/utils/GraphicAssetGifCollection';
|
||||
import { IGraphicAssetCollection } from '../../room/object/visualization/utils/IGraphicAssetCollection';
|
||||
import { Nitro } from '../Nitro';
|
||||
import { FurnitureType } from '../session/furniture/FurnitureType';
|
||||
@ -42,6 +43,7 @@ export class RoomContentLoader implements IFurnitureDataListener
|
||||
private _waitingForSessionDataManager: boolean;
|
||||
private _iconListener: IRoomContentListener;
|
||||
private _collections: Map<string, IGraphicAssetCollection>;
|
||||
private _gifCollections: Map<string, GraphicAssetGifCollection>;
|
||||
private _images: Map<string, HTMLImageElement>;
|
||||
|
||||
private _events: Map<string, IEventDispatcher>;
|
||||
@ -69,6 +71,7 @@ export class RoomContentLoader implements IFurnitureDataListener
|
||||
this._waitingForSessionDataManager = false;
|
||||
this._iconListener = null;
|
||||
this._collections = new Map();
|
||||
this._gifCollections = new Map();
|
||||
this._images = new Map();
|
||||
|
||||
this._events = new Map();
|
||||
@ -312,6 +315,13 @@ export class RoomContentLoader implements IFurnitureDataListener
|
||||
return existing;
|
||||
}
|
||||
|
||||
public getGifCollection(name: string): GraphicAssetGifCollection
|
||||
{
|
||||
if(!name) return null;
|
||||
|
||||
return this._gifCollections.get(name) || null;
|
||||
}
|
||||
|
||||
public getImage(name: string): HTMLImageElement
|
||||
{
|
||||
if(!name) return null;
|
||||
@ -336,6 +346,17 @@ export class RoomContentLoader implements IFurnitureDataListener
|
||||
return collection.addAsset(assetName, texture, override, 0, 0, false, false);
|
||||
}
|
||||
|
||||
public createGifCollection(collectionName: string, textures: Texture<Resource>[], durations: number[]): GraphicAssetGifCollection
|
||||
{
|
||||
if(!collectionName || !textures || !durations) return null;
|
||||
|
||||
const collection = new GraphicAssetGifCollection(collectionName, textures, durations);
|
||||
|
||||
this._gifCollections.set(collectionName, collection);
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
private createCollection(data: IAssetData, spritesheet: Spritesheet): GraphicAssetCollection
|
||||
{
|
||||
if(!data || !spritesheet) return null;
|
||||
@ -480,149 +501,111 @@ export class RoomContentLoader implements IFurnitureDataListener
|
||||
return false;
|
||||
}
|
||||
|
||||
public downloadAsset(type: string, events: IEventDispatcher): boolean
|
||||
public downloadAsset(type: string, events: IEventDispatcher): void
|
||||
{
|
||||
const assetUrls: string[] = this.getAssetUrls(type);
|
||||
|
||||
if(!assetUrls || !assetUrls.length) return false;
|
||||
if(!assetUrls || !assetUrls.length) return;
|
||||
|
||||
if((this._pendingContentTypes.indexOf(type) >= 0) || this.getOrRemoveEventDispatcher(type)) return false;
|
||||
if((this._pendingContentTypes.indexOf(type) >= 0) || this.getOrRemoveEventDispatcher(type)) return;
|
||||
|
||||
this._pendingContentTypes.push(type);
|
||||
this._events.set(type, events);
|
||||
|
||||
const totalToDownload = assetUrls.length;
|
||||
let totalDownloaded = 0;
|
||||
|
||||
const onDownloaded = (loader: Loader, resource: LoaderResource, flag: boolean) =>
|
||||
{
|
||||
if(loader) loader.destroy();
|
||||
|
||||
if(!flag)
|
||||
{
|
||||
this._logger.error('Failed to download asset: ' + resource.url);
|
||||
|
||||
events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_FAILURE, type));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
totalDownloaded++;
|
||||
|
||||
if(totalDownloaded === totalToDownload)
|
||||
{
|
||||
const events = this._events.get(type);
|
||||
|
||||
if(!events) return;
|
||||
|
||||
events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_SUCCESS, type));
|
||||
}
|
||||
};
|
||||
const loader = new Loader();
|
||||
|
||||
for(const url of assetUrls)
|
||||
{
|
||||
if(!url) continue;
|
||||
|
||||
const loader = new Loader();
|
||||
if(!url || !url.endsWith('.nitro')) continue;
|
||||
|
||||
loader
|
||||
.add({
|
||||
url,
|
||||
crossOrigin: 'anonymous',
|
||||
xhrType: url.endsWith('.nitro') ? LoaderResource.XHR_RESPONSE_TYPE.BUFFER : LoaderResource.XHR_RESPONSE_TYPE.JSON
|
||||
})
|
||||
.use((resource: LoaderResource, next: Function) =>
|
||||
{
|
||||
this.assetLoader(loader, resource, onDownloaded);
|
||||
|
||||
next();
|
||||
})
|
||||
.load();
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
let remaining = assetUrls.length;
|
||||
|
||||
private assetLoader(loader: Loader, resource: LoaderResource, onDownloaded: Function): void
|
||||
{
|
||||
if(!resource || resource.error)
|
||||
const onDownloaded = (status: boolean, url: string) =>
|
||||
{
|
||||
if(resource && resource.texture) resource.texture.destroy(true);
|
||||
|
||||
onDownloaded(loader, resource, false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(resource.extension === 'nitro')
|
||||
{
|
||||
const nitroBundle = new NitroBundle(resource.data);
|
||||
const assetData = (nitroBundle.jsonFile as IAssetData);
|
||||
|
||||
if(!assetData)
|
||||
if(!status)
|
||||
{
|
||||
onDownloaded(loader, resource, false);
|
||||
this._logger.error('Failed to download asset: ' + url);
|
||||
|
||||
loader.destroy();
|
||||
|
||||
events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_FAILURE, type));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(assetData.spritesheet && Object.keys(assetData.spritesheet).length)
|
||||
{
|
||||
const baseTexture = nitroBundle.baseTexture;
|
||||
remaining--;
|
||||
|
||||
if(!baseTexture)
|
||||
if(!remaining)
|
||||
{
|
||||
loader.destroy();
|
||||
|
||||
const events = this._events.get(type);
|
||||
|
||||
if(!events) return;
|
||||
|
||||
events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_SUCCESS, type));
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
loader.load((loader, resources) =>
|
||||
{
|
||||
for(const key in resources)
|
||||
{
|
||||
const resource = resources[key];
|
||||
|
||||
if(!resource || resource.error)
|
||||
{
|
||||
onDownloaded(loader, resource, false);
|
||||
onDownloaded(false, resource.url);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(baseTexture.valid)
|
||||
if(resource.extension === 'nitro')
|
||||
{
|
||||
const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet);
|
||||
const nitroBundle = new NitroBundle(resource.data);
|
||||
|
||||
spritesheet.parse(() =>
|
||||
this.processAsset(nitroBundle.baseTexture, (nitroBundle.jsonFile as IAssetData), status =>
|
||||
{
|
||||
this.createCollection(assetData, spritesheet);
|
||||
|
||||
onDownloaded(loader, resource, true);
|
||||
onDownloaded(true, resource.url);
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseTexture.once('loaded', () =>
|
||||
{
|
||||
baseTexture.removeAllListeners();
|
||||
|
||||
const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet);
|
||||
|
||||
spritesheet.parse(() =>
|
||||
{
|
||||
this.createCollection(assetData, spritesheet);
|
||||
|
||||
onDownloaded(loader, resource, true);
|
||||
});
|
||||
});
|
||||
|
||||
baseTexture.once('error', () =>
|
||||
{
|
||||
baseTexture.removeAllListeners();
|
||||
|
||||
onDownloaded(loader, resource, false);
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.createCollection(assetData, null);
|
||||
private processAsset(baseTexture: BaseTexture, data: IAssetData, onDownloaded: (status: boolean) => void): void
|
||||
{
|
||||
const spritesheetData = data.spritesheet;
|
||||
|
||||
onDownloaded(loader, resource, true);
|
||||
}
|
||||
else
|
||||
if(spritesheetData && Object.keys(spritesheetData).length)
|
||||
{
|
||||
onDownloaded(loader, resource, false);
|
||||
const spritesheet = new Spritesheet(baseTexture, spritesheetData);
|
||||
|
||||
spritesheet.parse(() =>
|
||||
{
|
||||
this.createCollection(data, spritesheet);
|
||||
|
||||
onDownloaded(true);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.createCollection(data, null);
|
||||
|
||||
onDownloaded(true);
|
||||
}
|
||||
|
||||
public setAssetAliasName(name: string, originalName: string): void
|
||||
|
@ -75,6 +75,7 @@ export class RoomObjectVariable
|
||||
public static FURNITURE_BRANDING_OFFSET_X: string = 'furniture_branding_offset_x';
|
||||
public static FURNITURE_BRANDING_OFFSET_Y: string = 'furniture_branding_offset_y';
|
||||
public static FURNITURE_BRANDING_OFFSET_Z: string = 'furniture_branding_offset_z';
|
||||
public static FURNITURE_BRANDING_IS_ANIMATED: string = 'furniture_branding_is_animated';
|
||||
public static FURNITURE_BADGE_IMAGE_STATUS: string = 'furniture_badge_image_status';
|
||||
public static FURNITURE_BADGE_ASSET_NAME: string = 'furniture_badge_asset_name';
|
||||
public static FURNITURE_BADGE_VISIBLE_IN_STATE: string = 'furniture_badge_visible_in_state';
|
||||
|
@ -23,6 +23,7 @@ import { FurnitureGiftWrappedVisualization } from './visualization/furniture/Fur
|
||||
import { FurnitureGuildCustomizedVisualization } from './visualization/furniture/FurnitureGuildCustomizedVisualization';
|
||||
import { FurnitureGuildIsometricBadgeVisualization } from './visualization/furniture/FurnitureGuildIsometricBadgeVisualization';
|
||||
import { FurnitureHabboWheelVisualization } from './visualization/furniture/FurnitureHabboWheelVisualization';
|
||||
import { FurnitureIsometricBBVisualization } from './visualization/furniture/FurnitureIsometricBBVisualization';
|
||||
import { FurnitureMannequinVisualization } from './visualization/furniture/FurnitureMannequinVisualization';
|
||||
import { FurnitureMannequinVisualizationData } from './visualization/furniture/FurnitureMannequinVisualizationData';
|
||||
import { FurniturePartyBeamerVisualization } from './visualization/furniture/FurniturePartyBeamerVisualization';
|
||||
@ -107,6 +108,9 @@ export class RoomObjectVisualizationFactory implements IRoomObjectVisualizationF
|
||||
case RoomObjectVisualizationType.FURNITURE_BB:
|
||||
visualization = FurnitureBBVisualization;
|
||||
break;
|
||||
case RoomObjectVisualizationType.FURNITURE_ISOMETRIC_BB:
|
||||
visualization = FurnitureIsometricBBVisualization;
|
||||
break;
|
||||
case RoomObjectVisualizationType.FURNITURE_BOTTLE:
|
||||
visualization = FurnitureBottleVisualization;
|
||||
break;
|
||||
@ -204,6 +208,7 @@ export class RoomObjectVisualizationFactory implements IRoomObjectVisualizationF
|
||||
case RoomObjectVisualizationType.FURNITURE_STATIC:
|
||||
case RoomObjectVisualizationType.FURNITURE_GIFT_WRAPPED:
|
||||
case RoomObjectVisualizationType.FURNITURE_BB:
|
||||
case RoomObjectVisualizationType.FURNITURE_ISOMETRIC_BB:
|
||||
case RoomObjectVisualizationType.FURNITURE_BG:
|
||||
case RoomObjectVisualizationType.FURNITURE_STICKIE:
|
||||
case RoomObjectVisualizationType.FURNITURE_BUILDER_PLACEHOLDER:
|
||||
|
@ -19,6 +19,7 @@ export class RoomObjectVisualizationType
|
||||
public static FURNITURE_SCORE_BOARD = 'furniture_score_board';
|
||||
public static FURNITURE_FIREWORKS = 'furniture_fireworks';
|
||||
public static FURNITURE_BB = 'furniture_bb';
|
||||
public static FURNITURE_ISOMETRIC_BB = 'furniture_isometric_bb';
|
||||
public static FURNITURE_BG = 'furniture_bg';
|
||||
public static FURNITURE_STICKIE = 'furniture_stickie';
|
||||
public static FURNITURE_MANNEQUIN = 'furniture_mannequin';
|
||||
@ -36,4 +37,4 @@ export class RoomObjectVisualizationType
|
||||
public static BOT = 'bot';
|
||||
public static RENTABLE_BOT = 'rentable_bot';
|
||||
public static TILE_CURSOR = 'tile_cursor';
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { BaseTexture, Texture } from '@pixi/core';
|
||||
import { decompressFrames, parseGIF } from 'gifuct-js';
|
||||
import { IAssetData } from '../../../../../core';
|
||||
import { IRoomGeometry, RoomSpriteMouseEvent } from '../../../../../room';
|
||||
import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage';
|
||||
@ -149,29 +151,89 @@ export class FurnitureRoomBrandingLogic extends FurnitureLogic
|
||||
|
||||
if(!imageUrl || (imageUrl === '') || (imageStatus === 1)) return;
|
||||
|
||||
const asset = Nitro.instance.core && Nitro.instance.core.asset;
|
||||
|
||||
if(!asset) return;
|
||||
|
||||
const texture = asset.getTexture(imageUrl);
|
||||
|
||||
if(!texture)
|
||||
if(imageUrl.endsWith('.gif'))
|
||||
{
|
||||
asset.downloadAsset(imageUrl, (flag: boolean) =>
|
||||
{
|
||||
if(flag)
|
||||
this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IS_ANIMATED, true);
|
||||
|
||||
fetch(imageUrl)
|
||||
.then(resp => resp.arrayBuffer())
|
||||
.then(buff => parseGIF(buff))
|
||||
.then(gif =>
|
||||
{
|
||||
const width = gif.lsd.width;
|
||||
const height = gif.lsd.height;
|
||||
const wh = width * height;
|
||||
const frames = decompressFrames(gif, false);
|
||||
const textures = [];
|
||||
const durations = [];
|
||||
|
||||
let frame = new Uint8Array(wh * 4);
|
||||
|
||||
for(let ind = 0; ind < frames.length; ind++)
|
||||
{
|
||||
if(ind > 0) frame = frame.slice(0);
|
||||
|
||||
const pixels = frames[ind].pixels;
|
||||
const colorTable = frames[ind].colorTable;
|
||||
const trans = frames[ind].transparentIndex;
|
||||
const dims = frames[ind].dims;
|
||||
|
||||
for(let j = 0; j < dims.height; j++)
|
||||
{
|
||||
for(let i = 0; i < dims.width; i++)
|
||||
{
|
||||
const pixel = pixels[j*dims.width + i];
|
||||
const coord = (j + dims.top) * width + (i + dims.left);
|
||||
|
||||
if(trans !== pixel)
|
||||
{
|
||||
const c = colorTable[pixel];
|
||||
|
||||
frame[ 4 * coord ] = c[0];
|
||||
frame[ 4 * coord + 1 ] = c[1];
|
||||
frame[ 4 * coord + 2 ] = c[2];
|
||||
frame[ 4 * coord + 3 ] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const baseTexture = BaseTexture.fromBuffer(frame, width, height);
|
||||
|
||||
textures.push(new Texture(baseTexture));
|
||||
durations.push(frames[ind].delay);
|
||||
}
|
||||
|
||||
Nitro.instance.roomEngine.roomContentLoader.createGifCollection(imageUrl, textures, durations);
|
||||
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADING_FAILED));
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
const asset = Nitro.instance.core && Nitro.instance.core.asset;
|
||||
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED));
|
||||
if(!asset) return;
|
||||
|
||||
const texture = asset.getTexture(imageUrl);
|
||||
|
||||
if(!texture)
|
||||
{
|
||||
asset.downloadAsset(imageUrl, (flag: boolean) =>
|
||||
{
|
||||
if(flag)
|
||||
{
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADING_FAILED));
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,4 +16,4 @@ export class FurnitureBBVisualization extends FurnitureBrandedImageVisualization
|
||||
{
|
||||
return super.getLayerZOffset(scale, direction, layerId) + this._offsetZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,28 @@
|
||||
import { Resource, Texture } from '@pixi/core';
|
||||
import { GraphicAssetGifCollection } from '../../../../../room/object/visualization/utils/GraphicAssetGifCollection';
|
||||
import { Nitro } from '../../../../Nitro';
|
||||
import { RoomObjectVariable } from '../../RoomObjectVariable';
|
||||
import { FurnitureVisualization } from './FurnitureVisualization';
|
||||
|
||||
export class FurnitureBrandedImageVisualization extends FurnitureVisualization
|
||||
{
|
||||
private static BRANDED_IMAGE: string = 'branded_image';
|
||||
private static STATE_0: number = 0;
|
||||
private static STATE_1: number = 1;
|
||||
private static STATE_2: number = 2;
|
||||
private static STATE_3: number = 3;
|
||||
protected static BRANDED_IMAGE: string = 'branded_image';
|
||||
protected static STATE_0: number = 0;
|
||||
protected static STATE_1: number = 1;
|
||||
protected static STATE_2: number = 2;
|
||||
protected static STATE_3: number = 3;
|
||||
|
||||
protected _imageUrl: string;
|
||||
protected _shortUrl: string;
|
||||
protected _imageReady: boolean;
|
||||
protected _isAnimated: boolean;
|
||||
protected _gifCollection: GraphicAssetGifCollection;
|
||||
|
||||
protected _offsetX: number;
|
||||
protected _offsetY: number;
|
||||
protected _offsetZ: number;
|
||||
protected _currentFrame: number;
|
||||
protected _totalFrames: number;
|
||||
|
||||
constructor()
|
||||
{
|
||||
@ -26,17 +31,25 @@ export class FurnitureBrandedImageVisualization extends FurnitureVisualization
|
||||
this._imageUrl = null;
|
||||
this._shortUrl = null;
|
||||
this._imageReady = false;
|
||||
this._isAnimated = false;
|
||||
this._gifCollection = null;
|
||||
|
||||
this._offsetX = 0;
|
||||
this._offsetY = 0;
|
||||
this._offsetZ = 0;
|
||||
this._currentFrame = -1;
|
||||
this._totalFrames = -1;
|
||||
}
|
||||
|
||||
public dispose(): void
|
||||
{
|
||||
super.dispose();
|
||||
|
||||
if(this._imageUrl) (this.asset && this.asset.disposeAsset(this._imageUrl));
|
||||
if(this._imageUrl)
|
||||
{
|
||||
(this.asset && this.asset.disposeAsset(this._imageUrl));
|
||||
// dispose all
|
||||
}
|
||||
}
|
||||
|
||||
protected updateObject(scale: number, direction: number): boolean
|
||||
@ -54,9 +67,10 @@ export class FurnitureBrandedImageVisualization extends FurnitureVisualization
|
||||
|
||||
if(flag)
|
||||
{
|
||||
this._offsetX = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_X);
|
||||
this._offsetY = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Y);
|
||||
this._offsetZ = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Z);
|
||||
this._offsetX = (this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_X) || 0);
|
||||
this._offsetY = (this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Y) || 0);
|
||||
this._offsetZ = (this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Z) || 0);
|
||||
this._isAnimated = (this.object.model.getValue<boolean>(RoomObjectVariable.FURNITURE_BRANDING_IS_ANIMATED) || false);
|
||||
}
|
||||
|
||||
if(!this._imageReady)
|
||||
@ -84,26 +98,21 @@ export class FurnitureBrandedImageVisualization extends FurnitureVisualization
|
||||
return flag;
|
||||
}
|
||||
|
||||
protected imageReady(texture: Texture<Resource>, imageUrl: string): void
|
||||
{
|
||||
if(!texture)
|
||||
{
|
||||
this._imageUrl = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this._imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
private checkIfImageChanged(): boolean
|
||||
{
|
||||
const imageUrl = this.object.model.getValue<string>(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_URL);
|
||||
|
||||
if(imageUrl && (imageUrl === this._imageUrl)) return false;
|
||||
|
||||
if(this._gifCollection)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
(this.asset && this.asset.disposeAsset(this._imageUrl));
|
||||
|
||||
// dispose all
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -123,7 +132,23 @@ export class FurnitureBrandedImageVisualization extends FurnitureVisualization
|
||||
|
||||
if(imageStatus === 1)
|
||||
{
|
||||
const texture = Nitro.instance.core.asset.getTexture(imageUrl);
|
||||
let texture: Texture = null;
|
||||
|
||||
if(this._isAnimated)
|
||||
{
|
||||
const gifCollection = Nitro.instance.roomEngine.roomContentLoader.getGifCollection(imageUrl);
|
||||
|
||||
if(gifCollection)
|
||||
{
|
||||
this._gifCollection = gifCollection;
|
||||
|
||||
texture = gifCollection.textures[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = Nitro.instance.core.asset.getTexture(imageUrl);
|
||||
}
|
||||
|
||||
if(!texture) return false;
|
||||
|
||||
@ -135,8 +160,27 @@ export class FurnitureBrandedImageVisualization extends FurnitureVisualization
|
||||
return false;
|
||||
}
|
||||
|
||||
protected imageReady(texture: Texture<Resource>, imageUrl: string): void
|
||||
{
|
||||
if(!texture)
|
||||
{
|
||||
this._imageUrl = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this._imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
protected checkAndCreateImageForCurrentState(): void
|
||||
{
|
||||
if(this._isAnimated)
|
||||
{
|
||||
this.buildAssetsForGif();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!this._imageUrl) return;
|
||||
|
||||
const texture = Nitro.instance.core.asset.getTexture(this._imageUrl);
|
||||
@ -145,6 +189,36 @@ export class FurnitureBrandedImageVisualization extends FurnitureVisualization
|
||||
|
||||
const state = this.object.getState(0);
|
||||
|
||||
this.addBackgroundAsset(texture, state, 0);
|
||||
}
|
||||
|
||||
protected buildAssetsForGif(): void
|
||||
{
|
||||
if(!this._gifCollection) return;
|
||||
|
||||
const textures = this._gifCollection.textures;
|
||||
const durations = this._gifCollection.durations;
|
||||
|
||||
if(!textures.length || !durations.length || (textures.length !== durations.length)) return;
|
||||
|
||||
const state = this.object.getState(0);
|
||||
|
||||
for(let i = 0; i < textures.length; i++)
|
||||
{
|
||||
const texture = textures[i];
|
||||
const duration = durations[i];
|
||||
|
||||
if(!texture) continue;
|
||||
|
||||
this.addBackgroundAsset(texture, state, i);
|
||||
}
|
||||
|
||||
this._currentFrame = -1;
|
||||
this._totalFrames = textures.length;
|
||||
}
|
||||
|
||||
protected addBackgroundAsset(texture: Texture<Resource>, state: number, frame: number): void
|
||||
{
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
let flipH = false;
|
||||
@ -178,15 +252,54 @@ export class FurnitureBrandedImageVisualization extends FurnitureVisualization
|
||||
break;
|
||||
}
|
||||
|
||||
this.asset.addAsset(this._imageUrl, texture, true, x, y, flipH, flipV);
|
||||
this.asset.addAsset(`${ this._imageUrl }_${ frame }`, texture, true, x, y, flipH, flipV);
|
||||
}
|
||||
|
||||
protected getSpriteAssetName(scale: number, layerId: number): string
|
||||
{
|
||||
const tag = this.getLayerTag(scale, this._direction, layerId);
|
||||
|
||||
if((tag === FurnitureBrandedImageVisualization.BRANDED_IMAGE) && this._imageUrl) return this._imageUrl;
|
||||
if((tag === FurnitureBrandedImageVisualization.BRANDED_IMAGE) && this._imageUrl)
|
||||
{
|
||||
return `${ this._imageUrl }_${ this.getFrameNumber(scale, layerId) }`;
|
||||
}
|
||||
|
||||
return super.getSpriteAssetName(scale, layerId);
|
||||
}
|
||||
|
||||
protected updateAnimation(scale: number): number
|
||||
{
|
||||
if(!this._imageReady || !this._isAnimated || (this._totalFrames <= 0)) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected getFrameNumber(scale: number, layerId: number): number
|
||||
{
|
||||
if(!this._imageReady || !this._isAnimated || (this._totalFrames <= 0)) return 0;
|
||||
|
||||
const tag = this.getLayerTag(scale, this._direction, layerId);
|
||||
|
||||
if((tag === FurnitureBrandedImageVisualization.BRANDED_IMAGE) && this._imageUrl)
|
||||
{
|
||||
let newFrame = this._currentFrame;
|
||||
|
||||
if(newFrame < 0)
|
||||
{
|
||||
newFrame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
newFrame += 1;
|
||||
}
|
||||
|
||||
if(newFrame === this._totalFrames) newFrame = 0;
|
||||
|
||||
this._currentFrame = newFrame;
|
||||
|
||||
return this._currentFrame;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,172 @@
|
||||
import { RenderTexture, Resource, Texture } from '@pixi/core';
|
||||
import { Matrix } from '@pixi/math';
|
||||
import { NitroSprite } from '../../../../../core/utils/proxy/NitroSprite';
|
||||
import { IGraphicAsset } from '../../../../../room/object/visualization/utils/IGraphicAsset';
|
||||
import { TextureUtils } from '../../../../../room/utils/TextureUtils';
|
||||
import { Nitro } from '../../../../Nitro';
|
||||
import { FurnitureBBVisualization } from './FurnitureBBVisualization';
|
||||
import { FurnitureBrandedImageVisualization } from './FurnitureBrandedImageVisualization';
|
||||
|
||||
export class FurnitureIsometricBBVisualization extends FurnitureBBVisualization
|
||||
{
|
||||
private _needsTransform: boolean = true;
|
||||
|
||||
protected transformGifTextures(asset: IGraphicAsset): void
|
||||
{
|
||||
if(!this._gifCollection) return;
|
||||
|
||||
const textures = this._gifCollection.textures;
|
||||
|
||||
if(!textures.length) return;
|
||||
|
||||
for(let i = 0; i < textures.length; i++)
|
||||
{
|
||||
const texture = textures[i];
|
||||
|
||||
if(!texture) continue;
|
||||
|
||||
const existingAsset = this.getAsset(`${ this._imageUrl }_${ i }`);
|
||||
|
||||
if(!existingAsset) continue;
|
||||
|
||||
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 NitroSprite(texture);
|
||||
|
||||
const x = asset.x;
|
||||
const y = asset.y;
|
||||
const flipH = asset.flipH;
|
||||
const flipV = asset.flipV;
|
||||
|
||||
const renderTexture = RenderTexture.create({
|
||||
width: asset.width,
|
||||
height: asset.height
|
||||
});
|
||||
|
||||
Nitro.instance.renderer.render(sprite, {
|
||||
renderTexture: renderTexture,
|
||||
clear: true,
|
||||
transform: matrix
|
||||
});
|
||||
|
||||
const newTexture = TextureUtils.generateTexture(sprite);
|
||||
|
||||
this.asset.disposeAsset(`${ this._imageUrl }_${ i }`);
|
||||
this.asset.addAsset(`${ this._imageUrl }_${ i }`, newTexture, true, x, y, flipH, flipV);
|
||||
}
|
||||
|
||||
this._needsTransform = false;
|
||||
}
|
||||
|
||||
protected generateTransformedImage(texture: Texture<Resource>, asset: IGraphicAsset): void
|
||||
{
|
||||
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 NitroSprite(texture);
|
||||
|
||||
sprite.transform.setFromMatrix(matrix);
|
||||
|
||||
const x = asset.x;
|
||||
const y = asset.y;
|
||||
const flipH = asset.flipH;
|
||||
const flipV = asset.flipV;
|
||||
|
||||
const newTexture = TextureUtils.generateTexture(sprite);
|
||||
|
||||
this.asset.disposeAsset(`${ this._imageUrl }_0`);
|
||||
this.asset.addAsset(`${ this._imageUrl }_0`, newTexture, true, x, y, flipH, flipV);
|
||||
|
||||
this._needsTransform = false;
|
||||
}
|
||||
|
||||
protected checkAndCreateImageForCurrentState(): void
|
||||
{
|
||||
super.checkAndCreateImageForCurrentState();
|
||||
|
||||
this._needsTransform = true;
|
||||
}
|
||||
|
||||
protected getSpriteAssetName(scale: number, layerId: number): string
|
||||
{
|
||||
const tag = this.getLayerTag(scale, this._direction, layerId);
|
||||
|
||||
if((tag === FurnitureBrandedImageVisualization.BRANDED_IMAGE) && this._imageUrl)
|
||||
{
|
||||
if(this._needsTransform)
|
||||
{
|
||||
if(this._isAnimated)
|
||||
{
|
||||
this.transformGifTextures(this.getAsset(super.getSpriteAssetName(scale, layerId)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.generateTransformedImage(Nitro.instance.core.asset.getTexture(this._imageUrl), this.getAsset(super.getSpriteAssetName(scale, layerId)));
|
||||
}
|
||||
}
|
||||
|
||||
return `${ this._imageUrl }_${ this.getFrameNumber(scale, layerId) }`;
|
||||
}
|
||||
|
||||
return super.getSpriteAssetName(scale, layerId);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import { Resource, Texture } from '@pixi/core';
|
||||
|
||||
export class GraphicAssetGifCollection
|
||||
{
|
||||
constructor(
|
||||
public name: string,
|
||||
public textures: Texture<Resource>[],
|
||||
public durations: number[]
|
||||
)
|
||||
{}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
export * from './GraphicAsset';
|
||||
export * from './GraphicAssetGifCollection';
|
||||
//export * from './GraphicAssetCollection';
|
||||
export * from './GraphicAssetPalette';
|
||||
export * from './IGraphicAsset';
|
||||
|
Loading…
Reference in New Issue
Block a user