123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790 |
- import XrFrame from 'XrFrame';
- import BasicParticle from './SystemProperty/BasicParticle'
- import SubEmitter, { SubEmitterState } from './Util/SubEmitter'
- import ParticleInstance from './SystemProperty/ParticleInstance'
- import { BasicGradientMethod } from './Util/Gradient'
- const xrFrameSystem = wx.getXrFrameSystem();
- const tempVec1 = xrFrameSystem.Vector3.createFromNumber(0, 0, 0);
- const tempVec2 = xrFrameSystem.Vector3.createFromNumber(0, 0, 0);
- function randomBetween(v1, v2, randomSeed = Math.random()) {
- if (v1 === v2) {
- return v1;
- } else {
- return randomSeed * Math.abs(v1 - v2) + Math.min(v1, v2);
- }
- };
- // 继承了控制粒子系统渲染的基础类,这里将实现粒子运作的逻辑
- export default class CustomParticle extends BasicParticle {
- public readonly priority: number = 300;
- public subEmitters = null;
- private _start: boolean = false;
- private _stop: boolean = false;
- private _alive: boolean = false;
- private _actualFrame: number = 0;
- private _excessInstance: number = 0;
- private _emitterWorldMatrix: XrFrame.Matrix4;
- private _emitterInverseWorldMatrix: XrFrame.Matrix4;
- private _tempEndColor: XrFrame.Vector4 = xrFrameSystem.Vector4.createFromNumber(0, 0, 0, 0);
- private _tempDiffColor: XrFrame.Vector4 = xrFrameSystem.Vector4.createFromNumber(0, 0, 0, 0);
- private _tempAccColorStep: XrFrame.Vector4 = xrFrameSystem.Vector4.createFromNumber(0, 0, 0, 0);
- private _activeSubEmitterSystem;
- private _rootEmitterSystem;
- get material() {
- return this._material;
- }
- set material(value: Material) {
- if (!this._mesh) {
- return;
- }
- }
- get id() {
- return this._mesh.id;
- }
- get data() {
- return this._data;
- }
- get particleEmitter() {
- return this._particleEmitter;
- }
- set data(value: IParticleData) {
- this._data = value;
- }
- /**
- * 粒子系统开始播放。
- *
- * @param delay 设定粒子延时几秒后再播放。
- */
- public start(delay) {
- if (delay) {
- setTimeout(() => {
- this.start(0);
- }, delay);
- return;
- }
- this._start = true;
- this._stop = false;
- if (this._preWarmCycles) {
- for (var index = 0; index < this._preWarmCycles; index++) {
- this._updateRenderData(0, true);
- }
- }
- }
- /**
- * 停止粒子系统与其子发射器的播放。
- */
- public stop() {
- if (this._stop) {
- return;
- }
- this._stop = true;
- this.stopSubEmitters();
- }
- /**
- * 当粒子系统添加到场景中时会执行的函数
- */
- public onAdd(parent: Element, data: IParticleData) {
- if (this._mesh) {
- return;
- }
- // 将元素和粒子所在场景给予对应成员变量
- this.particleEl = this.el;
- this.particleScene = this.el.scene;
- this._data = data;
- this.initParticle(this._data);
- // 检查是否存在子发射器
- this._prepareSubEmitterArray();
- // 粒子系统开始运行,delay控制几秒后执行
- this.start(this._delay);
- }
- /**
- * 初始化粒子系统的状态。
- */
- public initParticle(data: IParticleData) {
- this._systemId = CustomParticle.count++;
- this._parseProperties(data);
- this._parseAttribute();
- this._createVertexBuffers();
- this._createIndexBuffer();
- this._registerGeometry();
- this._createMesh();
- this._chooseEmitterProcess();
- this._setMeshData(this._material, data.uniforms, data.states);
- }
- /**
- * 获取一个粒子子发射器。
- */
- public createSubEmitter(data: IParticleData) {
- var particleSystem = new CustomParticle();
- var tempData: IParticleData = {};
- particleSystem.data = tempData;
- particleSystem.particleEl = this.particleEl || this.el;
- particleSystem.particleScene = this.particleScene || this.el.scene;
- for (var key in data) {
- particleSystem.data[key] = data[key];
- }
- //此时还未解析后加入的properties数据, 当此subEmitter被clone后成员数据更新生效
- var subEmitter = new SubEmitter(particleSystem)
- return subEmitter;
- }
- /**
- * 获取一个拷贝的粒子系统。
- */
- public clone() {
- var cloneParticleSystem = new CustomParticle();
- var tempData: IParticleData = {};
- for (var key in this._data) {
- tempData[key] = this._data[key]
- }
- cloneParticleSystem.data = tempData;
- cloneParticleSystem.particleEl = this.particleScene.createElement(xrFrameSystem.XRNode, {
- position: "0 0 0"
- });
- this.particleEl.addChild(cloneParticleSystem.particleEl);
- cloneParticleSystem.particleScene = this.particleScene;
- return cloneParticleSystem;
- }
- /**
- * 重置粒子系统的状态。
- */
- public resetParticle() {
- this._stockInstances.length = 0;
- this._instances.length = 0;
- // canvas must be redrawed to make right phenomenon
- this._updateRenderData(0);
- this._setMeshData(this._material)
- };
- /**
- * 检测子发射器的类型
- */
- protected _prepareSubEmitterArray() {
- this._subEmitters = [];
- if (this.subEmitters) {
- this.subEmitters.forEach((subEmitter) => {
- if (subEmitter instanceof CustomParticle) {
- this._subEmitters.push([new SubEmitter(subEmitter)]);
- } else if (subEmitter instanceof SubEmitter) {
- this._subEmitters.push([subEmitter]);
- } else if (subEmitter instanceof Array) {
- this._subEmitters.push(subEmitter);
- }
- })
- }
- if (this._subEmitters && this._subEmitters.length != 0) {
- this._activeSubEmitterSystem = new Array();
- }
- }
- /**
- * 停止所有粒子子系统的发射状态。
- */
- protected stopSubEmitters() {
- if (!this._activeSubEmitterSystem) {
- return;
- }
- this._activeSubEmitterSystem.forEach((subEmitterSystem) => {
- subEmitterSystem.stop();
- })
- this._activeSubEmitterSystem = new Array();
- }
- /**
- * 粒子子发射系统从依附的粒子系统中剥离。
- */
- protected removeFromRoot() {
- if (!this._rootEmitterSystem) {
- return;
- }
- var index = this._rootEmitterSystem._activeSubEmitterSystem.indexOf(this);
- if (index !== -1) {
- this._rootEmitterSystem._activeSubEmitterSystem.splice(index, 1);
- }
- this._rootEmitterSystem = null;
- }
- /**
- * 每一帧粒子系统更新的逻辑
- */
- public onTick(deltaTime: number, data: IParticleData): void {
- this._updateSpeed = deltaTime / 1000;
- //layout发生变化时,会重置粒子系统
- if (this._vertexLayoutDirty) {
- this.onUpdate(data, null);
- } else {
- this._updateRenderData(deltaTime);
- this._setMeshData(this._material, data.uniforms);
- }
- this._material?._checkTextures(deltaTime);
- }
- public onUpdate(data: IParticleData, preData: IParticleData) {
- if (!this._mesh) {
- return;
- }
- // 如果顶点布局发生变化,则需要重置粒子系统
- if (this._vertexLayoutDirty) {
- this.resetParticle();
- this._parseAttribute();
- this._createVertexBuffers();
- this._setMeshData(this._material, data.uniforms);
- this._vertexLayoutDirty = false;
- } else {
- //wxml属性更新
- this.resetParticle();
- this.initParticle(data);
- }
- }
- // 每一帧进行粒子生成和粒子位置与轨迹运算的核心逻辑
- protected _updateRenderData(deltaTime: number, isPreWarm: boolean = false) {
- if (!this._start) {
- return;
- }
- var newInstanceSum;
- var rate = this._emitRate;
- var _scaledUpdateSpeed = this._updateSpeed * (isPreWarm ? this._preWarmStepOffset : 1);
- newInstanceSum = (rate * _scaledUpdateSpeed) >> 0;
- this._excessInstance += rate * _scaledUpdateSpeed - newInstanceSum;
- if (this._excessInstance > 1.0) {
- newInstanceSum += this._excessInstance >> 0;
- this._excessInstance -= this._excessInstance >> 0;
- }
- //burst mode
- //控制粒子喷射效果的逻辑
- if (this._burstCount > 0) {
- var cycle: boolean = false;
- var begin: boolean = false;
- //达到喷射时间时,开始第一次喷射
- if (this._burstCountTime < this._burstTime) {
- this._burstCountTime += this._updateSpeed;
- } else {
- begin = true;
- }
- if (begin) {
- // 判断喷射间隙, 如果喷射间隙过短则视为仅喷射一次
- if (this._burstInterval < 0.01) {
- if (this._burstInterval >= 0) {
- newInstanceSum += this._burstCount;
- this._burstInterval = -1;
- }
- } else {
- this._burstCountInterval += this._updateSpeed;
- if (this._burstCountInterval > this._burstInterval) {
- cycle = true;
- this._burstCountInterval = 0
- }
- }
- }
- // 判断喷射循环的次数
- if (cycle) {
- if (this._burstCycle != -1) {
- if (this._burstCountCycle >= this._burstCycle >> 0) {
- cycle = false;
- } else {
- this._burstCountCycle++;
- }
- }
- }
- if (cycle) {
- newInstanceSum += this._burstCount >> 0;
- }
- }
- this._alive = false;
- if (!this._stop) {
- this._actualFrame += _scaledUpdateSpeed;
- if (this._stopDuration && this._actualFrame >= this._stopDuration) {
- this.stop();
- }
- }
- else {
- newInstanceSum = 0;
- }
- this.update(newInstanceSum);
- if (this._stop) {
- if (!this._alive) {
- this._start = false;
- this.resetParticle();
- this.removeFromRoot();
- }
- }
- if (!isPreWarm) {
- var offset = 0;
- // 每帧此处需要清空_vertexData
- this._vertexData.fill(0);
- for (var index = 0; index < this._instances.length; index++) {
- var particle = this._instances[index];
- this._appendParticleVertices(offset, particle);
- if (this._useRenderMesh) {
- offset += this._vertexCount;
- } else {
- offset += 4;
- }
- if (particle.subEmitterMuster && particle.subEmitterMuster.length > 0) {
- particle.subEmitterMuster.forEach((subEmitter: SubEmitter) => {
- subEmitter.particleSystem.onTick(deltaTime, subEmitter.particleSystem.data);
- })
- }
- }
- if (this._activeSubEmitterSystem && this._activeSubEmitterSystem.length > 0) {
- this._activeSubEmitterSystem.forEach((particleSystem) => {
- particleSystem.onTick(deltaTime, particleSystem.data);
- })
- }
- }
- }
- /**
- * 创建一个粒子实例。
- */
- protected createParticle() {
- var instance: ParticleInstance;
- if (this._stockInstances.length !== 0) {
- instance = this._stockInstances.pop();
- instance.reset();
- }
- else {
- instance = new ParticleInstance(this);
- }
- if (this._subEmitters && this._subEmitters.length > 0) {
- var subEmitters = this._subEmitters[Math.floor(Math.random() * this._subEmitters.length)];
- instance.subEmitterMuster = [];
- subEmitters.forEach((subEmitter) => {
- if (subEmitter.state == SubEmitterState.ATTACH) {
- var tempEmitter = subEmitter.clone();
- instance.subEmitterMuster.push(tempEmitter);
- tempEmitter.particleSystem.start();
- }
- })
- }
- return instance;
- };
- /**
- * 启动处于END状态的粒子子发射器。
- * @param {ParticleInstance} instance 粒子实例
- */
- protected particleSubEmitter(instance: ParticleInstance) {
- if (!this._subEmitters || this._subEmitters.length == 0) {
- return;
- }
- var tempIndex = Math.floor(Math.random() * this._subEmitters.length);
- this._subEmitters[tempIndex].forEach((subEmitter) => {
- if (subEmitter.state == SubEmitterState.END) {
- var tempEmitter = subEmitter.clone();
- tempEmitter.particleSystem._rootEmitterSystem = this;
- // the position of sub emitter from one particle
- tempEmitter.particleSystem.emitterPosition = instance.position.clone();
- this._activeSubEmitterSystem.push(tempEmitter.particleSystem);
- tempEmitter.particleSystem.start();
- }
- })
- }
- /**
- * 回收当前粒子实例,并放入储备粒子队列。
- * @param {ParticleInstance} particle 粒子实例
- */
- protected recycleParticle(particle: ParticleInstance) {
- var lastParticle = this._instances.pop();
- if (lastParticle !== particle) {
- lastParticle.copyTo(particle);
- }
- this._stockInstances.push(lastParticle);
- }
- /**
- * 更新每一个粒子的状态。
- * @param {number} instancesSum 新生成的粒子数
- */
- protected update(instancesSum: number) {
- // Update current
- this._alive = this._instances.length > 0;
- if (!this._alive && this._stop) {
- return;
- }
- var emitterPosition = this._emitterPosition;
- this._emitterWorldMatrix = xrFrameSystem.Matrix4.IDENTITY.translate(emitterPosition.x, emitterPosition.y, emitterPosition.z);
- this._emitterWorldMatrix.inverse(this._emitterInverseWorldMatrix);
- var instance: ParticleInstance;
- var loop = (index) => {
- if (this._instances.length === this._capacity) {
- return "break";
- }
- instance = this.createParticle();
- this._instances.push(instance);
- this.initInstanceProperty(instance);
- };
- for (var index = 0; index < instancesSum; index++) {
- var state = loop(index);
- if (state === "break")
- break;
- }
- this.updateInstanceProperty(this._instances);
- };
- /**
- * 初始化粒子实例。
- * @param {ParticleInstance} instance 需要初始化的粒子实例
- */
- protected initInstanceProperty(instance: ParticleInstance) {
- instance.lifeTime = randomBetween(this._minLifeTime, this._maxLifeTime);
- //Ramp
- if (this._useRampGradients) {
- instance.rampPos = xrFrameSystem.Vector4.createFromNumber(0, 1, 0, 1);
- }
- //Position
- this._particleEmitter.startPosition(this._emitterWorldMatrix, instance.position);
- //Rotation
- instance.angularSpeed = randomBetween(this._minAngularSpeed, this._maxAngularSpeed);
- instance.angle = randomBetween(this._startAngle, this._startAngle2);
- //Direction
- instance.speed = randomBetween(this._minSpeed, this._maxSpeed);
- this._particleEmitter.startDirection(this._emitterWorldMatrix, instance.direction, instance.position);
- //Color
- if (this._colorGradients && this._colorGradients.length > 0) {
- instance.currentColorGradient = this._colorGradients[0];
- instance.currentColorGradient.getColor(instance.currentColor);
- instance.color = instance.currentColor.clone();
- if (this._colorGradients.length > 1) {
- this._colorGradients[1].getColor(instance.currentColor2);
- } else {
- instance.currentColor2 = instance.currentColor.clone();
- }
- } else {
- var lerpStep = Math.random();
- var startColor2, endColor;
- startColor2 = this._startColor2 ?? this._startColor;
- endColor = this._endColor ?? this._startColor;
- this.lerpNumberArrayToVector(instance.color, this._startColor, startColor2, lerpStep);
- this.lerpNumberArrayToVector(this._tempEndColor, endColor, endColor, lerpStep);
- this._tempEndColor.sub(instance.color, this._tempDiffColor);
- this._tempDiffColor.scale(1 / instance.lifeTime, instance.colorStep);
- }
- //Color-alpha
- if (this._alphaGradients && this._alphaGradients.length > 0) {
- instance.currentAlphaGradient = this._alphaGradients[0];
- instance.currentAlpha = instance.currentAlphaGradient.getFactor();
- instance.color.w = instance.currentAlpha;
- if (this._alphaGradients.length > 1) {
- instance.currentAlpha2 = this._alphaGradients[1].getFactor();
- } else {
- instance.currentAlpha2 = instance.currentAlpha;
- }
- }
- //Speed
- if (this._speedScaleGradients && this._speedScaleGradients.length > 0) {
- instance.currentSpeedScaleGradient = this._speedScaleGradients[0];
- instance.currentSpeedScale = instance.currentSpeedScaleGradient.getFactor();
- if (this._speedScaleGradients.length > 1) {
- instance.currentSpeedScale2 = this._speedScaleGradients[1].getFactor();
- } else {
- instance.currentSpeedScale2 = instance.currentSpeedScale;
- }
- }
- //Limit-speed
- if (this._limitSpeedGradients && this._limitSpeedGradients.length > 0) {
- instance.currentLimitSpeedGradient = this._limitSpeedGradients[0];
- instance.currentLimitSpeed = instance.currentLimitSpeedGradient.getFactor();
- if (this._limitSpeedGradients.length > 1) {
- instance.currentLimitSpeed2 = this._limitSpeedGradients[1].getFactor();
- } else {
- instance.currentLimitSpeed2 = instance.currentLimitSpeed;
- }
- }
- //Drag
- if (this._dragGradients && this._dragGradients.length > 0) {
- instance.currentDragGradient = this._dragGradients[0];
- instance.currentDrag = instance.currentDragGradient.getFactor();
- if (this._dragGradients.length > 1) {
- instance.currentDrag2 = this._dragGradients[1].getFactor();
- } else {
- instance.currentDrag2 = instance.currentDrag;
- }
- }
- //Scale
- instance.scale.setValue(randomBetween(this._minScaleX, this._maxScaleX), randomBetween(this._minScaleY, this._maxScaleY));
- if (this._sizeGradients && this._sizeGradients.length > 0) {
- instance.currentSizeGradient = this._sizeGradients[0];
- instance.currentSize = instance.currentSizeGradient.getFactor();
- instance.sizeGradientFactor = instance.currentSize;
- instance.startSize = randomBetween(this._minSize, this._maxSize);
- instance.size = instance.startSize * instance.sizeGradientFactor;
- if (this._sizeGradients.length > 1) {
- instance.currentSize2 = this._sizeGradients[1].getFactor();
- } else {
- instance.currentSize2 = instance.currentSize;
- }
- } else {
- instance.size = randomBetween(this._minSize, this._maxSize);
- }
- //SpriteSheet
- if (this.useSpriteSheet) {
- instance.startSpriteCellIndex = this._startSpriteCellIndex;
- instance.endSpriteCellIndex = this._endSpriteCellIndex;
- }
- }
- protected fetch(u, v, width, height, content) {
- u = u * 0.5 + 0.5;
- v = v * 0.5 + 0.5;
- const wrappedU = (u * width) % width | 0;
- const wrappedV = (v * height) % height | 0;
- const position = (wrappedU + wrappedV * width) * 4;
- return content[position] / 255;
- }
- /**
- * 更新运动过程中粒子实例的各项属性以及子发射器状态。
- * @param {Array} instances 粒子实例数组
- */
- protected updateInstanceProperty(instances) {
- var loop = (index) => {
- var instance: ParticleInstance = instances[index];
- var scaledUpdateSpeed = this._updateSpeed;
- var previousAge = instance.age;
- instance.age += this._updateSpeed;
- if (instance.age > instance.lifeTime) {
- var diff = instance.age - previousAge;
- var oldDiff = instance.lifeTime - previousAge;
- scaledUpdateSpeed = (oldDiff * scaledUpdateSpeed) / diff;
- instance.age = instance.lifeTime;
- }
- this.processInstance(instance);
- if (this._particleEmitter.processInstance) {
- this._particleEmitter.processInstance(instance, this._updateSpeed);
- }
- // attached subemitter dynamic position
- if (instance.subEmitterMuster) {
- instance.subEmitterMuster.forEach((subEmitter) => {
- subEmitter.particleSystem.emitterPosition = instance.position.clone();
- })
- }
- if (this.useSpriteSheet) {
- instance.updateCellIndex();
- }
- if (instance.age >= instance.lifeTime) {
- this.particleSubEmitter(instance);
- if (instance.subEmitterMuster) {
- instance.subEmitterMuster.forEach((subEmitter) => {
- subEmitter.particleSystem.stop();
- })
- instance.subEmitterMuster = null;
- }
- this.recycleParticle(instance);
- index--;
- }
- popIndex = index;
- }
- var popIndex;
- for (var index = 0; index < instances.length; index++) {
- loop(index);
- index = popIndex;
- }
- }
- /**
- * 更新粒子实例的各项属性。
- * @param {ParticleInstance} instance 待更新的粒子实例
- */
- protected processInstance(instance: ParticleInstance) {
- var ratio = instance.age / instance.lifeTime;
- var scaledUpdateSpeed = this._updateSpeed;
- //RampColor
- if (this._useRampGradients) {
- if (this._colorRemapGradients && this._colorRemapGradients.length > 0) {
- BasicGradientMethod.GetCurrentGradient(ratio, this._colorRemapGradients, (currentGradient, nextGradient, lerp) => {
- var min = currentGradient.factor + (nextGradient.factor - currentGradient.factor) * lerp;
- var max = currentGradient.factor2 + (nextGradient.factor2 - currentGradient.factor2) * lerp;
- instance.rampPos.x = min;
- instance.rampPos.y = max - min;
- })
- }
- }
- //Color
- if (this._colorGradients && this._colorGradients.length > 0) {
- BasicGradientMethod.GetCurrentGradient(ratio, this._colorGradients, (currentGradient, nextGradient, lerp) => {
- if (instance.currentColorGradient != currentGradient) {
- instance.currentColor = instance.currentColor2.clone();
- nextGradient.getColor(instance.currentColor2);
- instance.currentColorGradient = currentGradient;
- }
- instance.color.x = instance.currentColor.x + (instance.currentColor2.x - instance.currentColor.x) * lerp;
- instance.color.y = instance.currentColor.y + (instance.currentColor2.y - instance.currentColor.y) * lerp;
- instance.color.z = instance.currentColor.z + (instance.currentColor2.z - instance.currentColor.z) * lerp;
- instance.color.w = instance.currentColor.w + (instance.currentColor2.w - instance.currentColor.w) * lerp;
- })
- } else {
- instance.colorStep.scale(scaledUpdateSpeed, this._tempAccColorStep);
- instance.color.add(this._tempAccColorStep, instance.color);
- if (instance.color.w < 0) {
- instance.color.w = 0;
- }
- if (instance.color.w > 1) {
- instance.color.w = 1;
- }
- }
- //Color Alpha
- if (this._alphaGradients && this._alphaGradients.length > 0) {
- BasicGradientMethod.GetCurrentGradient(ratio, this._alphaGradients, (currentGradient, nextGradient, lerp) => {
- if (instance.currentAlphaGradient != currentGradient) {
- instance.currentAlpha = instance.currentAlpha2;
- instance.currentAlpha2 = nextGradient.getFactor();
- instance.currentAlphaGradient = currentGradient;
- }
- instance.color.w = instance.currentAlpha + (instance.currentAlpha2 - instance.currentAlpha) * lerp;
- })
- }
- //--- Velocity ---//
- var speed = instance.speed;
- //Speed
- if (this._speedScaleGradients && this._speedScaleGradients.length > 0) {
- BasicGradientMethod.GetCurrentGradient(ratio, this._speedScaleGradients, (currentGradient, nextGradient, lerp) => {
- if (instance.currentSpeedScaleGradient != currentGradient) {
- instance.currentSpeedScale = instance.currentSpeedScale2;
- instance.currentSpeedScale = nextGradient.getFactor();
- instance.currentSpeedScaleGradient = currentGradient;
- }
- var currentSpeedScale = instance.currentSpeedScale + (instance.currentSpeedScale2 - instance.currentSpeedScale) * lerp;
- speed = speed * currentSpeedScale;
- })
- }
- //Limit-speed
- if (this._limitSpeedGradients && this._limitSpeedGradients.length > 0) {
- BasicGradientMethod.GetCurrentGradient(ratio, this._limitSpeedGradients, (currentGradient, nextGradient, lerp) => {
- if (instance.currentLimitSpeedGradient != currentGradient) {
- instance.currentLimitSpeed = instance.currentSpeedScale2;
- instance.currentLimitSpeed = nextGradient.getFactor();
- instance.currentLimitSpeedGradient = currentGradient;
- }
- var limitSpeed = instance.currentLimitSpeed + (instance.currentLimitSpeed2 - instance.currentLimitSpeed) * lerp;
- if (Math.abs(instance.speed) > limitSpeed) {
- speed = speed * (1 - this._speedDampenFactor);
- }
- })
- }
- //Drag
- if (this._dragGradients && this._dragGradients.length > 0) {
- BasicGradientMethod.GetCurrentGradient(ratio, this._dragGradients, (currentGradient, nextGradient, lerp) => {
- if (instance.currentDragGradient != currentGradient) {
- instance.currentDrag = instance.currentSpeedScale2;
- instance.currentDrag = nextGradient.getFactor();
- instance.currentDragGradient = currentGradient;
- }
- instance.drag = instance.currentDrag + (instance.currentDrag2 - instance.currentDrag) * lerp;
- })
- }
- var velocity = instance.direction.scale(speed * (1 - instance.drag));
- //--- End Velocity ---//
- //Angle
- instance.angle += instance.angularSpeed * scaledUpdateSpeed;
- //Gravity
- var scaledGravityDirection = xrFrameSystem.Vector3.createFromNumber(0, -1 * this._gravity, 0);
- //Direction
- var scaledDirection = velocity.add(scaledGravityDirection).scale(scaledUpdateSpeed);
- //Position
- instance.position.add(scaledDirection, instance.position);
- //Size
- if (this._sizeGradients && this._sizeGradients.length > 0) {
- BasicGradientMethod.GetCurrentGradient(ratio, this._sizeGradients, (currentGradient, nextGradient, lerp) => {
- if (instance.currentSizeGradient != currentGradient) {
- instance.currentSize = instance.currentSize2;
- instance.currentSize2 = nextGradient.getFactor();
- instance.currentSizeGradient = currentGradient;
- }
- instance.sizeGradientFactor = instance.currentSize + (instance.currentSize2 - instance.currentSize) * lerp;
- instance.size = instance.startSize * instance.sizeGradientFactor;
- })
- }
- }
- }
- xrFrameSystem.registerComponent('custom-particle', CustomParticle)
|