particles and warp zones
This commit is contained in:
parent
913c74db96
commit
6e4b7e63f2
9
docs/warp.md
Normal file
9
docs/warp.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Warp effects
|
||||||
|
|
||||||
|
Warp effects deal with particles as well as physics based rigidbodies.
|
||||||
|
|
||||||
|
- Motor: Apply torque.
|
||||||
|
- Vortex: A whirlpool like force.
|
||||||
|
- Gravity: A simple gravity force.
|
||||||
|
- Wind: Wind like force, with simulated turbulence.
|
||||||
|
- Bomb: Short force radially outwards
|
|
@ -189,16 +189,25 @@ struct rgba shape_color(cpShape *shape) {
|
||||||
return static_color;
|
return static_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static warp_gravity *space_gravity;
|
||||||
|
|
||||||
void phys2d_init()
|
void phys2d_init()
|
||||||
{
|
{
|
||||||
space = cpSpaceNew();
|
space = cpSpaceNew();
|
||||||
cpSpaceSetSleepTimeThreshold(space, 1);
|
cpSpaceSetSleepTimeThreshold(space, 1);
|
||||||
cpSpaceSetCollisionSlop(space, 0.01);
|
cpSpaceSetCollisionSlop(space, 0.01);
|
||||||
cpSpaceSetCollisionBias(space, cpfpow(1.0-0.5, 165.f));
|
cpSpaceSetCollisionBias(space, cpfpow(1.0-0.5, 165.f));
|
||||||
|
space_gravity = warp_gravity_make();
|
||||||
|
YughWarn("Made gravity with %d spherical", space_gravity->spherical);
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_set_gravity(cpVect v) {
|
void phys2d_set_gravity(HMM_Vec2 v)
|
||||||
cpSpaceSetGravity(space, v);
|
{
|
||||||
|
float str = HMM_LenV2(v);
|
||||||
|
HMM_Vec2 dir = HMM_NormV2(v);
|
||||||
|
space_gravity->strength = str;
|
||||||
|
space_gravity->t.scale = (HMM_Vec3){v.x,v.y, 0};
|
||||||
|
space_gravity->planar_force = (HMM_Vec3){v.x,v.y,0};
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_update(float deltaT) { cpSpaceStep(space, deltaT); }
|
void phys2d_update(float deltaT) { cpSpaceStep(space, deltaT); }
|
||||||
|
|
|
@ -99,7 +99,7 @@ struct shape_cb {
|
||||||
void fire_hits();
|
void fire_hits();
|
||||||
|
|
||||||
void phys2d_rm_go_handlers(gameobject *go);
|
void phys2d_rm_go_handlers(gameobject *go);
|
||||||
void phys2d_set_gravity(cpVect v);
|
void phys2d_set_gravity(HMM_Vec2 v);
|
||||||
|
|
||||||
void shape_enabled(struct phys2d_shape *shape, int enabled);
|
void shape_enabled(struct phys2d_shape *shape, int enabled);
|
||||||
int shape_is_enabled(struct phys2d_shape *shape);
|
int shape_is_enabled(struct phys2d_shape *shape);
|
||||||
|
|
|
@ -124,17 +124,19 @@ void gameobject_apply(gameobject *go) {
|
||||||
static void velocityFn(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
|
static void velocityFn(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
|
||||||
{
|
{
|
||||||
gameobject *go = body2go(body);
|
gameobject *go = body2go(body);
|
||||||
|
cpVect pos = cpBodyGetPosition(body);
|
||||||
|
HMM_Vec2 g = warp_force((HMM_Vec3){pos.x, pos.y, 0}, gravmask).xy;
|
||||||
if (!go) {
|
if (!go) {
|
||||||
cpBodyUpdateVelocity(body,gravity,damping,dt);
|
cpBodyUpdateVelocity(body,g.cp,damping,dt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpFloat d = isfinite(go->damping) ? go->damping : damping;
|
cpFloat d = isfinite(go->damping) ? go->damping : damping;
|
||||||
cpVect g = gravity;
|
|
||||||
if (isfinite(go->gravity.x) && isfinite(go->gravity.y))
|
if (isfinite(go->gravity.x) && isfinite(go->gravity.y))
|
||||||
g = go->gravity.cp;
|
g = go->gravity;
|
||||||
|
|
||||||
cpBodyUpdateVelocity(body,g,d,dt*go->timescale);
|
cpBodyUpdateVelocity(body,g.cp,d,dt*go->timescale);
|
||||||
|
|
||||||
if (isfinite(go->maxvelocity))
|
if (isfinite(go->maxvelocity))
|
||||||
cpBodySetVelocity(body, cpvclamp(cpBodyGetVelocity(body), go->maxvelocity));
|
cpBodySetVelocity(body, cpvclamp(cpBodyGetVelocity(body), go->maxvelocity));
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "HandmadeMath.h"
|
#include "HandmadeMath.h"
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
#include "warp.h"
|
||||||
|
|
||||||
#define dag_rm(p,c) do{\
|
#define dag_rm(p,c) do{\
|
||||||
for (int i = arrlen(p->children)-1; i--; i >=0) {\
|
for (int i = arrlen(p->children)-1; i--; i >=0) {\
|
||||||
|
@ -40,6 +41,7 @@ struct gameobject {
|
||||||
float damping;
|
float damping;
|
||||||
unsigned int layer;
|
unsigned int layer;
|
||||||
cpShapeFilter filter;
|
cpShapeFilter filter;
|
||||||
|
// warpmask warpmask;
|
||||||
struct phys_cbs cbs;
|
struct phys_cbs cbs;
|
||||||
struct shape_cb *shape_cbs;
|
struct shape_cb *shape_cbs;
|
||||||
JSValue ref;
|
JSValue ref;
|
||||||
|
|
|
@ -548,7 +548,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
phys2d_set_gravity(js2vec2(argv[1]).cp);
|
phys2d_set_gravity(js2vec2(argv[1]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
|
|
|
@ -22,7 +22,6 @@ static int draw_count;
|
||||||
struct scheduler sched;
|
struct scheduler sched;
|
||||||
void *mem;
|
void *mem;
|
||||||
|
|
||||||
|
|
||||||
struct par_vert {
|
struct par_vert {
|
||||||
HMM_Vec2 pos;
|
HMM_Vec2 pos;
|
||||||
float angle;
|
float angle;
|
||||||
|
@ -88,25 +87,19 @@ void particle_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
emitter *make_emitter() {
|
emitter *make_emitter() {
|
||||||
emitter *e = NULL;
|
emitter *e = calloc(sizeof(*e),1);
|
||||||
e = malloc(sizeof(*e));
|
|
||||||
e->max = 20;
|
e->max = 20;
|
||||||
e->particles = NULL;
|
|
||||||
arrsetcap(e->particles, e->max);
|
arrsetcap(e->particles, e->max);
|
||||||
for (int i = 0; i < arrlen(e->particles); i++)
|
for (int i = 0; i < arrlen(e->particles); i++)
|
||||||
e->particles[i].life = 0;
|
e->particles[i].life = 0;
|
||||||
|
|
||||||
e->life = 10;
|
e->life = 10;
|
||||||
e->explosiveness = 0;
|
|
||||||
e->tte = lerp(e->explosiveness, e->life/e->max, 0);
|
e->tte = lerp(e->explosiveness, e->life/e->max, 0);
|
||||||
e->color.times = NULL;
|
// e->warp_mask = gravmask;
|
||||||
e->color.data = NULL;
|
|
||||||
e->color.type = LINEAR;
|
|
||||||
sampler_add(&e->color, 0, (HMM_Vec4){1,1,1,1});
|
sampler_add(&e->color, 0, (HMM_Vec4){1,1,1,1});
|
||||||
e->scale = 1;
|
e->scale = 1;
|
||||||
e->speed = 20;
|
e->speed = 20;
|
||||||
e->gravity = 1;
|
|
||||||
e->on = 0;
|
|
||||||
e->texture = texture_pullfromfile("glass_chunk2.gif");
|
e->texture = texture_pullfromfile("glass_chunk2.gif");
|
||||||
arrpush(emitters,e);
|
arrpush(emitters,e);
|
||||||
return e;
|
return e;
|
||||||
|
@ -193,9 +186,10 @@ void parallel_step(emitter *e, struct scheduler *shed, struct sched_task_partiti
|
||||||
{
|
{
|
||||||
for (int i = t.end-1; i >=0; i--) {
|
for (int i = t.end-1; i >=0; i--) {
|
||||||
if (e->particles[i].life <= 0) continue;
|
if (e->particles[i].life <= 0) continue;
|
||||||
if (e->gravity)
|
|
||||||
|
if (e->warp_mask & gravmask)
|
||||||
e->particles[i].v = HMM_AddV4(e->particles[i].v, g_accel);
|
e->particles[i].v = HMM_AddV4(e->particles[i].v, g_accel);
|
||||||
e->particles[i].v = HMM_AddV4(e->particles[i].v, HMM_MulV4F((HMM_Vec4){frand(2)-1, frand(2)-1, 0,0}, 1000*dt));
|
|
||||||
e->particles[i].pos = HMM_AddV4(e->particles[i].pos, HMM_MulV4F(e->particles[i].v, dt));
|
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].angle += e->particles[i].av*dt;
|
||||||
e->particles[i].life -= dt;
|
e->particles[i].life -= dt;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define PARTICLE_H
|
#define PARTICLE_H
|
||||||
|
|
||||||
#include "HandmadeMath.h"
|
#include "HandmadeMath.h"
|
||||||
|
#include "warp.h"
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "anim.h"
|
#include "anim.h"
|
||||||
|
@ -22,13 +23,28 @@ typedef struct emitter {
|
||||||
float explosiveness; /* 0 for a stream, 1 for all at once. Range of values allowed. */
|
float explosiveness; /* 0 for a stream, 1 for all at once. Range of values allowed. */
|
||||||
int max; /* number of particles */
|
int max; /* number of particles */
|
||||||
double life; /* how long a particle lasts */
|
double life; /* how long a particle lasts */
|
||||||
double tte; /* time to emit */
|
/* PARTICLE GEN */
|
||||||
|
float speed; /* initial speed of particle */
|
||||||
|
float variation; /* variation on speed */
|
||||||
|
float divergence; /* angular degree of variation from emitter normal, up to 1 */
|
||||||
sampler color; /* color over particle lifetime */
|
sampler color; /* color over particle lifetime */
|
||||||
float scale;
|
float scale;
|
||||||
float speed;
|
float scale_var;
|
||||||
int gravity; /* true if affected by gravity */
|
float grow_for; /* seconds to grow from small until scale */
|
||||||
|
float fade_for; /* seconds to shrink to small prior to its death */
|
||||||
|
/* PARTICLE TYPE */
|
||||||
texture *texture;
|
texture *texture;
|
||||||
|
/* ROTATION AND COLLISION */
|
||||||
|
int collision_mask; /* mask for collision */
|
||||||
|
float bounce; /* bounce back after collision */
|
||||||
|
/* PARTICLE SPAWN */
|
||||||
|
int die_after_collision;
|
||||||
|
float persist; /* how long to linger after death */
|
||||||
|
float persist_var;
|
||||||
|
/* TRAILS */
|
||||||
|
warpmask warp_mask;
|
||||||
int on;
|
int on;
|
||||||
|
double tte; /* time to emit */
|
||||||
} emitter;
|
} emitter;
|
||||||
|
|
||||||
void particle_init();
|
void particle_init();
|
||||||
|
|
44
source/engine/warp.c
Normal file
44
source/engine/warp.c
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#include "warp.h"
|
||||||
|
#include "stb_ds.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
static warp_gravity **warps = NULL;
|
||||||
|
|
||||||
|
warp_gravity *warp_gravity_make()
|
||||||
|
{
|
||||||
|
warp_gravity *n = calloc(sizeof(*n),0);
|
||||||
|
n->t.pos = (HMM_Vec3){0,0,0};
|
||||||
|
n->strength = 9.8;
|
||||||
|
n->t.scale = (HMM_Vec3){0,-1,0};
|
||||||
|
n->planar_force = HMM_MulV3F(n->t.scale, n->strength);
|
||||||
|
n->mask = gravmask;
|
||||||
|
n->spherical = 0;
|
||||||
|
arrput(warps, n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
HMM_Vec3 warp_gravity_force(warp_gravity *g, HMM_Vec3 pos)
|
||||||
|
{
|
||||||
|
|
||||||
|
HMM_Vec3 f = (HMM_Vec3){0,0,0};
|
||||||
|
if (g->strength == 0) return f;
|
||||||
|
if (g->spherical) {
|
||||||
|
HMM_Vec3 dir = HMM_SubV3(g->t.pos, pos);
|
||||||
|
float len = HMM_LenV3(dir);
|
||||||
|
if (len == 0) return f;
|
||||||
|
HMM_Vec3 norm = HMM_NormV3(HMM_SubV3(g->t.pos, pos));
|
||||||
|
return HMM_MulV3F(norm,g->strength);
|
||||||
|
} else {
|
||||||
|
return g->planar_force;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HMM_Vec3 warp_force(HMM_Vec3 pos, warpmask mask)
|
||||||
|
{
|
||||||
|
HMM_Vec3 f = (HMM_Vec3){0,0,0};
|
||||||
|
for (int i = 0; i < arrlen(warps); i++) {
|
||||||
|
// if (!(mask & warps[i]->mask)) continue;
|
||||||
|
f = HMM_AddV3(f, warp_gravity_force(warps[i], pos));
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
27
source/engine/warp.h
Normal file
27
source/engine/warp.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef WARP_H
|
||||||
|
#define WARP_H
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "transform.h"
|
||||||
|
|
||||||
|
typedef uint32_t warpmask;
|
||||||
|
|
||||||
|
#define gravmask 1U
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
transform3d t;
|
||||||
|
float strength;
|
||||||
|
float decay;
|
||||||
|
int spherical;
|
||||||
|
HMM_Vec3 planar_force;
|
||||||
|
warpmask mask;
|
||||||
|
} warp_gravity;
|
||||||
|
|
||||||
|
/* returns the total force for an object at pos */
|
||||||
|
HMM_Vec3 warp_force(HMM_Vec3 pos, warpmask mask);
|
||||||
|
|
||||||
|
warp_gravity *warp_gravity_make();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue