UNPKG

@awayjs/graphics

Version:
126 lines (125 loc) 7.55 kB
import { __extends } from "tslib"; import { Vector3D } from '@awayjs/core'; import { ShaderRegisterElement } from '@awayjs/stage'; import { ParticlePropertiesMode } from '../data/ParticlePropertiesMode'; import { ParticleOrbitState } from '../states/ParticleOrbitState'; import { ParticleNodeBase } from './ParticleNodeBase'; /** * A particle animation node used to control the position of a particle over time around a circular orbit. */ var ParticleOrbitNode = /** @class */ (function (_super) { __extends(ParticleOrbitNode, _super); /** * Creates a new <code>ParticleOrbitNode</code> object. * * @param mode Defines whether the mode of operation acts on local properties of a particle or global properties of the node. * @param [optional] usesEulers Defines whether the node uses the <code>eulers</code> property in the shader to calculate a rotation on the orbit. Defaults to true. * @param [optional] usesCycle Defines whether the node uses the <code>cycleDuration</code> property in the shader to calculate the period of the orbit independent of particle duration. Defaults to false. * @param [optional] usesPhase Defines whether the node uses the <code>cyclePhase</code> property in the shader to calculate a starting offset to the cycle rotation of the particle. Defaults to false. * @param [optional] radius Defines the radius of the orbit when in global mode. Defaults to 100. * @param [optional] cycleDuration Defines the duration of the orbit in seconds, used as a period independent of particle duration when in global mode. Defaults to 1. * @param [optional] cyclePhase Defines the phase of the orbit in degrees, used as the starting offset of the cycle when in global mode. Defaults to 0. * @param [optional] eulers Defines the euler rotation in degrees, applied to the orientation of the orbit when in global mode. */ function ParticleOrbitNode(mode, usesEulers, usesCycle, usesPhase, radius, cycleDuration, cyclePhase, eulers) { if (usesEulers === void 0) { usesEulers = true; } if (usesCycle === void 0) { usesCycle = false; } if (usesPhase === void 0) { usesPhase = false; } if (radius === void 0) { radius = 100; } if (cycleDuration === void 0) { cycleDuration = 1; } if (cyclePhase === void 0) { cyclePhase = 0; } if (eulers === void 0) { eulers = null; } var _this = this; var len = 3; if (usesPhase) len++; _this = _super.call(this, 'ParticleOrbit', mode, len) || this; _this._pStateClass = ParticleOrbitState; _this._iUsesEulers = usesEulers; _this._iUsesCycle = usesCycle; _this._iUsesPhase = usesPhase; _this._iRadius = radius; _this._iCycleDuration = cycleDuration; _this._iCyclePhase = cyclePhase; _this._iEulers = eulers || new Vector3D(); return _this; } /** * @inheritDoc */ ParticleOrbitNode.prototype.getAGALVertexCode = function (shader, animationSet, registerCache, animationRegisterData) { var orbitRegister = (this._pMode == ParticlePropertiesMode.GLOBAL) ? registerCache.getFreeVertexConstant() : registerCache.getFreeVertexAttribute(); animationRegisterData.setRegisterIndex(this, ParticleOrbitState.ORBIT_INDEX, orbitRegister.index); var eulersMatrixRegister = registerCache.getFreeVertexConstant(); animationRegisterData.setRegisterIndex(this, ParticleOrbitState.EULERS_INDEX, eulersMatrixRegister.index); registerCache.getFreeVertexConstant(); registerCache.getFreeVertexConstant(); registerCache.getFreeVertexConstant(); var temp1 = registerCache.getFreeVertexVectorTemp(); registerCache.addVertexTempUsages(temp1, 1); var distance = new ShaderRegisterElement(temp1.regName, temp1.index); var temp2 = registerCache.getFreeVertexVectorTemp(); var cos = new ShaderRegisterElement(temp2.regName, temp2.index, 0); var sin = new ShaderRegisterElement(temp2.regName, temp2.index, 1); var degree = new ShaderRegisterElement(temp2.regName, temp2.index, 2); registerCache.removeVertexTempUsage(temp1); var code = ''; if (this._iUsesCycle) { code += 'mul ' + degree + ',' + animationRegisterData.vertexTime + ',' + orbitRegister + '.y\n'; if (this._iUsesPhase) code += 'add ' + degree + ',' + degree + ',' + orbitRegister + '.w\n'; } else code += 'mul ' + degree + ',' + animationRegisterData.vertexLife + ',' + orbitRegister + '.y\n'; code += 'cos ' + cos + ',' + degree + '\n'; code += 'sin ' + sin + ',' + degree + '\n'; code += 'mul ' + distance + '.x,' + cos + ',' + orbitRegister + '.x\n'; code += 'mul ' + distance + '.y,' + sin + ',' + orbitRegister + '.x\n'; code += 'mov ' + distance + '.wz' + animationRegisterData.vertexZeroConst + '\n'; if (this._iUsesEulers) code += 'm44 ' + distance + ',' + distance + ',' + eulersMatrixRegister + '\n'; code += 'add ' + animationRegisterData.positionTarget + '.xyz,' + distance + '.xyz,' + animationRegisterData.positionTarget + '.xyz\n'; if (animationSet.needVelocity) { code += 'neg ' + distance + '.x,' + sin + '\n'; code += 'mov ' + distance + '.y,' + cos + '\n'; code += 'mov ' + distance + '.zw,' + animationRegisterData.vertexZeroConst + '\n'; if (this._iUsesEulers) code += 'm44 ' + distance + ',' + distance + ',' + eulersMatrixRegister + '\n'; code += 'mul ' + distance + ',' + distance + ',' + orbitRegister + '.z\n'; code += 'div ' + distance + ',' + distance + ',' + orbitRegister + '.y\n'; if (!this._iUsesCycle) code += 'div ' + distance + ',' + distance + ',' + animationRegisterData.vertexLife + '\n'; code += 'add ' + animationRegisterData.velocityTarget + '.xyz,' + animationRegisterData.velocityTarget + '.xyz,' + distance + '.xyz\n'; } return code; }; /** * @inheritDoc */ ParticleOrbitNode.prototype.getAnimationState = function (animator) { return animator.getAnimationState(this); }; /** * @inheritDoc */ ParticleOrbitNode.prototype._iGeneratePropertyOfOneParticle = function (param) { //Vector3D.x is radius, Vector3D.y is cycle duration, Vector3D.z is phase var orbit = param[ParticleOrbitNode.ORBIT_VECTOR3D]; if (!orbit) throw new Error('there is no ' + ParticleOrbitNode.ORBIT_VECTOR3D + ' in param!'); this._pOneData[0] = orbit.x; if (this._iUsesCycle && orbit.y <= 0) throw (new Error('the cycle duration must be greater than zero')); this._pOneData[1] = Math.PI * 2 / (!this._iUsesCycle ? 1 : orbit.y); this._pOneData[2] = orbit.x * Math.PI * 2; if (this._iUsesPhase) this._pOneData[3] = orbit.z * Math.PI / 180; }; /** * Reference for orbit node properties on a single particle (when in local property mode). * Expects a <code>Vector3D</code> object representing the radius (x), cycle speed (y) and cycle phase (z) of the motion on the particle. */ ParticleOrbitNode.ORBIT_VECTOR3D = 'OrbitVector3D'; return ParticleOrbitNode; }(ParticleNodeBase)); export { ParticleOrbitNode };