636 lines
32 KiB
JavaScript
Raw Normal View History

2021-07-21 23:11:13 +08:00
(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));