UNPKG

@awayjs/graphics

Version:
212 lines (211 loc) 10.6 kB
import { __extends } from "tslib"; import { Vector3D } from '@awayjs/core'; import { ContextGLVertexBufferFormat } from '@awayjs/stage'; import { ParticleStateBase } from './ParticleStateBase'; /** * ... */ var ParticleFollowState = /** @class */ (function (_super) { __extends(ParticleFollowState, _super); function ParticleFollowState(animator, particleFollowNode) { var _this = _super.call(this, animator, particleFollowNode, true) || this; _this._targetPos = new Vector3D(); _this._targetEuler = new Vector3D(); //temporary vector3D for calculation _this._temp = new Vector3D(); _this._particleFollowNode = particleFollowNode; _this._smooth = particleFollowNode._iSmooth; return _this; } Object.defineProperty(ParticleFollowState.prototype, "followTarget", { get: function () { return this._followTarget; }, set: function (value) { this._followTarget = value; }, enumerable: false, configurable: true }); Object.defineProperty(ParticleFollowState.prototype, "smooth", { get: function () { return this._smooth; }, set: function (value) { this._smooth = value; }, enumerable: false, configurable: true }); /** * @inheritDoc */ ParticleFollowState.prototype.setRenderState = function (shader, renderable, animationElements, animationRegisterData) { if (this._followTarget) { if (this._particleFollowNode._iUsesPosition) { this._targetPos.x = this._followTarget.transform.position.x / renderable.node.container.transform.scale.x; this._targetPos.y = this._followTarget.transform.position.y / renderable.node.container.transform.scale.y; this._targetPos.z = this._followTarget.transform.position.z / renderable.node.container.transform.scale.z; } if (this._particleFollowNode._iUsesRotation) { this._targetEuler.x = this._followTarget.transform.rotation.x; this._targetEuler.y = this._followTarget.transform.rotation.y; this._targetEuler.z = this._followTarget.transform.rotation.z; } } //initialization if (!this._prePos) this._prePos = this._targetPos.clone(); if (!this._preEuler) this._preEuler = this._targetEuler.clone(); var currentTime = this._pTime / 1000; var previousTime = animationElements.previousTime; var deltaTime = currentTime - previousTime; var needProcess = previousTime != currentTime; if (this._particleFollowNode._iUsesPosition && this._particleFollowNode._iUsesRotation) { if (needProcess) this.processPositionAndRotation(currentTime, deltaTime, animationElements); animationElements.activateVertexBuffer(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_POSITION_INDEX), this._particleFollowNode._iDataOffset, shader.stage, ContextGLVertexBufferFormat.FLOAT_3); animationElements.activateVertexBuffer(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_ROTATION_INDEX), this._particleFollowNode._iDataOffset + 3, shader.stage, ContextGLVertexBufferFormat.FLOAT_3); } else if (this._particleFollowNode._iUsesPosition) { if (needProcess) this.processPosition(currentTime, deltaTime, animationElements); animationElements.activateVertexBuffer(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_POSITION_INDEX), this._particleFollowNode._iDataOffset, shader.stage, ContextGLVertexBufferFormat.FLOAT_3); } else if (this._particleFollowNode._iUsesRotation) { if (needProcess) this.precessRotation(currentTime, deltaTime, animationElements); animationElements.activateVertexBuffer(animationRegisterData.getRegisterIndex(this._pAnimationNode, ParticleFollowState.FOLLOW_ROTATION_INDEX), this._particleFollowNode._iDataOffset, shader.stage, ContextGLVertexBufferFormat.FLOAT_3); } this._prePos.copyFrom(this._targetPos); this._targetEuler.copyFrom(this._targetEuler); animationElements.previousTime = currentTime; }; ParticleFollowState.prototype.processPosition = function (currentTime, deltaTime, animationElements) { var data = animationElements.animationParticles; var vertexData = animationElements.vertexData; var changed = false; var len = data.length; var interpolatedPos; var posVelocity; if (this._smooth) { posVelocity = this._prePos.subtract(this._targetPos); posVelocity.scaleBy(1 / deltaTime); } else interpolatedPos = this._targetPos; for (var i = 0; i < len; i++) { var k = (currentTime - data[i].startTime) / data[i].totalTime; var t = (k - Math.floor(k)) * data[i].totalTime; if (t - deltaTime <= 0) { var inc = data[i].startVertexIndex * animationElements.totalLenOfOneVertex + this._particleFollowNode._iDataOffset; if (this._smooth) { this._temp.copyFrom(posVelocity); this._temp.scaleBy(t); interpolatedPos = this._targetPos.add(this._temp); } if (vertexData[inc] != interpolatedPos.x || vertexData[inc + 1] != interpolatedPos.y || vertexData[inc + 2] != interpolatedPos.z) { changed = true; for (var j = 0; j < data[i].numVertices; j++) { vertexData[inc++] = interpolatedPos.x; vertexData[inc++] = interpolatedPos.y; vertexData[inc++] = interpolatedPos.z; } } } } if (changed) animationElements.invalidateBuffer(); }; ParticleFollowState.prototype.precessRotation = function (currentTime, deltaTime, animationElements) { var data = animationElements.animationParticles; var vertexData = animationElements.vertexData; var changed = false; var len = data.length; var interpolatedRotation; var rotationVelocity; if (this._smooth) { rotationVelocity = this._preEuler.subtract(this._targetEuler); rotationVelocity.scaleBy(1 / deltaTime); } else interpolatedRotation = this._targetEuler; for (var i = 0; i < len; i++) { var k = (currentTime - data[i].startTime) / data[i].totalTime; var t = (k - Math.floor(k)) * data[i].totalTime; if (t - deltaTime <= 0) { var inc = data[i].startVertexIndex * animationElements.totalLenOfOneVertex + this._particleFollowNode._iDataOffset; if (this._smooth) { this._temp.copyFrom(rotationVelocity); this._temp.scaleBy(t); interpolatedRotation = this._targetEuler.add(this._temp); } if (vertexData[inc] != interpolatedRotation.x || vertexData[inc + 1] != interpolatedRotation.y || vertexData[inc + 2] != interpolatedRotation.z) { changed = true; for (var j = 0; j < data[i].numVertices; j++) { vertexData[inc++] = interpolatedRotation.x; vertexData[inc++] = interpolatedRotation.y; vertexData[inc++] = interpolatedRotation.z; } } } } if (changed) animationElements.invalidateBuffer(); }; ParticleFollowState.prototype.processPositionAndRotation = function (currentTime, deltaTime, animationElements) { var data = animationElements.animationParticles; var vertexData = animationElements.vertexData; var changed = false; var len = data.length; var interpolatedPos; var interpolatedRotation; var posVelocity; var rotationVelocity; if (this._smooth) { posVelocity = this._prePos.subtract(this._targetPos); posVelocity.scaleBy(1 / deltaTime); rotationVelocity = this._preEuler.subtract(this._targetEuler); rotationVelocity.scaleBy(1 / deltaTime); } else { interpolatedPos = this._targetPos; interpolatedRotation = this._targetEuler; } for (var i = 0; i < len; i++) { var k = (currentTime - data[i].startTime) / data[i].totalTime; var t = (k - Math.floor(k)) * data[i].totalTime; if (t - deltaTime <= 0) { var inc = data[i].startVertexIndex * animationElements.totalLenOfOneVertex + this._particleFollowNode._iDataOffset; if (this._smooth) { this._temp.copyFrom(posVelocity); this._temp.scaleBy(t); interpolatedPos = this._targetPos.add(this._temp); this._temp.copyFrom(rotationVelocity); this._temp.scaleBy(t); interpolatedRotation = this._targetEuler.add(this._temp); } if (vertexData[inc] != interpolatedPos.x || vertexData[inc + 1] != interpolatedPos.y || vertexData[inc + 2] != interpolatedPos.z || vertexData[inc + 3] != interpolatedRotation.x || vertexData[inc + 4] != interpolatedRotation.y || vertexData[inc + 5] != interpolatedRotation.z) { changed = true; for (var j = 0; j < data[i].numVertices; j++) { vertexData[inc++] = interpolatedPos.x; vertexData[inc++] = interpolatedPos.y; vertexData[inc++] = interpolatedPos.z; vertexData[inc++] = interpolatedRotation.x; vertexData[inc++] = interpolatedRotation.y; vertexData[inc++] = interpolatedRotation.z; } } } } if (changed) animationElements.invalidateBuffer(); }; /** @private */ ParticleFollowState.FOLLOW_POSITION_INDEX = 0; /** @private */ ParticleFollowState.FOLLOW_ROTATION_INDEX = 1; return ParticleFollowState; }(ParticleStateBase)); export { ParticleFollowState };