var emitter = {}; emitter.particles = {}; emitter.life = 10; emitter.scale = 1; emitter.grow_for = 0; emitter.spawn_timer = 0; emitter.pps = 0; emitter.color = Color.white; emitter.draw = function() { var pars = Object.values(this.particles); if (pars.length === 0) return; render.use_shader(this.shader); render.use_mat(this); render.make_particle_ssbo(pars, this.ssbo); render.draw(this.shape, this.ssbo, pars.length); } emitter.kill = function() { emitters.remove(this); } var std_step = function(p) { if (p.time < this.grow_for) { var s = Math.lerp(0, this.scale, p.time/this.grow_for); p.transform.scale = [s,s,s]; } else if (p.time > (p.life - this.shrink_for)) { var s = Math.lerp(0,this.scale,(p.life-p.time)/this.shrink_for); p.transform.scale=[s,s,s]; } else p.transform.scale = [this.scale,this.scale,this.scale]; } emitter.step_hook = std_step; emitter.spawn = function(t) { t ??= this.transform; var par = this.dead.shift(); if (par) { par.body.pos = t.pos; par.transform.scale = [this.scale,this.scale,this.scale]; this.particles[par.id] = par; par.time = 0; this.spawn_hook?.(par); par.life = this.life; return; } par = { transform: os.make_transform(), life: this.life, time: 0, color: this.color }; par.body = os.make_body(par.transform); par.body.pos = t.pos; par.transform.scale = [this.scale,this.scale,this.scale]; par.id = prosperon.guid(); this.particles[par.id] = par; this.spawn_hook(par); } emitter.step = function(dt) { // update spawning particles if (this.on && this.pps > 0) { this.spawn_timer += dt; var pp = 1/this.pps; while (this.spawn_timer > pp) { this.spawn_timer -= pp; this.spawn(); } } // update all particles for (var p of Object.values(this.particles)) { p.time += dt; this.step_hook?.(p); if (this.kill_hook?.(p) || p.time >= p.life) { this.die_hook?.(p); this.dead.push(this.particles[p.id]); delete this.particles[p.id]; } } } emitter.burst = function(count, t) { for (var i = 0; i < count; i++) this.spawn(t); } var emitters = []; var make_emitter = function() { var e = Object.create(emitter); e.ssbo = render.make_textssbo(); e.shape = shape.centered_quad; e.shader = "shaders/baseparticle.cg"; e.dead = []; emitters.push(e); return e; } function update_emitters(dt) { for (var e of emitters) e.step(dt); } function draw_emitters() { for (var e of emitters) e.draw(); } return {make_emitter, update_emitters, draw_emitters};