summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoresquizo <esquizo+noreply@esquizo.net>2026-05-31 18:34:27 -0300
committeresquizo <esquizo+noreply@esquizo.net>2026-05-31 18:34:27 -0300
commit0f7d5def595f9b3472aaf70b36f9a9894f882922 (patch)
treeda640759fa1513ea18971ec5e747c5dee7390767
parent86e64f00ad1452c0a2e528d37d169b8eb125e299 (diff)
libphysics: funções de broadphase
-rw-r--r--libphysics/blockmap.c66
-rw-r--r--libphysics/dat.h5
-rw-r--r--libphysics/tick.c66
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;
- }
-}