BroadPhase
Generated from engine/collision/broad_phase.h at 862e08b. The text under each declaration is the header's own comment, word for word. About the reference says how these pages are made.
#include "engine/collision/broad_phase.h" · namespace labrador
class BroadPhase
Section titled “class BroadPhase”Which pairs are worth measuring.
PHILOSOPHY's Collision section promises this. Without it the pair enumeration is all-pairs, O(n^2) in the object count, and bench/ says what that costs: on a release build, an all-pairs Scene::resolve is 25 us at 64 objects, 380 us at 256, 6.1 ms at 1,024 and 106 ms at 4,096 - which is six times the whole 60 Hz frame budget, from one call, at an object count a 2D engine has no business finding difficult.
The same benchmark is why there is no spatial index in front of the *render* cull. That loop is 6.2 ns per object and flat from 64 to 4,096 - 102 us for four views over four thousand objects, well under one percent of a frame. An index there would be ceremony.
WHY A UNIFORM GRID. The world it is built for is a plane of static geometry of broadly similar size, mostly not touching, with characters and projectiles moving through it. That is the case a uniform grid is best at and a tree is worst at: no rebalancing, no per-frame allocation once the buffers are warm, and cell membership is arithmetic rather than a descent. Where it degrades - one object far larger than the rest - it degrades towards the all-pairs sweep rather than towards anything worse, and the large-object list below bounds even that.
WHAT IT GUARANTEES. Exactly the pairs the all-pairs sweep considers, minus ones whose bounding boxes cannot overlap, in the same ascending (a, b) index order. Same order matters: a contact list is a value the game reads, and dispatch re-measures each pair in list order, so a different order is a different resolution. tests/collision asserts the two enumerations agree object-for-object on randomised scenes.
BroadPhase
Section titled “BroadPhase”BroadPhase();find_pairs
Section titled “find_pairs” std::vector<std::pair<int, int>>& pairs);Fills pairs with the index pairs worth measuring, ascending by first index then second, with no duplicates.
pairs is cleared and reused, and so is every buffer inside this object - which is what makes the steady state allocation-free (PHILOSOPHY, Performance: per-frame code performs no heap allocation). Objects flagged for deletion are skipped here rather than by the caller, because a pair that cannot produce a contact should not reach the grid at all.
cell_size
Section titled “cell_size”float cell_size() const;The cell edge the last call chose, in world units. For tests and for anyone wondering why a scene got slow.
large_object_count
Section titled “large_object_count”int large_object_count() const;How many objects the last call put in the large-object list - the ones whose bounding box covers so much of the grid that indexing them costs more than testing them against everything.
pairs_buffer
Section titled “pairs_buffer”std::vector<std::pair<int, int>>& pairs_buffer();The pair list this object keeps across frames, so find_contacts has somewhere allocation-free to receive one. A caller driving find_pairs itself may pass its own vector instead.
Related types
Section titled “Related types”Named in the public declarations above: CollisionObject.
In the samples and tests
Section titled “In the samples and tests”The files that include this header directly. A file can also reach it through another header.
tests/collision/broad_phase_tests.cpp,contacts_tests.cpp
Development documentation (unreleased). Built from Labrador 862e08b of 2026-10-08.