From ba5e4d8baaa32f2995a3e17480d717dfe97ad55a Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Wed, 27 Jan 2021 16:14:32 +0000 Subject: [PATCH] BVH fix stale changed items, causing dangling pairs In the octree collisions are flushed as objects are moved, whereas in the BVH they are usually flushed once per frame. This was causing problems in the render tree in some rare situations where objects were being created (perhaps deleted and recreated using the same handle in the same frame). This PR flushes the collisions before creating objects, and set_pairable. set_pairable may not be necessary but it is done for safety until proven not necessary. Also a small potential for a bug is closed in remove_unordered use. --- core/math/bvh.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/core/math/bvh.h b/core/math/bvh.h index a1ec0201477..3cb58f6c4ae 100644 --- a/core/math/bvh.h +++ b/core/math/bvh.h @@ -90,6 +90,12 @@ public: BVHHandle create(T *p_userdata, const AABB &p_aabb = AABB(), int p_subindex = 0, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t p_pairable_mask = 1) { + // not completely sure why, but the order of the pairing callbacks seems to be causing problems in + // the render tree unless these are flushed before creating a new object + if (USE_PAIRS) { + _check_for_collisions(); + } + #ifdef TOOLS_ENABLED if (!USE_PAIRS) { if (p_pairable) { @@ -185,6 +191,13 @@ public: tree.item_set_pairable(p_handle, p_pairable, p_pairable_type, p_pairable_mask); if (USE_PAIRS) { + + // not completely sure why, but the order of the pairing callbacks seems to be causing problems in + // the render tree unless these are flushed before creating a new object.. we will do this for set_pairable + // to just in case. This may not be required, and may slow things down slightly when there are a lot + // of visibility changes in a frame + _check_for_collisions(); + // when the pairable state changes, we need to force a collision check because newly pairable // items may be in collision, and unpairable items might move out of collision. // We cannot depend on waiting for the next update, because that may come much later. @@ -536,9 +549,15 @@ private: _remove_pairs_containing(p_handle); // remove from changed items (not very efficient yet) - for (unsigned int n = 0; n < changed_items.size(); n++) { + for (int n = 0; n < (int)changed_items.size(); n++) { if (changed_items[n] == p_handle) { changed_items.remove_unordered(n); + + // because we are using an unordered remove, + // the last changed item will now be at spot 'n', + // and we need to redo it, so we prevent moving on to + // the next n at the next for iteration. + n--; } }