Archived
1
0
Fork 0
This repository has been archived on 2025-09-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
skcblitz/bbox.h

193 lines
5.3 KiB
C
Raw Permalink Normal View History

2025-09-02 14:43:36 +02:00
bbox_t *box_offset_to(bbox_t *aa, bbox_t *bb, double x, double y, double z) {
bb->x1 = aa->x1 + x;
bb->x2 = aa->x2 + x;
bb->y1 = aa->y1 + y;
bb->y2 = aa->y2 + y;
bb->z1 = aa->z1 + z;
bb->z2 = aa->z2 + z;
return bb;
}
bbox_t *box_add_coord(bbox_t *aa, bbox_t *bb, double x, double y, double z) {
if(aa)
AABB_PCOPY(aa, bb);
if(x < 0.0D)
bb->x1 += x;
else if(x > 0.0D)
bb->x2 += x;
if(y < 0.0D)
bb->y1 += y;
else if(y > 0.0D)
bb->y2 += y;
if(z < 0.0D)
bb->z1 += z;
else if(z > 0.0D)
bb->z2 += z;
return bb;
}
bbox_t *box_union(bbox_t *aa, bbox_t *bb, double x, double y, double z) {
if(aa)
AABB_PCOPY(aa, bb);
bb->x1 = MIN_VALUE(bb->x1, x);
bb->y1 = MIN_VALUE(bb->y1, y);
bb->z1 = MIN_VALUE(bb->z1, z);
bb->x2 = MAX_VALUE(bb->x2, x);
bb->y2 = MAX_VALUE(bb->y2, y);
bb->z2 = MAX_VALUE(bb->z2, z);
return bb;
}
#define BOX_OFFSET_FUNC(cc, cd, ce) \
double box_calc_ ## cc ## off(bbox_t *aa, bbox_t *bb, double offset) { \
if(bb->cd ## 2 > aa->cd ## 1 && bb->cd ## 1 < aa->cd ## 2 && bb->ce ## 2 > aa->ce ## 1 && bb->ce ## 1 < aa->ce ## 2) { \
if(offset > 0.0 && bb->cc ## 2 <= aa->cc ## 1) { \
double pdelta = aa->cc ## 1 - bb->cc ## 2; \
if(pdelta < offset) \
offset = pdelta; \
} \
else if(offset < 0.0 && bb->cc ## 1 >= aa->cc ## 2) { \
double ndelta = aa->cc ## 2 - bb->cc ## 1; \
if(ndelta > offset) \
offset = ndelta; \
} \
return offset; \
} \
else { \
return offset; \
} \
}
BOX_OFFSET_FUNC(x, y, z)
BOX_OFFSET_FUNC(y, x, z)
BOX_OFFSET_FUNC(z, x, y)
byte box_intersects(bbox_t *aa, bbox_t *bb) {
return bb->x2 > aa->x1 && bb->x1 < aa->x2 && bb->y2 > aa->y1 && bb->y1 < aa->y2 && bb->z2 > aa->z1 && bb->z1 < aa->z2;
}
chunk_t *chunk_get(world_t *world, int x, int y, int z, byte load);
int box_get_colliding(world_t *world, bbox_t **listptr, bbox_t *box) {
bbox_t *list = sys.collision_list;
int x1 = ((int)(double)(box->x1 + (box->x2 - box->x1) / 2.0)) / CHUNK_SIZE;
int y1 = ((int)(double)(box->y1 + (box->y2 - box->y1) / 2.0)) / CHUNK_SIZE;
int z1 = ((int)(double)(box->z1 + (box->z2 - box->z1) / 2.0)) / CHUNK_SIZE;
int x2 = x1 + 2;
int y2 = y1 + 2;
int z2 = z1 + 2;
x1 -= 2;
y1 -= 2;
z1 -= 2;
// x1 = CHUNK_CLAMP(world, x1, x);
// y1 = CHUNK_CLAMP(world, y1, y);
// z1 = CHUNK_CLAMP(world, z1, z);
// x2 = CHUNK_CLAMP(world, x2, x);
// y2 = CHUNK_CLAMP(world, y2, y);
// z2 = CHUNK_CLAMP(world, z2, z);
int boxes = 0;
ulong pos = 0;
chunk_t *chunk; // = &world->global;
geometry_t **gptr;
geometry_t *geom;
if(listptr)
*listptr = list;
while(gptr = tbl_iter(&world->global_geom, &pos)) {
geom = *gptr;
if(box_intersects(&geom->collision, box)) {
list[boxes++] = geom->collision;
if(boxes == COLL_MAX)
return boxes;
}
}
for(int cx = x1; cx <= x2; cx++) {
for(int cz = z1; cz <= z2; cz++) {
for(int cy = y1; cy <= y2; cy++) {
if(!(chunk = chunk_get(world, cx, cy, cz, 0)))
continue;
pos = 0;
while(geom = tbl_iter(&chunk->obj_table, &pos)) {
if(!geom->global && box_intersects(&geom->collision, box)) {
list[boxes++] = geom->collision;
if(boxes == COLL_MAX)
return boxes;
}
}
}
}
}
return boxes;
}
byte box_check_intersect(vec3 origin, vec3 dir, chunk_t *chunk, polygon_t *poly, float *dist) {
vec3 vects[3];
for(int n = 0; n < 3; n++) {
VEC3_SET(vects[n], poly->vertices[n].pos X + (float)chunk->box.x1, poly->vertices[n].pos Y + (float)chunk->box.y1,
poly->vertices[n].pos Z + (float)chunk->box.z1);
}
return glm_ray_triangle(origin, dir, vects[0], vects[1], vects[2], dist);
}
ulong box_get_pointed(world_t *world, camera_t *cam, vec3 pos) {
vec3 origin;
ulong iter = 0;
ulong id = 0;
float dist;
float mdist = 1000000.0f;
chunk_t *chunk;
geometry_t **gptr;
geometry_t *geom;
polygon_t *poly;
int x = (int)NEG_OFFSET(cam->pos_x, CHUNK_SIZE);
int y = (int)NEG_OFFSET(cam->pos_y, CHUNK_SIZE);
int z = (int)NEG_OFFSET(cam->pos_z, CHUNK_SIZE);
VEC3_SET(origin, (float)cam->pos_x, (float)cam->pos_y, (float)cam->pos_z);
while(gptr = tbl_iter(&world->global_geom, &iter)) {
geom = *gptr;
if(!(chunk = chunk_get(world, geom->chunk_x, geom->chunk_y, geom->chunk_z, 0)))
continue;
poly = &chunk->poly_pool[geom->polys];
while(poly) {
if(box_check_intersect(origin, cam->front, chunk, poly, &dist) && (dist < mdist)) {
mdist = dist;
id = geom->id;
if(pos) {
glm_vec3_scale(cam->front, dist, pos);
glm_vec3_add(origin, pos, pos);
}
}
poly = (poly->next == 0xffffffff) ? NULL : &chunk->poly_pool[poly->next];
}
}
for(int cx = -1; cx <= 1; cx++) {
for(int cz = -1; cz <= 1; cz++) {
for(int cy = -1; cy <= 1; cy++) {
if(!(chunk = chunk_get(world, x + cx, y + cy, z + cz, 0)))
continue;
iter = 0;
while(geom = tbl_iter(&chunk->obj_table, &iter)) {
if(!geom->global) {
poly = &chunk->poly_pool[geom->polys];
while(poly) {
if(box_check_intersect(origin, cam->front, chunk, poly, &dist) && (dist < mdist)) {
mdist = dist;
id = geom->id;
if(pos) {
glm_vec3_scale(cam->front, dist, pos);
glm_vec3_add(origin, pos, pos);
}
}
poly = (poly->next == 0xffffffff) ? NULL : &chunk->poly_pool[poly->next];
}
}
}
}
}
}
return id;
}