UNPKG

@awayjs/graphics

Version:
162 lines (161 loc) 8.66 kB
import { __extends } from "tslib"; import { ShaderRegisterElement } from '@awayjs/stage'; import { ParticlePropertiesMode } from '../data/ParticlePropertiesMode'; import { ParticleSpriteSheetState } from '../states/ParticleSpriteSheetState'; import { ParticleAnimationSet } from '../ParticleAnimationSet'; import { ParticleNodeBase } from './ParticleNodeBase'; /** * A particle animation node used when a spritesheet texture is required to animate the particle. * NB: to enable use of this node, the <code>repeat</code> property on the material has to be set to true. */ var ParticleSpriteSheetNode = /** @class */ (function (_super) { __extends(ParticleSpriteSheetNode, _super); /** * Creates a new <code>ParticleSpriteSheetNode</code> * * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node. * @param [optional] numColumns Defines the number of columns in the spritesheet, when in global mode. Defaults to 1. * @param [optional] numRows Defines the number of rows in the spritesheet, when in global mode. Defaults to 1. * @param [optional] cycleDuration Defines the default cycle duration in seconds, when in global mode. Defaults to 1. * @param [optional] cyclePhase Defines the default cycle phase, when in global mode. Defaults to 0. * @param [optional] totalFrames Defines the total number of frames used by the spritesheet, when in global mode. Defaults to the number defined by numColumns and numRows. * @param [optional] looping Defines whether the spritesheet animation is set to loop indefinitely. Defaults to true. */ function ParticleSpriteSheetNode(mode, usesCycle, usesPhase, numColumns, numRows, cycleDuration, cyclePhase, totalFrames) { if (numColumns === void 0) { numColumns = 1; } if (numRows === void 0) { numRows = 1; } if (cycleDuration === void 0) { cycleDuration = 1; } if (cyclePhase === void 0) { cyclePhase = 0; } if (totalFrames === void 0) { totalFrames = Number.MAX_VALUE; } var _this = _super.call(this, 'ParticleSpriteSheet', mode, usesCycle ? (usesPhase ? 3 : 2) : 1, ParticleAnimationSet.POST_PRIORITY + 1) || this; _this._pStateClass = ParticleSpriteSheetState; _this._iUsesCycle = usesCycle; _this._iUsesPhase = usesPhase; _this._iNumColumns = numColumns; _this._iNumRows = numRows; _this._iCyclePhase = cyclePhase; _this._iCycleDuration = cycleDuration; _this._iTotalFrames = Math.min(totalFrames, numColumns * numRows); return _this; } Object.defineProperty(ParticleSpriteSheetNode.prototype, "numColumns", { /** * Defines the number of columns in the spritesheet, when in global mode. Defaults to 1. Read only. */ get: function () { return this._iNumColumns; }, enumerable: false, configurable: true }); Object.defineProperty(ParticleSpriteSheetNode.prototype, "numRows", { /** * Defines the number of rows in the spritesheet, when in global mode. Defaults to 1. Read only. */ get: function () { return this._iNumRows; }, enumerable: false, configurable: true }); Object.defineProperty(ParticleSpriteSheetNode.prototype, "totalFrames", { /** * Defines the total number of frames used by the spritesheet, when in global mode. Defaults to the number defined by numColumns and numRows. Read only. */ get: function () { return this._iTotalFrames; }, enumerable: false, configurable: true }); /** * @inheritDoc */ ParticleSpriteSheetNode.prototype.getAGALUVCode = function (shader, animationSet, registerCache, animationRegisterData) { //get 2 vc var uvParamConst1 = registerCache.getFreeVertexConstant(); var uvParamConst2 = (this._pMode == ParticlePropertiesMode.GLOBAL) ? registerCache.getFreeVertexConstant() : registerCache.getFreeVertexAttribute(); animationRegisterData.setRegisterIndex(this, ParticleSpriteSheetState.UV_INDEX_0, uvParamConst1.index); animationRegisterData.setRegisterIndex(this, ParticleSpriteSheetState.UV_INDEX_1, uvParamConst2.index); var uTotal = new ShaderRegisterElement(uvParamConst1.regName, uvParamConst1.index, 0); var uStep = new ShaderRegisterElement(uvParamConst1.regName, uvParamConst1.index, 1); var vStep = new ShaderRegisterElement(uvParamConst1.regName, uvParamConst1.index, 2); var uSpeed = new ShaderRegisterElement(uvParamConst2.regName, uvParamConst2.index, 0); var cycle = new ShaderRegisterElement(uvParamConst2.regName, uvParamConst2.index, 1); var phaseTime = new ShaderRegisterElement(uvParamConst2.regName, uvParamConst2.index, 2); var temp = registerCache.getFreeVertexVectorTemp(); var time = new ShaderRegisterElement(temp.regName, temp.index, 0); var vOffset = new ShaderRegisterElement(temp.regName, temp.index, 1); temp = new ShaderRegisterElement(temp.regName, temp.index, 2); var temp2 = new ShaderRegisterElement(temp.regName, temp.index, 3); var u = new ShaderRegisterElement(animationRegisterData.uvTarget.regName, animationRegisterData.uvTarget.index, 0); var v = new ShaderRegisterElement(animationRegisterData.uvTarget.regName, animationRegisterData.uvTarget.index, 1); var code = ''; //scale uv code += 'mul ' + u + ',' + u + ',' + uStep + '\n'; if (this._iNumRows > 1) code += 'mul ' + v + ',' + v + ',' + vStep + '\n'; if (this._iUsesCycle) { if (this._iUsesPhase) code += 'add ' + time + ',' + animationRegisterData.vertexTime + ',' + phaseTime + '\n'; else code += 'mov ' + time + ',' + animationRegisterData.vertexTime + '\n'; code += 'div ' + time + ',' + time + ',' + cycle + '\n'; code += 'frc ' + time + ',' + time + '\n'; code += 'mul ' + time + ',' + time + ',' + cycle + '\n'; code += 'mul ' + temp + ',' + time + ',' + uSpeed + '\n'; } else code += 'mul ' + temp.toString() + ',' + animationRegisterData.vertexLife + ',' + uTotal + '\n'; if (this._iNumRows > 1) { code += 'frc ' + temp2 + ',' + temp + '\n'; code += 'sub ' + vOffset + ',' + temp + ',' + temp2 + '\n'; code += 'mul ' + vOffset + ',' + vOffset + ',' + vStep + '\n'; code += 'add ' + v + ',' + v + ',' + vOffset + '\n'; } code += 'div ' + temp2 + ',' + temp + ',' + uStep + '\n'; code += 'frc ' + temp + ',' + temp2 + '\n'; code += 'sub ' + temp2 + ',' + temp2 + ',' + temp + '\n'; code += 'mul ' + temp + ',' + temp2 + ',' + uStep + '\n'; if (this._iNumRows > 1) code += 'frc ' + temp + ',' + temp + '\n'; code += 'add ' + u + ',' + u + ',' + temp + '\n'; return code; }; /** * @inheritDoc */ ParticleSpriteSheetNode.prototype.getAnimationState = function (animator) { return animator.getAnimationState(this); }; /** * @inheritDoc */ ParticleSpriteSheetNode.prototype._iProcessAnimationSetting = function (particleAnimationSet) { particleAnimationSet.hasUVNode = true; }; /** * @inheritDoc */ ParticleSpriteSheetNode.prototype._iGeneratePropertyOfOneParticle = function (param) { if (this._iUsesCycle) { var uvCycle = param[ParticleSpriteSheetNode.UV_VECTOR3D]; if (!uvCycle) throw (new Error('there is no ' + ParticleSpriteSheetNode.UV_VECTOR3D + ' in param!')); if (uvCycle.x <= 0) throw (new Error('the cycle duration must be greater than zero')); var uTotal = this._iTotalFrames / this._iNumColumns; this._pOneData[0] = uTotal / uvCycle.x; this._pOneData[1] = uvCycle.x; if (this._iUsesPhase) this._pOneData[2] = uvCycle.y; } }; /** * Reference for spritesheet node properties on a single particle (when in local property mode). * Expects a <code>Vector3D</code> representing the cycleDuration (x), optional phaseTime (y). */ ParticleSpriteSheetNode.UV_VECTOR3D = 'UVVector3D'; return ParticleSpriteSheetNode; }(ParticleNodeBase)); export { ParticleSpriteSheetNode };