Files
Cesarus85--mjolnir-vr/port/linux/game/object_bounds_cache.c
T
Addison Bair 04713926d1 Pass over far objects on a packed copy of their bounding spheres
A collision query (collision_get_features_in_sphere) reads the bounding
sphere of every collideable object in every cluster it touches, to pass
over the far ones. Every biped queries each tick, so a crowded cluster
(co-op's extra enemies, a carrier burst) costs the square of the crowd in
scattered object reads.

object_bounds_cache.c keeps the spheres packed by absolute index, written
by their only writer (object_compute_node_matrices). The loop runs the same
point_in_sphere on the copy, so the same objects are passed over and the
same features gathered, in order. game_state.c invalidates the copy when
the game state is replaced (revert, loaded core or game, new map).

Deterministic offline crowd (c20, legendary, extra enemies x8, 24 carriers
burst, seed pinned): game state identical tick for tick; collision queries
4.2 -> 3.0 us (-28%), object updates -15%.
2026-10-07 22:11:47 +00:00

59 lines
1.7 KiB
C

/*
OBJECT_BOUNDS_CACHE.C
The objects' bounding spheres packed by absolute index, so collision's object
loop (collisions.c) passes over the far objects of a crowded cluster without
reading each one. Written by their only writer (object_compute_node_matrices);
an entry counts only for its datum index and until the game state is next
replaced (game_state.c). The same test on the same values: the features
gathered do not change. (Kept out of the game state, whose layout the saved
games share.)
*/
#include "cseries.h"
#include "math/real_math.h"
#include "objects/objects.h"
struct object_bounds
{
long object_index;
long epoch;
real_point3d center;
real radius;
};
static struct object_bounds object_bounds[MAXIMUM_OBJECTS_PER_MAP];
static long object_bounds_epoch = 1;
void object_bounds_cache_update(
long object_index,
real_point3d const *center,
real radius)
{
struct object_bounds *bounds = &object_bounds[DATUM_INDEX_TO_ABSOLUTE_INDEX(object_index)];
bounds->object_index = object_index;
bounds->epoch = object_bounds_epoch;
bounds->center = *center;
bounds->radius = radius;
}
void object_bounds_cache_invalidate(
void)
{
object_bounds_epoch++;
}
/* whether the object's bounding sphere is known to be out of the reach of
the point (collision's own test on the copy); FALSE when it is not known */
boolean object_bounds_cache_out_of_reach(
long object_index,
real_point3d const *point,
real radius)
{
struct object_bounds const *bounds = &object_bounds[DATUM_INDEX_TO_ABSOLUTE_INDEX(object_index)];
return bounds->object_index == object_index && bounds->epoch == object_bounds_epoch &&
!point_in_sphere(point, &bounds->center, bounds->radius + radius);
}