193 lines
5.3 KiB
C
193 lines
5.3 KiB
C
|
|
||
|
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;
|
||
|
}
|