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);
|
List* contacts = rigidbody_get_contacts(body);
|
||||||
if(contacts->len > 0) {
|
if(contacts->len > 0) {
|
||||||
self.tc->collision_solver(self.data, contacts);
|
if(rigidbody_get_overlap(body)) {
|
||||||
list_foreach(Contact*, contact, contacts)
|
list_foreach(Contact*, contact, contacts)
|
||||||
self.tc->on_collision(self.data, contact->hit);
|
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);
|
rigidbody_collect_contacts(body);
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,17 @@
|
||||||
|
|
||||||
typedef struct Collision Collision;
|
typedef struct Collision Collision;
|
||||||
typedef struct RigidBody RigidBody;
|
typedef struct RigidBody RigidBody;
|
||||||
|
typedef struct PhysicsEntity PhysicsEntity;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct IPhysicsEntity {
|
||||||
RigidBody* (*const get_rigidbody)(void* self);
|
RigidBody* (*const get_rigidbody)(void* self);
|
||||||
Shape* (*const get_shape)(void* self);
|
Shape* (*const get_shape)(void* self);
|
||||||
void(*const on_collision)(void* self, Collision collision);
|
void(*const on_collision)(void* self, Collision collision);
|
||||||
|
void(*const on_overlap)(void* self, PhysicsEntity other);
|
||||||
void(*const collision_solver)(void* self, List* collisions);
|
void(*const collision_solver)(void* self, List* collisions);
|
||||||
} IPhysicsEntity;
|
} IPhysicsEntity;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct PhysicsEntity {
|
||||||
void* data;
|
void* data;
|
||||||
IPhysicsEntity const* tc;
|
IPhysicsEntity const* tc;
|
||||||
ITransformable const* transformable;
|
ITransformable const* transformable;
|
||||||
|
@ -27,18 +29,20 @@ extern void physics_entity_solve_contacts(PhysicsEntity self, List* contacts);
|
||||||
extern void physics_entity_update(PhysicsEntity self);
|
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) {\
|
static inline PhysicsEntity T##_as_PhysicsEntity(T* x) {\
|
||||||
TC_FN_TYPECHECK(Transformable, T##_as_Transformable, T*);\
|
TC_FN_TYPECHECK(Transformable, T##_as_Transformable, T*);\
|
||||||
TC_FN_TYPECHECK(RigidBody*, get_rigidbody_f, T*);\
|
TC_FN_TYPECHECK(RigidBody*, get_rigidbody_f, T*);\
|
||||||
TC_FN_TYPECHECK(Shape*, get_shape_f, T*);\
|
TC_FN_TYPECHECK(Shape*, get_shape_f, T*);\
|
||||||
TC_FN_TYPECHECK(void, on_collision_f, T*, Collision);\
|
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*);\
|
TC_FN_TYPECHECK(void, collision_solver_f, T*, List*);\
|
||||||
static IPhysicsEntity const tc = {\
|
static IPhysicsEntity const tc = {\
|
||||||
.get_rigidbody = (RigidBody*(*const)(void*)) get_rigidbody_f,\
|
.get_rigidbody = (RigidBody*(*const)(void*)) get_rigidbody_f,\
|
||||||
.get_shape = (Shape*(*const)(void*)) get_shape_f,\
|
.get_shape = (Shape*(*const)(void*)) get_shape_f,\
|
||||||
.on_collision = (void(*const)(void*,Collision)) on_collision_f,\
|
.on_collision = (void(*const)(void*,Collision)) on_collision_f,\
|
||||||
.collision_solver = (void(*const)(void*,List*)) collision_solver_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);\
|
Transformable transformable = T##_as_Transformable(x);\
|
||||||
return (PhysicsEntity){.data = x, .tc = &tc, .transformable = transformable.tc};\
|
return (PhysicsEntity){.data = x, .tc = &tc, .transformable = transformable.tc};\
|
||||||
|
|
|
@ -9,7 +9,6 @@ struct RigidBody {
|
||||||
Transformable transformable;
|
Transformable transformable;
|
||||||
|
|
||||||
float mass;
|
float mass;
|
||||||
|
|
||||||
float bounce;
|
float bounce;
|
||||||
|
|
||||||
Vector last_linear_force;
|
Vector last_linear_force;
|
||||||
|
@ -17,7 +16,10 @@ struct RigidBody {
|
||||||
Vector linear_velocity;
|
Vector linear_velocity;
|
||||||
Transform internal_transform;
|
Transform internal_transform;
|
||||||
|
|
||||||
int is_static;
|
PhysicsMask layers;
|
||||||
|
PhysicsMask collision_mask;
|
||||||
|
|
||||||
|
int overlap;
|
||||||
|
|
||||||
List contacts;
|
List contacts;
|
||||||
};
|
};
|
||||||
|
@ -36,7 +38,11 @@ RigidBody* rigidbody_make(Transformable transform) {
|
||||||
|
|
||||||
.internal_transform = *transform.tc->get_transform(transform.data),
|
.internal_transform = *transform.tc->get_transform(transform.data),
|
||||||
|
|
||||||
.is_static = 0,
|
.layers = 0x1,
|
||||||
|
.collision_mask = 0x1,
|
||||||
|
|
||||||
|
.overlap = 0,
|
||||||
|
|
||||||
.contacts = list_from_type(Contact),
|
.contacts = list_from_type(Contact),
|
||||||
};
|
};
|
||||||
return self;
|
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);
|
self->next_linear_force = vaddf(self->next_linear_force, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rigidbody_is_static(const RigidBody* self) {
|
PhysicsMask rigidbody_get_layers(RigidBody* self) {
|
||||||
return self->is_static;
|
return self->layers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rigidbody_set_static(RigidBody* self, int is_static) {
|
void rigidbody_set_layers(RigidBody* self, PhysicsMask layers) {
|
||||||
self->is_static = is_static;
|
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) {
|
Vector rigidbody_get_velocity(const RigidBody* self) {
|
||||||
|
|
|
@ -5,13 +5,19 @@
|
||||||
#include "transformable.h"
|
#include "transformable.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "collision.h"
|
#include "collision.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
typedef uint32_t PhysicsMask;
|
||||||
|
|
||||||
struct Collision;
|
struct Collision;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct Collision hit;
|
struct Collision hit;
|
||||||
float duration;
|
float duration;
|
||||||
} Contact;
|
} Contact;
|
||||||
|
|
||||||
typedef struct RigidBody RigidBody;
|
typedef struct RigidBody RigidBody;
|
||||||
|
typedef struct PhysicsEntity PhysicsEntity;
|
||||||
|
|
||||||
typedef void (*CollisionHandlerFn)(void* obj, List* collisions);
|
typedef void (*CollisionHandlerFn)(void* obj, List* collisions);
|
||||||
|
|
||||||
// Referenced transform is stored but not owned by the rigidbody.
|
// 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_add_impulse(RigidBody* self, Vector force, int use_mass);
|
||||||
extern void rigidbody_accelerate(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 PhysicsMask rigidbody_get_layers(RigidBody* self);
|
||||||
extern void rigidbody_set_static(RigidBody* self, int is_static);
|
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 Vector rigidbody_get_velocity(const RigidBody* self);
|
||||||
extern void rigidbody_set_velocity(RigidBody* self, Vector velocity);
|
extern void rigidbody_set_velocity(RigidBody* self, Vector velocity);
|
||||||
|
|
Loading…
Reference in a new issue