From 2eb75491ea0634c9a25961ad49f186ded12b3858 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sun, 21 Jul 2024 15:03:43 -0500 Subject: [PATCH] particle system support --- docs/api/mum.md | 169 ++++++++++++++++++++++++++++++++++++++- docs/api/tween.md | 16 +++- shaders/baseparticle.cg | 10 ++- source/engine/jsffi.c | 6 ++ source/engine/particle.c | 19 +++-- source/engine/particle.h | 4 +- 6 files changed, 206 insertions(+), 18 deletions(-) diff --git a/docs/api/mum.md b/docs/api/mum.md index fdb0ae54..2a28b14f 100644 --- a/docs/api/mum.md +++ b/docs/api/mum.md @@ -1,9 +1,172 @@ -# mum -#### screengui() +# Mum +#### padding +**array** + +[ + 0, + 0 +] + +#### offset +**array** + +[ + 0, + 0 +] + +#### font +**string** -#### prompt(msg = "prompt", value = "", list = [], cb = function() +#### selectable +**boolean** + + + +#### selected +**boolean** + + + +#### font_size +**number** + + + +#### text_align +**string** + + + +#### scale +**number** + + + +#### angle +**number** + + + +#### anchor +**array** + +[ + 0, + 1 +] + +#### hovered +**object** + + + +#### text_shadow +**object** + + + +#### text_outline +**number** + + + +#### color +**array** + +[ + 1, + 1, + 1, + 1 +] + +#### margin +**array** + +[ + 0, + 0 +] + +#### width +**number** + + + +#### height +**number** + + + +#### max_width +**number** + + + +#### max_height +**number** + + + +#### image_repeat +**boolean** + + + +#### image_repeat_offset +**array** + +[ + 0, + 0 +] + +#### debug +**boolean** + + + +#### make(def) + + + +#### prestart() + + + +#### start() + + + +#### extend(def) + + + +#### text(def) + + + +#### button(def) + + + +#### window(def) + + + +#### image(def) + + + +#### column(def) + + + +#### debug_colors +**object** diff --git a/docs/api/tween.md b/docs/api/tween.md index 61af74ef..f12f082e 100644 --- a/docs/api/tween.md +++ b/docs/api/tween.md @@ -1 +1,15 @@ -scripts/debug.js:205: [2024-07-03 12:13:12] warn, script: Cannot print the API of something that isn't an object. +# Tween +#### default +**object** + + + +#### start(obj, target, tvals, options) + + + +#### make(obj, target, tvals, options) + + + + diff --git a/shaders/baseparticle.cg b/shaders/baseparticle.cg index 1ff1a2c9..45a07cc4 100644 --- a/shaders/baseparticle.cg +++ b/shaders/baseparticle.cg @@ -21,13 +21,17 @@ out vec2 fuv; out vec4 color0; vec2 pos; - uniform mat4 vp; void main() { particle p = par[gl_InstanceIndex]; - pos = p.pos+(a_pos); + pos = a_pos - 0.5; + vec2 rot = pos; + rot.x = pos.x*cos(p.angle) - pos.y*sin(p.angle); + rot.y = pos.x*sin(p.angle) + pos.y*cos(p.angle); + pos = rot*p.scale; + pos += p.pos; color0 = p.color; gl_Position = vp * vec4(pos, 0.0, 1.0); } @@ -46,8 +50,6 @@ sampler smp; void main() { color = color0; - color.r = 1; - color.a = 1; } @end diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index 46ba1e9b..59d568b0 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -670,11 +670,14 @@ JSC_GETSET(emitter, scale, number) JSC_GETSET(emitter, scale_var, number) JSC_GETSET(emitter, grow_for, number) JSC_GETSET(emitter, shrink_for, number) +JSC_GETSET(emitter, color, vec4) JSC_GETSET(emitter, max, number) JSC_GETSET(emitter, explosiveness, number) JSC_GETSET(emitter, bounce, number) JSC_GETSET(emitter, collision_mask, bitmask) JSC_GETSET(emitter, die_after_collision, boolean) +JSC_GETSET(emitter, tumble, number) +JSC_GETSET(emitter, tumble_rate, number) JSC_GETSET(emitter, persist, number) JSC_GETSET(emitter, persist_var, number) JSC_GETSET(emitter, warp_mask, bitmask) @@ -1492,6 +1495,9 @@ static const JSCFunctionListEntry js_emitter_funcs[] = { CGETSET_ADD(emitter, grow_for), CGETSET_ADD(emitter, shrink_for), CGETSET_ADD(emitter, max), + CGETSET_ADD(emitter, color), + CGETSET_ADD(emitter, tumble), + CGETSET_ADD(emitter, tumble_rate), CGETSET_ADD(emitter, explosiveness), CGETSET_ADD(emitter, bounce), CGETSET_ADD(emitter, collision_mask), diff --git a/source/engine/particle.c b/source/engine/particle.c index 7807f3d2..60d81a8f 100644 --- a/source/engine/particle.c +++ b/source/engine/particle.c @@ -17,6 +17,7 @@ emitter *make_emitter() { e->tte = lerp(e->explosiveness, e->life/e->max, 0); e->scale = 1; e->speed = 20; + e->color = (HMM_Vec4){1,1,1,1}; return e; } @@ -46,7 +47,8 @@ int emitter_spawn(emitter *e, transform *t) HMM_Vec2 v2n = HMM_V2Rotate((HMM_Vec2){0,1}, newan); HMM_Vec3 norm = (HMM_Vec3){v2n.x, v2n.y,0}; p.v = HMM_MulV4F((HMM_Vec4){norm.x,norm.y,norm.z,0}, variate(e->speed, e->variation)); - p.angle = 0.25; + p.angle = e->tumble; + p.av = e->tumble_rate; p.scale = variate(e->scale*t->scale.x, e->scale_var); arrput(e->particles,p); return 1; @@ -58,9 +60,9 @@ void emitter_emit(emitter *e, int count, transform *t) emitter_spawn(e, t); } -int emitter_draw(emitter *e, sg_buffer *b) +void emitter_draw(emitter *e, sg_buffer *b) { - if (arrlen(e->particles) == 0) return 0; + if (arrlen(e->particles) == 0) return; arrsetlen(e->verts, arrlen(e->particles)); for (int i = 0; i < arrlen(e->particles); i++) { if (e->particles[i].time >= e->particles[i].life) continue; @@ -68,10 +70,10 @@ int emitter_draw(emitter *e, sg_buffer *b) e->verts[i].pos = p->pos.xy; e->verts[i].angle = p->angle; e->verts[i].scale = p->scale; -/* if (p->time < e->grow_for) + if (p->time < e->grow_for) e->verts[i].scale = lerp(p->time/e->grow_for, 0, p->scale); else if (p->time > (p->life - e->shrink_for)) - e->verts[i].scale = lerp((p->time-(p->life-e->shrink_for))/e->shrink_for, p->scale, 0);*/ + e->verts[i].scale = lerp((p->time-(p->life-e->shrink_for))/e->shrink_for, p->scale, 0); e->verts[i].color = p->color; } @@ -96,13 +98,14 @@ void emitter_step(emitter *e, double dt, transform *t) { for (int i = 0; i < arrlen(e->particles); i++) { if (e->particles[i].time >= e->particles[i].life) continue; - //if (e->warp_mask & gravmask) -// e->particles[i].v = HMM_AddV4(e->particles[i].v, g_accel); + if (e->warp_mask & gravmask) + e->particles[i].v = HMM_AddV4(e->particles[i].v, g_accel); e->particles[i].pos = HMM_AddV4(e->particles[i].pos, HMM_MulV4F(e->particles[i].v, dt)); e->particles[i].angle += e->particles[i].av*dt; e->particles[i].time += dt; - e->particles[i].color = sample_sampler(&e->color, e->particles[i].time/e->particles[i].life); + e->particles[i].color = e->color; + //e->particles[i].color = sample_sampler(&e->color, e->particles[i].time/e->particles[i].life); e->particles[i].scale = e->scale; if (e->particles[i].time >= e->particles[i].life) diff --git a/source/engine/particle.h b/source/engine/particle.h index 6a846a00..6cdef77d 100644 --- a/source/engine/particle.h +++ b/source/engine/particle.h @@ -47,7 +47,7 @@ typedef struct emitter { float divergence; /* angular degree of variation from emitter normal, up to 1 */ float tumble; /* amount of random rotation of particles */ float tumble_rate; /* tumble rotation */ - sampler color; /* color over particle lifetime */ + HMM_Vec4 color; /* color over particle lifetime */ float scale; float scale_var; float grow_for; /* seconds to grow from small until scale */ @@ -69,6 +69,6 @@ void emitter_free(emitter *e); void emitter_emit(emitter *e, int count, transform *t); void emitter_step(emitter *e, double dt, transform *t); -int emitter_draw(emitter *e, sg_buffer *b); +void emitter_draw(emitter *e, sg_buffer *b); #endif