UNPKG

@awayjs/graphics

Version:
158 lines (157 loc) 10.3 kB
import { __extends } from "tslib"; import { ShaderRegisterElement } from '@awayjs/stage'; import { ParticlePropertiesMode } from '../data/ParticlePropertiesMode'; import { ParticleRotateToHeadingState } from '../states/ParticleRotateToHeadingState'; import { ParticleNodeBase } from './ParticleNodeBase'; /** * A particle animation node used to control the rotation of a particle to match its heading vector. */ var ParticleRotateToHeadingNode = /** @class */ (function (_super) { __extends(ParticleRotateToHeadingNode, _super); /** * Creates a new <code>ParticleBillboardNode</code> */ function ParticleRotateToHeadingNode() { var _this = _super.call(this, 'ParticleRotateToHeading', ParticlePropertiesMode.GLOBAL, 0, 3) || this; _this._pStateClass = ParticleRotateToHeadingState; return _this; } /** * @inheritDoc */ ParticleRotateToHeadingNode.prototype.getAGALVertexCode = function (shader, animationSet, registerCache, animationRegisterData) { var code = ''; var len = animationRegisterData.rotationRegisters.length; var i; if (animationSet.hasBillboard) { var temp1 = registerCache.getFreeVertexVectorTemp(); registerCache.addVertexTempUsages(temp1, 1); var temp2 = registerCache.getFreeVertexVectorTemp(); registerCache.addVertexTempUsages(temp2, 1); var temp3 = registerCache.getFreeVertexVectorTemp(); var rotationMatrixRegister = registerCache.getFreeVertexConstant(); animationRegisterData.setRegisterIndex(this, ParticleRotateToHeadingState.MATRIX_INDEX, rotationMatrixRegister.index); registerCache.getFreeVertexConstant(); registerCache.getFreeVertexConstant(); registerCache.getFreeVertexConstant(); registerCache.removeVertexTempUsage(temp1); registerCache.removeVertexTempUsage(temp2); //process the velocity code += 'm33 ' + temp1 + '.xyz,' + animationRegisterData.velocityTarget + '.xyz,' + rotationMatrixRegister + '\n'; code += 'mov ' + temp3 + ',' + animationRegisterData.vertexZeroConst + '\n'; code += 'mov ' + temp3 + '.xy,' + temp1 + '.xy\n'; code += 'nrm ' + temp3 + '.xyz,' + temp3 + '.xyz\n'; //temp3.x=cos,temp3.y=sin //only process z axis code += 'mov ' + temp2 + ',' + animationRegisterData.vertexZeroConst + '\n'; code += 'mov ' + temp2 + '.x,' + temp3 + '.y\n'; code += 'mov ' + temp2 + '.y,' + temp3 + '.x\n'; code += 'mov ' + temp1 + ',' + animationRegisterData.vertexZeroConst + '\n'; code += 'mov ' + temp1 + '.x,' + temp3 + '.x\n'; code += 'neg ' + temp1 + '.y,' + temp3 + '.y\n'; code += 'mov ' + temp3 + ',' + animationRegisterData.vertexZeroConst + '\n'; code += 'mov ' + temp3 + '.z,' + animationRegisterData.vertexOneConst + '\n'; code += 'm33 ' + animationRegisterData.scaleAndRotateTarget + '.xyz,' + animationRegisterData.scaleAndRotateTarget + '.xyz,' + temp1 + '\n'; for (i = 0; i < len; i++) code += 'm33 ' + animationRegisterData.rotationRegisters[i] + '.xyz,' + animationRegisterData.rotationRegisters[i] + ',' + temp1 + '\n'; } else { var nrmVel = registerCache.getFreeVertexVectorTemp(); registerCache.addVertexTempUsages(nrmVel, 1); var xAxis = registerCache.getFreeVertexVectorTemp(); registerCache.addVertexTempUsages(xAxis, 1); var R = registerCache.getFreeVertexVectorTemp(); registerCache.addVertexTempUsages(R, 1); var R_rev = registerCache.getFreeVertexVectorTemp(); var cos = new ShaderRegisterElement(R.regName, R.index, 3); var sin = new ShaderRegisterElement(R_rev.regName, R_rev.index, 3); var cos2 = new ShaderRegisterElement(nrmVel.regName, nrmVel.index, 3); var tempSingle = sin; registerCache.removeVertexTempUsage(nrmVel); registerCache.removeVertexTempUsage(xAxis); registerCache.removeVertexTempUsage(R); code += 'mov ' + xAxis + '.x,' + animationRegisterData.vertexOneConst + '\n'; code += 'mov ' + xAxis + '.yz,' + animationRegisterData.vertexZeroConst + '\n'; code += 'nrm ' + nrmVel + '.xyz,' + animationRegisterData.velocityTarget + '.xyz\n'; code += 'dp3 ' + cos2 + ',' + nrmVel + '.xyz,' + xAxis + '.xyz\n'; code += 'crs ' + nrmVel + '.xyz,' + xAxis + '.xyz,' + nrmVel + '.xyz\n'; code += 'nrm ' + nrmVel + '.xyz,' + nrmVel + '.xyz\n'; //use R as temp to judge if nrm is (0,0,0). //if nrm is (0,0,0) ,change it to (0,0,1). code += 'dp3 ' + R + '.x,' + nrmVel + '.xyz,' + nrmVel + '.xyz\n'; code += 'sge ' + R + '.x,' + animationRegisterData.vertexZeroConst + ',' + R + '.x\n'; code += 'add ' + nrmVel + '.z,' + R + '.x,' + nrmVel + '.z\n'; code += 'add ' + tempSingle + ',' + cos2 + ',' + animationRegisterData.vertexOneConst + '\n'; code += 'div ' + tempSingle + ',' + tempSingle + ',' + animationRegisterData.vertexTwoConst + '\n'; code += 'sqt ' + cos + ',' + tempSingle + '\n'; code += 'sub ' + tempSingle + ',' + animationRegisterData.vertexOneConst + ',' + cos2 + '\n'; code += 'div ' + tempSingle + ',' + tempSingle + ',' + animationRegisterData.vertexTwoConst + '\n'; code += 'sqt ' + sin + ',' + tempSingle + '\n'; code += 'mul ' + R + '.xyz,' + sin + ',' + nrmVel + '.xyz\n'; //use cos as R.w code += 'mul ' + R_rev + '.xyz,' + sin + ',' + nrmVel + '.xyz\n'; code += 'neg ' + R_rev + '.xyz,' + R_rev + '.xyz\n'; //use cos as R_rev.w //nrmVel and xAxis are used as temp register code += 'crs ' + nrmVel + '.xyz,' + R + '.xyz,' + animationRegisterData.scaleAndRotateTarget + '.xyz\n'; //use cos as R.w code += 'mul ' + xAxis + '.xyz,' + cos + ',' + animationRegisterData.scaleAndRotateTarget + '.xyz\n'; code += 'add ' + nrmVel + '.xyz,' + nrmVel + '.xyz,' + xAxis + '.xyz\n'; code += 'dp3 ' + xAxis + '.w,' + R + '.xyz,' + animationRegisterData.scaleAndRotateTarget + '.xyz\n'; code += 'neg ' + nrmVel + '.w,' + xAxis + '.w\n'; code += 'crs ' + R + '.xyz,' + nrmVel + '.xyz,' + R_rev + '.xyz\n'; //code += "mul " + xAxis + ".xyzw," + nrmVel + ".xyzw," +R_rev + ".w\n"; code += 'mul ' + xAxis + '.xyzw,' + nrmVel + '.xyzw,' + cos + '\n'; code += 'add ' + R + '.xyz,' + R + '.xyz,' + xAxis + '.xyz\n'; code += 'mul ' + xAxis + '.xyz,' + nrmVel + '.w,' + R_rev + '.xyz\n'; code += 'add ' + animationRegisterData.scaleAndRotateTarget + '.xyz,' + R + '.xyz,' + xAxis + '.xyz\n'; for (i = 0; i < len; i++) { //just repeat the calculate above //because of the limited registers, no need to optimise code += 'mov ' + xAxis + '.x,' + animationRegisterData.vertexOneConst + '\n'; code += 'mov ' + xAxis + '.yz,' + animationRegisterData.vertexZeroConst + '\n'; code += 'nrm ' + nrmVel + '.xyz,' + animationRegisterData.velocityTarget + '.xyz\n'; code += 'dp3 ' + cos2 + ',' + nrmVel + '.xyz,' + xAxis + '.xyz\n'; code += 'crs ' + nrmVel + '.xyz,' + xAxis + '.xyz,' + nrmVel + '.xyz\n'; code += 'nrm ' + nrmVel + '.xyz,' + nrmVel + '.xyz\n'; code += 'dp3 ' + R + '.x,' + nrmVel + '.xyz,' + nrmVel + '.xyz\n'; code += 'sge ' + R + '.x,' + animationRegisterData.vertexZeroConst + ',' + R + '.x\n'; code += 'add ' + nrmVel + '.z,' + R + '.x,' + nrmVel + '.z\n'; code += 'add ' + tempSingle + ',' + cos2 + ',' + animationRegisterData.vertexOneConst + '\n'; code += 'div ' + tempSingle + ',' + tempSingle + ',' + animationRegisterData.vertexTwoConst + '\n'; code += 'sqt ' + cos + ',' + tempSingle + '\n'; code += 'sub ' + tempSingle + ',' + animationRegisterData.vertexOneConst + ',' + cos2 + '\n'; code += 'div ' + tempSingle + ',' + tempSingle + ',' + animationRegisterData.vertexTwoConst + '\n'; code += 'sqt ' + sin + ',' + tempSingle + '\n'; code += 'mul ' + R + '.xyz,' + sin + ',' + nrmVel + '.xyz\n'; code += 'mul ' + R_rev + '.xyz,' + sin + ',' + nrmVel + '.xyz\n'; code += 'neg ' + R_rev + '.xyz,' + R_rev + '.xyz\n'; code += 'crs ' + nrmVel + '.xyz,' + R + '.xyz,' + animationRegisterData.rotationRegisters[i] + '.xyz\n'; code += 'mul ' + xAxis + '.xyz,' + cos + ',' + animationRegisterData.rotationRegisters[i] + '.xyz\n'; code += 'add ' + nrmVel + '.xyz,' + nrmVel + '.xyz,' + xAxis + '.xyz\n'; code += 'dp3 ' + xAxis + '.w,' + R + '.xyz,' + animationRegisterData.rotationRegisters[i] + '.xyz\n'; code += 'neg ' + nrmVel + '.w,' + xAxis + '.w\n'; code += 'crs ' + R + '.xyz,' + nrmVel + '.xyz,' + R_rev + '.xyz\n'; code += 'mul ' + xAxis + '.xyzw,' + nrmVel + '.xyzw,' + cos + '\n'; code += 'add ' + R + '.xyz,' + R + '.xyz,' + xAxis + '.xyz\n'; code += 'mul ' + xAxis + '.xyz,' + nrmVel + '.w,' + R_rev + '.xyz\n'; code += 'add ' + animationRegisterData.rotationRegisters[i] + '.xyz,' + R + '.xyz,' + xAxis + '.xyz\n'; } } return code; }; /** * @inheritDoc */ ParticleRotateToHeadingNode.prototype.getAnimationState = function (animator) { return animator.getAnimationState(this); }; /** * @inheritDoc */ ParticleRotateToHeadingNode.prototype._iProcessAnimationSetting = function (particleAnimationSet) { particleAnimationSet.needVelocity = true; }; return ParticleRotateToHeadingNode; }(ParticleNodeBase)); export { ParticleRotateToHeadingNode };