diff --git a/source/engine/2dphysics.c b/source/engine/2dphysics.c index 151eb40..9b04785 100644 --- a/source/engine/2dphysics.c +++ b/source/engine/2dphysics.c @@ -13,7 +13,6 @@ #include "log.h" -cpBody *ballBody = NULL; cpSpace *space = NULL; float phys2d_gravity = -50.f; @@ -42,6 +41,8 @@ void phys2d_shape_apply(struct phys2d_shape *shape) void init_phys2dshape(struct phys2d_shape *shape, struct gameobject *go) { shape->go = go; + cpShapeSetCollisionType(shape->shape, go); + YughInfo("Added shape type %d", go); phys2d_shape_apply(shape); } @@ -140,9 +141,7 @@ struct phys2d_box *Make2DBox(struct gameobject *go) void phys2d_boxinit(struct phys2d_box *box, struct gameobject *go) { - box->shape.shape = - cpSpaceAddShape(space, - cpBoxShapeNew(go->body, box->w, box->h, box->r)); + box->shape.shape = cpSpaceAddShape(space, cpBoxShapeNew(go->body, box->w, box->h, box->r)); init_phys2dshape(&box->shape, go); phys2d_applybox(box); } @@ -179,9 +178,7 @@ void phys2d_polyinit(struct phys2d_poly *poly, struct gameobject *go) { cpTransform T = { 0 }; poly->shape.shape = - cpSpaceAddShape(space, - cpPolyShapeNew(go->body, 0, NULL, T, - poly->radius)); + cpSpaceAddShape(space, cpPolyShapeNew(go->body, 0, NULL, T, poly->radius)); init_phys2dshape(&poly->shape, go); phys2d_applypoly(poly); } @@ -231,14 +228,10 @@ struct phys2d_edge *Make2DEdge(struct gameobject *go) void phys2d_edgeinit(struct phys2d_edge *edge, struct gameobject *go) { edge->shapes[0] = - cpSpaceAddShape(space, - cpSegmentShapeNew(go->body, cpvzero, cpvzero, - edge->thickness)); + cpSpaceAddShape(space, cpSegmentShapeNew(go->body, cpvzero, cpvzero, edge->thickness)); edge->shape.go = go; phys2d_edgeshapeapply(&edge->shape, edge->shapes[0]); - - phys2d_applyedge(edge); } @@ -283,11 +276,8 @@ void edge_gui(struct phys2d_edge *edge) { if (nk_button_label(ctx, "Add Edge Vertex")) phys2d_edgeaddvert(edge); - for (int i = 0; i < edge->n; i++) { - //ImGui::PushID(i); + for (int i = 0; i < edge->n; i++) nk_property_float2(ctx, "E", 0.f, &edge->points[i*2], 1.f, 0.01f, 0.01f); - //ImGui::PopID(); - } nk_property_float(ctx, "Thickness", 0.01f, &edge->thickness, 1.f, 0.01f, 0.01f); @@ -304,9 +294,7 @@ void phys2d_applycircle(struct phys2d_circle *circle) cpCircleShapeSetRadius(circle->shape.shape, radius); cpCircleShapeSetOffset(circle->shape.shape, offset); - cpBodySetMoment(circle->shape.go->body, - cpMomentForCircle(circle->shape.go->mass, 0, radius, - offset)); + cpBodySetMoment(circle->shape.go->body, cpMomentForCircle(circle->shape.go->mass, 0, radius, offset)); } void phys2d_applyseg(struct phys2d_segment *seg) @@ -461,18 +449,67 @@ void phys2d_dbgdrawedge(struct phys2d_edge *edge) } } -s7_pointer *cbs; - -static cpBool s7_phys_cb(cpArbiter *arb, cpSpace *space, void *data) { - s7_pointer *cb = data; - script_call_sym(*cb); +void phys2d_reindex_body(cpBody *body) { + cpSpaceReindexShapesForBody(space, body); } -void phys2d_add_begin_handler(s7_pointer cb) { - arrput(cbs, cb); - cpCollisionHandler *handler = cpSpaceAddDefaultCollisionHandler(space); - handler->userData = &arrlast(cbs); - handler->beginFunc = s7_phys_cb; - YughInfo("Added a phys collider CB."); +static cpBool s7_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data) { + struct gameobject *go = data; + script_call_sym(go->cbs->begin); + + YughInfo("Gameobject %p began collision.", data); + + cpBody *body1; + cpBody *body2; + cpArbiterGetBodies(arb, &body1, &body2); + + cpShape *shape1; + cpShape *shape2; + cpArbiterGetShapes(arb, &shape1, &shape2); + + YughInfo("Body %p began collision with body %p.", body1, body2); + YughInfo("Shape %p began collision with shape %p.", shape1, shape2); + return 1; +} + +static cpBool s7_phys_cb_presolve(cpArbiter *arb, cpSpace *space, void *data) { + +} + +static void s7_phys_cb_postsolve(cpArbiter *arb, cpSpace *space, void *data) { + +} + +static void s7_phys_cb_separate(cpArbiter *Arb, cpSpace *space, void *data) { + struct gameobject *go = data; + script_call_sym(go->cbs->separate); +} + +void phys2d_add_handler_type(int cmd, struct gameobject *go, s7_pointer cb) { + cpCollisionHandler *handler = cpSpaceAddWildcardHandler(space, go); + + if (!go->cbs) + go->cbs = malloc(sizeof(*go->cbs)); + + handler->userData = go; + YughInfo("Making phys handler %d for type %d", cmd, go); + + switch (cmd) { + case 0: + handler->beginFunc = s7_phys_cb_begin; + go->cbs->begin = cb; + break; + + case 1: + break; + + case 2: + break; + + case 3: + handler->separateFunc = s7_phys_cb_separate; + go->cbs->separate = cb; + break; + } } \ No newline at end of file diff --git a/source/engine/2dphysics.h b/source/engine/2dphysics.h index ce331b7..e1db0c3 100644 --- a/source/engine/2dphysics.h +++ b/source/engine/2dphysics.h @@ -11,6 +11,11 @@ extern float phys2d_gravity; extern int physOn; extern cpSpace *space; +struct phys_cbs { + s7_pointer begin; + s7_pointer separate; +}; + struct phys2d_shape { cpShape *shape; struct gameobject *go; @@ -95,8 +100,10 @@ void phys2d_init(); void phys2d_update(float deltaT); void phys2d_apply(); -void phys2d_add_begin_handler(s7_pointer cb); +void phys2d_add_handler_type(int cmd, struct gameobject *go, s7_pointer cb); void shape_gui(struct phys2d_shape *shape); +void phys2d_reindex_body(cpBody *body); + #endif diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index 8bd7825..e62071a 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -3,6 +3,7 @@ #include "openglrender.h" #include "shader.h" +#include "log.h" static uint32_t circleVBO; static uint32_t circleVAO; @@ -68,10 +69,10 @@ void draw_circle(int x, int y, float radius, int pixels) shader_use(circleShader); float verts[] = { - x - radius, y - radius, - x + radius, y - radius, - x - radius, y + radius, - x + radius, y + radius, + x - radius, y - radius, -1, -1, + x + radius, y - radius, 1, -1, + x - radius, y + radius, -1, 1, + x + radius, y + radius, 1, 1 }; glBindBuffer(GL_ARRAY_BUFFER, circleVBO); @@ -82,7 +83,7 @@ void draw_circle(int x, int y, float radius, int pixels) glBindVertexArray(circleVAO); glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } diff --git a/source/engine/gameobject.c b/source/engine/gameobject.c index d0d2d04..36b4686 100644 --- a/source/engine/gameobject.c +++ b/source/engine/gameobject.c @@ -57,7 +57,8 @@ struct gameobject *MakeGameobject() gameobject_setpickcolor(&go); strncpy(go.editor.mname, "New object", MAXNAME); - go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f)); + go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f)); + arrput(gameobjects, go); @@ -151,13 +152,6 @@ void gameobject_init(struct gameobject *go, FILE * fprefab) int n; for (int i = 0; i < comp_n; i++) { - /* - fread(&n, sizeof(int), 1, fprefab); - go->components[i] = components[n]; - struct component *newc = &go->components[i]; - newc->go = go; - newc->data = calloc(1, newc->datasize); - */ fread(&n, sizeof(int), 1, fprefab); arrput(go->components, components[n]); struct component *newc = &arrlast(go->components); @@ -217,18 +211,14 @@ void toggleprefab(struct gameobject *go) } } -void gameobject_update(struct gameobject *go) -{ - if (go->script) - script_run(go->script); -} - void gameobject_move(struct gameobject *go, float xs, float ys) { cpVect p = cpBodyGetPosition(go->body); p.x += xs * deltaT; p.y += ys * deltaT; cpBodySetPosition(go->body, p); + + phys2d_reindex_body(go->body); } void gameobject_rotate(struct gameobject *go, float as) @@ -236,10 +226,14 @@ void gameobject_rotate(struct gameobject *go, float as) cpFloat a = cpBodyGetAngle(go->body); a += as * deltaT; cpBodySetAngle(go->body, a); + + phys2d_reindex_body(go->body); } void gameobject_setangle(struct gameobject *go, float angle) { cpBodySetAngle(go->body, angle); + + phys2d_reindex_body(go->body); } void gameobject_setpos(struct gameobject *go, float x, float y) { @@ -248,14 +242,10 @@ void gameobject_setpos(struct gameobject *go, float x, float y) { p.x = x; p.y = y; cpBodySetPosition(go->body, p); -} -void update_gameobjects() { - for (int i = 0; i < arrlen(gameobjects); i++) - gameobject_update(&gameobjects[i]); + phys2d_reindex_body(go->body); } - void object_gui(struct gameobject *go) { float temp_pos[2]; @@ -323,3 +313,13 @@ void object_gui(struct gameobject *go) gameobject_delcomponent(go, n); } + +void gameobject_draw_debugs() { + for (int i = 0; i < arrlen(gameobjects); i++) { + for (int j = 0; j < arrlen(gameobjects[i].components); j++) { + struct component *c = &gameobjects[i].components[j]; + + if (c->draw_debug) c->draw_debug(c->data); + } + } +} \ No newline at end of file diff --git a/source/engine/gameobject.h b/source/engine/gameobject.h index 56568d6..375410f 100644 --- a/source/engine/gameobject.h +++ b/source/engine/gameobject.h @@ -7,6 +7,7 @@ #include "config.h" #include #include +#include "2dphysics.h" struct shader; struct sprite; @@ -23,6 +24,10 @@ struct editor { char rootPrefabName[MAXNAME]; }; +struct go_temp { + struct phys_cbs phys_cbs; +}; + struct gameobject { struct mTransform transform; struct editor editor; @@ -33,7 +38,7 @@ struct gameobject { float f; /* friction */ float e; /* elasticity */ struct component *components; - char *script; + struct phys_cbs *cbs; }; extern struct gameobject *gameobjects; @@ -62,14 +67,13 @@ void gameobject_revertprefab(struct gameobject *go); void gameobject_init(struct gameobject *go, FILE * fprefab); -void gameobject_update(struct gameobject *go); -void update_gameobjects(); - void gameobject_move(struct gameobject *go, float xs, float ys); void gameobject_rotate(struct gameobject *go, float as); void gameobject_setangle(struct gameobject *go, float angle); void gameobject_setpos(struct gameobject *go, float x, float y); +void gameobject_draw_debugs(); + void object_gui(struct gameobject *go); #endif diff --git a/source/engine/input.c b/source/engine/input.c index 1cba45e..75f1bbb 100644 --- a/source/engine/input.c +++ b/source/engine/input.c @@ -87,6 +87,7 @@ void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods char keybuf[10]; if (key > 289 && key < 302) { sprintf(keybuf, "f%d", key-289); + strcat(keystr, keybuf); } else { switch(key) { case GLFW_KEY_ENTER: diff --git a/source/engine/mrbffi.c b/source/engine/mrbffi.c index 87fb483..a8f7dfd 100644 --- a/source/engine/mrbffi.c +++ b/source/engine/mrbffi.c @@ -11,6 +11,7 @@ #include "log.h" #include "input.h" #include "gameobject.h" +#include "openglrender.h" #include "s7.h" @@ -69,7 +70,7 @@ s7_pointer s7_gui_text(s7_scheme *sc, s7_pointer args) { s7_pointer s7_settings_cmd(s7_scheme *sc, s7_pointer args) { int cmd = s7_integer(s7_car(args)); double val = s7_real(s7_cadr(args)); - YughInfo("Changing a setting."); + switch(cmd) { case 0: // render fps renderMS = val; @@ -82,6 +83,10 @@ s7_pointer s7_settings_cmd(s7_scheme *sc, s7_pointer args) { case 2: physMS = val; break; + + case 3: + debug_draw_phys(val); + break; } return args; @@ -277,14 +282,13 @@ s7_pointer s7_set_body_pos(s7_scheme *sc, s7_pointer args) { } s7_pointer s7_phys_cmd(s7_scheme *sc, s7_pointer args) { - int cmd = s7_integer(s7_car(args)); - s7_pointer env = s7_cadr(args); + int go = s7_integer(s7_car(args)); + int cmd = s7_integer(s7_cadr(args)); + s7_pointer env = s7_caddr(args); - switch(cmd) { - case 0: - phys2d_add_begin_handler(env); - break; - } + if (go == -1) return; + + phys2d_add_handler_type(cmd, get_gameobject_from_id(go), env); } #define S7_FUNC(NAME, ARGS) s7_define_function(s7, #NAME, s7_ ##NAME, ARGS, 0, 0, "") @@ -309,6 +313,6 @@ void ffi_load() { S7_FUNC(set_pawn, 1); S7_FUNC(set_body, 3); S7_FUNC(set_body_pos, 4); - S7_FUNC(phys_cmd, 2); + S7_FUNC(phys_cmd, 3); } diff --git a/source/engine/openglrender.c b/source/engine/openglrender.c index 4a128e3..f866467 100644 --- a/source/engine/openglrender.c +++ b/source/engine/openglrender.c @@ -62,6 +62,10 @@ struct sprite *tsprite = NULL; static unsigned int projUBO; +void debug_draw_phys(int draw) { + debugDrawPhysics = draw; +} + void openglInit() { if (!mainwin) { @@ -129,6 +133,10 @@ void openglRender(struct window *window) //script_call_sym(window->gui_cb); call_gui(); + //// DEBUG + if (debugDrawPhysics) + gameobject_draw_debugs(); + ///// Sprites glDepthFunc(GL_LESS); shader_use(spriteShader); diff --git a/source/engine/openglrender.h b/source/engine/openglrender.h index 2a613bb..41ea6ad 100644 --- a/source/engine/openglrender.h +++ b/source/engine/openglrender.h @@ -42,7 +42,8 @@ void openglRender(struct window *window); void openglInit3d(struct window *window); void openglRender3d(struct window *window, struct mCamera *camera); -void BindUniformBlock(GLuint shaderID, const char *bufferName, - GLuint bufferBind); +void debug_draw_phys(int draw); + +void BindUniformBlock(GLuint shaderID, const char *bufferName, GLuint bufferBind); #endif diff --git a/source/scripts/engine.scm b/source/scripts/engine.scm index 29f134c..26545f8 100644 --- a/source/scripts/engine.scm +++ b/source/scripts/engine.scm @@ -90,8 +90,29 @@ (define (body_pos! body x y) (set_body_pos body 0 x y)) (define (body_move! body x y) (set_body_pos body 1 x y)) -(define-macro (collide . expr) +(define (b2i val) (if (eq? val #f) 0 1)) +(define (dbg_draw_phys val) (settings_cmd 3 (b2i val))) + +(define-macro (register-phys type body . expr) (let ((f (gensym))) `(begin (define (,f) (begin . ,expr)) - (phys_cmd 0 ,f)))) + (phys_cmd ,body ,(case type + ((collide) 0) + ((separate) 3)) ,f)))) + +(define (collide . expr) + (register-phys collide body expr)) + +(define-macro (separate . expr) + `(register-phys separate body ,@expr)) + +(define-macro (not! var) + `(set! ,var (not ,var))) + +(define-macro* (define-script name (lets ()) . expr ) + `(define* (,name (gameobject -1)) + (let ((body gameobject) + ,@lets) + ,@expr + (curlet)))) diff --git a/source/shaders/circlefrag.glsl b/source/shaders/circlefrag.glsl index 39d38bb..8067611 100644 --- a/source/shaders/circlefrag.glsl +++ b/source/shaders/circlefrag.glsl @@ -8,12 +8,14 @@ uniform int thickness; void main() { + // int tt = thickness + 1; float R1 = 1.f; float R2 = 1.f - (thickness / radius); float dist = sqrt(dot(coords, coords)); if (dist <= R2 || dist >= R1) discard; + /* float smoother = 0.01f - (radius * 0.00003f); float sm = smoothstep(R1, R1-smoother, dist); diff --git a/source/shaders/circlevert.glsl b/source/shaders/circlevert.glsl index c530cd6..e98286a 100644 --- a/source/shaders/circlevert.glsl +++ b/source/shaders/circlevert.glsl @@ -1,5 +1,5 @@ #version 330 core -layout (location = 0) in vec2 vertex; +layout (location = 0) in vec4 vertex; out vec2 coords; layout (std140) uniform Projection @@ -10,4 +10,5 @@ layout (std140) uniform Projection void main() { gl_Position = projection * vec4(vertex.xy, 0.0, 1.0); + coords = vertex.zw; } \ No newline at end of file