Improved collision system use of BVH

This commit is contained in:
Yousef Khadadeh 2025-07-21 16:54:48 +03:00
parent f74298d21d
commit f75a5133d5
5 changed files with 38 additions and 8 deletions

View file

@ -176,7 +176,7 @@ bool DrawComponent::collides_with_cam_coords(const CoordSpaceHelper& camCoords,
bool DrawComponent::collides_with(const CoordSpaceHelper& camCoords, const SCollision::ColliderCollection<WorldScalar>& checkAgainstWorld, const SCollision::ColliderCollection<float>& checkAgainstCam, bool colliderAllocated) {
if((camCoords.inverseScale << DRAWCOMP_MAX_SHIFT_BEFORE_DISAPPEAR) < coords.inverseScale) // Object is too large, just dismiss the collision
return false;
else if((camCoords.inverseScale >> DRAWCOMP_MIN_SHIFT_BEFORE_DISAPPEAR) >= coords.inverseScale) {
else if((camCoords.inverseScale >> DRAWCOMP_COLLIDE_MIN_SHIFT_TINY) >= coords.inverseScale) {
if(!worldAABB)
return false;
return SCollision::collide(checkAgainstCam, camCoords.to_space(worldAABB->min));

View file

@ -19,6 +19,7 @@
#define DRAWCOMP_MAX_SHIFT_BEFORE_DISAPPEAR 20
#define DRAWCOMP_MIN_SHIFT_BEFORE_DISAPPEAR 11
#define DRAWCOMP_COLLIDE_MIN_SHIFT_TINY 9
#define DRAWCOMP_MIPMAP_LEVEL_ONE 2
#define DRAWCOMP_MIPMAP_LEVEL_TWO 5

View file

@ -163,13 +163,7 @@ void DrawingProgram::parallel_loop_all_components(std::function<void(const std::
}
void DrawingProgram::check_all_collisions_base(const SCollision::ColliderCollection<WorldScalar>& checkAgainstWorld, const SCollision::ColliderCollection<float>& checkAgainstCam) {
for(auto& c : components.client_list())
c->obj->globalCollisionCheck = false;
compCache.traverse_bvh_run_function(checkAgainstWorld.bounds, [&](const std::shared_ptr<DrawingProgramCache::BVHNode>& node, const std::vector<CollabListType::ObjectInfoPtr>& comps) {
for(auto& c : comps)
c->obj->globalCollisionCheck = c->obj->collides_with(world.drawData.cam.c, checkAgainstWorld, checkAgainstCam, colliderAllocated);
return true;
});
compCache.traverse_bvh_collision_check(checkAgainstWorld, checkAgainstCam);
}
void DrawingProgram::check_all_collisions(const SCollision::ColliderCollection<WorldScalar>& checkAgainst) {

View file

@ -77,6 +77,37 @@ std::pair<std::shared_ptr<DrawingProgramCache::BVHNode>, std::vector<DrawingProg
return {nullptr, bvhNode->components.end()};
}
void DrawingProgramCache::traverse_bvh_collision_check(const SCollision::ColliderCollection<WorldScalar>& checkAgainstWorld, const SCollision::ColliderCollection<float>& checkAgainstCam) {
for(auto& c : drawP.components.client_list())
c->obj->globalCollisionCheck = false;
for(auto& c : unsortedComponents)
c->obj->globalCollisionCheck = c->obj->collides_with(drawP.world.drawData.cam.c, checkAgainstWorld, checkAgainstCam, drawP.colliderAllocated);
traverse_bvh_collision_check_recursive(bvhRoot, checkAgainstWorld, checkAgainstCam);
}
void DrawingProgramCache::traverse_bvh_collision_check_recursive_tiny(const std::shared_ptr<BVHNode>& bvhNode, bool collided) {
if(bvhNode) {
for(auto& c : bvhNode->components)
c->obj->globalCollisionCheck = collided;
for(auto& p : bvhNode->children)
traverse_bvh_collision_check_recursive_tiny(p, collided);
}
}
void DrawingProgramCache::traverse_bvh_collision_check_recursive(const std::shared_ptr<BVHNode>& bvhNode, const SCollision::ColliderCollection<WorldScalar>& checkAgainstWorld, const SCollision::ColliderCollection<float>& checkAgainstCam) {
if(bvhNode) {
auto& camCoords = drawP.world.drawData.cam.c;
if((camCoords.inverseScale >> DRAWCOMP_COLLIDE_MIN_SHIFT_TINY) >= bvhNode->coords.inverseScale)
traverse_bvh_collision_check_recursive_tiny(bvhNode, SCollision::collide(checkAgainstCam, camCoords.to_space(bvhNode->bounds.min)));
else {
for(auto& c : bvhNode->components)
c->obj->globalCollisionCheck = c->obj->collides_with(drawP.world.drawData.cam.c, checkAgainstWorld, checkAgainstCam, drawP.colliderAllocated);
for(auto& p : bvhNode->children)
traverse_bvh_collision_check_recursive(p, checkAgainstWorld, checkAgainstCam);
}
}
}
void DrawingProgramCache::traverse_bvh_run_function(const SCollision::AABB<WorldScalar>& aabb, std::function<bool(const std::shared_ptr<BVHNode> node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f) {
f(nullptr, unsortedComponents);
traverse_bvh_run_function_recursive(bvhRoot, aabb, f);

View file

@ -37,6 +37,7 @@ class DrawingProgramCache {
std::unordered_set<std::shared_ptr<BVHNode>> nodesWithCachedSurfaces;
void traverse_bvh_collision_check(const SCollision::ColliderCollection<WorldScalar>& checkAgainstWorld, const SCollision::ColliderCollection<float>& checkAgainstCam);
void traverse_bvh_run_function(const SCollision::AABB<WorldScalar>& aabb, std::function<bool(const std::shared_ptr<BVHNode> node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f);
void force_rebuild();
@ -45,6 +46,9 @@ class DrawingProgramCache {
void invalidate_cache_before_pos(uint64_t placementToInvalidateAt);
private:
void traverse_bvh_collision_check_recursive(const std::shared_ptr<BVHNode>& bvhNode, const SCollision::ColliderCollection<WorldScalar>& checkAgainstWorld, const SCollision::ColliderCollection<float>& checkAgainstCam);
void traverse_bvh_collision_check_recursive_tiny(const std::shared_ptr<BVHNode>& bvhNode, bool collided);
void build_bvh_node_coords_and_resolution(BVHNode& node);
void refresh_draw_cache(const std::shared_ptr<BVHNode>& bvhNode, const DrawData& drawData);