mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-29 00:00:38 +01:00
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%.
59 lines
1.7 KiB
C
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);
|
|
}
|