optimize collision detection
This commit is contained in:
parent
9c0287fbc4
commit
0fd05c5aea
|
@ -155,6 +155,9 @@ struct game {
|
|||
struct element_mirror *mirror;
|
||||
struct element_plane *plane;
|
||||
struct element_text *text;
|
||||
/* A dynamic plane y value; mostly redundant from plane->y, used to optimize
|
||||
away some checks during collisions with the plane */
|
||||
num plane_collision[2];
|
||||
|
||||
/* Distance traversed within the current level */
|
||||
num depth;
|
||||
|
|
15
src/main.cc
15
src/main.cc
|
@ -459,6 +459,19 @@ int game_update(struct game *g, bool *debug)
|
|||
game_next_level_or_menu(g);
|
||||
}
|
||||
|
||||
// Pre-compute plane collision info
|
||||
|
||||
num pc = g->plane ? g->plane->y - g->depth : num(0x7fff);
|
||||
|
||||
if(g->plane->type == ELEMENT_PLANE_INVIS) {
|
||||
g->plane_collision[0] = num(0x7fff);
|
||||
g->plane_collision[1] = pc;
|
||||
}
|
||||
else {
|
||||
g->plane_collision[0] = pc;
|
||||
g->plane_collision[1] = pc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -504,6 +517,8 @@ int main(void)
|
|||
g.blank_frames = 0;
|
||||
g.neon_position = 0;
|
||||
g.neon_period = 64;
|
||||
g.plane_collision[0] = num(0x7fff);
|
||||
g.plane_collision[1] = num(0x7fff);
|
||||
game_load_menu(&g);
|
||||
game = &g;
|
||||
|
||||
|
|
|
@ -79,16 +79,16 @@ static int cast_ray(struct game const *g, svec3 const &origin,
|
|||
|
||||
if(hitz && (!hitx || (tz_rx_rz < tx_rx_rz) ^ rx_rz_sign)) {
|
||||
if(hitz == TOP)
|
||||
*t = num16::div_positive(num16(WORLD_SIZE) - origin.z, rayDir.z);
|
||||
*t = (num16(WORLD_SIZE) - origin.z) / rayDir.z;
|
||||
else
|
||||
*t = num16::div_positive(origin.z + num16(WORLD_SIZE), -rayDir.z);
|
||||
*t = (origin.z + num16(WORLD_SIZE)) / -rayDir.z;
|
||||
hit = hitz;
|
||||
}
|
||||
else if(__builtin_expect(hitx, 1)) {
|
||||
if(hitx == RIGHT)
|
||||
*t = num16::div_positive(num16(WORLD_SIZE) - origin.x, rayDir.x);
|
||||
*t = (num16(WORLD_SIZE) - origin.x) / rayDir.x;
|
||||
else
|
||||
*t = num16::div_positive(origin.x + num16(WORLD_SIZE), -rayDir.x);
|
||||
*t = (origin.x + num16(WORLD_SIZE)) / -rayDir.x;
|
||||
hit = hitx;
|
||||
}
|
||||
|
||||
|
@ -101,19 +101,16 @@ static int cast_ray(struct game const *g, svec3 const &origin,
|
|||
|
||||
/* Determine if there is an intersection with the object plane */
|
||||
|
||||
if(__builtin_expect(
|
||||
g->plane
|
||||
&& (*collision_y > g->plane->y - g->depth)
|
||||
&& (g->plane->type != ELEMENT_PLANE_INVIS || secondary),
|
||||
0)) {
|
||||
num16 plane_y = num16(g->plane->y - g->depth);
|
||||
num pc = g->plane_collision[secondary];
|
||||
if(__builtin_expect(*collision_y > pc, 0)) {
|
||||
num16 plane_y = num16(pc);
|
||||
num16 plane_t = (plane_y - origin.y) / rayDir.y;
|
||||
num16 plane_x = origin.x + plane_t * rayDir.x;
|
||||
num16 plane_z = origin.z + plane_t * rayDir.z;
|
||||
|
||||
if(level_plane_collides(plane_x, plane_z, g->plane->shape)) {
|
||||
*t = plane_t;
|
||||
*collision_y = g->plane->y - g->depth;
|
||||
*collision_y = pc;
|
||||
return OBJECT_PLANE;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue