diff --git a/src/game.c b/src/game.c index c381a58..e4f2dd0 100644 --- a/src/game.c +++ b/src/game.c @@ -161,7 +161,7 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) { if(e1 != ENT_ID_INVALID) { struct CPhysics *cp = game_getcomponent(e1, physics); if(!cp) { - // Entity being killed + // Entity being killed maybe return; } @@ -173,7 +173,7 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) { if(e2 != ENT_ID_INVALID) { struct CPhysics *cp = game_getcomponent(e2, physics); if(!cp) { - // Entity being killed + // Entity being killed maybe return; } @@ -189,35 +189,6 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) { friction *= c->friction; - vec4 q; - if(b1) { - memcpy(q, dBodyGetQuaternion(b1), sizeof(q)); - } else { - dGeomGetQuaternion(c->geom, q); - } - { - float temp = q[0]; - q[0] = q[1]; - q[1] = q[2]; - q[2] = q[3]; - q[3] = temp; - } - - vec3 n = {0, 1, 0}; - glm_quat_rotatev(q, n, n); - - /*if(!ghost) for(int i = 0; i < numc; i++) { - if(glm_vec3_dot(contact[i].geom.normal, n) >= 0.7) { - struct CMovement *m = game_getcomponent(e1, movement); - if(m) { - if(m->holding != ENT_ID_INVALID && m->holding == e2) { - ghost = 1; - } - break; - } - } - }*/ - if(c->trigger != TRIGGER_INVALID) { Game.triggers[c->trigger - 1](c->trigger, e1, e2, triggerType); } @@ -228,34 +199,6 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) { friction *= c->friction; - vec4 q; - if(b2) { - memcpy(q, dBodyGetQuaternion(b2), sizeof(q)); - } else { - dGeomGetQuaternion(c->geom, q); - } - { - float temp = q[0]; - q[0] = q[1]; - q[1] = q[2]; - q[2] = q[3]; - q[3] = temp; - } - - vec3 n = {0, -1, 0}; - glm_quat_rotatev(q, n, n); - - /*if(!ghost) for(int i = 0; i < numc; i++) { - if(glm_vec3_dot(contact[i].geom.normal, n) >= 0.7) { - struct CMovement *m = game_getcomponent(e2, movement); - if(m) { - if(m->holding != ENT_ID_INVALID && m->holding == e1) { - ghost = 1; - } - } - } - }*/ - if(c->trigger != TRIGGER_INVALID) { Game.triggers[c->trigger - 1](c->trigger, e2, e1, triggerType); } @@ -358,36 +301,47 @@ static void game_character_controller_raycast_handler(void *data, dGeomID g1, dG return; } + uint16_t e1 = (uintptr_t) dGeomGetData(g1); + uint16_t e2 = (uintptr_t) dGeomGetData(g2); + + if(e1 == e2) { + // This means the ray is hitting the entity casting it. + return; + } + dContact contact[1]; memset(contact, 0, sizeof(contact)); int numc = dCollide(g1, g2, 1, &contact[0].geom, sizeof(dContact)); - uint16_t e1 = (uintptr_t) dGeomGetData(g1); - uint16_t e2 = (uintptr_t) dGeomGetData(g2); - if(numc) { vec3 n = {0, -1, 0}; if(dGeomGetClass(g1) == dRayClass) { - struct CMovement *cm = &Game.entities.movement[(uintptr_t) dGeomGetData(g1)]; + struct CMovement *cm = game_getcomponent(e1, movement); + + struct CPhysics *cp2 = game_getcomponent(e2, physics); + if(cp2 && (cp2->dynamics & CPHYSICS_GHOST)) { + return; + } if(glm_vec3_dot(contact[0].geom.normal, n) <= -0.7) { cm->canJump = 1; glm_vec3_scale(contact[0].geom.normal, 1, cm->groundNormal); } - - return; } else if(dGeomGetClass(g2) == dRayClass) { - struct CMovement *cm = &Game.entities.movement[(uintptr_t) dGeomGetData(g2)]; + struct CMovement *cm = game_getcomponent(e2, movement); + + struct CPhysics *cp1 = game_getcomponent(e1, physics); + if(cp1 && (cp1->dynamics & CPHYSICS_GHOST)) { + return; + } if(glm_vec3_dot(contact[0].geom.normal, n) <= -0.7) { cm->canJump = 1; glm_vec3_scale(contact[0].geom.normal, -1, cm->groundNormal); } - - return; } } @@ -403,9 +357,11 @@ void game_character_controller_raycast() { continue; } - rayGeoms[i] = dCreateRay(Game.space, 1); + const float raylen = 0.5; - dGeomSetData(rayGeoms[i], (void*) (uintptr_t) i); + rayGeoms[i] = dCreateRay(Game.space, raylen); + + dGeomSetData(rayGeoms[i], (void*) (uintptr_t) Game.entities.movement[i].entity); dGeomSetCategoryBits(rayGeoms[i], CATEGORY_RAY); dGeomSetCollideBits(rayGeoms[i], CATEGORY_STATIC | CATEGORY_ENTITY); @@ -414,7 +370,7 @@ void game_character_controller_raycast() { const float *position = dBodyGetPosition(bid); - dGeomRaySet(rayGeoms[i], position[0], position[1] - cp->capsule.length / 2 + 0.5, position[2], 0, -1, 0); + dGeomRaySet(rayGeoms[i], position[0], position[1] - cp->capsule.length / 2 - cp->capsule.radius + raylen / 2, position[2], 0, -1, 0); } dSpaceCollide(Game.space, NULL, game_character_controller_raycast_handler); @@ -608,6 +564,8 @@ void game_update() { glm_vec3_scale_as(wishvel, 3, wishvel); } } else { + // We project the movement vector onto the ground plane (set by game_character_controller_raycast_handler) + // to "slide" along the ground with minimal bouncing vec3_project_to_plane(wishvel, Game.entities.movement[mi].groundNormal, wishvel); }