diff options
| author | esquizo <esquizo+noreply@esquizo.net> | 2026-05-31 18:34:27 -0300 |
|---|---|---|
| committer | esquizo <esquizo+noreply@esquizo.net> | 2026-05-31 18:34:27 -0300 |
| commit | 0f7d5def595f9b3472aaf70b36f9a9894f882922 (patch) | |
| tree | da640759fa1513ea18971ec5e747c5dee7390767 | |
| parent | 86e64f00ad1452c0a2e528d37d169b8eb125e299 (diff) | |
libphysics: funções de broadphase
| -rw-r--r-- | libphysics/blockmap.c | 66 | ||||
| -rw-r--r-- | libphysics/dat.h | 5 | ||||
| -rw-r--r-- | libphysics/tick.c | 66 |
3 files changed, 81 insertions, 56 deletions
diff --git a/libphysics/blockmap.c b/libphysics/blockmap.c index 7f02b1a..26af021 100644 --- a/libphysics/blockmap.c +++ b/libphysics/blockmap.c @@ -13,15 +13,46 @@ #define PHI 1.618033988749895 #define HMUL (int)(BUCKETS / PHI) +#define LENGTH(X) (sizeof (X) / sizeof (X)[0]) + static int hash(int a); static void makeblockmap(Body *b); +static void enqueuetest(TestCollision *t); +static void bodycollisionmap(Body *); +static void bodycollisionmapsub(Body *, BlockmapNode *); static BlockmapNode *allocnode(void); +static void phxmakeblkmap(void); +static BlockmapNode *phxnodelist(float x, float y); + static BlockmapNode nodes[(1 << 20)]; static int nodesi; static BlockmapNode *lists[BUCKETS]; +static TestCollision testcollision[0x1000]; +static int testcollisioncount; + +void +__phxbroadphasereset(void) +{ + static int count = 0; + if(count == 0) + phxmakeblkmap(); + count = (count + 1) % 4; +} + +void +__phxbroadphase(int n, BodyID bid[n]) +{ + testcollisioncount = 0; + for(int i = 0; i < n; i++) { + Body *b = phxbodypool + bid[i]; + bodycollisionmap(b); + } + __phxnarrowphase(testcollisioncount, testcollision); +} + void phxmakeblkmap() { @@ -78,3 +109,38 @@ phxnodelist(float x, float y) int h = hash(mapx + hash(mapy)); return lists[h]; } + +void +bodycollisionmap(Body *a) +{ + for(int y = -1; y <= 1; y++) + for(int x = -1; x <= 1; x++) { + bodycollisionmapsub(a, phxnodelist( + a->pos[0] + x * BLOCK_SIZE, + a->pos[1] + y * BLOCK_SIZE + )); + } +} + +void +bodycollisionmapsub(Body *a, BlockmapNode *n) +{ + while(n) { + Body *b = phxbodypool + n->id; + enqueuetest(&(TestCollision) { + .a = a - phxbodypool, + .b = b - phxbodypool + }); + n = n->next; + } +} + +void +enqueuetest(TestCollision *t) +{ + testcollision[testcollisioncount++] = *t; + if(testcollisioncount >= LENGTH(testcollision)) { + __phxnarrowphase(testcollisioncount, testcollision); + testcollisioncount = 0; + } +} diff --git a/libphysics/dat.h b/libphysics/dat.h index da858c3..035bdcc 100644 --- a/libphysics/dat.h +++ b/libphysics/dat.h @@ -30,9 +30,8 @@ void phxaabbresolv(Body *a, Body *b, vec2 p, vec2 n); int phxenqevent(CollisionEvent *ev); int phxdeqevent(CollisionEvent *ev); -void phxmakeblkmap(void); -BlockmapNode *phxnodelist(float x, float y); - +void __phxbroadphasereset(void); +void __phxbroadphase(int n, BodyID bid[n]); void __phxnarrowphase(int n, TestCollision coll[n]); extern int phxmapwidth, phxmapheight; diff --git a/libphysics/tick.c b/libphysics/tick.c index 3ba60f8..dbc5f27 100644 --- a/libphysics/tick.c +++ b/libphysics/tick.c @@ -5,7 +5,8 @@ #include "dat.h" #define TILE_SIZE 16 -#define TEST_BUFFER_SIZE 0x10000 + +#define LENGTH(X) (sizeof (X) / sizeof (X)[0]) static void tick(void); static void mapcollision(Body *); @@ -14,10 +15,9 @@ static void bodycollision(Body *); static void bodycollisionmap(Body *); static void bodycollisionmapsub(Body *, BlockmapNode *); -static void enqueuetest(TestCollision *t); +static BodyID bids[0x10000]; +static int bidsi; -static TestCollision testcollision[TEST_BUFFER_SIZE]; -static int testcollisioncount; void phxtick(float delta) @@ -59,13 +59,6 @@ phxfixtick(void) void tick(void) { - static int count = 0; - - if(!count) { - phxmakeblkmap(); - } - count = (count + 1) % 4; - for(int i = 0; i < phxbodypoolsize; i++) { Body *b = phxbodypool + i; if(!b->active) @@ -74,21 +67,21 @@ tick(void) vec2_add_scaled(b->vel, b->vel, b->accel, PHX_TICK_TIME); } + __phxbroadphasereset(); + bidsi = 0; for(int i = 0; i < phxbodypoolsize; i++) { Body *b = phxbodypool + i; if(!b->active) continue; - mapcollision(b); - } - testcollisioncount = 0; - for(int i = 0; i < phxbodypoolsize; i++) { - Body *b = phxbodypool + i; - if(!b->active) - continue; - bodycollisionmap(b); + mapcollision(b); + bids[bidsi++] = i; + if(bidsi >= LENGTH(bids)) { + __phxbroadphase(bidsi, bids); + bidsi = 0; + } } - __phxnarrowphase(testcollisioncount, testcollision); + __phxbroadphase(bidsi, bids); for(int i = 0; i < phxbodypoolsize; i++) { Body *b = phxbodypool + i; @@ -145,38 +138,5 @@ mapcollision(Body *a) } } -void -bodycollisionmap(Body *a) -{ - for(int y = -1; y <= 1; y++) - for(int x = -1; x <= 1; x++) { - bodycollisionmapsub(a, phxnodelist( - a->pos[0] + x * BLOCK_SIZE, - a->pos[1] + y * BLOCK_SIZE - )); - } -} - -void -bodycollisionmapsub(Body *a, BlockmapNode *n) -{ - while(n) { - Body *b = phxbodypool + n->id; - enqueuetest(&(TestCollision) { - .a = a - phxbodypool, - .b = b - phxbodypool - }); - n = n->next; - } -} -void -enqueuetest(TestCollision *t) -{ - testcollision[testcollisioncount++] = *t; - if(testcollisioncount >= TEST_BUFFER_SIZE) { - __phxnarrowphase(testcollisioncount, testcollision); - testcollisioncount = 0; - } -} |
