import { Vector3D } from '@awayjs/core'; import { ContextGLVertexBufferFormat } from '@awayjs/stage'; import { ShaderBase, _Render_RenderableBase, AnimationRegisterData } from '@awayjs/renderer'; import { AnimationElements } from '../data/AnimationElements'; import { ParticlePropertiesMode } from '../data/ParticlePropertiesMode'; import { ParticleOscillatorNode } from '../nodes/ParticleOscillatorNode'; import { ParticleAnimator } from '../ParticleAnimator'; import { ParticleStateBase } from './ParticleStateBase'; /** * ... */ export class ParticleOscillatorState extends ParticleStateBase { /** @private */ public static OSCILLATOR_INDEX: number = 0; private _particleOscillatorNode: ParticleOscillatorNode; private _oscillator: Vector3D; private _oscillatorData: Vector3D; /** * Defines the default oscillator axis (x, y, z) and cycleDuration (w) of the state, used when in global mode. */ public get oscillator(): Vector3D { return this._oscillator; } public set oscillator(value: Vector3D) { this._oscillator = value; this.updateOscillatorData(); } constructor(animator: ParticleAnimator, particleOscillatorNode: ParticleOscillatorNode) { super(animator, particleOscillatorNode); this._particleOscillatorNode = particleOscillatorNode; this._oscillator = this._particleOscillatorNode._iOscillator; this.updateOscillatorData(); } /** * @inheritDoc */ public setRenderState(shader: ShaderBase, renderable: _Render_RenderableBase, animationElements: AnimationElements, animationRegisterData: AnimationRegisterData): void { const index: number = animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleOscillatorState.OSCILLATOR_INDEX); if (this._particleOscillatorNode.mode == ParticlePropertiesMode.LOCAL_STATIC) animationElements.activateVertexBuffer(index, this._particleOscillatorNode._iDataOffset, shader.stage, ContextGLVertexBufferFormat.FLOAT_4); else shader.setVertexConst(index, this._oscillatorData.x, this._oscillatorData.y, this._oscillatorData.z, this._oscillatorData.w); } private updateOscillatorData(): void { if (this._particleOscillatorNode.mode == ParticlePropertiesMode.GLOBAL) { if (this._oscillator.w <= 0) throw (new Error('the cycle duration must greater than zero')); if (this._oscillatorData == null) this._oscillatorData = new Vector3D(); this._oscillatorData.x = this._oscillator.x; this._oscillatorData.y = this._oscillator.y; this._oscillatorData.z = this._oscillator.z; this._oscillatorData.w = Math.PI * 2 / this._oscillator.w; } } }