From e7e952e57d14c357ff0afa93db9fd75490314677 Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 24 Nov 2023 19:07:51 +0100 Subject: [PATCH] feat(physics): physics entity now supports overlap --- core/src/physics_entity.c | 11 ++++++++--- core/src/physics_entity.h | 18 +++++++++++------- core/src/rigidbody.c | 36 +++++++++++++++++++++++++++++------- core/src/rigidbody.h | 16 ++++++++++++++-- 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/core/src/physics_entity.c b/core/src/physics_entity.c index 4d2f5bb..982f252 100644 --- a/core/src/physics_entity.c +++ b/core/src/physics_entity.c @@ -81,9 +81,14 @@ void physics_entity_update(PhysicsEntity self) { List* contacts = rigidbody_get_contacts(body); if(contacts->len > 0) { - self.tc->collision_solver(self.data, contacts); - list_foreach(Contact*, contact, contacts) - self.tc->on_collision(self.data, contact->hit); + if(rigidbody_get_overlap(body)) { + list_foreach(Contact*, contact, contacts) + self.tc->on_overlap(self.data, contact->hit.other); + } else { + self.tc->collision_solver(self.data, contacts); + list_foreach(Contact*, contact, contacts) + self.tc->on_collision(self.data, contact->hit); + } } rigidbody_collect_contacts(body); diff --git a/core/src/physics_entity.h b/core/src/physics_entity.h index 5fc278b..d1c05d7 100644 --- a/core/src/physics_entity.h +++ b/core/src/physics_entity.h @@ -8,15 +8,17 @@ typedef struct Collision Collision; typedef struct RigidBody RigidBody; +typedef struct PhysicsEntity PhysicsEntity; -typedef struct { +typedef struct IPhysicsEntity { RigidBody* (*const get_rigidbody)(void* self); Shape* (*const get_shape)(void* self); void(*const on_collision)(void* self, Collision collision); + void(*const on_overlap)(void* self, PhysicsEntity other); void(*const collision_solver)(void* self, List* collisions); } IPhysicsEntity; -typedef struct { +typedef struct PhysicsEntity { void* data; IPhysicsEntity const* tc; ITransformable const* transformable; @@ -27,18 +29,20 @@ extern void physics_entity_solve_contacts(PhysicsEntity self, List* contacts); extern void physics_entity_update(PhysicsEntity self); -#define impl_PhysicsEntity_for(T, get_rigidbody_f, get_shape_f, on_collision_f, collision_solver_f)\ +#define impl_PhysicsEntity_for(T, get_rigidbody_f, get_shape_f, on_collision_f, on_overlap_f, collision_solver_f)\ static inline PhysicsEntity T##_as_PhysicsEntity(T* x) {\ TC_FN_TYPECHECK(Transformable, T##_as_Transformable, T*);\ TC_FN_TYPECHECK(RigidBody*, get_rigidbody_f, T*);\ TC_FN_TYPECHECK(Shape*, get_shape_f, T*);\ TC_FN_TYPECHECK(void, on_collision_f, T*, Collision);\ + TC_FN_TYPECHECK(void, on_overlap_f, T*, PhysicsEntity);\ TC_FN_TYPECHECK(void, collision_solver_f, T*, List*);\ static IPhysicsEntity const tc = {\ - .get_rigidbody = (RigidBody*(*const)(void*)) get_rigidbody_f,\ - .get_shape = (Shape*(*const)(void*)) get_shape_f,\ - .on_collision = (void(*const)(void*,Collision)) on_collision_f,\ - .collision_solver = (void(*const)(void*,List*)) collision_solver_f,\ + .get_rigidbody = (RigidBody*(*const)(void*)) get_rigidbody_f,\ + .get_shape = (Shape*(*const)(void*)) get_shape_f,\ + .on_collision = (void(*const)(void*,Collision)) on_collision_f,\ + .on_overlap = (void(*const)(void*,PhysicsEntity)) on_overlap_f\ + .collision_solver = (void(*const)(void*,List*)) collision_solver_f,\ };\ Transformable transformable = T##_as_Transformable(x);\ return (PhysicsEntity){.data = x, .tc = &tc, .transformable = transformable.tc};\ diff --git a/core/src/rigidbody.c b/core/src/rigidbody.c index 09b1c87..1749f22 100644 --- a/core/src/rigidbody.c +++ b/core/src/rigidbody.c @@ -9,7 +9,6 @@ struct RigidBody { Transformable transformable; float mass; - float bounce; Vector last_linear_force; @@ -17,7 +16,10 @@ struct RigidBody { Vector linear_velocity; Transform internal_transform; - int is_static; + PhysicsMask layers; + PhysicsMask collision_mask; + + int overlap; List contacts; }; @@ -36,7 +38,11 @@ RigidBody* rigidbody_make(Transformable transform) { .internal_transform = *transform.tc->get_transform(transform.data), - .is_static = 0, + .layers = 0x1, + .collision_mask = 0x1, + + .overlap = 0, + .contacts = list_from_type(Contact), }; return self; @@ -129,12 +135,28 @@ void rigidbody_accelerate(RigidBody* self, Vector force, int use_mass) { self->next_linear_force = vaddf(self->next_linear_force, force); } -int rigidbody_is_static(const RigidBody* self) { - return self->is_static; +PhysicsMask rigidbody_get_layers(RigidBody* self) { + return self->layers; } -void rigidbody_set_static(RigidBody* self, int is_static) { - self->is_static = is_static; +void rigidbody_set_layers(RigidBody* self, PhysicsMask layers) { + self->layers = layers; +} + +PhysicsMask rigidbody_get_collision_mask(RigidBody* self) { + return self->collision_mask; +} + +void rigidbody_set_collision_mask(RigidBody* self, PhysicsMask mask) { + self->collision_mask = mask; +} + +int rigidbody_get_overlap(RigidBody* self) { + return self->overlap; +} + +void rigidbody_set_overlap(RigidBody* self, int value) { + self->overlap = 1; } Vector rigidbody_get_velocity(const RigidBody* self) { diff --git a/core/src/rigidbody.h b/core/src/rigidbody.h index 74e5ba5..c954c3c 100644 --- a/core/src/rigidbody.h +++ b/core/src/rigidbody.h @@ -5,13 +5,19 @@ #include "transformable.h" #include "list.h" #include "collision.h" +#include "stdint.h" + +typedef uint32_t PhysicsMask; struct Collision; typedef struct { struct Collision hit; float duration; } Contact; + typedef struct RigidBody RigidBody; +typedef struct PhysicsEntity PhysicsEntity; + typedef void (*CollisionHandlerFn)(void* obj, List* collisions); // Referenced transform is stored but not owned by the rigidbody. @@ -33,8 +39,14 @@ extern void rigidbody_set_bounce(RigidBody* self, float bounce); extern void rigidbody_add_impulse(RigidBody* self, Vector force, int use_mass); extern void rigidbody_accelerate(RigidBody* self, Vector force, int use_mass); -extern int rigidbody_is_static(const RigidBody* self); -extern void rigidbody_set_static(RigidBody* self, int is_static); +extern PhysicsMask rigidbody_get_layers(RigidBody* self); +extern void rigidbody_set_layers(RigidBody* self, PhysicsMask layers); + +extern PhysicsMask rigidbody_get_collision_mask(RigidBody* self); +extern void rigidbody_set_collision_mask(RigidBody* self, PhysicsMask mask); + +extern int rigidbody_get_overlap(RigidBody* self); +extern void rigidbody_set_overlap(RigidBody* self, int value); extern Vector rigidbody_get_velocity(const RigidBody* self); extern void rigidbody_set_velocity(RigidBody* self, Vector velocity);