From 7193bcbc41a18ad6786273554811eb7e88a9479c Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Sun, 1 Feb 2026 00:38:33 +0900 Subject: [PATCH] basic physics --- engine/include/GearSrc/TypeDefs.h | 5 ++-- engine/src/physics.c | 39 ++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/engine/include/GearSrc/TypeDefs.h b/engine/include/GearSrc/TypeDefs.h index 488ad10..6a7be03 100644 --- a/engine/include/GearSrc/TypeDefs.h +++ b/engine/include/GearSrc/TypeDefs.h @@ -316,8 +316,9 @@ struct _GSNetSocket { struct _GSPhysics { GSEngine engine; - dWorldID world; - dSpaceID space; + dWorldID world; + dSpaceID space; + dJointGroupID contact_group; }; struct _GSClient { diff --git a/engine/src/physics.c b/engine/src/physics.c index 45aff69..9e3e51b 100644 --- a/engine/src/physics.c +++ b/engine/src/physics.c @@ -15,8 +15,11 @@ GSPhysics GSPhysicsCreate(GSServer server) { physics->engine = server->engine; - physics->world = dWorldCreate(); - physics->space = dSimpleSpaceCreate(0); + physics->world = dWorldCreate(); + physics->space = dSimpleSpaceCreate(0); + physics->contact_group = dJointGroupCreate(0); + + dWorldSetGravity(physics->world, 0, 0, -9.81); GSLog(server->engine, GSLogInfo, "Created physics engine"); @@ -24,6 +27,7 @@ GSPhysics GSPhysicsCreate(GSServer server) { } void GSPhysicsDestroy(GSPhysics physics) { + dJointGroupDestroy(physics->contact_group); dSpaceDestroy(physics->space); dWorldDestroy(physics->world); @@ -32,5 +36,34 @@ void GSPhysicsDestroy(GSPhysics physics) { free(physics); } -void GSPhysicsStep(GSPhysics physics) { +static void near_callback(void* data, dGeomID o1, dGeomID o2) { + const int N = 256; + dContact contact[256]; + GSPhysics physics = data; + + if(dGeomIsSpace(o1) || dGeomIsSpace(o2)) { + dSpaceCollide2(o1, o2, data, near_callback); + if(dGeomIsSpace(o1)) dSpaceCollide((dSpaceID)o1, data, near_callback); + if(dGeomIsSpace(o2)) dSpaceCollide((dSpaceID)o2, data, near_callback); + } else { + int how_many = dCollide(o1, o2, N, &contact[0].geom, sizeof(dContact)); + int i; + + for(i = 0; i < how_many; i++) { + dJointID joint; + + contact[i].surface.mode = dContactApprox1; + contact[i].surface.mu = 2; + + joint = dJointCreateContact(physics->world, physics->contact_group, &contact[i]); + + dJointAttach(joint, dGeomGetBody(contact[i].geom.g1), dGeomGetBody(contact[i].geom.g2)); + } + } +} + +void GSPhysicsStep(GSPhysics physics) { + dSpaceCollide(physics->space, physics, near_callback); + dWorldStep(physics->world, 1.0 / physics->engine->tps); + dJointGroupEmpty(physics->contact_group); }