CollisionWorld¶
CollisionWorld — центральный объект для управления коллайдерами и обнаружения столкновений.
Namespace: termin::collision.
Управление коллайдерами¶
CollisionWorld world;
// Добавить/удалить
world.add(collider);
world.remove(collider);
// Обновить позицию одного коллайдера в BVH
world.update_pose(collider);
// Обновить все позиции (вызывать раз за кадр)
world.update_all();
// Проверки
world.contains(collider);
world.size();
CollisionWorld не владеет коллайдерами — хранит raw-указатели. Вызывающий код отвечает за время жизни.
Детекция контактов¶
std::vector<ContactManifold> manifolds = world.detect_contacts();
Поток:
1. Broad-phase: BVH::query_all_pairs() — все пары с пересекающимися AABB.
2. Narrow-phase: Collider::closest_to_collider() — точная проверка.
3. Для box-box: дополнительно Sutherland-Hodgman clipping для множественных контактных точек.
ContactManifold¶
struct ContactManifold {
static constexpr int MAX_POINTS = 4;
Collider* collider_a;
Collider* collider_b;
Vec3 normal; // от A к B
std::array<ContactPoint, MAX_POINTS> points;
int point_count;
void* body_a; // пользовательские данные (для физики)
void* body_b;
};
ContactPoint¶
struct ContactPoint {
Vec3 position; // мировые координаты
Vec3 local_a; // на коллайдере A
Vec3 local_b; // на коллайдере B
double penetration; // < 0 = пенетрация, > 0 = разделение
ContactID id; // для матчинга между кадрами
double normal_impulse; // для warm-starting (заполняется солвером)
double tangent1_impulse;
double tangent2_impulse;
};
Raycast¶
// Все попадания, отсортированные по расстоянию
std::vector<collision::RayHit> hits = world.raycast(ray);
// Только ближайшее
collision::RayHit closest = world.raycast_closest(ray);
collision::RayHit:
- collider — указатель на коллайдер
- point — точка попадания
- normal — нормаль в точке попадания
- distance — расстояние от origin луча
- hit() — true если collider != nullptr
AABB-запрос¶
std::vector<Collider*> result = world.query_aabb(aabb);
Возвращает все коллайдеры, чьи AABB пересекаются с заданным.
BVH (Bounding Volume Hierarchy)¶
Динамическое дерево для broad-phase.
Характеристики: - Fattened AABB: margin 0.1 уменьшает перестройки при малых движениях - SAH (Surface Area Heuristic): оптимальный выбор sibling при вставке - AVL-балансировка: ротации при дисбалансе > 1 - O(log n) для insert/remove/update/query - Free-list для переиспользования нод
Публичные запросы:
- query_aabb(aabb, callback) — все листья, пересекающиеся с AABB
- query_ray(ray, callback) — все листья на пути луча (slab test)
- query_all_pairs(callback) — все пары листьев с пересекающимися AABB
Доступ к BVH: world.bvh().
Интеграция со сценой¶
// C++ — получить CollisionWorld из сцены
CollisionWorld* cw = CollisionWorld::from_scene(scene_handle);
// C API
tc_collision_world* cw = tc_collision_world_get_scene(scene);
CollisionWorld хранится как scene extension с типом TC_SCENE_EXT_TYPE_COLLISION_WORLD.