skip redundant manifold based on manifold iteration
This commit is contained in:
parent
5593db5202
commit
1f0c8964d0
26
src/common.h
26
src/common.h
@ -205,18 +205,18 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
|
||||
# define READONLY __declspec(allocate(".rdata"))
|
||||
# endif
|
||||
#elif PLATFORM_MAC
|
||||
#define READONLY __attribute((section("__TEXT,__const")))
|
||||
# define READONLY __attribute((section("__TEXT,__const")))
|
||||
#else
|
||||
#define READONLY __attribute((section(".rodata")))
|
||||
# define READONLY __attribute((section(".rodata")))
|
||||
#endif
|
||||
|
||||
/* Markup */
|
||||
#define UNUSED void
|
||||
|
||||
#if COMPILER_CLANG
|
||||
#define FALLTHROUGH __attribute((fallthrough))
|
||||
# define FALLTHROUGH __attribute((fallthrough))
|
||||
#else
|
||||
#define FALLTHROUGH
|
||||
# define FALLTHROUGH
|
||||
#endif
|
||||
|
||||
/* Sizes */
|
||||
@ -226,15 +226,14 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
|
||||
#define TERABYTE(n) (n*GIGABYTE(1024ULL))
|
||||
|
||||
/* typeof */
|
||||
|
||||
#if COMPILER_MSVC
|
||||
/* Typeof not supported in MSVC */
|
||||
# define typeof(type) ASSERT(false)
|
||||
# define TYPEOF_DEFINED 0
|
||||
# define typeof(type) ASSERT(false)
|
||||
#else
|
||||
# if LANGUAGE_CPP || (__STDC_VERSION__ < 202311L)
|
||||
# define TYPEOF_DEFINED 1
|
||||
# if LANGUAGE_CPP || (__STDC_VERSION__ < 202311L)
|
||||
# define typeof(type) __typeof__(type)
|
||||
# define TYPEOF_DEFINED 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -307,17 +306,6 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
|
||||
#define STRINGIZE2(x) #x
|
||||
#define STRINGIZE(x) STRINGIZE2(x)
|
||||
|
||||
|
||||
#if 0
|
||||
/* ========================== *
|
||||
* Bit utils
|
||||
* ========================== */
|
||||
|
||||
#define bit_set(i, mask) (i |= mask)
|
||||
#define bit_clear(i, mask) (i &= ~mask)
|
||||
#define bit_flip(i, mask) (i ^= mask)
|
||||
#endif
|
||||
|
||||
/* ========================== *
|
||||
* Primitive types
|
||||
* ========================== */
|
||||
|
||||
@ -132,6 +132,7 @@ struct entity {
|
||||
struct entity_handle manifold_e0;
|
||||
struct entity_handle manifold_e1;
|
||||
struct v2 manifold_normal; /* Normal vector of collision from e0 -> e1 */
|
||||
u64 last_manifold_iteration;
|
||||
struct contact contacts[2];
|
||||
u32 num_contacts;
|
||||
|
||||
|
||||
73
src/game.c
73
src/game.c
@ -246,6 +246,10 @@ INTERNAL void spawn_test_entities(void)
|
||||
|
||||
INTERNAL void create_contact_manifolds(void)
|
||||
{
|
||||
/* TODO: Remove this */
|
||||
static u64 manifold_iteration = 0;
|
||||
++manifold_iteration;
|
||||
|
||||
struct entity_store *store = G.tick.entity_store;
|
||||
struct sprite_scope *sprite_frame_scope = G.sprite_frame_scope;
|
||||
struct entity *root = G.root;
|
||||
@ -253,8 +257,8 @@ INTERNAL void create_contact_manifolds(void)
|
||||
struct entity *e0 = &store->entities[e0_index];
|
||||
if (!(e0->valid && entity_has_prop(e0, ENTITY_PROP_ACTIVE))) continue;
|
||||
if (!entity_has_prop(e0, ENTITY_PROP_PHYSICAL)) continue;
|
||||
if (!entity_has_prop(e0, ENTITY_PROP_PLAYER_CONTROLLED) && !entity_has_prop(e0, ENTITY_PROP_BULLET)) continue;
|
||||
|
||||
/* Calculate entity 0 shape */
|
||||
struct xform e0_xf = entity_get_xform(e0);
|
||||
struct quad e0_quad;
|
||||
struct v2_array e0_poly;
|
||||
@ -274,8 +278,41 @@ INTERNAL void create_contact_manifolds(void)
|
||||
if (e1 == e0) continue;
|
||||
if (!(e1->valid && entity_has_prop(e1, ENTITY_PROP_ACTIVE))) continue;
|
||||
if (!entity_has_prop(e1, ENTITY_PROP_PHYSICAL)) continue;
|
||||
if (entity_has_prop(e1, ENTITY_PROP_PLAYER_CONTROLLED)) continue;
|
||||
|
||||
/* TODO: Remove this */
|
||||
static struct arena dict_arena = ZI;
|
||||
static struct fixed_dict dict = ZI;
|
||||
if (dict.buckets_count == 0) {
|
||||
dict_arena = arena_alloc(GIGABYTE(64));
|
||||
dict = fixed_dict_init(&dict_arena, 4096);
|
||||
}
|
||||
|
||||
/* Retrieve manifold */
|
||||
u64 manifold_hash;
|
||||
struct string manifold_key;
|
||||
{
|
||||
struct entity_handle h0 = e0->handle;
|
||||
struct entity_handle h1 = e1->handle;
|
||||
if (h0.idx > h1.idx) {
|
||||
h0 = e1->handle;
|
||||
h1 = e0->handle;
|
||||
}
|
||||
manifold_hash = hash_fnv64(HASH_FNV64_BASIS, BUFFER_FROM_STRUCT(&h0));
|
||||
manifold_hash = hash_fnv64(manifold_hash, BUFFER_FROM_STRUCT(&h1));
|
||||
manifold_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&manifold_hash));
|
||||
}
|
||||
struct entity *manifold = fixed_dict_get(&dict, manifold_key);
|
||||
|
||||
/* Ensure manifold hasn't already been computed this iteration */
|
||||
if (manifold) {
|
||||
if (manifold->last_manifold_iteration == manifold_iteration) {
|
||||
/* Already iterated this manifold from The other entity's perspective, skip */
|
||||
continue;
|
||||
}
|
||||
manifold->last_manifold_iteration = manifold_iteration;
|
||||
}
|
||||
|
||||
/* Calculate entity 1 shape */
|
||||
struct xform e1_xf = entity_get_xform(e1);
|
||||
struct quad e1_quad;
|
||||
struct v2_array e1_poly;
|
||||
@ -290,29 +327,6 @@ INTERNAL void create_contact_manifolds(void)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Remove this */
|
||||
static struct arena dict_arena = ZI;
|
||||
static struct fixed_dict dict = ZI;
|
||||
if (dict.buckets_count == 0) {
|
||||
dict_arena = arena_alloc(GIGABYTE(64));
|
||||
dict = fixed_dict_init(&dict_arena, 4096);
|
||||
}
|
||||
|
||||
u64 manifold_hash;
|
||||
struct string manifold_key;
|
||||
{
|
||||
manifold_hash = hash_fnv64(HASH_FNV64_BASIS, BUFFER_FROM_STRUCT(&e0->handle));
|
||||
/* FIXME: Contact should be same regardless of entity order */
|
||||
manifold_hash = hash_fnv64(manifold_hash, BUFFER_FROM_STRUCT(&e1->handle));
|
||||
manifold_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&manifold_hash));
|
||||
}
|
||||
|
||||
struct entity *manifold = fixed_dict_get(&dict, manifold_key);
|
||||
|
||||
|
||||
|
||||
|
||||
#if 1
|
||||
const f32 remove_contact_threshold_global_dist_sq = 0.005f * 0.005f;
|
||||
const f32 insert_contact_threshold_global_dist_sq = 0.005f * 0.005f;
|
||||
@ -321,8 +335,6 @@ INTERNAL void create_contact_manifolds(void)
|
||||
const f32 insert_contact_threshold_global_dist_sq = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
struct gjk_contact_points_result res = gjk_contact_points(e0_poly, e1_poly);
|
||||
if (res.num_pairs > 0) {
|
||||
if (!manifold) {
|
||||
@ -337,19 +349,12 @@ INTERNAL void create_contact_manifolds(void)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* TODO: Remove this (debugging) */
|
||||
manifold->prototype = res.prototype;
|
||||
manifold->simplex = res.simplex;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Update contact depths, and remove contacts that are no longer penetrating or have drifted too far from original position */
|
||||
struct v2 old_normal = manifold->manifold_normal;
|
||||
for (i32 j = 0; j < (i32)manifold->num_contacts; ++j) {
|
||||
|
||||
10
src/gjk.c
10
src/gjk.c
@ -34,6 +34,8 @@ b32 gjk_boolean(struct v2_array shape0, struct v2_array shape1)
|
||||
{
|
||||
struct { struct v2 a, b, c; } s = ZI;
|
||||
|
||||
/* FIXME: Infinite loop when shapes exactly overlap same space */
|
||||
|
||||
/* First point is support point in shape's general directions to eachother */
|
||||
s.a = menkowski_point(shape0, shape1, v2_sub(shape1.points[0], shape0.points[0]));
|
||||
|
||||
@ -187,6 +189,8 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
||||
* ========================== */
|
||||
|
||||
{
|
||||
/* FIXME: Collision is false when 2 shapes exactly overlap */
|
||||
|
||||
/* First point is support point in shape's general directions to eachother */
|
||||
s.a = menkowski_point_extended(shape0, shape1, v2_sub(shape1.points[0], shape0.points[0]));
|
||||
s.len = 1;
|
||||
@ -194,7 +198,7 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
||||
/* Second point is support point towards origin */
|
||||
dir = v2_neg(s.a.p);
|
||||
m = menkowski_point_extended(shape0, shape1, dir);
|
||||
if (v2_dot(dir, m.p) >= 0) {
|
||||
if (v2_dot(dir, m.p) > 0) {
|
||||
s.b = s.a;
|
||||
s.a = m;
|
||||
s.len = 2;
|
||||
@ -217,13 +221,13 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
||||
struct v2 a_to_origin = v2_neg(s.a.p);
|
||||
|
||||
dir = v2_perp_towards_dir(vab, v2_neg(vac)); /* Normal of ab pointing away from c */
|
||||
if (v2_dot(dir, a_to_origin) >= 0) {
|
||||
if (v2_dot(dir, a_to_origin) > 0) {
|
||||
/* Point is in region ab, remove c from simplex */
|
||||
s.len = 2;
|
||||
} else {
|
||||
/* Point is not in region ab */
|
||||
dir = v2_perp_towards_dir(vac, v2_neg(vab)); /* Normal of ac pointing away from b */
|
||||
if (v2_dot(dir, a_to_origin) >= 0) {
|
||||
if (v2_dot(dir, a_to_origin) > 0) {
|
||||
/* Point is in region ac, remove b from simplex */
|
||||
s.b = s.c;
|
||||
s.len = 2;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user