@awayjs/graphics
Version:
AwayJS graphics classes
143 lines (115 loc) • 5.1 kB
text/typescript
import { IElements, ShaderBase, _Render_RenderableBase, AnimationRegisterData } from '@awayjs/renderer';
import { _Render_Shape } from '../renderables/Shape';
import { AnimationElements } from './data/AnimationElements';
import { ParticleCollection } from './data/ParticleCollection';
import { ParticlePropertiesMode } from './data/ParticlePropertiesMode';
import { ParticleNodeBase } from './nodes/ParticleNodeBase';
import { ParticleStateBase } from './states/ParticleStateBase';
import { ParticleAnimationSet } from './ParticleAnimationSet';
import { AnimatorBase } from './AnimatorBase';
/**
* Provides an interface for assigning paricle-based animation data sets to sprite-based entity objects
* and controlling the various available states of animation through an interative playhead that can be
* automatically updated or manually triggered.
*
* Requires that the containing geometry of the parent sprite is particle geometry
*
* @see away.base.ParticleAnimator
*/
export class ParticleAnimator extends AnimatorBase {
private _particleAnimationSet: ParticleAnimationSet;
private _animationParticleStates: Array<ParticleStateBase> = new Array<ParticleStateBase>();
private _animatorParticleStates: Array<ParticleStateBase> = new Array<ParticleStateBase>();
private _timeParticleStates: Array<ParticleStateBase> = new Array<ParticleStateBase>();
private _totalLenOfOneVertex: number = 0;
private _animatorSubGeometries: Object = new Object();
/**
* Creates a new <code>ParticleAnimator</code> object.
*
* @param particleAnimationSet The animation data set containing the particle animations used by the animator.
*/
constructor(particleAnimationSet: ParticleAnimationSet) {
super(particleAnimationSet);
this._particleAnimationSet = particleAnimationSet;
let state: ParticleStateBase;
let node: ParticleNodeBase;
for (let i: number = 0; i < this._particleAnimationSet.particleNodes.length; i++) {
node = this._particleAnimationSet.particleNodes[i];
state = <ParticleStateBase> this.getAnimationState(node);
if (node.mode == ParticlePropertiesMode.LOCAL_DYNAMIC) {
this._animatorParticleStates.push(state);
node._iDataOffset = this._totalLenOfOneVertex;
this._totalLenOfOneVertex += node.dataLength;
} else {
this._animationParticleStates.push(state);
}
if (state.needUpdateTime)
this._timeParticleStates.push(state);
}
}
/**
* @inheritDoc
*/
public clone(): AnimatorBase {
return new ParticleAnimator(this._particleAnimationSet);
}
/**
* @inheritDoc
*/
public setRenderState(shader: ShaderBase, renderable: _Render_Shape): void {
const animationRegisterData: AnimationRegisterData = this._particleAnimationSet._iAnimationRegisterData;
const particleCollection: ParticleCollection = renderable.shape.particleCollection;
const elements: IElements = renderable.shape.elements;
//process animation sub geometries
const animationElements: AnimationElements = this._particleAnimationSet.getAnimationElements(particleCollection, elements);
let i: number;
for (i = 0; i < this._animationParticleStates.length; i++)
this._animationParticleStates[i].setRenderState(shader, renderable, animationElements, animationRegisterData);
//process animator subgeometries
const animatorElements: AnimationElements = this.getAnimatorElements(particleCollection, elements);
for (i = 0; i < this._animatorParticleStates.length; i++)
this._animatorParticleStates[i].setRenderState(shader, renderable, animatorElements, animationRegisterData);
}
/**
* @inheritDoc
*/
public testGPUCompatibility(shader: ShaderBase): void {
}
/**
* @inheritDoc
*/
public start(): void {
super.start();
for (let i: number = 0; i < this._timeParticleStates.length; i++)
this._timeParticleStates[i].offset(this._pAbsoluteTime);
}
/**
* @inheritDoc
*/
public _pUpdateDeltaTime(dt: number): void {
this._pAbsoluteTime += dt;
for (let i: number = 0; i < this._timeParticleStates.length; i++)
this._timeParticleStates[i].update(this._pAbsoluteTime);
}
/**
* @inheritDoc
*/
public resetTime(offset: number = 0): void {
for (let i: number = 0; i < this._timeParticleStates.length; i++)
this._timeParticleStates[i].offset(this._pAbsoluteTime + offset);
this.update(this.time);
}
public dispose(): void {
for (const key in this._animatorSubGeometries)
(<AnimationElements> this._animatorSubGeometries[key]).dispose();
}
private getAnimatorElements(particleCollection: ParticleCollection, elements: IElements): AnimationElements {
if (!this._animatorParticleStates.length)
return;
const animatorElements: AnimationElements = this._animatorSubGeometries[elements.id] = new AnimationElements();
//create the vertexData vector that will be used for local state data
animatorElements.createVertexData(elements.numVertices, this._totalLenOfOneVertex);
//pass the particles data to the animator elements
animatorElements.animationParticles = this._particleAnimationSet.getAnimationElements(particleCollection, elements).animationParticles;
}
}