2021-07-21 23:11:13 +08:00

636 lines
32 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function (exports, Laya) {
'use strict';
class ParticleSetting {
constructor() {
this.textureName = null;
this.textureCount = 1;
this.maxPartices = 100;
this.duration = 1;
this.ageAddScale = 0;
this.emitterVelocitySensitivity = 1;
this.minStartSize = 100;
this.maxStartSize = 100;
this.minEndSize = 100;
this.maxEndSize = 100;
this.minHorizontalVelocity = 0;
this.maxHorizontalVelocity = 0;
this.minVerticalVelocity = 0;
this.maxVerticalVelocity = 0;
this.endVelocity = 1;
this.gravity = new Float32Array([0, 0, 0]);
this.minRotateSpeed = 0;
this.maxRotateSpeed = 0;
this.minStartRadius = 0;
this.maxStartRadius = 0;
this.minEndRadius = 0;
this.maxEndRadius = 0;
this.minHorizontalStartRadian = 0;
this.maxHorizontalStartRadian = 0;
this.minVerticalStartRadian = 0;
this.maxVerticalStartRadian = 0;
this.useEndRadian = true;
this.minHorizontalEndRadian = 0;
this.maxHorizontalEndRadian = 0;
this.minVerticalEndRadian = 0;
this.maxVerticalEndRadian = 0;
this.minStartColor = new Float32Array([1, 1, 1, 1]);
this.maxStartColor = new Float32Array([1, 1, 1, 1]);
this.minEndColor = new Float32Array([1, 1, 1, 1]);
this.maxEndColor = new Float32Array([1, 1, 1, 1]);
this.colorComponentInter = false;
this.disableColor = false;
this.blendState = 0;
this.emitterType = "null";
this.emissionRate = 0;
this.pointEmitterPosition = new Float32Array([0, 0, 0]);
this.pointEmitterPositionVariance = new Float32Array([0, 0, 0]);
this.pointEmitterVelocity = new Float32Array([0, 0, 0]);
this.pointEmitterVelocityAddVariance = new Float32Array([0, 0, 0]);
this.boxEmitterCenterPosition = new Float32Array([0, 0, 0]);
this.boxEmitterSize = new Float32Array([0, 0, 0]);
this.boxEmitterVelocity = new Float32Array([0, 0, 0]);
this.boxEmitterVelocityAddVariance = new Float32Array([0, 0, 0]);
this.sphereEmitterCenterPosition = new Float32Array([0, 0, 0]);
this.sphereEmitterRadius = 1;
this.sphereEmitterVelocity = 0;
this.sphereEmitterVelocityAddVariance = 0;
this.ringEmitterCenterPosition = new Float32Array([0, 0, 0]);
this.ringEmitterRadius = 30;
this.ringEmitterVelocity = 0;
this.ringEmitterVelocityAddVariance = 0;
this.ringEmitterUp = 2;
this.positionVariance = new Float32Array([0, 0, 0]);
}
static checkSetting(setting) {
var key;
for (key in ParticleSetting._defaultSetting) {
if (!(key in setting)) {
setting[key] = ParticleSetting._defaultSetting[key];
}
}
setting.endVelocity = +setting.endVelocity;
setting.gravity[0] = +setting.gravity[0];
setting.gravity[1] = +setting.gravity[1];
setting.gravity[2] = +setting.gravity[2];
}
}
ParticleSetting._defaultSetting = new ParticleSetting();
class ParticleTemplateBase {
constructor() {
}
addParticleArray(position, velocity) {
}
}
class ParticleData {
constructor() {
}
static Create(settings, position, velocity, time) {
var particleData = new ParticleData();
particleData.position = position;
Laya.MathUtil.scaleVector3(velocity, settings.emitterVelocitySensitivity, ParticleData._tempVelocity);
var horizontalVelocity = Laya.MathUtil.lerp(settings.minHorizontalVelocity, settings.maxHorizontalVelocity, Math.random());
var horizontalAngle = Math.random() * Math.PI * 2;
ParticleData._tempVelocity[0] += horizontalVelocity * Math.cos(horizontalAngle);
ParticleData._tempVelocity[2] += horizontalVelocity * Math.sin(horizontalAngle);
ParticleData._tempVelocity[1] += Laya.MathUtil.lerp(settings.minVerticalVelocity, settings.maxVerticalVelocity, Math.random());
particleData.velocity = ParticleData._tempVelocity;
particleData.startColor = ParticleData._tempStartColor;
particleData.endColor = ParticleData._tempEndColor;
var i;
if (settings.disableColor) {
for (i = 0; i < 3; i++) {
particleData.startColor[i] = 1;
particleData.endColor[i] = 1;
}
particleData.startColor[i] = Laya.MathUtil.lerp(settings.minStartColor[i], settings.maxStartColor[i], Math.random());
particleData.endColor[i] = Laya.MathUtil.lerp(settings.minEndColor[i], settings.maxEndColor[i], Math.random());
}
else {
if (settings.colorComponentInter) {
for (i = 0; i < 4; i++) {
particleData.startColor[i] = Laya.MathUtil.lerp(settings.minStartColor[i], settings.maxStartColor[i], Math.random());
particleData.endColor[i] = Laya.MathUtil.lerp(settings.minEndColor[i], settings.maxEndColor[i], Math.random());
}
}
else {
Laya.MathUtil.lerpVector4(settings.minStartColor, settings.maxStartColor, Math.random(), particleData.startColor);
Laya.MathUtil.lerpVector4(settings.minEndColor, settings.maxEndColor, Math.random(), particleData.endColor);
}
}
particleData.sizeRotation = ParticleData._tempSizeRotation;
var sizeRandom = Math.random();
particleData.sizeRotation[0] = Laya.MathUtil.lerp(settings.minStartSize, settings.maxStartSize, sizeRandom);
particleData.sizeRotation[1] = Laya.MathUtil.lerp(settings.minEndSize, settings.maxEndSize, sizeRandom);
particleData.sizeRotation[2] = Laya.MathUtil.lerp(settings.minRotateSpeed, settings.maxRotateSpeed, Math.random());
particleData.radius = ParticleData._tempRadius;
var radiusRandom = Math.random();
particleData.radius[0] = Laya.MathUtil.lerp(settings.minStartRadius, settings.maxStartRadius, radiusRandom);
particleData.radius[1] = Laya.MathUtil.lerp(settings.minEndRadius, settings.maxEndRadius, radiusRandom);
particleData.radian = ParticleData._tempRadian;
particleData.radian[0] = Laya.MathUtil.lerp(settings.minHorizontalStartRadian, settings.maxHorizontalStartRadian, Math.random());
particleData.radian[1] = Laya.MathUtil.lerp(settings.minVerticalStartRadian, settings.maxVerticalStartRadian, Math.random());
var useEndRadian = settings.useEndRadian;
particleData.radian[2] = useEndRadian ? Laya.MathUtil.lerp(settings.minHorizontalEndRadian, settings.maxHorizontalEndRadian, Math.random()) : particleData.radian[0];
particleData.radian[3] = useEndRadian ? Laya.MathUtil.lerp(settings.minVerticalEndRadian, settings.maxVerticalEndRadian, Math.random()) : particleData.radian[1];
particleData.durationAddScale = settings.ageAddScale * Math.random();
particleData.time = time;
return particleData;
}
}
ParticleData._tempVelocity = new Float32Array(3);
ParticleData._tempStartColor = new Float32Array(4);
ParticleData._tempEndColor = new Float32Array(4);
ParticleData._tempSizeRotation = new Float32Array(3);
ParticleData._tempRadius = new Float32Array(2);
ParticleData._tempRadian = new Float32Array(4);
class ParticleTemplateWebGL extends ParticleTemplateBase {
constructor(parSetting) {
super();
this._floatCountPerVertex = 29;
this._firstActiveElement = 0;
this._firstNewElement = 0;
this._firstFreeElement = 0;
this._firstRetiredElement = 0;
this._currentTime = 0;
this.settings = parSetting;
}
reUse(context, pos) {
return 0;
}
initialize() {
var floatStride = 0;
this._vertices = this._mesh._vb.getFloat32Array();
floatStride = this._mesh._stride / 4;
var bufi = 0;
var bufStart = 0;
for (var i = 0; i < this.settings.maxPartices; i++) {
var random = Math.random();
var cornerYSegement = this.settings.textureCount ? 1.0 / this.settings.textureCount : 1.0;
var cornerY;
for (cornerY = 0; cornerY < this.settings.textureCount; cornerY += cornerYSegement) {
if (random < cornerY + cornerYSegement)
break;
}
this._vertices[bufi++] = -1;
this._vertices[bufi++] = -1;
this._vertices[bufi++] = 0;
this._vertices[bufi++] = cornerY;
bufi = (bufStart += floatStride);
this._vertices[bufi++] = 1;
this._vertices[bufi++] = -1;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = cornerY;
bufi = bufStart += floatStride;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = cornerY + cornerYSegement;
bufi = bufStart += floatStride;
this._vertices[bufi++] = -1;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = 0;
this._vertices[bufi++] = cornerY + cornerYSegement;
bufi = bufStart += floatStride;
}
}
update(elapsedTime) {
this._currentTime += elapsedTime / 1000;
this.retireActiveParticles();
this.freeRetiredParticles();
if (this._firstActiveElement == this._firstFreeElement)
this._currentTime = 0;
if (this._firstRetiredElement == this._firstActiveElement)
this._drawCounter = 0;
}
retireActiveParticles() {
const epsilon = 0.0001;
var particleDuration = this.settings.duration;
while (this._firstActiveElement != this._firstNewElement) {
var offset = this._firstActiveElement * this._floatCountPerVertex * 4;
var index = offset + 28;
var particleAge = this._currentTime - this._vertices[index];
particleAge *= (1.0 + this._vertices[offset + 27]);
if (particleAge + epsilon < particleDuration)
break;
this._vertices[index] = this._drawCounter;
this._firstActiveElement++;
if (this._firstActiveElement >= this.settings.maxPartices)
this._firstActiveElement = 0;
}
}
freeRetiredParticles() {
while (this._firstRetiredElement != this._firstActiveElement) {
var age = this._drawCounter - this._vertices[this._firstRetiredElement * this._floatCountPerVertex * 4 + 28];
if (age < 3)
break;
this._firstRetiredElement++;
if (this._firstRetiredElement >= this.settings.maxPartices)
this._firstRetiredElement = 0;
}
}
addNewParticlesToVertexBuffer() {
}
addParticleArray(position, velocity) {
var nextFreeParticle = this._firstFreeElement + 1;
if (nextFreeParticle >= this.settings.maxPartices)
nextFreeParticle = 0;
if (nextFreeParticle === this._firstRetiredElement)
return;
var particleData = ParticleData.Create(this.settings, position, velocity, this._currentTime);
var startIndex = this._firstFreeElement * this._floatCountPerVertex * 4;
for (var i = 0; i < 4; i++) {
var j, offset;
for (j = 0, offset = 4; j < 3; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.position[j];
for (j = 0, offset = 7; j < 3; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.velocity[j];
for (j = 0, offset = 10; j < 4; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.startColor[j];
for (j = 0, offset = 14; j < 4; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.endColor[j];
for (j = 0, offset = 18; j < 3; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.sizeRotation[j];
for (j = 0, offset = 21; j < 2; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.radius[j];
for (j = 0, offset = 23; j < 4; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.radian[j];
this._vertices[startIndex + i * this._floatCountPerVertex + 27] = particleData.durationAddScale;
this._vertices[startIndex + i * this._floatCountPerVertex + 28] = particleData.time;
}
this._firstFreeElement = nextFreeParticle;
}
}
var parvs = "attribute vec4 a_CornerTextureCoordinate;\r\nattribute vec3 a_Position;\r\nattribute vec3 a_Velocity;\r\nattribute vec4 a_StartColor;\r\nattribute vec4 a_EndColor;\r\nattribute vec3 a_SizeRotation;\r\nattribute vec2 a_Radius;\r\nattribute vec4 a_Radian;\r\nattribute float a_AgeAddScale;\r\nattribute float a_Time;\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\n\r\nuniform float u_CurrentTime;\r\nuniform float u_Duration;\r\nuniform float u_EndVelocity;\r\nuniform vec3 u_Gravity;\r\n\r\nuniform vec2 size;\r\nuniform mat4 u_mmat;\r\n\r\nvec4 ComputeParticlePosition(in vec3 position, in vec3 velocity,in float age,in float normalizedAge)\r\n{\r\n\r\n float startVelocity = length(velocity);//起始标量速度\r\n float endVelocity = startVelocity * u_EndVelocity;//结束标量速度\r\n\r\n float velocityIntegral = startVelocity * normalizedAge +(endVelocity - startVelocity) * normalizedAge *normalizedAge/2.0;//计算当前速度的标量单位空间vt=v0*t+(1/2)*a*(t^2)\r\n \r\n vec3 addPosition = normalize(velocity) * velocityIntegral * u_Duration;//计算受自身速度影响的位置,转换标量到矢量 \r\n addPosition += u_Gravity * age * normalizedAge;//计算受重力影响的位置\r\n \r\n float radius=mix(a_Radius.x, a_Radius.y, normalizedAge); //计算粒子受半径和角度影响(无需计算角度和半径时,可用宏定义优化屏蔽此计算)\r\n float radianHorizontal =mix(a_Radian.x,a_Radian.z,normalizedAge);\r\n float radianVertical =mix(a_Radian.y,a_Radian.w,normalizedAge);\r\n \r\n float r =cos(radianVertical)* radius;\r\n addPosition.y += sin(radianVertical) * radius;\r\n\t\r\n addPosition.x += cos(radianHorizontal) *r;\r\n addPosition.z += sin(radianHorizontal) *r;\r\n \r\n addPosition.y=-addPosition.y;//2D粒子位置更新需要取负2D粒子坐标系Y轴正向朝上\r\n position+=addPosition;\r\n return vec4(position,1.0);\r\n}\r\n\r\nfloat ComputeParticleSize(in float startSize,in float endSize, in float normalizedAge)\r\n{ \r\n float size = mix(startSize, endSize, normalizedAge);\r\n return size;\r\n}\r\n\r\nmat2 ComputeParticleRotation(in float rot,in float age)\r\n{ \r\n float rotation =rot * age;\r\n //计算2x2旋转矩阵.\r\n float c = cos(rotation);\r\n float s = sin(rotation);\r\n return mat2(c, -s, s, c);\r\n}\r\n\r\nvec4 ComputeParticleColor(in vec4 startColor,in vec4 endColor,in float normalizedAge)\r\n{\r\n\tvec4 color=mix(startColor,endColor,normalizedAge);\r\n //硬编码设置,使粒子淡入很快,淡出很慢,6.7的缩放因子把置归一在0到1之间可以谷歌x*(1-x)*(1-x)*6.7的制图表\r\n color.a *= normalizedAge * (1.0-normalizedAge) * (1.0-normalizedAge) * 6.7;\r\n \r\n return color;\r\n}\r\n\r\nvoid main()\r\n{\r\n float age = u_CurrentTime - a_Time;\r\n age *= 1.0 + a_AgeAddScale;\r\n float normalizedAge = clamp(age / u_Duration,0.0,1.0);\r\n gl_Position = ComputeParticlePosition(a_Position, a_Velocity, age, normalizedAge);//计算粒子位置\r\n float pSize = ComputeParticleSize(a_SizeRotation.x,a_SizeRotation.y, normalizedAge);\r\n mat2 rotation = ComputeParticleRotation(a_SizeRotation.z, age);\r\n\t\r\n mat4 mat=u_mmat;\r\n gl_Position=vec4((mat*gl_Position).xy,0.0,1.0);\r\n gl_Position.xy += (rotation*a_CornerTextureCoordinate.xy) * pSize*vec2(mat[0][0],mat[1][1]);\r\n gl_Position=vec4((gl_Position.x/size.x-0.5)*2.0,(0.5-gl_Position.y/size.y)*2.0,0.0,1.0);\r\n \r\n v_Color = ComputeParticleColor(a_StartColor,a_EndColor, normalizedAge);\r\n v_TextureCoordinate =a_CornerTextureCoordinate.zw;\r\n}\r\n\r\n";
var parps = "#if defined(GL_FRAGMENT_PRECISION_HIGH)\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\nuniform sampler2D u_texture;\r\n\r\nvoid main()\r\n{\t\r\n\tgl_FragColor=texture2D(u_texture,v_TextureCoordinate)*v_Color;\r\n\tgl_FragColor.xyz *= v_Color.w;\r\n}";
class ParticleShader extends Laya.Shader {
constructor() {
super(parvs, parps, "ParticleShader", null, ['a_CornerTextureCoordinate', 0, 'a_Position', 1, 'a_Velocity', 2, 'a_StartColor', 3,
'a_EndColor', 4, 'a_SizeRotation', 5, 'a_Radius', 6, 'a_Radian', 7, 'a_AgeAddScale', 8, 'a_Time', 9]);
}
}
ParticleShader.vs = parvs;
ParticleShader.ps = parps;
class ParticleShaderValue extends Laya.Value2D {
constructor() {
super(0, 0);
if (!ParticleShaderValue.pShader) {
ParticleShaderValue.pShader = new ParticleShader();
}
}
upload() {
var size = this.size;
size[0] = Laya.RenderState2D.width;
size[1] = Laya.RenderState2D.height;
this.alpha = this.ALPHA * Laya.RenderState2D.worldAlpha;
ParticleShaderValue.pShader.upload(this);
}
}
ParticleShaderValue.pShader = null;
class ParticleTemplate2D extends ParticleTemplateWebGL {
constructor(parSetting) {
super(parSetting);
this.x = 0;
this.y = 0;
this.sv = new ParticleShaderValue();
this._key = {};
var _this = this;
Laya.ILaya.loader.load(this.settings.textureName, Laya.Handler.create(null, function (texture) {
_this.texture = texture;
}), null, Laya.Loader.IMAGE);
this.sv.u_Duration = this.settings.duration;
this.sv.u_Gravity = this.settings.gravity;
this.sv.u_EndVelocity = this.settings.endVelocity;
this._blendFn = Laya.BlendMode.fns[parSetting.blendState];
this._mesh = Laya.MeshParticle2D.getAMesh(this.settings.maxPartices);
this.initialize();
}
getRenderType() { return -111; }
releaseRender() { }
addParticleArray(position, velocity) {
position[0] += this.x;
position[1] += this.y;
super.addParticleArray(position, velocity);
}
addNewParticlesToVertexBuffer() {
var _vertexBuffer2D = this._mesh._vb;
_vertexBuffer2D.clear();
_vertexBuffer2D.append(this._vertices);
var start;
if (this._firstNewElement < this._firstFreeElement) {
start = this._firstNewElement * 4 * this._floatCountPerVertex * 4;
_vertexBuffer2D.subUpload(start, start, start + (this._firstFreeElement - this._firstNewElement) * 4 * this._floatCountPerVertex * 4);
}
else {
start = this._firstNewElement * 4 * this._floatCountPerVertex * 4;
_vertexBuffer2D.subUpload(start, start, start + (this.settings.maxPartices - this._firstNewElement) * 4 * this._floatCountPerVertex * 4);
if (this._firstFreeElement > 0) {
_vertexBuffer2D.setNeedUpload();
_vertexBuffer2D.subUpload(0, 0, this._firstFreeElement * 4 * this._floatCountPerVertex * 4);
}
}
this._firstNewElement = this._firstFreeElement;
}
renderSubmit() {
if (this.texture && this.texture.getIsReady()) {
this.update(Laya.ILaya.timer._delta);
this.sv.u_CurrentTime = this._currentTime;
if (this._firstNewElement != this._firstFreeElement) {
this.addNewParticlesToVertexBuffer();
}
this.blend();
if (this._firstActiveElement != this._firstFreeElement) {
var gl = Laya.WebGLContext.mainContext;
this._mesh.useMesh(gl);
this.sv.u_texture = this.texture._getSource();
this.sv.upload();
if (this._firstActiveElement < this._firstFreeElement) {
gl.drawElements(gl.TRIANGLES, (this._firstFreeElement - this._firstActiveElement) * 6, gl.UNSIGNED_SHORT, this._firstActiveElement * 6 * 2);
}
else {
Laya.WebGLContext.mainContext.drawElements(gl.TRIANGLES, (this.settings.maxPartices - this._firstActiveElement) * 6, gl.UNSIGNED_SHORT, this._firstActiveElement * 6 * 2);
if (this._firstFreeElement > 0)
gl.drawElements(gl.TRIANGLES, this._firstFreeElement * 6, gl.UNSIGNED_SHORT, 0);
}
Laya.Stat.renderBatches++;
}
this._drawCounter++;
}
return 1;
}
updateParticleForNative() {
if (this.texture && this.texture.getIsReady()) {
this.update(Laya.ILaya.timer._delta);
this.sv.u_CurrentTime = this._currentTime;
if (this._firstNewElement != this._firstFreeElement) {
this._firstNewElement = this._firstFreeElement;
}
}
}
getMesh() {
return this._mesh;
}
getConchMesh() {
return this._conchMesh;
}
getFirstNewElement() {
return this._firstNewElement;
}
getFirstFreeElement() {
return this._firstFreeElement;
}
getFirstActiveElement() {
return this._firstActiveElement;
}
getFirstRetiredElement() {
return this._firstRetiredElement;
}
setFirstFreeElement(_value) {
this._firstFreeElement = _value;
}
setFirstNewElement(_value) {
this._firstNewElement = _value;
}
addDrawCounter() {
this._drawCounter++;
}
blend() {
if (Laya.BlendMode.activeBlendFunction !== this._blendFn) {
var gl = Laya.WebGLContext.mainContext;
gl.enable(gl.BLEND);
this._blendFn(gl);
Laya.BlendMode.activeBlendFunction = this._blendFn;
}
}
dispose() {
this._mesh.releaseMesh();
}
}
ParticleTemplate2D.activeBlendType = -1;
class EmitterBase {
constructor() {
this._frameTime = 0;
this._emissionRate = 60;
this._emissionTime = 0;
this.minEmissionTime = 1 / 60;
}
set particleTemplate(particleTemplate) {
this._particleTemplate = particleTemplate;
}
set emissionRate(_emissionRate) {
if (_emissionRate <= 0)
return;
this._emissionRate = _emissionRate;
(_emissionRate > 0) && (this.minEmissionTime = 1 / _emissionRate);
}
get emissionRate() {
return this._emissionRate;
}
start(duration = Number.MAX_VALUE) {
if (this._emissionRate != 0)
this._emissionTime = duration;
}
stop() {
this._emissionTime = 0;
}
clear() {
this._emissionTime = 0;
}
emit() {
}
advanceTime(passedTime = 1) {
this._emissionTime -= passedTime;
if (this._emissionTime < 0)
return;
this._frameTime += passedTime;
if (this._frameTime < this.minEmissionTime)
return;
while (this._frameTime > this.minEmissionTime) {
this._frameTime -= this.minEmissionTime;
this.emit();
}
}
}
class Emitter2D extends EmitterBase {
constructor(_template) {
super();
this.template = _template;
}
set template(template) {
this._particleTemplate = template;
if (!template) {
this._emitFun = null;
this.setting = null;
this._posRange = null;
}
this.setting = template.settings;
this._posRange = this.setting.positionVariance;
if (this._particleTemplate instanceof ParticleTemplate2D) {
this._emitFun = this.webGLEmit;
}
}
get template() {
return this._particleTemplate;
}
emit() {
super.emit();
if (this._emitFun != null)
this._emitFun();
}
getRandom(value) {
return (Math.random() * 2 - 1) * value;
}
webGLEmit() {
var pos = new Float32Array(3);
pos[0] = this.getRandom(this._posRange[0]);
pos[1] = this.getRandom(this._posRange[1]);
pos[2] = this.getRandom(this._posRange[2]);
var v = new Float32Array(3);
v[0] = 0;
v[1] = 0;
v[2] = 0;
this._particleTemplate.addParticleArray(pos, v);
}
canvasEmit() {
var pos = new Float32Array(3);
pos[0] = this.getRandom(this._posRange[0]);
pos[1] = this.getRandom(this._posRange[1]);
pos[2] = this.getRandom(this._posRange[2]);
var v = new Float32Array(3);
v[0] = 0;
v[1] = 0;
v[2] = 0;
this._particleTemplate.addParticleArray(pos, v);
}
}
class Particle2D extends Laya.Sprite {
constructor(setting) {
super();
this._matrix4 = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
this.autoPlay = true;
this.customRenderEnable = true;
if (setting)
this.setParticleSetting(setting);
}
set url(url) {
this.load(url);
}
load(url) {
Laya.ILaya.loader.load(url, Laya.Handler.create(this, this.setParticleSetting), null, Laya.ILaya.Loader.JSON);
}
setParticleSetting(setting) {
if (!setting)
return this.stop();
ParticleSetting.checkSetting(setting);
this.customRenderEnable = true;
this._particleTemplate = new ParticleTemplate2D(setting);
this.graphics._saveToCmd(null, Laya.DrawParticleCmd.create(this._particleTemplate));
if (!this._emitter) {
this._emitter = new Emitter2D(this._particleTemplate);
}
else {
this._emitter.template = this._particleTemplate;
}
if (this.autoPlay) {
this.emitter.start();
this.play();
}
}
get emitter() {
return this._emitter;
}
play() {
Laya.ILaya.timer.frameLoop(1, this, this._loop);
}
stop() {
Laya.ILaya.timer.clear(this, this._loop);
}
_loop() {
this.advanceTime(1 / 60);
}
advanceTime(passedTime = 1) {
if (this._canvasTemplate) {
this._canvasTemplate.advanceTime(passedTime);
}
if (this._emitter) {
this._emitter.advanceTime(passedTime);
}
}
customRender(context, x, y) {
this._matrix4[0] = context._curMat.a;
this._matrix4[1] = context._curMat.b;
this._matrix4[4] = context._curMat.c;
this._matrix4[5] = context._curMat.d;
this._matrix4[12] = context._curMat.tx;
this._matrix4[13] = context._curMat.ty;
var sv = this._particleTemplate.sv;
sv.u_mmat = this._matrix4;
if (this._canvasTemplate) {
this._canvasTemplate.render(context, x, y);
}
}
destroy(destroyChild = true) {
if (this._particleTemplate instanceof ParticleTemplate2D)
this._particleTemplate.dispose();
super.destroy(destroyChild);
}
}
Laya.ClassUtils.regClass("laya.particle.Particle2D", Particle2D);
Laya.ClassUtils.regClass("Laya.Particle2D", Particle2D);
Laya.ILaya.regClass(Particle2D);
class ParticleEmitter {
constructor(templet, particlesPerSecond, initialPosition) {
this._timeLeftOver = 0;
this._tempVelocity = new Float32Array([0, 0, 0]);
this._tempPosition = new Float32Array([0, 0, 0]);
this._templet = templet;
this._timeBetweenParticles = 1.0 / particlesPerSecond;
this._previousPosition = initialPosition;
}
update(elapsedTime, newPosition) {
elapsedTime = elapsedTime / 1000;
if (elapsedTime > 0) {
Laya.MathUtil.subtractVector3(newPosition, this._previousPosition, this._tempVelocity);
Laya.MathUtil.scaleVector3(this._tempVelocity, 1 / elapsedTime, this._tempVelocity);
var timeToSpend = this._timeLeftOver + elapsedTime;
var currentTime = -this._timeLeftOver;
while (timeToSpend > this._timeBetweenParticles) {
currentTime += this._timeBetweenParticles;
timeToSpend -= this._timeBetweenParticles;
Laya.MathUtil.lerpVector3(this._previousPosition, newPosition, currentTime / elapsedTime, this._tempPosition);
this._templet.addParticleArray(this._tempPosition, this._tempVelocity);
}
this._timeLeftOver = timeToSpend;
}
this._previousPosition[0] = newPosition[0];
this._previousPosition[1] = newPosition[1];
this._previousPosition[2] = newPosition[2];
}
}
exports.Emitter2D = Emitter2D;
exports.EmitterBase = EmitterBase;
exports.Particle2D = Particle2D;
exports.ParticleData = ParticleData;
exports.ParticleEmitter = ParticleEmitter;
exports.ParticleSetting = ParticleSetting;
exports.ParticleShader = ParticleShader;
exports.ParticleShaderValue = ParticleShaderValue;
exports.ParticleTemplate2D = ParticleTemplate2D;
exports.ParticleTemplateBase = ParticleTemplateBase;
exports.ParticleTemplateWebGL = ParticleTemplateWebGL;
}(window.Laya = window.Laya || {}, Laya));