feat(physics): physics entity now supports overlap
This commit is contained in:
parent
27d6c7e0d7
commit
e7e952e57d
|
@ -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);
|
||||
|
||||
|
|
|
@ -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};\
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue