From f4d08bcacbad6d3aadc86ad050b7b56956b79d40 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sun, 5 Feb 2023 23:42:36 +0000 Subject: [PATCH] box selection --- source/engine/2dphysics.c | 43 +++++++++++++++++++++++++++++++++ source/engine/2dphysics.h | 2 +- source/engine/debug/debugdraw.c | 12 +++++++++ source/engine/debug/debugdraw.h | 2 ++ source/engine/ffi.c | 29 ++++++++++++++++++++++ source/engine/gameobject.c | 18 +++++++++++--- source/engine/gameobject.h | 1 + 7 files changed, 103 insertions(+), 4 deletions(-) diff --git a/source/engine/2dphysics.c b/source/engine/2dphysics.c index 5af8a6b..b7cde57 100644 --- a/source/engine/2dphysics.c +++ b/source/engine/2dphysics.c @@ -57,6 +57,49 @@ cpShape *phys2d_query_pos(cpVect pos) return find; } +int *qhits; + +void querylist(cpShape *shape, cpContactPointSet *points, void *data) +{ + arrput(qhits, shape2gameobject(shape)); +} + +void querylistbodies(cpBody *body, void *data) +{ + cpBB *bbox = data; + if (cpBBContainsVect(*bbox, cpBodyGetPosition(body))) { + int go = body2id(body); + if (go < 0) return; + + int in = 0; + for (int i = 0; i < arrlen(qhits); i++) { + if (qhits[i] == go) { + in = 1; + break; + } + } + + if (!in) arrput(qhits, go); + } +} + +int *phys2d_query_box(cpVect pos, cpVect wh) +{ + cpBB bbox = cpBBNewForExtents(pos, wh.x, wh.y); + cpShape *box = cpBoxShapeNew2(NULL, bbox, 0.f); + + if (qhits) arrfree(qhits); + cpSpaceShapeQuery(space, box, querylist, NULL); + + YughInfo("FInished query."); + + cpSpaceEachBody(space, querylistbodies, &bbox); + + cpShapeFree(box); + + return qhits; +} + int cpshape_enabled(cpShape *c) { cpShapeFilter filter = cpShapeGetFilter(c); diff --git a/source/engine/2dphysics.h b/source/engine/2dphysics.h index 749a904..3143b2b 100644 --- a/source/engine/2dphysics.h +++ b/source/engine/2dphysics.h @@ -15,7 +15,6 @@ extern float dynamic_color[3]; extern float kinematic_color[3]; extern float static_color[3]; - struct phys2d_shape { cpShape *shape; int go; @@ -97,6 +96,7 @@ void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val); void phys2d_init(); void phys2d_update(float deltaT); cpShape *phys2d_query_pos(cpVect pos); +int *phys2d_query_box(cpVect pos, cpVect wh); struct phys_cbs { struct callee begin; diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index ce63d64..cf34331 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -119,6 +119,12 @@ void draw_rect(int x, int y, int w, int h, float *color) draw_poly(verts, 4, color); } +void draw_box(struct cpVect c, struct cpVect wh) +{ + float white[3] = {1, 1, 1}; + draw_rect(c.x, c.y, wh.x, wh.y, white); +} + void draw_grid(int width, int span) { shader_use(gridShader); @@ -135,6 +141,12 @@ void draw_point(int x, int y, float r, float *color) draw_circle(x, y, r, r, color, 0); } +void draw_cppoint(struct cpVect point, float r) +{ + float white[3] = {1.f, 1.f, 1.f}; + draw_point(point.x, point.y, r, white); +} + void draw_points(struct cpVect *points, int n, float size, float *color) { for (int i = 0; i < n; i++) diff --git a/source/engine/debug/debugdraw.h b/source/engine/debug/debugdraw.h index 2004ece..b31ec33 100644 --- a/source/engine/debug/debugdraw.h +++ b/source/engine/debug/debugdraw.h @@ -10,7 +10,9 @@ void draw_points(struct cpVect *points, int n, float size, float *color); void draw_circle(int x, int y, float radius, int pixels, float *color, int fill); void draw_grid(int width, int span); void draw_rect(int x, int y, int w, int h, float *color); +void draw_box(struct cpVect c, struct cpVect wh); void draw_point(int x, int y, float r, float *color); +void draw_cppoint(struct cpVect point, float r); void draw_poly(float *points, int n, float *color); diff --git a/source/engine/ffi.c b/source/engine/ffi.c index 15a44c0..3932033 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -22,6 +22,8 @@ #include "level.h" #include "tinyspline.h" #include "mix.h" +#include "debugdraw.h" +#include "stb_ds.h" #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" #define BYTE_TO_BINARY(byte) \ @@ -275,6 +277,16 @@ duk_ret_t duk_spline_cmd(duk_context *duk) return 1; } +void ints2duk(int *ints) +{ + int idx = duk_push_array(duk); + + for (int i = 0; i < arrlen(ints); i++) { + duk_push_int(duk, ints[i]); + duk_put_prop_index(duk, idx, i); + } +} + duk_ret_t duk_cmd(duk_context *duk) { int cmd = duk_to_int(duk, 0); @@ -483,6 +495,23 @@ duk_ret_t duk_cmd(duk_context *duk) { case 49: duk_push_int(duk, mainwin->height); return 1; + + case 50: + duk_push_boolean(duk, action_down(duk_to_int(duk, 1))); + return 1; + + case 51: + draw_cppoint(duk2vec2(duk, 1), duk_to_number(duk, 2)); + return 0; + + case 52: + ints2duk(phys2d_query_box(duk2vec2(duk, 1), duk2vec2(duk, 2))); + return 1; + + case 53: + draw_box(duk2vec2(duk, 1), duk2vec2(duk, 2)); + return 0; + } return 0; diff --git a/source/engine/gameobject.c b/source/engine/gameobject.c index 1c481a3..e54bc51 100644 --- a/source/engine/gameobject.c +++ b/source/engine/gameobject.c @@ -26,19 +26,31 @@ struct gameobject *get_gameobject_from_id(int id) return &gameobjects[id]; } -struct gameobject *id2go(int id) { +struct gameobject *id2go(int id) +{ if (id < 0) return NULL; return &gameobjects[id]; } +int body2id(cpBody *body) +{ + struct gameobject *go = cpBodyGetUserData(body); + return id_from_gameobject(go); +} + +int shape2gameobject(cpShape *shape) +{ + struct phys2d_shape *s = cpShapeGetUserData(shape); + return s->go; +} + int pos2gameobject(cpVect pos) { cpShape *hit = phys2d_query_pos(pos); if (hit) { - struct phys2d_shape *shape = cpShapeGetUserData(hit); - return shape->go; + return shape2gameobject(hit); } for (int i = 0; i < arrlen(gameobjects); i++) { diff --git a/source/engine/gameobject.h b/source/engine/gameobject.h index 89a9491..154e475 100644 --- a/source/engine/gameobject.h +++ b/source/engine/gameobject.h @@ -49,6 +49,7 @@ void toggleprefab(struct gameobject *go); struct gameobject *get_gameobject_from_id(int id); struct gameobject *id2go(int id); int id_from_gameobject(struct gameobject *go); +int body2id(cpBody *body); void go_shape_apply(cpBody *body, cpShape *shape, struct gameobject *go);