summaryrefslogtreecommitdiffstats
path: root/core/math/bvh_structs.inc
diff options
context:
space:
mode:
Diffstat (limited to 'core/math/bvh_structs.inc')
-rw-r--r--core/math/bvh_structs.inc89
1 files changed, 60 insertions, 29 deletions
diff --git a/core/math/bvh_structs.inc b/core/math/bvh_structs.inc
index 1d1e0e6468..58c8f0479a 100644
--- a/core/math/bvh_structs.inc
+++ b/core/math/bvh_structs.inc
@@ -14,25 +14,38 @@ struct ItemRef {
// extra info kept in separate parallel list to the references,
// as this is less used as keeps cache better
struct ItemExtra {
- uint32_t last_updated_tick;
- uint32_t pairable;
- uint32_t pairable_mask;
- uint32_t pairable_type;
+ // Before doing user defined pairing checks (especially in the find_leavers function),
+ // we may want to check that two items have compatible tree ids and tree masks,
+ // as if they are incompatible they should not pair / collide.
+ bool are_item_trees_compatible(const ItemExtra &p_other) const {
+ uint32_t other_type = 1 << p_other.tree_id;
+ if (tree_collision_mask & other_type) {
+ return true;
+ }
+ uint32_t our_type = 1 << tree_id;
+ if (p_other.tree_collision_mask & our_type) {
+ return true;
+ }
+ return false;
+ }
+
+ // There can be multiple user defined trees
+ uint32_t tree_id;
+
+ // Defines which trees this item should collision check against.
+ // 1 << tree_id, and normally items would collide against there own
+ // tree (but not always).
+ uint32_t tree_collision_mask;
+ uint32_t last_updated_tick;
int32_t subindex;
+ T *userdata;
+
// the active reference is a separate list of which references
// are active so that we can slowly iterate through it over many frames for
// slow optimize.
uint32_t active_ref_id;
-
- T *userdata;
-};
-
-// this is an item OR a child node depending on whether a leaf node
-struct Item {
- BVHABB_CLASS aabb;
- uint32_t item_ref_id;
};
// tree leaf
@@ -47,11 +60,23 @@ private:
public:
// accessors
- BVHABB_CLASS &get_aabb(uint32_t p_id) { return aabbs[p_id]; }
- const BVHABB_CLASS &get_aabb(uint32_t p_id) const { return aabbs[p_id]; }
+ BVHABB_CLASS &get_aabb(uint32_t p_id) {
+ BVH_ASSERT(p_id < MAX_ITEMS);
+ return aabbs[p_id];
+ }
+ const BVHABB_CLASS &get_aabb(uint32_t p_id) const {
+ BVH_ASSERT(p_id < MAX_ITEMS);
+ return aabbs[p_id];
+ }
- uint32_t &get_item_ref_id(uint32_t p_id) { return item_ref_ids[p_id]; }
- const uint32_t &get_item_ref_id(uint32_t p_id) const { return item_ref_ids[p_id]; }
+ uint32_t &get_item_ref_id(uint32_t p_id) {
+ BVH_ASSERT(p_id < MAX_ITEMS);
+ return item_ref_ids[p_id];
+ }
+ const uint32_t &get_item_ref_id(uint32_t p_id) const {
+ BVH_ASSERT(p_id < MAX_ITEMS);
+ return item_ref_ids[p_id];
+ }
bool is_dirty() const { return dirty; }
void set_dirty(bool p) { dirty = p; }
@@ -133,13 +158,13 @@ struct TNode {
// instead of using linked list we maintain
// item references (for quick lookup)
-PooledList<ItemRef, true> _refs;
-PooledList<ItemExtra, true> _extra;
+PooledList<ItemRef, uint32_t, true> _refs;
+PooledList<ItemExtra, uint32_t, true> _extra;
PooledList<ItemPairs> _pairs;
// these 2 are not in sync .. nodes != leaves!
-PooledList<TNode, true> _nodes;
-PooledList<TLeaf, true> _leaves;
+PooledList<TNode, uint32_t, true> _nodes;
+PooledList<TLeaf, uint32_t, true> _leaves;
// we can maintain an un-ordered list of which references are active,
// in order to do a slow incremental optimize of the tree over each frame.
@@ -152,15 +177,11 @@ uint32_t _current_active_ref = 0;
// for pairing collision detection
LocalVector<uint32_t, uint32_t, true> _cull_hits;
-// we now have multiple root nodes, allowing us to store
-// more than 1 tree. This can be more efficient, while sharing the same
-// common lists
-enum { NUM_TREES = 2,
-};
-
-// Tree 0 - Non pairable
-// Tree 1 - Pairable
-// This is more efficient because in physics we only need check non pairable against the pairable tree.
+// We can now have a user definable number of trees.
+// This allows using e.g. a non-pairable and pairable tree,
+// which can be more efficient for example, if we only need check non pairable against the pairable tree.
+// It also may be more efficient in terms of separating static from dynamic objects, by reducing housekeeping.
+// However this is a trade off, as there is a cost of traversing two trees.
uint32_t _root_node_id[NUM_TREES];
// these values may need tweaking according to the project
@@ -177,4 +198,14 @@ bool _auto_node_expansion = true;
// larger values gives more 'sticky' pairing, and is less likely to exhibit tunneling
// we can either use auto mode, where the expansion is based on the root node size, or specify manually
real_t _pairing_expansion = 0.1;
+
+#ifdef BVH_ALLOW_AUTO_EXPANSION
bool _auto_pairing_expansion = true;
+#endif
+
+// when using an expanded bound, we must detect the condition where a new AABB
+// is significantly smaller than the expanded bound, as this is a special case where we
+// should override the optimization and create a new expanded bound.
+// This threshold is derived from the _pairing_expansion, and should be recalculated
+// if _pairing_expansion is changed.
+real_t _aabb_shrinkage_threshold = 0.0;