@awayjs/graphics
Version:
AwayJS graphics classes
178 lines (147 loc) • 8.76 kB
text/typescript
import { Vector3D, ColorTransform } 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 { ParticleColorNode } from '../nodes/ParticleColorNode';
import { ParticleAnimator } from '../ParticleAnimator';
import { ParticleStateBase } from './ParticleStateBase';
/**
* ...
* @author ...
*/
export class ParticleColorState extends ParticleStateBase {
/** @private */
public static START_MULTIPLIER_INDEX: number = 0;
/** @private */
public static DELTA_MULTIPLIER_INDEX: number = 1;
/** @private */
public static START_OFFSET_INDEX: number = 2;
/** @private */
public static DELTA_OFFSET_INDEX: number = 3;
/** @private */
public static CYCLE_INDEX: number = 4;
private _particleColorNode: ParticleColorNode;
private _usesMultiplier: boolean;
private _usesOffset: boolean;
private _usesCycle: boolean;
private _usesPhase: boolean;
private _startColor: ColorTransform;
private _endColor: ColorTransform;
private _cycleDuration: number;
private _cyclePhase: number;
private _cycleData: Vector3D;
private _startMultiplierData: Vector3D;
private _deltaMultiplierData: Vector3D;
private _startOffsetData: Vector3D;
private _deltaOffsetData: Vector3D;
/**
* Defines the start color transform of the state, when in global mode.
*/
public get startColor(): ColorTransform {
return this._startColor;
}
public set startColor(value: ColorTransform) {
this._startColor = value;
this.updateColorData();
}
/**
* Defines the end color transform of the state, when in global mode.
*/
public get endColor(): ColorTransform {
return this._endColor;
}
public set endColor(value: ColorTransform) {
this._endColor = value;
this.updateColorData();
}
/**
* Defines the duration of the animation in seconds, used as a period independent of particle duration when in global mode. Defaults to 1.
*/
public get cycleDuration(): number {
return this._cycleDuration;
}
public set cycleDuration(value: number) {
this._cycleDuration = value;
this.updateColorData();
}
/**
* Defines the phase of the cycle in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0.
*/
public get cyclePhase(): number {
return this._cyclePhase;
}
public set cyclePhase(value: number) {
this._cyclePhase = value;
this.updateColorData();
}
constructor(animator: ParticleAnimator, particleColorNode: ParticleColorNode) {
super(animator, particleColorNode);
this._particleColorNode = particleColorNode;
this._usesMultiplier = this._particleColorNode._iUsesMultiplier;
this._usesOffset = this._particleColorNode._iUsesOffset;
this._usesCycle = this._particleColorNode._iUsesCycle;
this._usesPhase = this._particleColorNode._iUsesPhase;
this._startColor = this._particleColorNode._iStartColor;
this._endColor = this._particleColorNode._iEndColor;
this._cycleDuration = this._particleColorNode._iCycleDuration;
this._cyclePhase = this._particleColorNode._iCyclePhase;
this.updateColorData();
}
public setRenderState(shader: ShaderBase, renderable: _Render_RenderableBase, animationElements: AnimationElements, animationRegisterData: AnimationRegisterData): void {
if (shader.usesFragmentAnimation) {
let dataOffset: number = this._particleColorNode._iDataOffset;
if (this._usesCycle)
shader.setVertexConst(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleColorState.CYCLE_INDEX), this._cycleData.x, this._cycleData.y, this._cycleData.z, this._cycleData.w);
if (this._usesMultiplier) {
if (this._particleColorNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
animationElements.activateVertexBuffer(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_MULTIPLIER_INDEX), dataOffset, shader.stage, ContextGLVertexBufferFormat.FLOAT_4);
dataOffset += 4;
animationElements.activateVertexBuffer(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_MULTIPLIER_INDEX), dataOffset, shader.stage, ContextGLVertexBufferFormat.FLOAT_4);
dataOffset += 4;
} else {
shader.setVertexConst(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_MULTIPLIER_INDEX), this._startMultiplierData.x, this._startMultiplierData.y, this._startMultiplierData.z, this._startMultiplierData.w);
shader.setVertexConst(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_MULTIPLIER_INDEX), this._deltaMultiplierData.x, this._deltaMultiplierData.y, this._deltaMultiplierData.z, this._deltaMultiplierData.w);
}
}
if (this._usesOffset) {
if (this._particleColorNode.mode == ParticlePropertiesMode.LOCAL_STATIC) {
animationElements.activateVertexBuffer(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_OFFSET_INDEX), dataOffset, shader.stage, ContextGLVertexBufferFormat.FLOAT_4);
dataOffset += 4;
animationElements.activateVertexBuffer(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_OFFSET_INDEX), dataOffset, shader.stage, ContextGLVertexBufferFormat.FLOAT_4);
} else {
shader.setVertexConst(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleColorState.START_OFFSET_INDEX), this._startOffsetData.x, this._startOffsetData.y, this._startOffsetData.z, this._startOffsetData.w);
shader.setVertexConst(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleColorState.DELTA_OFFSET_INDEX), this._deltaOffsetData.x, this._deltaOffsetData.y, this._deltaOffsetData.z, this._deltaOffsetData.w);
}
}
}
}
private updateColorData(): void {
if (this._usesCycle) {
if (this._cycleDuration <= 0)
throw (new Error('the cycle duration must be greater than zero'));
this._cycleData = new Vector3D(Math.PI * 2 / this._cycleDuration, this._cyclePhase * Math.PI / 180, 0, 0);
}
if (this._particleColorNode.mode == ParticlePropertiesMode.GLOBAL) {
if (this._usesCycle) {
if (this._usesMultiplier) {
this._startMultiplierData = new Vector3D((this._startColor.redMultiplier + this._endColor.redMultiplier) / 2, (this._startColor.greenMultiplier + this._endColor.greenMultiplier) / 2, (this._startColor.blueMultiplier + this._endColor.blueMultiplier) / 2, (this._startColor.alphaMultiplier + this._endColor.alphaMultiplier) / 2);
this._deltaMultiplierData = new Vector3D((this._endColor.redMultiplier - this._startColor.redMultiplier) / 2, (this._endColor.greenMultiplier - this._startColor.greenMultiplier) / 2, (this._endColor.blueMultiplier - this._startColor.blueMultiplier) / 2, (this._endColor.alphaMultiplier - this._startColor.alphaMultiplier) / 2);
}
if (this._usesOffset) {
this._startOffsetData = new Vector3D((this._startColor.redOffset + this._endColor.redOffset) / (255 * 2), (this._startColor.greenOffset + this._endColor.greenOffset) / (255 * 2), (this._startColor.blueOffset + this._endColor.blueOffset) / (255 * 2), (this._startColor.alphaOffset + this._endColor.alphaOffset) / (255 * 2));
this._deltaOffsetData = new Vector3D((this._endColor.redOffset - this._startColor.redOffset) / (255 * 2), (this._endColor.greenOffset - this._startColor.greenOffset) / (255 * 2), (this._endColor.blueOffset - this._startColor.blueOffset) / (255 * 2), (this._endColor.alphaOffset - this._startColor.alphaOffset) / (255 * 2));
}
} else {
if (this._usesMultiplier) {
this._startMultiplierData = new Vector3D(this._startColor.redMultiplier, this._startColor.greenMultiplier, this._startColor.blueMultiplier, this._startColor.alphaMultiplier);
this._deltaMultiplierData = new Vector3D((this._endColor.redMultiplier - this._startColor.redMultiplier), (this._endColor.greenMultiplier - this._startColor.greenMultiplier), (this._endColor.blueMultiplier - this._startColor.blueMultiplier), (this._endColor.alphaMultiplier - this._startColor.alphaMultiplier));
}
if (this._usesOffset) {
this._startOffsetData = new Vector3D(this._startColor.redOffset / 255, this._startColor.greenOffset / 255, this._startColor.blueOffset / 255, this._startColor.alphaOffset / 255);
this._deltaOffsetData = new Vector3D((this._endColor.redOffset - this._startColor.redOffset) / 255, (this._endColor.greenOffset - this._startColor.greenOffset) / 255, (this._endColor.blueOffset - this._startColor.blueOffset) / 255, (this._endColor.alphaOffset - this._startColor.alphaOffset) / 255);
}
}
}
}
}