mirror of
https://github.com/billsonnn/nitro-renderer.git
synced 2024-11-27 01:40:52 +01:00
Update furni visualizations
This commit is contained in:
parent
7ca4141931
commit
402eedf738
@ -4,6 +4,7 @@ import { IAssetAlias } from './IAssetAlias';
|
||||
import { IAssetDimension } from './IAssetDimension';
|
||||
import { IAssetPalette } from './IAssetPalette';
|
||||
import { IPlanetSystem } from './IPlanetSystem';
|
||||
import { IParticleSystem } from './particlesystem';
|
||||
import { ISpritesheet } from './spritesheet';
|
||||
import { IAssetVisualizationData } from './visualization';
|
||||
|
||||
@ -16,7 +17,8 @@ export interface IAssetData {
|
||||
credits?: string;
|
||||
soundSample?: { id?: number, noPitch?: boolean };
|
||||
action?: { link?: string, startState?: number };
|
||||
planetSystem?: IPlanetSystem;
|
||||
planetSystems?: IPlanetSystem[];
|
||||
particleSystems?: IParticleSystem[];
|
||||
spritesheet?: ISpritesheet;
|
||||
dimensions?: IAssetDimension;
|
||||
directions?: number[];
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { IPlanetSystemObject } from './IPlanetSystemObject';
|
||||
|
||||
export interface IPlanetSystem
|
||||
{
|
||||
objects?: IPlanetSystemObject[];
|
||||
id?: number;
|
||||
name?: string;
|
||||
parent?: string;
|
||||
radius?: number;
|
||||
arcSpeed?: number;
|
||||
arcOffset?: number;
|
||||
blend?: number;
|
||||
height?: number;
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
export interface IPlanetSystemObject
|
||||
{
|
||||
id?: number;
|
||||
name?: string;
|
||||
parent?: string;
|
||||
radius?: number;
|
||||
arcSpeed?: number;
|
||||
arcOffset?: number;
|
||||
blend?: number;
|
||||
height?: number;
|
||||
}
|
@ -5,6 +5,5 @@ export * from './IAssetData';
|
||||
export * from './IAssetDimension';
|
||||
export * from './IAssetPalette';
|
||||
export * from './IPlanetSystem';
|
||||
export * from './IPlanetSystemObject';
|
||||
export * from './spritesheet';
|
||||
export * from './visualization';
|
||||
|
11
src/core/asset/interfaces/particlesystem/IParticleSystem.ts
Normal file
11
src/core/asset/interfaces/particlesystem/IParticleSystem.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { IParticleSystemEmitter } from './IParticleSystemEmitter';
|
||||
|
||||
export interface IParticleSystem
|
||||
{
|
||||
size?: number;
|
||||
canvasId?: number;
|
||||
offsetY?: number;
|
||||
blend?: number;
|
||||
bgColor?: string;
|
||||
emitters?: IParticleSystemEmitter[];
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
import { IParticleSystemParticle } from './IParticleSystemParticle';
|
||||
import { IParticleSystemSimulation } from './IParticleSystemSimulation';
|
||||
|
||||
export interface IParticleSystemEmitter
|
||||
{
|
||||
id?: number;
|
||||
name?: string;
|
||||
spriteId?: number;
|
||||
maxNumParticles?: number;
|
||||
particlesPerFrame?: number;
|
||||
burstPulse?: number;
|
||||
fuseTime?: number;
|
||||
simulation?: IParticleSystemSimulation;
|
||||
particles?: IParticleSystemParticle[];
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
export interface IParticleSystemParticle
|
||||
{
|
||||
isEmitter?: boolean;
|
||||
lifeTime?: number;
|
||||
fade?: boolean;
|
||||
frames?: string[];
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
export interface IParticleSystemSimulation
|
||||
{
|
||||
force?: number;
|
||||
direction?: number;
|
||||
gravity?: number;
|
||||
airFriction?: number;
|
||||
shape?: string;
|
||||
energy?: number;
|
||||
}
|
4
src/core/asset/interfaces/particlesystem/index.ts
Normal file
4
src/core/asset/interfaces/particlesystem/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './IParticleSystem';
|
||||
export * from './IParticleSystemEmitter';
|
||||
export * from './IParticleSystemParticle';
|
||||
export * from './IParticleSystemSimulation';
|
@ -71,6 +71,13 @@
|
||||
this._z = (this._z * k);
|
||||
}
|
||||
|
||||
public scaleBy(value: number): void
|
||||
{
|
||||
this._x *= value;
|
||||
this._y *= value;
|
||||
this._z *= value;
|
||||
}
|
||||
|
||||
public length(): number
|
||||
{
|
||||
return Math.sqrt((((this._x * this._x) + (this._y * this._y)) + (this._z * this._z)));
|
||||
|
@ -1,27 +0,0 @@
|
||||
import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper';
|
||||
import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser';
|
||||
|
||||
export class AuthenticationParser implements IMessageParser
|
||||
{
|
||||
private _sso: string;
|
||||
|
||||
public flush(): boolean
|
||||
{
|
||||
this._sso = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public parse(wrapper: IMessageDataWrapper): boolean
|
||||
{
|
||||
if(!wrapper) return false;
|
||||
|
||||
this._sso = wrapper.readString();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public get sso(): string
|
||||
{
|
||||
return this._sso;
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './AuthenticationParser';
|
@ -102,6 +102,7 @@ export class RoomObjectVariable
|
||||
public static FURNITURE_CLOTHING_BOY: string = 'furniture_clothing_boy';
|
||||
public static FURNITURE_CLOTHING_GIRL: string = 'furniture_clothing_girl';
|
||||
public static FURNITURE_PLANETSYSTEM_DATA: string = 'furniture_planetsystem_data';
|
||||
public static FURNITURE_FIREWORKS_DATA: string = 'furniture_fireworks_data';
|
||||
public static PET_PALETTE_INDEX: string = 'pet_palette_index';
|
||||
public static PET_COLOR: string = 'pet_color';
|
||||
public static PET_HEAD_ONLY: string = 'pet_head_only';
|
||||
|
@ -1,6 +1,67 @@
|
||||
import { IAssetData } from '../../../../../core';
|
||||
import { IParticleSystem } from '../../../../../core/asset/interfaces/particlesystem';
|
||||
import { RoomObjectEvent } from '../../../../../room/events/RoomObjectEvent';
|
||||
import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent';
|
||||
import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry';
|
||||
import { MouseEventType } from '../../../../ui/MouseEventType';
|
||||
import { RoomObjectStateChangedEvent } from '../../../events/RoomObjectStateChangedEvent';
|
||||
import { RoomObjectVariable } from '../../RoomObjectVariable';
|
||||
import { FurnitureLogic } from './FurnitureLogic';
|
||||
|
||||
export class FurnitureFireworksLogic extends FurnitureLogic
|
||||
{
|
||||
public getEventTypes(): string[]
|
||||
{
|
||||
const types = [ RoomObjectStateChangedEvent.STATE_CHANGE ];
|
||||
|
||||
return this.mergeTypes(super.getEventTypes(), types);
|
||||
}
|
||||
|
||||
public initialize(asset: IAssetData): void
|
||||
{
|
||||
super.initialize(asset);
|
||||
|
||||
if(asset.particleSystems && asset.particleSystems.length)
|
||||
{
|
||||
this.object.model.setValue<IParticleSystem[]>(RoomObjectVariable.FURNITURE_FIREWORKS_DATA, asset.particleSystems);
|
||||
}
|
||||
}
|
||||
|
||||
public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void
|
||||
{
|
||||
if(!event|| !geometry || !this.object) return;
|
||||
|
||||
let objectEvent: RoomObjectEvent = null;
|
||||
|
||||
switch(event.type)
|
||||
{
|
||||
case MouseEventType.DOUBLE_CLICK:
|
||||
switch(event.spriteTag)
|
||||
{
|
||||
case 'start_stop':
|
||||
objectEvent = new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 1);
|
||||
break;
|
||||
case 'reset':
|
||||
objectEvent = new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
if(this.eventDispatcher && objectEvent)
|
||||
{
|
||||
this.eventDispatcher.dispatchEvent(objectEvent);
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
super.mouseEvent(event, geometry);
|
||||
}
|
||||
|
||||
public useObject(): void
|
||||
{
|
||||
if(!this.object || !this.eventDispatcher) return;
|
||||
|
||||
this.eventDispatcher.dispatchEvent(new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 0));
|
||||
}
|
||||
}
|
@ -8,9 +8,9 @@ export class FurniturePlanetSystemLogic extends FurnitureLogic
|
||||
{
|
||||
super.initialize(asset);
|
||||
|
||||
if(asset.planetSystem)
|
||||
if(asset.planetSystems)
|
||||
{
|
||||
this.object.model.setValue<IPlanetSystem>(RoomObjectVariable.FURNITURE_PLANETSYSTEM_DATA, asset.planetSystem);
|
||||
this.object.model.setValue<IPlanetSystem[]>(RoomObjectVariable.FURNITURE_PLANETSYSTEM_DATA, asset.planetSystems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
import { IGraphicAsset } from '../../../../../room';
|
||||
|
||||
export interface ParticleSystemParticle
|
||||
{
|
||||
isEmitter?: boolean;
|
||||
lifeTime?: number;
|
||||
fade?: boolean;
|
||||
frames?: IGraphicAsset[];
|
||||
}
|
@ -10,5 +10,6 @@ export * from './ColorData';
|
||||
export * from './DirectionalOffsetData';
|
||||
export * from './DirectionData';
|
||||
export * from './LayerData';
|
||||
export * from './ParticleSystemParticle';
|
||||
export * from './PetSizeData';
|
||||
export * from './SizeData';
|
||||
|
@ -11,6 +11,7 @@ export class FurnitureDynamicThumbnailVisualization extends FurnitureThumbnailVi
|
||||
super();
|
||||
|
||||
this._cachedUrl = null;
|
||||
this._hasOutline = true;
|
||||
}
|
||||
|
||||
protected updateModel(scale: number): boolean
|
||||
|
@ -1,6 +1,111 @@
|
||||
import { AdvancedMap, NitroLogger } from '../../../../../core';
|
||||
import { IParticleSystem } from '../../../../../core/asset/interfaces/particlesystem';
|
||||
import { RoomObjectVariable } from '../../RoomObjectVariable';
|
||||
import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization';
|
||||
import { FurnitureParticleSystem } from './FurnitureParticleSystem';
|
||||
|
||||
export class FurnitureFireworksVisualization extends FurnitureAnimatedVisualization
|
||||
{
|
||||
private _particleSystems: AdvancedMap<number, FurnitureParticleSystem>;
|
||||
private _currentParticleSystem: FurnitureParticleSystem;
|
||||
|
||||
public dispose():void
|
||||
{
|
||||
super.dispose();
|
||||
|
||||
this._currentParticleSystem = null;
|
||||
|
||||
if(this._particleSystems)
|
||||
{
|
||||
for(const particleSystem of this._particleSystems.getValues()) particleSystem.dispose();
|
||||
|
||||
this._particleSystems = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected updateObject(scale: number, direction: number): boolean
|
||||
{
|
||||
if(super.updateObject(scale, direction))
|
||||
{
|
||||
if(!this._particleSystems)
|
||||
{
|
||||
this._Str_18684();
|
||||
|
||||
if(this._particleSystems) this._currentParticleSystem = this._particleSystems.getValue(scale);
|
||||
|
||||
else NitroLogger.log(('ERROR Particle systems could not be read! ' + this.object.type));
|
||||
}
|
||||
else
|
||||
{
|
||||
if((scale !== this._scale) || (this._particleSystems.getValue(scale) !== this._currentParticleSystem))
|
||||
{
|
||||
const particleSystem = this._particleSystems.getValue(scale);
|
||||
|
||||
particleSystem._Str_17988(this._currentParticleSystem);
|
||||
|
||||
if(this._currentParticleSystem) this._currentParticleSystem.reset();
|
||||
|
||||
this._currentParticleSystem = particleSystem;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected updateSprites(scale: number, update: boolean, animation: number):void
|
||||
{
|
||||
super.updateSprites(scale, update, animation);
|
||||
|
||||
if(this._currentParticleSystem) this._currentParticleSystem.updateSprites();
|
||||
}
|
||||
|
||||
protected updateAnimation(scale: number): number
|
||||
{
|
||||
if(this._currentParticleSystem) this._currentParticleSystem.updateAnimation();
|
||||
|
||||
return super.updateAnimation(scale);
|
||||
}
|
||||
|
||||
protected setAnimation(id: number):void
|
||||
{
|
||||
if(this._currentParticleSystem) this._currentParticleSystem.setAnimation(id);
|
||||
|
||||
super.setAnimation(id);
|
||||
}
|
||||
|
||||
protected getLayerYOffset(scale: number, direction: number, layerId: number): number
|
||||
{
|
||||
if(this._currentParticleSystem && this._currentParticleSystem.controlsSprite(layerId))
|
||||
{
|
||||
return this._currentParticleSystem.getLayerYOffset(scale, direction, layerId);
|
||||
}
|
||||
|
||||
return super.getLayerYOffset(scale, direction, layerId);
|
||||
}
|
||||
|
||||
private _Str_18684(): boolean
|
||||
{
|
||||
if(!this.object || !this.object.model) return false;
|
||||
|
||||
const fireworksData = this.object.model.getValue<IParticleSystem[]>(RoomObjectVariable.FURNITURE_FIREWORKS_DATA);
|
||||
|
||||
if(!fireworksData || !fireworksData.length) return false;
|
||||
|
||||
this._particleSystems = new AdvancedMap();
|
||||
|
||||
for(const particleData of fireworksData)
|
||||
{
|
||||
const size = particleData.size;
|
||||
const particleSystem = new FurnitureParticleSystem(this);
|
||||
|
||||
particleSystem.parseData(particleData);
|
||||
|
||||
this._particleSystems.add(size, particleSystem);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,344 @@
|
||||
import { RenderTexture, Texture } from '@pixi/core';
|
||||
import { AlphaFilter } from '@pixi/filter-alpha';
|
||||
import { Graphics } from '@pixi/graphics';
|
||||
import { Matrix } from '@pixi/math';
|
||||
import { AdvancedMap, NitroPoint, NitroSprite } from '../../../../../core';
|
||||
import { IParticleSystem } from '../../../../../core/asset/interfaces/particlesystem';
|
||||
import { IGraphicAsset, IRoomObjectSprite } from '../../../../../room';
|
||||
import { Vector3D } from '../../../../avatar';
|
||||
import { Nitro } from '../../../../Nitro';
|
||||
import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization';
|
||||
import { FurnitureParticleSystemEmitter } from './FurnitureParticleSystemEmitter';
|
||||
|
||||
export class FurnitureParticleSystem
|
||||
{
|
||||
private _emitters: AdvancedMap<number, FurnitureParticleSystemEmitter>;
|
||||
private _visualization: FurnitureAnimatedVisualization;
|
||||
private _size: number;
|
||||
private _canvasId: number = -1;
|
||||
private _offsetY: number;
|
||||
private _currentEmitter: FurnitureParticleSystemEmitter;
|
||||
private _canvasTexture: RenderTexture;
|
||||
private _roomSprite: IRoomObjectSprite;
|
||||
private _hasIgnited: boolean = false;
|
||||
private _centerX: number = 0;
|
||||
private _centerY: number = 0;
|
||||
private _scaleMultiplier: number = 1;
|
||||
private _blackOverlay: Graphics;
|
||||
private _blackOverlayAlphaTransform: AlphaFilter;
|
||||
private _particleColorTransform: AlphaFilter;
|
||||
private _identityMatrix: Matrix;
|
||||
private _translationMatrix: Matrix;
|
||||
private _blend: number = 1;
|
||||
private _bgColor: number = 0xFF000000;
|
||||
private _emptySprite: NitroSprite;
|
||||
private _isDone: boolean = false;
|
||||
|
||||
constructor(visualization: FurnitureAnimatedVisualization)
|
||||
{
|
||||
this._emitters = new AdvancedMap();
|
||||
this._visualization = visualization;
|
||||
this._blackOverlayAlphaTransform = new AlphaFilter();
|
||||
this._blackOverlayAlphaTransform.alpha = 1;
|
||||
this._particleColorTransform = new AlphaFilter();
|
||||
this._identityMatrix = new Matrix();
|
||||
this._translationMatrix = new Matrix();
|
||||
}
|
||||
|
||||
public dispose(): void
|
||||
{
|
||||
for(const emitter of this._emitters.getValues()) emitter.dispose();
|
||||
|
||||
this._emitters = null;
|
||||
|
||||
if(this._canvasTexture)
|
||||
{
|
||||
this._canvasTexture.destroy();
|
||||
this._canvasTexture = null;
|
||||
}
|
||||
|
||||
if(this._blackOverlay)
|
||||
{
|
||||
this._blackOverlay.destroy();
|
||||
this._blackOverlay = null;
|
||||
}
|
||||
|
||||
if(this._emptySprite)
|
||||
{
|
||||
this._emptySprite.destroy();
|
||||
this._emptySprite = null;
|
||||
}
|
||||
|
||||
this._blackOverlayAlphaTransform = null;
|
||||
this._particleColorTransform = null;
|
||||
this._identityMatrix = null;
|
||||
this._translationMatrix = null;
|
||||
}
|
||||
|
||||
public reset(): void
|
||||
{
|
||||
if(this._currentEmitter) this._currentEmitter.reset();
|
||||
|
||||
this._currentEmitter = null;
|
||||
this._hasIgnited = false;
|
||||
this._isDone = false;
|
||||
|
||||
this.updateCanvas();
|
||||
}
|
||||
|
||||
public setAnimation(id: number): void
|
||||
{
|
||||
if(this._currentEmitter) this._currentEmitter.reset();
|
||||
|
||||
this._currentEmitter = this._emitters.getValue(id);
|
||||
this._hasIgnited = false;
|
||||
this._isDone = false;
|
||||
|
||||
this.updateCanvas();
|
||||
}
|
||||
|
||||
private updateCanvas(): void
|
||||
{
|
||||
if(!this._currentEmitter || (this._canvasId === -1)) return;
|
||||
|
||||
this._roomSprite = this._visualization.getSprite(this._canvasId);
|
||||
|
||||
if(this._roomSprite && this._roomSprite.texture)
|
||||
{
|
||||
if((this._roomSprite.width <= 1) || (this._roomSprite.height <= 1)) return;
|
||||
|
||||
if(this._canvasTexture && ((this._canvasTexture.width !== this._roomSprite.width) || (this._canvasTexture.height !== this._roomSprite.height))) this._canvasTexture = null;
|
||||
|
||||
if(!this._canvasTexture)
|
||||
{
|
||||
this._canvasTexture = RenderTexture.create({
|
||||
width: this._roomSprite.width,
|
||||
height: this._roomSprite.height
|
||||
});
|
||||
}
|
||||
|
||||
if(!this._emptySprite)
|
||||
{
|
||||
this._emptySprite = new NitroSprite(Texture.WHITE);
|
||||
|
||||
this._emptySprite.tint = this._bgColor;
|
||||
}
|
||||
|
||||
this._centerX = -(this._roomSprite.offsetX);
|
||||
this._centerY = -(this._roomSprite.offsetY);
|
||||
this._roomSprite.texture = this._canvasTexture;
|
||||
}
|
||||
}
|
||||
|
||||
public getLayerYOffset(scale: number, direction: number, layerId: number): number
|
||||
{
|
||||
if(this._currentEmitter && (this._currentEmitter.roomObjectSpriteId === layerId))
|
||||
{
|
||||
return this._currentEmitter.y * this._scaleMultiplier;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public controlsSprite(k: number): boolean
|
||||
{
|
||||
if(this._currentEmitter) return this._currentEmitter.roomObjectSpriteId == k;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public updateSprites(): void
|
||||
{
|
||||
if(!this._currentEmitter || !this._roomSprite) return;
|
||||
|
||||
if(this._canvasTexture && (this._roomSprite.texture !== this._canvasTexture))
|
||||
{
|
||||
this._roomSprite.texture = this._canvasTexture;
|
||||
}
|
||||
|
||||
if(this._hasIgnited)
|
||||
{
|
||||
if(this._currentEmitter.roomObjectSpriteId >= 0) this._visualization.getSprite(this._currentEmitter.roomObjectSpriteId).visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
public updateAnimation(): void
|
||||
{
|
||||
if(!this._currentEmitter || !this._roomSprite || this._isDone) return;
|
||||
|
||||
const k = 10;
|
||||
|
||||
if(!this._hasIgnited && this._currentEmitter.hasIgnited) this._hasIgnited = true;
|
||||
|
||||
const offsetY = (this._offsetY * this._scaleMultiplier);
|
||||
|
||||
this._currentEmitter.update();
|
||||
|
||||
if(this._hasIgnited)
|
||||
{
|
||||
if(this._currentEmitter.roomObjectSpriteId >= 0)
|
||||
{
|
||||
this._visualization.getSprite(this._currentEmitter.roomObjectSpriteId).visible = false;
|
||||
}
|
||||
|
||||
if(!this._canvasTexture) this.updateCanvas();
|
||||
|
||||
if(this._blackOverlayAlphaTransform.alpha === 1)
|
||||
{
|
||||
this._emptySprite.filters = null;
|
||||
|
||||
Nitro.instance.renderer.render(this._emptySprite, {
|
||||
renderTexture: this._canvasTexture,
|
||||
clear: true
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
this._emptySprite.filters = [ this._blackOverlayAlphaTransform ];
|
||||
|
||||
Nitro.instance.renderer.render(this._emptySprite, {
|
||||
renderTexture: this._canvasTexture,
|
||||
transform: this._identityMatrix,
|
||||
clear: true
|
||||
});
|
||||
}
|
||||
|
||||
for(const particle of this._currentEmitter.particles)
|
||||
{
|
||||
const tx = (this._centerX + ((((particle.x - particle.z) * k) / 10) * this._scaleMultiplier));
|
||||
const ty = ((this._centerY - offsetY) + ((((particle.y + ((particle.x + particle.z) / 2)) * k) / 10) * this._scaleMultiplier));
|
||||
const asset = particle.getAsset();
|
||||
|
||||
if(asset)
|
||||
{
|
||||
const texture = asset.texture;
|
||||
|
||||
if(particle.fade && (particle.alphaMultiplier < 1))
|
||||
{
|
||||
this._translationMatrix.identity();
|
||||
this._translationMatrix.translate((tx + asset.offsetX), (ty + asset.offsetY));
|
||||
|
||||
const sprite = new NitroSprite(texture);
|
||||
|
||||
this._particleColorTransform.alpha = particle.alphaMultiplier;
|
||||
|
||||
sprite.filters = [ this._particleColorTransform ];
|
||||
|
||||
Nitro.instance.renderer.render(sprite, {
|
||||
renderTexture: this._canvasTexture,
|
||||
transform: this._translationMatrix,
|
||||
clear: false
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
const point = new NitroPoint((tx + asset.offsetX), (ty + asset.offsetY));
|
||||
|
||||
const sprite = new NitroSprite(texture);
|
||||
|
||||
sprite.x = point.x;
|
||||
sprite.y = point.y;
|
||||
|
||||
Nitro.instance.renderer.render(sprite, {
|
||||
renderTexture: this._canvasTexture,
|
||||
clear: false
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const sprite = new NitroSprite(Texture.WHITE);
|
||||
|
||||
sprite.tint = 0xFFFFFF;
|
||||
sprite.x = (tx - 1);
|
||||
sprite.y = (ty - 1);
|
||||
sprite.width = 2;
|
||||
sprite.height = 2;
|
||||
|
||||
Nitro.instance.renderer.render(sprite, {
|
||||
renderTexture: this._canvasTexture,
|
||||
clear: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(!this._currentEmitter.particles.length)
|
||||
{
|
||||
this._isDone = true;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public parseData(particleSystem: IParticleSystem): void
|
||||
{
|
||||
this._size = particleSystem.size;
|
||||
this._canvasId = ((particleSystem.canvasId !== undefined) ? particleSystem.canvasId : -1);
|
||||
this._offsetY = ((particleSystem.offsetY !== undefined) ? particleSystem.offsetY : 10);
|
||||
this._scaleMultiplier = (this._size / 64);
|
||||
this._blend = ((particleSystem.blend !== undefined) ? particleSystem.blend : 1);
|
||||
this._blend = Math.min(this._blend, 1);
|
||||
|
||||
this._blackOverlayAlphaTransform.alpha = this._blend;
|
||||
|
||||
const bgColor = ((particleSystem.bgColor !== undefined) ? particleSystem.bgColor : '0');
|
||||
|
||||
this._bgColor = (parseInt(bgColor, 16) || 0x000000);
|
||||
|
||||
if(!particleSystem.emitters || !particleSystem.emitters.length) return;
|
||||
|
||||
for(const emitter of particleSystem.emitters)
|
||||
{
|
||||
const emitterId = emitter.id;
|
||||
const emitterName = emitter.name;
|
||||
const emitterSpriteId = emitter.spriteId;
|
||||
|
||||
const particleEmitter = new FurnitureParticleSystemEmitter(emitterName, emitterSpriteId);
|
||||
|
||||
this._emitters.add(emitterId, particleEmitter);
|
||||
|
||||
const maxNumParticles = emitter.maxNumParticles;
|
||||
const particlesPerFrame = emitter.particlesPerFrame;
|
||||
const burstPulse = ((emitter.burstPulse !== undefined) ? emitter.burstPulse : 1);
|
||||
const fuseTime = emitter.fuseTime;
|
||||
const simulationForce = emitter.simulation.force;
|
||||
const simulationDirection = emitter.simulation.direction;
|
||||
const simulationGravity = emitter.simulation.gravity;
|
||||
const simulationAirFriction = emitter.simulation.airFriction;
|
||||
const simulationShape = emitter.simulation.shape;
|
||||
const simulationEnergy = emitter.simulation.energy;
|
||||
|
||||
for(const particle of emitter.particles)
|
||||
{
|
||||
const lifeTime = particle.lifeTime;
|
||||
const isEmitter = (particle.isEmitter || false);
|
||||
const fade = (particle.fade || false);
|
||||
|
||||
const frames: IGraphicAsset[] = [];
|
||||
|
||||
for(const name of particle.frames) frames.push(this._visualization.asset.getAsset(name));
|
||||
|
||||
particleEmitter.configureParticle(lifeTime, isEmitter, frames, fade);
|
||||
}
|
||||
|
||||
particleEmitter.setup(maxNumParticles, particlesPerFrame, simulationForce, new Vector3D(0, simulationDirection, 0), simulationGravity, simulationAirFriction, simulationShape, simulationEnergy, fuseTime, burstPulse);
|
||||
}
|
||||
}
|
||||
|
||||
public _Str_17988(particleSystem: FurnitureParticleSystem): void
|
||||
{
|
||||
let emitterId = 0;
|
||||
|
||||
if(particleSystem._emitters && particleSystem._currentEmitter)
|
||||
{
|
||||
emitterId = particleSystem._emitters.getKey(particleSystem._emitters.getValues().indexOf(particleSystem._currentEmitter));
|
||||
}
|
||||
|
||||
this.setAnimation(emitterId);
|
||||
|
||||
if(this._currentEmitter) this._currentEmitter.copyStateFrom(particleSystem._currentEmitter, (particleSystem._size / this._size));
|
||||
|
||||
this._canvasTexture = null;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { GraphicAsset } from '../../../../../room/object/visualization/utils/GraphicAsset';
|
||||
import { IGraphicAsset } from '../../../../../room';
|
||||
import { Vector3D } from '../../../../avatar/geometry/Vector3D';
|
||||
import { ParticleSystemParticle } from '../data';
|
||||
import { FurnitureParticleSystemParticle } from './FurnitureParticleSystemParticle';
|
||||
|
||||
export class FurnitureParticleSystemEmitter extends FurnitureParticleSystemParticle
|
||||
@ -15,7 +16,7 @@ export class FurnitureParticleSystemEmitter extends FurnitureParticleSystemParti
|
||||
private _gravity: number;
|
||||
private _airFriction: number;
|
||||
private _explosionShape: string;
|
||||
private _particleConfigurations: { [index: string]: any }[];
|
||||
private _particleConfigurations: ParticleSystemParticle[];
|
||||
private _particles: FurnitureParticleSystemParticle[];
|
||||
private _maxNumberOfParticles: number;
|
||||
private _particlesPerFrame: number;
|
||||
@ -24,14 +25,15 @@ export class FurnitureParticleSystemEmitter extends FurnitureParticleSystemParti
|
||||
private _energy: number = 1;
|
||||
private _hasIgnited: boolean = false;
|
||||
private _burstPulse: number = 1;
|
||||
private _emitterDirection: Vector3D;
|
||||
|
||||
constructor(k: string='', _arg_2: number=-1)
|
||||
constructor(name: string = '', spriteId: number = -1)
|
||||
{
|
||||
super();
|
||||
|
||||
this._particles = [];
|
||||
this._name = k;
|
||||
this._roomObjectSpriteId = _arg_2;
|
||||
this._name = name;
|
||||
this._roomObjectSpriteId = spriteId;
|
||||
this._particleConfigurations = [];
|
||||
}
|
||||
|
||||
@ -40,205 +42,204 @@ export class FurnitureParticleSystemEmitter extends FurnitureParticleSystemParti
|
||||
for(const k of this._particles) k.dispose();
|
||||
|
||||
this._particles = null;
|
||||
this._direction = null;
|
||||
this._particleConfigurations = null;
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public setup(k: number, _arg_2: number, _arg_3: number, _arg_4: Vector3D, _arg_5: number, _arg_6: number, _arg_7: string, _arg_8: number, _arg_9: number, _arg_10: number): void
|
||||
public setup(maxNumOfParticles: number, particlesPerFrame: number, force: number, direction: Vector3D, gravity: number, airFriction: number, explosionShape: string, energy: number, fuseTime: number, burstPulse: number): void
|
||||
{
|
||||
this._maxNumberOfParticles = k;
|
||||
this._particlesPerFrame = _arg_2;
|
||||
this._force = _arg_3;
|
||||
this._direction = _arg_4;
|
||||
this._direction.normalize();
|
||||
this._gravity = _arg_5;
|
||||
this._airFriction = _arg_6;
|
||||
this._explosionShape = _arg_7;
|
||||
this._fuseTime = _arg_9;
|
||||
this._energy = _arg_8;
|
||||
this._burstPulse = _arg_10;
|
||||
this._maxNumberOfParticles = maxNumOfParticles;
|
||||
this._particlesPerFrame = particlesPerFrame;
|
||||
this._force = force;
|
||||
this._emitterDirection = direction;
|
||||
this._emitterDirection.normalize();
|
||||
this._gravity = gravity;
|
||||
this._airFriction = airFriction;
|
||||
this._explosionShape = explosionShape;
|
||||
this._fuseTime = fuseTime;
|
||||
this._energy = energy;
|
||||
this._burstPulse = burstPulse;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
public reset(): void
|
||||
{
|
||||
let k:FurnitureParticleSystemParticle;
|
||||
for(const k of this._particles) k.dispose();
|
||||
for(const particle of this._particles) particle.dispose();
|
||||
|
||||
this._particles = [];
|
||||
this._emittedParticles = 0;
|
||||
this._hasIgnited = false;
|
||||
this.init(0, 0, 0, this._direction, this._force, this._timeStep, this._fuseTime, true);
|
||||
|
||||
this.init(0, 0, 0, this._emitterDirection, this._force, this._timeStep, this._fuseTime, true);
|
||||
}
|
||||
|
||||
public copyStateFrom(k:FurnitureParticleSystemEmitter, _arg_2: number): void
|
||||
public copyStateFrom(emitter: FurnitureParticleSystemEmitter, scale: number): void
|
||||
{
|
||||
super.copy(k, _arg_2);
|
||||
this._force = k._force;
|
||||
this._direction = k._direction;
|
||||
this._gravity = k._gravity;
|
||||
this._airFriction = k._airFriction;
|
||||
this._explosionShape = k._explosionShape;
|
||||
this._fuseTime = k._fuseTime;
|
||||
this._energy = k._energy;
|
||||
this._burstPulse = k._burstPulse;
|
||||
this._timeStep = k._timeStep;
|
||||
this._hasIgnited = k._hasIgnited;
|
||||
super.copy(emitter, scale);
|
||||
|
||||
this._force = emitter._force;
|
||||
this._emitterDirection = emitter._emitterDirection;
|
||||
this._gravity = emitter._gravity;
|
||||
this._airFriction = emitter._airFriction;
|
||||
this._explosionShape = emitter._explosionShape;
|
||||
this._fuseTime = emitter._fuseTime;
|
||||
this._energy = emitter._energy;
|
||||
this._burstPulse = emitter._burstPulse;
|
||||
this._timeStep = emitter._timeStep;
|
||||
this._hasIgnited = emitter._hasIgnited;
|
||||
}
|
||||
|
||||
public configureParticle(k: number, _arg_2: boolean, _arg_3: GraphicAsset[], _arg_4: boolean): void
|
||||
public configureParticle(lifeTIme: number, isEmitter: boolean, frames: IGraphicAsset[], fade: boolean): void
|
||||
{
|
||||
const _local_5 = [];
|
||||
_local_5['lifeTime'] = k;
|
||||
_local_5['isEmitter'] = _arg_2;
|
||||
_local_5['frames'] = _arg_3;
|
||||
_local_5['fade'] = _arg_4;
|
||||
this._particleConfigurations.push(_local_5);
|
||||
const particle: ParticleSystemParticle = {};
|
||||
|
||||
particle.lifeTime = lifeTIme;
|
||||
particle.isEmitter = isEmitter;
|
||||
particle.frames = frames;
|
||||
particle.fade = fade;
|
||||
|
||||
this._particleConfigurations.push(particle);
|
||||
}
|
||||
|
||||
protected ignite(): void
|
||||
{
|
||||
this._hasIgnited = true;
|
||||
if((this._emittedParticles < this._maxNumberOfParticles))
|
||||
|
||||
if(this._emittedParticles < this._maxNumberOfParticles)
|
||||
{
|
||||
if(this.age > 1)
|
||||
{
|
||||
this.releaseParticles(this, this.direction);
|
||||
}
|
||||
if(this.age > 1) this.releaseParticles(this, this.direction);
|
||||
}
|
||||
}
|
||||
|
||||
private releaseParticles(k:FurnitureParticleSystemParticle, _arg_2: Vector3D = null): void
|
||||
private releaseParticles(particle: FurnitureParticleSystemParticle, direction: Vector3D = null): void
|
||||
{
|
||||
if(!_arg_2) _arg_2 = new Vector3D();
|
||||
if(!direction) direction = new Vector3D();
|
||||
|
||||
const _local_3 = new Vector3D();
|
||||
const _local_5 = this.getRandomParticleConfiguration();
|
||||
const newDirection = new Vector3D();
|
||||
const randomParticle = this.getRandomParticleConfiguration();
|
||||
|
||||
let _local_10 = 0;
|
||||
let i = 0;
|
||||
|
||||
while(_local_10 < this._particlesPerFrame)
|
||||
while(i < this._particlesPerFrame)
|
||||
{
|
||||
switch(this._explosionShape)
|
||||
{
|
||||
case FurnitureParticleSystemEmitter.CONE:
|
||||
_local_3.x = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
_local_3.y = -(Math.random() + 1);
|
||||
_local_3.z = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
newDirection.x = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
newDirection.y = -(Math.random() + 1);
|
||||
newDirection.z = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
break;
|
||||
case FurnitureParticleSystemEmitter.PLANE:
|
||||
_local_3.x = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
_local_3.y = 0;
|
||||
_local_3.z = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
newDirection.x = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
newDirection.y = 0;
|
||||
newDirection.z = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
break;
|
||||
case FurnitureParticleSystemEmitter.SPHERE:
|
||||
_local_3.x = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
_local_3.y = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
_local_3.z = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
newDirection.x = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
newDirection.y = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
newDirection.z = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random()));
|
||||
break;
|
||||
}
|
||||
|
||||
_local_3.normalize();
|
||||
newDirection.normalize();
|
||||
|
||||
const _local_4 = new FurnitureParticleSystemParticle();
|
||||
const newParticle = new FurnitureParticleSystemParticle();
|
||||
|
||||
let _local_6 = 0;
|
||||
let _local_7 = false;
|
||||
let _local_8 = false;
|
||||
let _local_9: GraphicAsset[] = [];
|
||||
let lifeTime = 0;
|
||||
let isEmitter = false;
|
||||
let fade = false;
|
||||
let frames: IGraphicAsset[] = [];
|
||||
|
||||
if(_local_5)
|
||||
if(randomParticle)
|
||||
{
|
||||
_local_6 = Math.floor(((Math.random() * _local_5['lifeTime']) + 10));
|
||||
_local_7 = _local_5['isEmitter'];
|
||||
_local_9 = _local_5['frames'];
|
||||
_local_8 = _local_5['fade'];
|
||||
lifeTime = Math.floor(((Math.random() * randomParticle.lifeTime) + 10));
|
||||
isEmitter = randomParticle.isEmitter;
|
||||
frames = randomParticle.frames;
|
||||
fade = randomParticle.fade;
|
||||
}
|
||||
else
|
||||
{
|
||||
_local_6 = Math.trunc(Math.floor(((Math.random() * 20) + 10)));
|
||||
_local_7 = false;
|
||||
_local_9 = [];
|
||||
lifeTime = Math.trunc(Math.floor(((Math.random() * 20) + 10)));
|
||||
isEmitter = false;
|
||||
frames = [];
|
||||
}
|
||||
|
||||
_local_4.init(k.x, k.y, k.z, _local_3, this._energy, this._timeStep, _local_6, _local_7, _local_9, _local_8);
|
||||
newParticle.init(particle.x, particle.y, particle.z, newDirection, this._energy, this._timeStep, lifeTime, isEmitter, frames, fade);
|
||||
|
||||
this._particles.push(_local_4);
|
||||
this._particles.push(newParticle);
|
||||
this._emittedParticles++;
|
||||
|
||||
_local_10++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private getRandomParticleConfiguration()
|
||||
private getRandomParticleConfiguration(): ParticleSystemParticle
|
||||
{
|
||||
const k: number = Math.trunc(Math.floor((Math.random() * this._particleConfigurations.length)));
|
||||
return this._particleConfigurations[k];
|
||||
const index: number = Math.trunc(Math.floor((Math.random() * this._particleConfigurations.length)));
|
||||
|
||||
return this._particleConfigurations[index];
|
||||
}
|
||||
|
||||
public update(): void
|
||||
{
|
||||
super.update();
|
||||
|
||||
this.accumulateForces();
|
||||
this.verlet();
|
||||
this.satisfyConstraints();
|
||||
if(((!(this.isAlive)) && (this._emittedParticles < this._maxNumberOfParticles)))
|
||||
|
||||
if(!this.isAlive && (this._emittedParticles < this._maxNumberOfParticles))
|
||||
{
|
||||
if((this.age % this._burstPulse) == 0)
|
||||
{
|
||||
this.releaseParticles(this, this.direction);
|
||||
}
|
||||
if((this.age % this._burstPulse) === 0) this.releaseParticles(this, this.direction);
|
||||
}
|
||||
}
|
||||
|
||||
public verlet(): void
|
||||
{
|
||||
let _local_2:FurnitureParticleSystemParticle;
|
||||
let _local_3: number;
|
||||
let _local_4: number;
|
||||
let _local_5: number;
|
||||
if(((this.isAlive) || (this._emittedParticles < this._maxNumberOfParticles)))
|
||||
if(this.isAlive || (this._emittedParticles < this._maxNumberOfParticles))
|
||||
{
|
||||
_local_3 = this.x;
|
||||
_local_4 = this.y;
|
||||
_local_5 = this.z;
|
||||
const x = this.x;
|
||||
const y = this.y;
|
||||
const z = this.z;
|
||||
|
||||
this.x = (((2 - this._airFriction) * this.x) - ((1 - this._airFriction) * this.lastX));
|
||||
this.y = ((((2 - this._airFriction) * this.y) - ((1 - this._airFriction) * this.lastY)) + ((this._gravity * this._timeStep) * this._timeStep));
|
||||
this.z = (((2 - this._airFriction) * this.z) - ((1 - this._airFriction) * this.lastZ));
|
||||
this.lastX = _local_3;
|
||||
this.lastY = _local_4;
|
||||
this.lastZ = _local_5;
|
||||
this.lastX = x;
|
||||
this.lastY = y;
|
||||
this.lastZ = z;
|
||||
}
|
||||
const k: FurnitureParticleSystemParticle[] = [];
|
||||
|
||||
for(const _local_2 of this._particles)
|
||||
const particles: FurnitureParticleSystemParticle[] = [];
|
||||
|
||||
for(const particle of this._particles)
|
||||
{
|
||||
_local_2.update();
|
||||
_local_3 = _local_2.x;
|
||||
_local_4 = _local_2.y;
|
||||
_local_5 = _local_2.z;
|
||||
_local_2.x = (((2 - this._airFriction) * _local_2.x) - ((1 - this._airFriction) * _local_2.lastX));
|
||||
_local_2.y = ((((2 - this._airFriction) * _local_2.y) - ((1 - this._airFriction) * _local_2.lastY)) + ((this._gravity * this._timeStep) * this._timeStep));
|
||||
_local_2.z = (((2 - this._airFriction) * _local_2.z) - ((1 - this._airFriction) * _local_2.lastZ));
|
||||
_local_2.lastX = _local_3;
|
||||
_local_2.lastY = _local_4;
|
||||
_local_2.lastZ = _local_5;
|
||||
if(((_local_2.y > 10) || (!(_local_2.isAlive))))
|
||||
{
|
||||
k.push(_local_2);
|
||||
particle.update();
|
||||
|
||||
const x = particle.x;
|
||||
const y = particle.y;
|
||||
const z = particle.z;
|
||||
particle.x = (((2 - this._airFriction) * particle.x) - ((1 - this._airFriction) * particle.lastX));
|
||||
particle.y = ((((2 - this._airFriction) * particle.y) - ((1 - this._airFriction) * particle.lastY)) + ((this._gravity * this._timeStep) * this._timeStep));
|
||||
particle.z = (((2 - this._airFriction) * particle.z) - ((1 - this._airFriction) * particle.lastZ));
|
||||
particle.lastX = x;
|
||||
particle.lastY = y;
|
||||
particle.lastZ = z;
|
||||
|
||||
if((particle.y > 10) || !particle.isAlive) particles.push(particle);
|
||||
}
|
||||
}
|
||||
for(const _local_2 of k)
|
||||
|
||||
for(const particle of particles)
|
||||
{
|
||||
if(_local_2.isEmitter)
|
||||
if(particle.isEmitter)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
this._particles.splice(this._particles.indexOf(_local_2), 1);
|
||||
this._particles.splice(this._particles.indexOf(particle), 1);
|
||||
|
||||
_local_2.dispose();
|
||||
particle.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GraphicAsset } from '../../../../../room/object/visualization/utils/GraphicAsset';
|
||||
import { IGraphicAsset } from '../../../../../room';
|
||||
import { Vector3D } from '../../../../avatar/geometry/Vector3D';
|
||||
|
||||
export class FurnitureParticleSystemParticle
|
||||
@ -10,51 +10,47 @@ export class FurnitureParticleSystemParticle
|
||||
private _lastY: number;
|
||||
private _lastZ: number;
|
||||
private _hasMoved: boolean = false;
|
||||
protected _direction: Vector3D;
|
||||
private _particleDirection: Vector3D;
|
||||
private _age: number = 0;
|
||||
private _lifeTime: number;
|
||||
private _isEmitter: boolean = false;
|
||||
private _fade: boolean = false;
|
||||
private _fadeTime: number;
|
||||
private _alphaMultiplier: number = 1;
|
||||
private _frames: GraphicAsset[];
|
||||
private _frames: IGraphicAsset[];
|
||||
|
||||
public init(k: number, _arg_2: number, _arg_3: number, _arg_4: Vector3D, _arg_5: number, _arg_6: number, _arg_7: number, _arg_8: boolean = false, _arg_9: GraphicAsset[] = null, _arg_10: boolean = false): void
|
||||
public init(x: number, y: number, z: number, direction: Vector3D, energy: number, timeStep: number, lifeTime: number, isEmitter: boolean = false, frames: IGraphicAsset[] = null, fade: boolean = false): void
|
||||
{
|
||||
this._x = k;
|
||||
this._y = _arg_2;
|
||||
this._z = _arg_3;
|
||||
this._direction = new Vector3D(_arg_4.x, _arg_4.y, _arg_4.z);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._z = z;
|
||||
this._particleDirection = new Vector3D(direction.x, direction.y, direction.z);
|
||||
this._particleDirection.scaleBy(energy);
|
||||
|
||||
this._direction.x *= _arg_5;
|
||||
this._direction.y *= _arg_5;
|
||||
this._direction.z *= _arg_5;
|
||||
|
||||
this._lastX = (this._x - (this._direction.x * _arg_6));
|
||||
this._lastY = (this._y - (this._direction.y * _arg_6));
|
||||
this._lastZ = (this._z - (this._direction.z * _arg_6));
|
||||
this._lastX = (this._x - (this._particleDirection.x * timeStep));
|
||||
this._lastY = (this._y - (this._particleDirection.y * timeStep));
|
||||
this._lastZ = (this._z - (this._particleDirection.z * timeStep));
|
||||
this._age = 0;
|
||||
this._hasMoved = false;
|
||||
this._lifeTime = _arg_7;
|
||||
this._isEmitter = _arg_8;
|
||||
this._frames = _arg_9;
|
||||
this._fade = _arg_10;
|
||||
this._lifeTime = lifeTime;
|
||||
this._isEmitter = isEmitter;
|
||||
this._frames = frames;
|
||||
this._fade = fade;
|
||||
this._alphaMultiplier = 1;
|
||||
this._fadeTime = (0.5 + (Math.random() * 0.5));
|
||||
}
|
||||
|
||||
public dispose(): void
|
||||
{
|
||||
this._direction = null;
|
||||
this._particleDirection = null;
|
||||
}
|
||||
|
||||
public update(): void
|
||||
{
|
||||
this._age++;
|
||||
if(this._age == this._lifeTime)
|
||||
{
|
||||
this.ignite();
|
||||
}
|
||||
|
||||
if(this._age === this._lifeTime) this.ignite();
|
||||
|
||||
if(this._fade)
|
||||
{
|
||||
if((this._age / this._lifeTime) > this._fadeTime)
|
||||
@ -64,7 +60,7 @@ export class FurnitureParticleSystemParticle
|
||||
}
|
||||
}
|
||||
|
||||
public getAsset(): GraphicAsset
|
||||
public getAsset(): IGraphicAsset
|
||||
{
|
||||
if(((this._frames) && (this._frames.length > 0)))
|
||||
{
|
||||
@ -89,7 +85,7 @@ export class FurnitureParticleSystemParticle
|
||||
|
||||
public get direction(): Vector3D
|
||||
{
|
||||
return this._direction;
|
||||
return this._particleDirection;
|
||||
}
|
||||
|
||||
public get age(): number
|
||||
@ -112,9 +108,9 @@ export class FurnitureParticleSystemParticle
|
||||
return this._x;
|
||||
}
|
||||
|
||||
public set x(k: number)
|
||||
public set x(x: number)
|
||||
{
|
||||
this._x = k;
|
||||
this._x = x;
|
||||
}
|
||||
|
||||
public get y(): number
|
||||
@ -122,9 +118,9 @@ export class FurnitureParticleSystemParticle
|
||||
return this._y;
|
||||
}
|
||||
|
||||
public set y(k: number)
|
||||
public set y(y: number)
|
||||
{
|
||||
this._y = k;
|
||||
this._y = y;
|
||||
}
|
||||
|
||||
public get z(): number
|
||||
@ -132,9 +128,9 @@ export class FurnitureParticleSystemParticle
|
||||
return this._z;
|
||||
}
|
||||
|
||||
public set z(k: number)
|
||||
public set z(z: number)
|
||||
{
|
||||
this._z = k;
|
||||
this._z = z;
|
||||
}
|
||||
|
||||
public get lastX(): number
|
||||
@ -142,10 +138,10 @@ export class FurnitureParticleSystemParticle
|
||||
return this._lastX;
|
||||
}
|
||||
|
||||
public set lastX(k: number)
|
||||
public set lastX(y: number)
|
||||
{
|
||||
this._hasMoved = true;
|
||||
this._lastX = k;
|
||||
this._lastX = y;
|
||||
}
|
||||
|
||||
public get lastY(): number
|
||||
@ -164,10 +160,10 @@ export class FurnitureParticleSystemParticle
|
||||
return this._lastZ;
|
||||
}
|
||||
|
||||
public set lastZ(k: number)
|
||||
public set lastZ(z: number)
|
||||
{
|
||||
this._hasMoved = true;
|
||||
this._lastZ = k;
|
||||
this._lastZ = z;
|
||||
}
|
||||
|
||||
public get hasMoved(): boolean
|
||||
@ -180,21 +176,21 @@ export class FurnitureParticleSystemParticle
|
||||
return [ this._x, this._y, this._z ].toString();
|
||||
}
|
||||
|
||||
public copy(k:FurnitureParticleSystemParticle, _arg_2: number): void
|
||||
public copy(particle: FurnitureParticleSystemParticle, scale: number): void
|
||||
{
|
||||
this._x = (k._x * _arg_2);
|
||||
this._y = (k._y * _arg_2);
|
||||
this._z = (k._z * _arg_2);
|
||||
this._lastX = (k._lastX * _arg_2);
|
||||
this._lastY = (k._lastY * _arg_2);
|
||||
this._lastZ = (k._lastZ * _arg_2);
|
||||
this._hasMoved = k.hasMoved;
|
||||
this._direction = k._direction;
|
||||
this._age = k._age;
|
||||
this._lifeTime = k._lifeTime;
|
||||
this._isEmitter = k._isEmitter;
|
||||
this._fade = k._fade;
|
||||
this._fadeTime = k._fadeTime;
|
||||
this._alphaMultiplier = k._alphaMultiplier;
|
||||
this._x = (particle._x * scale);
|
||||
this._y = (particle._y * scale);
|
||||
this._z = (particle._z * scale);
|
||||
this._lastX = (particle._lastX * scale);
|
||||
this._lastY = (particle._lastY * scale);
|
||||
this._lastZ = (particle._lastZ * scale);
|
||||
this._hasMoved = particle.hasMoved;
|
||||
this._particleDirection = particle._particleDirection;
|
||||
this._age = particle._age;
|
||||
this._lifeTime = particle._lifeTime;
|
||||
this._isEmitter = particle._isEmitter;
|
||||
this._fade = particle._fade;
|
||||
this._fadeTime = particle._fadeTime;
|
||||
this._alphaMultiplier = particle._alphaMultiplier;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,160 @@
|
||||
import { NitroPoint } from '../../../../../core';
|
||||
import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization';
|
||||
|
||||
export class FurniturePartyBeamerVisualization extends FurnitureAnimatedVisualization
|
||||
{
|
||||
private static UPDATE_INTERVAL: number = 2;
|
||||
private static AREA_DIAMETER_SMALL: number = 15;
|
||||
private static AREA_DIAMETER_LARGE: number = 31;
|
||||
private static ANIM_SPEED_FAST: number = 2;
|
||||
private static ANIM_SPEED_SLOW: number = 1;
|
||||
|
||||
private _animPhaseIndex: number[];
|
||||
private _animDirectionIndex: number[];
|
||||
private _animSpeedIndex: number[];
|
||||
private _animFactorIndex: number[];
|
||||
private _animOffsetIndex: NitroPoint[];
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
|
||||
this._animOffsetIndex = [];
|
||||
}
|
||||
|
||||
protected updateAnimation(scale: number): number
|
||||
{
|
||||
if(!this._animSpeedIndex) this.initItems(scale);
|
||||
|
||||
let sprite = this.getSprite(2);
|
||||
|
||||
if(sprite) this._animOffsetIndex[0] = this.getNewPoint(scale, 0);
|
||||
|
||||
sprite = this.getSprite(3);
|
||||
|
||||
if(sprite) this._animOffsetIndex[1] = this.getNewPoint(scale, 1);
|
||||
|
||||
return super.updateAnimation(scale);
|
||||
}
|
||||
|
||||
private getNewPoint(scale: number, layerId: number): NitroPoint
|
||||
{
|
||||
let diameter = 0;
|
||||
|
||||
let animationPhase: number = this._animPhaseIndex[layerId];
|
||||
let animationDirection: number = this._animDirectionIndex[layerId];
|
||||
|
||||
const animationSpeed: number = this._animSpeedIndex[layerId];
|
||||
const animationFactor: number = this._animFactorIndex[layerId];
|
||||
|
||||
let _local_7 = 1;
|
||||
|
||||
if(scale == 32)
|
||||
{
|
||||
diameter = FurniturePartyBeamerVisualization.AREA_DIAMETER_SMALL;
|
||||
_local_7 = 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
diameter = FurniturePartyBeamerVisualization.AREA_DIAMETER_LARGE;
|
||||
}
|
||||
|
||||
const _local_9: number = (animationPhase + (animationDirection * animationSpeed));
|
||||
|
||||
if(Math.abs(_local_9) >= diameter)
|
||||
{
|
||||
if(animationDirection > 0)
|
||||
{
|
||||
animationPhase = (animationPhase - (_local_9 - diameter));
|
||||
}
|
||||
else
|
||||
{
|
||||
animationPhase = (animationPhase + (-(diameter) - _local_9));
|
||||
}
|
||||
|
||||
animationDirection = -(animationDirection);
|
||||
|
||||
this._animDirectionIndex[layerId] = animationDirection;
|
||||
}
|
||||
|
||||
const _local_10: number = ((diameter - Math.abs(animationPhase)) * animationFactor);
|
||||
|
||||
let _local_11: number = ((animationDirection * Math.sin(Math.abs((animationPhase / 4)))) * _local_10);
|
||||
|
||||
if(animationDirection > 0)
|
||||
{
|
||||
_local_11 = (_local_11 - _local_10);
|
||||
}
|
||||
else
|
||||
{
|
||||
_local_11 = (_local_11 + _local_10);
|
||||
}
|
||||
|
||||
animationPhase = (animationPhase + ((animationDirection * animationSpeed) * _local_7));
|
||||
|
||||
this._animPhaseIndex[layerId] = animationPhase;
|
||||
|
||||
if(Math.trunc(_local_11) == 0) this._animFactorIndex[layerId] = this.getRandomAmplitudeFactor();
|
||||
|
||||
return new NitroPoint(animationPhase, _local_11);
|
||||
}
|
||||
|
||||
private initItems(scale: number):void
|
||||
{
|
||||
let diameter: number;
|
||||
|
||||
if(scale === 32)
|
||||
{
|
||||
diameter = FurniturePartyBeamerVisualization.AREA_DIAMETER_SMALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
diameter = FurniturePartyBeamerVisualization.AREA_DIAMETER_LARGE;
|
||||
}
|
||||
|
||||
this._animPhaseIndex = [];
|
||||
this._animPhaseIndex.push(((Math.random() * diameter) * 1.5));
|
||||
this._animPhaseIndex.push(((Math.random() * diameter) * 1.5));
|
||||
|
||||
this._animDirectionIndex = [];
|
||||
this._animDirectionIndex.push(1);
|
||||
this._animDirectionIndex.push(-1);
|
||||
|
||||
this._animSpeedIndex = [];
|
||||
this._animSpeedIndex.push(FurniturePartyBeamerVisualization.ANIM_SPEED_FAST);
|
||||
this._animSpeedIndex.push(FurniturePartyBeamerVisualization.ANIM_SPEED_SLOW);
|
||||
|
||||
this._animFactorIndex = [];
|
||||
this._animFactorIndex.push(this.getRandomAmplitudeFactor());
|
||||
this._animFactorIndex.push(this.getRandomAmplitudeFactor());
|
||||
}
|
||||
|
||||
protected getLayerXOffset(scale: number, direction: number, layerId: number): number
|
||||
{
|
||||
if((layerId === 2) || (layerId === 3))
|
||||
{
|
||||
if(this._animOffsetIndex.length == 2)
|
||||
{
|
||||
return this._animOffsetIndex[(layerId - 2)].x;
|
||||
}
|
||||
}
|
||||
return super.getLayerXOffset(scale, direction, layerId);
|
||||
}
|
||||
|
||||
protected getLayerYOffset(scale: number, direction: number, layerId: number): number
|
||||
{
|
||||
if((layerId === 2) || (layerId === 3))
|
||||
{
|
||||
if(this._animOffsetIndex.length == 2)
|
||||
{
|
||||
return this._animOffsetIndex[(layerId - 2)].y;
|
||||
}
|
||||
}
|
||||
return super.getLayerYOffset(scale, direction, layerId);
|
||||
}
|
||||
|
||||
private getRandomAmplitudeFactor(): number
|
||||
{
|
||||
return ((Math.random() * 30) / 100) + 0.15;
|
||||
}
|
||||
}
|
@ -1,6 +1,135 @@
|
||||
import { IPlanetSystem } from '../../../../../core';
|
||||
import { Vector3d } from '../../../../../room';
|
||||
import { RoomObjectVariable } from '../../RoomObjectVariable';
|
||||
import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization';
|
||||
import { FurniturePlanetSystemVisualizationPlanetObject } from './FurniturePlanetSystemVisualizationPlanetObject';
|
||||
|
||||
export class FurniturePlanetSystemVisualization extends FurnitureAnimatedVisualization
|
||||
{
|
||||
private _planetIndex: FurniturePlanetSystemVisualizationPlanetObject[];
|
||||
private _planetNameIndex: string[];
|
||||
private _offsetArray: Vector3d[];
|
||||
private _rootPosition: Vector3d;
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
|
||||
this._offsetArray = [];
|
||||
this._rootPosition = new Vector3d();
|
||||
}
|
||||
|
||||
public dispose():void
|
||||
{
|
||||
if(this._planetIndex)
|
||||
{
|
||||
while(this._planetIndex.length > 0)
|
||||
{
|
||||
const planet = this._planetIndex.shift();
|
||||
|
||||
planet.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
this._planetIndex = null;
|
||||
this._planetNameIndex = null;
|
||||
}
|
||||
|
||||
protected updateAnimation(scale: number): number
|
||||
{
|
||||
if(!this._planetIndex && (this.spriteCount > 0))
|
||||
{
|
||||
if(!this.processPlanets()) return 0;
|
||||
}
|
||||
|
||||
if(this._planetIndex)
|
||||
{
|
||||
for(const planet of this._planetIndex) planet.update(this._offsetArray, this._rootPosition, scale);
|
||||
|
||||
return super.updateAnimation(scale);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected getLayerXOffset(scale: number, direction: number, layerId: number): number
|
||||
{
|
||||
if(this._offsetArray[layerId])
|
||||
{
|
||||
return this._offsetArray[layerId].x;
|
||||
}
|
||||
|
||||
return super.getLayerXOffset(scale, direction, layerId);
|
||||
}
|
||||
|
||||
protected getLayerYOffset(scale: number, direction: number, layerId: number): number
|
||||
{
|
||||
if(this._offsetArray[layerId])
|
||||
{
|
||||
return this._offsetArray[layerId].y;
|
||||
}
|
||||
|
||||
return super.getLayerYOffset(scale, direction, layerId);
|
||||
}
|
||||
|
||||
protected getLayerZOffset(scale: number, direction: number, layerId: number): number
|
||||
{
|
||||
if(this._offsetArray[layerId])
|
||||
{
|
||||
return this._offsetArray[layerId].z;
|
||||
}
|
||||
|
||||
return super.getLayerZOffset(scale, direction, layerId);
|
||||
}
|
||||
|
||||
private processPlanets(): boolean
|
||||
{
|
||||
if(!this.object || !this.object.model) return;
|
||||
|
||||
const planetSystems = this.object.model.getValue<IPlanetSystem[]>(RoomObjectVariable.FURNITURE_PLANETSYSTEM_DATA);
|
||||
|
||||
if(!planetSystems) return false;
|
||||
|
||||
this._planetIndex = [];
|
||||
this._planetNameIndex = [];
|
||||
|
||||
for(const planet of planetSystems)
|
||||
{
|
||||
const sprite = this.getSprite(planet.id);
|
||||
|
||||
if(sprite)
|
||||
{
|
||||
this.addPlanet(planet.name, planet.id, planet.parent, (planet.radius || 0), (planet.arcSpeed || 0), (planet.arcOffset || 0), (planet.height || 0));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private addPlanet(name: string, index: number, parentName: string, radius: number, arcSpeed: number, arcOffset: number, height: number):void
|
||||
{
|
||||
if(!this._planetIndex) return;
|
||||
|
||||
const planet = new FurniturePlanetSystemVisualizationPlanetObject(name, index, radius, arcSpeed, arcOffset, height);
|
||||
const existingPlanet = this.getPlanet(parentName);
|
||||
|
||||
if(existingPlanet) existingPlanet.addChild(planet);
|
||||
else
|
||||
{
|
||||
this._planetIndex.push(planet);
|
||||
this._planetNameIndex.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
private getPlanet(name: string): FurniturePlanetSystemVisualizationPlanetObject
|
||||
{
|
||||
for(const planet of this._planetIndex)
|
||||
{
|
||||
if(planet.name === name) return planet;
|
||||
|
||||
if(planet.hasChild(name)) return planet.getChild(name);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
import { Vector3d } from '../../../../../room';
|
||||
|
||||
export class FurniturePlanetSystemVisualizationPlanetObject
|
||||
{
|
||||
private static SYSTEM_TEMPO: number = 30;
|
||||
|
||||
private _name: string;
|
||||
private _index: number;
|
||||
private _radius: number;
|
||||
private _arcSpeed: number;
|
||||
private _arcOffset: number;
|
||||
private _height: number;
|
||||
private _position: number;
|
||||
private _positionVector: Vector3d;
|
||||
private _children: FurniturePlanetSystemVisualizationPlanetObject[];
|
||||
|
||||
constructor(name: string, index: number, radius: number, arcSpeed: number, arcOffset: number, height: number)
|
||||
{
|
||||
this._name = name;
|
||||
this._index = index;
|
||||
this._radius = radius;
|
||||
this._arcSpeed = (((arcSpeed * Math.PI) * 2) / 360);
|
||||
this._arcOffset = (((arcOffset * Math.PI) * 2) / 360);
|
||||
this._height = height;
|
||||
this._position = 0;
|
||||
this._positionVector = new Vector3d(0, 0, 0);
|
||||
this._children = [];
|
||||
}
|
||||
|
||||
public dispose():void
|
||||
{
|
||||
while(this._children.length > 0)
|
||||
{
|
||||
const child = this._children.shift();
|
||||
|
||||
child.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public update(offsets: Vector3d[], rootPosition: Vector3d, scale: number):void
|
||||
{
|
||||
this._position = (this._position + (this._arcSpeed / FurniturePlanetSystemVisualizationPlanetObject.SYSTEM_TEMPO));
|
||||
|
||||
offsets[this._index] = this.getPositionVector(rootPosition, scale);
|
||||
|
||||
for(const child of this._children) child.update(offsets, this._positionVector, scale);
|
||||
}
|
||||
|
||||
public getPositionVector(position: Vector3d, scale: number): Vector3d
|
||||
{
|
||||
const cos = (this._radius * Math.cos((this._position + this._arcOffset)));
|
||||
const sine = (this._radius * Math.sin((this._position + this._arcOffset)));
|
||||
|
||||
this._positionVector.x = ((cos - sine) * (scale / 2));
|
||||
this._positionVector.y = ((((sine + cos) * (scale / 2)) * 0.5) - (this._height * (scale / 2)));
|
||||
this._positionVector.z = -(Math.trunc(((4 * (cos + sine)) - 0.7)));
|
||||
|
||||
if(position) this._positionVector.add(position);
|
||||
|
||||
return this._positionVector;
|
||||
}
|
||||
|
||||
public addChild(planetObject: FurniturePlanetSystemVisualizationPlanetObject):void
|
||||
{
|
||||
if(this._children.indexOf(planetObject) >= 0) return;
|
||||
|
||||
this._children.push(planetObject);
|
||||
}
|
||||
|
||||
public hasChild(name: string): boolean
|
||||
{
|
||||
return !!this.getChild(name);
|
||||
}
|
||||
|
||||
public getChild(name: string): FurniturePlanetSystemVisualizationPlanetObject
|
||||
{
|
||||
for(const child of this._children)
|
||||
{
|
||||
if(child.name === name) return child;
|
||||
|
||||
if(child.hasChild(name)) return child.getChild(name);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { Resource, Texture } from '@pixi/core';
|
||||
import { Matrix, Rectangle } from '@pixi/math';
|
||||
import { NitroSprite } from '../../../../../core';
|
||||
import { Matrix } from '@pixi/math';
|
||||
import { NitroRectangle, NitroSprite } from '../../../../../core';
|
||||
import { IGraphicAsset } from '../../../../../room/object/visualization/utils/IGraphicAsset';
|
||||
import { TextureUtils } from '../../../../../room/utils/TextureUtils';
|
||||
import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization';
|
||||
@ -13,6 +13,7 @@ export class FurnitureThumbnailVisualization extends FurnitureAnimatedVisualizat
|
||||
private _thumbnailImageNormal: Texture<Resource>;
|
||||
private _thumbnailDirection: number;
|
||||
private _thumbnailChanged: boolean;
|
||||
protected _hasOutline: boolean;
|
||||
|
||||
constructor()
|
||||
{
|
||||
@ -22,6 +23,7 @@ export class FurnitureThumbnailVisualization extends FurnitureAnimatedVisualizat
|
||||
this._thumbnailImageNormal = null;
|
||||
this._thumbnailDirection = -1;
|
||||
this._thumbnailChanged = false;
|
||||
this._hasOutline = false;
|
||||
}
|
||||
|
||||
public get hasThumbnailImage(): boolean
|
||||
@ -92,7 +94,7 @@ export class FurnitureThumbnailVisualization extends FurnitureAnimatedVisualizat
|
||||
|
||||
private generateTransformedThumbnail(texture: Texture<Resource>, asset: IGraphicAsset): Texture<Resource>
|
||||
{
|
||||
const _local_3 = 1.1;
|
||||
const scale = 1.1;
|
||||
const matrix = new Matrix();
|
||||
const _local_5 = (asset.width / texture.width);
|
||||
|
||||
@ -102,7 +104,7 @@ export class FurnitureThumbnailVisualization extends FurnitureAnimatedVisualizat
|
||||
matrix.a = _local_5;
|
||||
matrix.b = (-0.5 * _local_5);
|
||||
matrix.c = 0;
|
||||
matrix.d = (_local_5 * _local_3);
|
||||
matrix.d = (_local_5 * scale);
|
||||
matrix.tx = 0;
|
||||
matrix.ty = ((0.5 * _local_5) * texture.width);
|
||||
break;
|
||||
@ -111,7 +113,7 @@ export class FurnitureThumbnailVisualization extends FurnitureAnimatedVisualizat
|
||||
matrix.a = _local_5;
|
||||
matrix.b = (0.5 * _local_5);
|
||||
matrix.c = 0;
|
||||
matrix.d = (_local_5 * _local_3);
|
||||
matrix.d = (_local_5 * scale);
|
||||
matrix.tx = 0;
|
||||
matrix.ty = 0;
|
||||
break;
|
||||
@ -126,9 +128,14 @@ export class FurnitureThumbnailVisualization extends FurnitureAnimatedVisualizat
|
||||
|
||||
const sprite = new NitroSprite(texture);
|
||||
|
||||
if(this._hasOutline)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
sprite.transform.setFromMatrix(matrix);
|
||||
|
||||
return TextureUtils.generateTexture(sprite, new Rectangle(0, 0, asset.width, asset.height));
|
||||
return TextureUtils.generateTexture(sprite, new NitroRectangle(0, 0, (asset.width + 2), (asset.height + 2)));
|
||||
}
|
||||
|
||||
protected getSpriteAssetName(scale: number, layerId: number): string
|
||||
|
@ -17,6 +17,7 @@ export * from './FurnitureGuildIsometricBadgeVisualization';
|
||||
export * from './FurnitureHabboWheelVisualization';
|
||||
export * from './FurnitureMannequinVisualization';
|
||||
export * from './FurnitureMannequinVisualizationData';
|
||||
export * from './FurnitureParticleSystem';
|
||||
export * from './FurnitureParticleSystemEmitter';
|
||||
export * from './FurnitureParticleSystemParticle';
|
||||
export * from './FurniturePartyBeamerVisualization';
|
||||
|
Loading…
Reference in New Issue
Block a user