diff --git a/Makefile b/Makefile index 6db7c16..81b2b4d 100755 --- a/Makefile +++ b/Makefile @@ -62,7 +62,6 @@ endif ifeq ($(LEAK),1) CPPFLAGS += -fsanitize=address - INFO += _leak endif ifeq ($(OPT),small) diff --git a/scripts/components.js b/scripts/components.js index ad26141..7d70f84 100644 --- a/scripts/components.js +++ b/scripts/components.js @@ -874,13 +874,20 @@ component.particle = Object.copy(component, { return p; }, get pos() {}, - set pos(x) {}, + set pos(x) {cmd(238,this.id,x);}, get angle() {}, - set angle(x) {}, + set angle(x) {cmd(239,this.id,Math.turn2rad(x));}, get life() {}, set life(x) { cmd(235,this.id,x); }, get explosiveness() {}, - set explosiveness(x) {}, + set explosiveness(x) {cmd(237,this.id,x);}, + set speed(x) { cmd(240,this.id,x); }, + set speed_var(x) { cmd(241,this.id,x); }, + set divergence(x) { cmd(242,this.id,x); }, + set scale(x) { cmd(243,this.id,x); }, + set scale_var(x) { cmd(244,this.id,x); }, + set grow_for(x) { cmd(245,this.id,x); }, + set shrink_for(x) {cmd(246,this.id,x); }, get max() {}, set max(x) {}, emit(n) { diff --git a/source/engine/HandmadeMath.h b/source/engine/HandmadeMath.h index 1b0c97b..84a57cc 100644 --- a/source/engine/HandmadeMath.h +++ b/source/engine/HandmadeMath.h @@ -888,6 +888,14 @@ static inline float HMM_DistV2(HMM_Vec2 a, HMM_Vec2 b) { return HMM_LenV2(HMM_SubV2(a,b)); } +static inline HMM_Vec2 HMM_V2Rotate(HMM_Vec2 v, float angle) +{ + float r = HMM_LenV2(v); + angle += atan2(v.x, v.y); + return (HMM_Vec2){r*cos(angle), r*sin(angle)}; +} + + static inline float HMM_LenV3(HMM_Vec3 A) { return HMM_SqrtF(HMM_LenSqrV3(A)); } diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index c0defdd..6f24ba2 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -1433,6 +1433,36 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) case 236: emitter_emit(js2emitter(argv[1]), js2number(argv[2])); break; + case 237: + js2emitter(argv[1])->explosiveness = js2number(argv[2]); + break; + case 238: + js2emitter(argv[1])->t.pos.xy = js2vec2(argv[2]); + break; + case 239: + js2emitter(argv[1])->t.rotation.Elements[0] = js2number(argv[2]); + break; + case 240: + js2emitter(argv[1])->speed = js2number(argv[2]); + break; + case 241: + js2emitter(argv[1])->variation = js2number(argv[2]); + break; + case 242: + js2emitter(argv[1])->divergence = js2number(argv[2]); + break; + case 243: + js2emitter(argv[1])->scale = js2number(argv[2]); + break; + case 244: + js2emitter(argv[1])->scale_var = js2number(argv[2]); + break; + case 245: + js2emitter(argv[1])->grow_for = js2number(argv[2]); + break; + case 246: + js2emitter(argv[1])->shrink_for = js2number(argv[2]); + break; } if (str) diff --git a/source/engine/particle.c b/source/engine/particle.c index 36d0d3e..effbcf7 100644 --- a/source/engine/particle.c +++ b/source/engine/particle.c @@ -6,6 +6,7 @@ #include "log.h" #include "simplex.h" #include "pthread.h" +#include "math.h" #define SCHED_IMPLEMENTATION #include "sched.h" @@ -96,7 +97,6 @@ emitter *make_emitter() { e->life = 10; e->tte = lerp(e->explosiveness, e->life/e->max, 0); -// e->warp_mask = gravmask; sampler_add(&e->color, 0, (HMM_Vec4){1,1,1,1}); e->scale = 1; e->speed = 20; @@ -118,15 +118,25 @@ void free_emitter(emitter *e) void start_emitter(emitter *e) { e->on = 1; } void stop_emitter(emitter *e) { e->on = 0; } +/* Variate a value around variance. Variance between 0 and 1. */ + +float variate(float val, float variance) +{ + return val + val*(frand(variance)-(variance/2)); +} + int emitter_spawn(emitter *e) { particle p; p.life = e->life; - p.pos = (HMM_Vec4){0,0,0,0}; - p.v = (HMM_Vec4){frand(1)-0.5,frand(1)-0.5,0,0}; - p.v = HMM_MulV4F(HMM_NormV4(p.v), e->speed); + p.pos = (HMM_Vec4){e->t.pos.x,e->t.pos.y,0,0}; + float newan = e->t.rotation.Elements[0]+(2*HMM_PI*(frand(e->divergence)-(e->divergence/2))); + YughWarn("angle %g", newan); + HMM_Vec2 norm = HMM_V2Rotate((HMM_Vec2){0,1}, newan); + p.v = HMM_MulV4F((HMM_Vec4){norm.x,norm.y,0,0}, variate(e->speed, e->variation)); p.angle = 0; - p.av = 1; + p.scale = variate(e->scale, e->scale_var); +// p.av = 1; arrput(e->particles,p); return 1; } @@ -148,11 +158,16 @@ static struct par_vert pv[MAX_PARTICLES]; void parallel_pv(emitter *e, struct scheduler *sched, struct sched_task_partition t, sched_uint thread_num) { for (int i=t.start; i < t.end; i++) { - if (e->particles[i].life <= 0) continue; + if (e->particles[i].time >= e->particles[i].life) continue; particle *p = &e->particles[i]; pv[i].pos = p->pos.xy; pv[i].angle = p->angle; - pv[i].scale = HMM_ScaleV2(tex_get_dimensions(e->texture), p->scale); + float s = p->scale; + if (p->time < e->grow_for) + s = lerp(p->time/e->grow_for, 0, p->scale); + else if (p->time > (p->life - e->shrink_for)) + s = lerp((p->time-(p->life-e->shrink_for))/e->shrink_for, p->scale, 0); + pv[i].scale = HMM_ScaleV2(tex_get_dimensions(e->texture), s); pv[i].color = vec2rgba(p->color); } } @@ -185,21 +200,21 @@ static HMM_Vec4 g_accel; void parallel_step(emitter *e, struct scheduler *shed, struct sched_task_partition t, sched_uint thread_num) { for (int i = t.end-1; i >=0; i--) { - if (e->particles[i].life <= 0) continue; + 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); 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].life -= dt; - e->particles[i].color = sample_sampler(&e->color, (e->life-e->particles[i].life)/e->life); + e->particles[i].time += dt; + 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].life <= 0) -// arrdelswap(e->particles, i); -// else if (query_point(e->particles[i].pos.xy)) -// arrdelswap(e->particles,i); + if (e->particles[i].time >= e->particles[i].life) + arrdelswap(e->particles, i); + else if (query_point(e->particles[i].pos.xy)) + arrdelswap(e->particles,i); } } diff --git a/source/engine/particle.h b/source/engine/particle.h index d4d7055..ea5c2ca 100644 --- a/source/engine/particle.h +++ b/source/engine/particle.h @@ -13,6 +13,7 @@ typedef struct particle { float angle; float av; /* angular velocity */ float scale; + double time; double life; HMM_Vec4 color; } particle; @@ -23,6 +24,7 @@ typedef struct emitter { float explosiveness; /* 0 for a stream, 1 for all at once. Range of values allowed. */ int max; /* number of particles */ double life; /* how long a particle lasts */ + double life_var; /* PARTICLE GEN */ float speed; /* initial speed of particle */ float variation; /* variation on speed */ @@ -31,7 +33,7 @@ typedef struct emitter { float scale; float scale_var; float grow_for; /* seconds to grow from small until scale */ - float fade_for; /* seconds to shrink to small prior to its death */ + float shrink_for; /* seconds to shrink to small prior to its death */ /* PARTICLE TYPE */ texture *texture; /* ROTATION AND COLLISION */ diff --git a/source/engine/warp.c b/source/engine/warp.c index 25b0b76..84505c9 100644 --- a/source/engine/warp.c +++ b/source/engine/warp.c @@ -6,7 +6,7 @@ static warp_gravity **warps = NULL; warp_gravity *warp_gravity_make() { - warp_gravity *n = calloc(sizeof(*n),0); + warp_gravity *n = calloc(sizeof(*n),1); n->t.pos = (HMM_Vec3){0,0,0}; n->strength = 9.8; n->t.scale = (HMM_Vec3){0,-1,0};