Merge pull request #45576 from lawnjelly/bvh_visibility
BVH add support for visibility (activation)
This commit is contained in:
commit
a37095dd5e
8 changed files with 214 additions and 35 deletions
|
@ -88,7 +88,7 @@ public:
|
||||||
unpair_callback_userdata = p_userdata;
|
unpair_callback_userdata = p_userdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
BVHHandle create(T *p_userdata, bool p_active, 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 sure if absolutely necessary to flush collisions here. It will cost performance to, instead
|
// not sure if absolutely necessary to flush collisions here. It will cost performance to, instead
|
||||||
// of waiting for update, so only uncomment this if there are bugs.
|
// of waiting for update, so only uncomment this if there are bugs.
|
||||||
|
@ -104,7 +104,7 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BVHHandle h = tree.item_add(p_userdata, p_aabb, p_subindex, p_pairable, p_pairable_type, p_pairable_mask);
|
BVHHandle h = tree.item_add(p_userdata, p_active, p_aabb, p_subindex, p_pairable, p_pairable_type, p_pairable_mask);
|
||||||
|
|
||||||
if (USE_PAIRS) {
|
if (USE_PAIRS) {
|
||||||
// for safety initialize the expanded AABB
|
// for safety initialize the expanded AABB
|
||||||
|
@ -113,9 +113,10 @@ public:
|
||||||
expanded_aabb.grow_by(tree._pairing_expansion);
|
expanded_aabb.grow_by(tree._pairing_expansion);
|
||||||
|
|
||||||
// force a collision check no matter the AABB
|
// force a collision check no matter the AABB
|
||||||
_add_changed_item(h, p_aabb, false);
|
if (p_active) {
|
||||||
|
_add_changed_item(h, p_aabb, false);
|
||||||
_check_for_collisions(true);
|
_check_for_collisions(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
|
@ -136,6 +137,18 @@ public:
|
||||||
erase(h);
|
erase(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool activate(uint32_t p_handle, const AABB &p_aabb, bool p_delay_collision_check = false) {
|
||||||
|
BVHHandle h;
|
||||||
|
h.set(p_handle);
|
||||||
|
return activate(h, p_aabb, p_delay_collision_check);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool deactivate(uint32_t p_handle) {
|
||||||
|
BVHHandle h;
|
||||||
|
h.set(p_handle);
|
||||||
|
return deactivate(h);
|
||||||
|
}
|
||||||
|
|
||||||
void set_pairable(uint32_t p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
|
void set_pairable(uint32_t p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
|
||||||
BVHHandle h;
|
BVHHandle h;
|
||||||
h.set(p_handle);
|
h.set(p_handle);
|
||||||
|
@ -182,6 +195,54 @@ public:
|
||||||
_check_for_collisions(true);
|
_check_for_collisions(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// these should be read as set_visible for render trees,
|
||||||
|
// but generically this makes items add or remove from the
|
||||||
|
// tree internally, to speed things up by ignoring inactive items
|
||||||
|
bool activate(BVHHandle p_handle, const AABB &p_aabb, bool p_delay_collision_check = false) {
|
||||||
|
// sending the aabb here prevents the need for the BVH to maintain
|
||||||
|
// a redundant copy of the aabb.
|
||||||
|
// returns success
|
||||||
|
if (tree.item_activate(p_handle, p_aabb)) {
|
||||||
|
if (USE_PAIRS) {
|
||||||
|
|
||||||
|
// in the special case of the render tree, when setting visibility we are using the combination of
|
||||||
|
// activate then set_pairable. This would case 2 sets of collision checks. For efficiency here we allow
|
||||||
|
// deferring to have a single collision check at the set_pairable call.
|
||||||
|
// Watch for bugs! This may cause bugs if set_pairable is not called.
|
||||||
|
if (!p_delay_collision_check) {
|
||||||
|
_add_changed_item(p_handle, p_aabb, false);
|
||||||
|
|
||||||
|
// force an immediate collision check, much like calls to set_pairable
|
||||||
|
_check_for_collisions(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool deactivate(BVHHandle p_handle) {
|
||||||
|
// returns success
|
||||||
|
if (tree.item_deactivate(p_handle)) {
|
||||||
|
// call unpair and remove all references to the item
|
||||||
|
// before deleting from the tree
|
||||||
|
if (USE_PAIRS) {
|
||||||
|
_remove_changed_item(p_handle);
|
||||||
|
|
||||||
|
// force check for collisions, much like an erase was called
|
||||||
|
_check_for_collisions(true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_active(BVHHandle p_handle) const {
|
||||||
|
return tree.item_get_active(p_handle);
|
||||||
|
}
|
||||||
|
|
||||||
// call e.g. once per frame (this does a trickle optimize)
|
// call e.g. once per frame (this does a trickle optimize)
|
||||||
void update() {
|
void update() {
|
||||||
tree.update();
|
tree.update();
|
||||||
|
@ -206,21 +267,23 @@ public:
|
||||||
// of waiting for update, so only uncomment this if there are bugs.
|
// of waiting for update, so only uncomment this if there are bugs.
|
||||||
//_check_for_collisions();
|
//_check_for_collisions();
|
||||||
|
|
||||||
// when the pairable state changes, we need to force a collision check because newly pairable
|
if (get_active(p_handle)) {
|
||||||
// items may be in collision, and unpairable items might move out of collision.
|
// when the pairable state changes, we need to force a collision check because newly pairable
|
||||||
// We cannot depend on waiting for the next update, because that may come much later.
|
// items may be in collision, and unpairable items might move out of collision.
|
||||||
AABB aabb;
|
// We cannot depend on waiting for the next update, because that may come much later.
|
||||||
item_get_AABB(p_handle, aabb);
|
AABB aabb;
|
||||||
|
item_get_AABB(p_handle, aabb);
|
||||||
|
|
||||||
// passing false disables the optimization which prevents collision checks if
|
// passing false disables the optimization which prevents collision checks if
|
||||||
// the aabb hasn't changed
|
// the aabb hasn't changed
|
||||||
_add_changed_item(p_handle, aabb, false);
|
_add_changed_item(p_handle, aabb, false);
|
||||||
|
|
||||||
// force an immediate collision check (probably just for this one item)
|
// force an immediate collision check (probably just for this one item)
|
||||||
// but it must be a FULL collision check, also checking pairable state and masks.
|
// but it must be a FULL collision check, also checking pairable state and masks.
|
||||||
// This is because AABB intersecting objects may have changed pairable state / mask
|
// This is because AABB intersecting objects may have changed pairable state / mask
|
||||||
// such that they should no longer be paired. E.g. lights.
|
// such that they should no longer be paired. E.g. lights.
|
||||||
_check_for_collisions(true);
|
_check_for_collisions(true);
|
||||||
|
} // only if active
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@ void _logic_item_remove_and_reinsert(uint32_t p_ref_id) {
|
||||||
// get the reference
|
// get the reference
|
||||||
ItemRef &ref = _refs[p_ref_id];
|
ItemRef &ref = _refs[p_ref_id];
|
||||||
|
|
||||||
|
// no need to optimize inactive items
|
||||||
|
if (!ref.is_active())
|
||||||
|
return;
|
||||||
|
|
||||||
// special case of debug draw
|
// special case of debug draw
|
||||||
if (ref.item_id == BVHCommon::INVALID)
|
if (ref.item_id == BVHCommon::INVALID)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
public:
|
public:
|
||||||
BVHHandle item_add(T *p_userdata, const AABB &p_aabb, int32_t p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask, bool p_invisible = false) {
|
BVHHandle item_add(T *p_userdata, bool p_active, const AABB &p_aabb, int32_t p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask, bool p_invisible = false) {
|
||||||
#ifdef BVH_VERBOSE_TREE
|
#ifdef BVH_VERBOSE_TREE
|
||||||
VERBOSE_PRINT("\nitem_add BEFORE");
|
VERBOSE_PRINT("\nitem_add BEFORE");
|
||||||
_debug_recursive_print_tree(0);
|
_debug_recursive_print_tree(0);
|
||||||
|
@ -60,15 +60,19 @@ BVHHandle item_add(T *p_userdata, const AABB &p_aabb, int32_t p_subindex, bool p
|
||||||
create_root_node(_current_tree);
|
create_root_node(_current_tree);
|
||||||
|
|
||||||
// we must choose where to add to tree
|
// we must choose where to add to tree
|
||||||
ref->tnode_id = _logic_choose_item_add_node(_root_node_id[_current_tree], abb);
|
if (p_active) {
|
||||||
|
ref->tnode_id = _logic_choose_item_add_node(_root_node_id[_current_tree], abb);
|
||||||
|
|
||||||
bool refit = _node_add_item(ref->tnode_id, ref_id, abb);
|
bool refit = _node_add_item(ref->tnode_id, ref_id, abb);
|
||||||
|
|
||||||
if (refit) {
|
if (refit) {
|
||||||
// only need to refit from the parent
|
// only need to refit from the parent
|
||||||
const TNode &add_node = _nodes[ref->tnode_id];
|
const TNode &add_node = _nodes[ref->tnode_id];
|
||||||
if (add_node.parent_id != BVHCommon::INVALID)
|
if (add_node.parent_id != BVHCommon::INVALID)
|
||||||
refit_upward_and_balance(add_node.parent_id);
|
refit_upward_and_balance(add_node.parent_id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ref->set_inactive();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BVH_VERBOSE
|
#ifdef BVH_VERBOSE
|
||||||
|
@ -100,11 +104,14 @@ void _debug_print_refs() {
|
||||||
bool item_move(BVHHandle p_handle, const AABB &p_aabb) {
|
bool item_move(BVHHandle p_handle, const AABB &p_aabb) {
|
||||||
uint32_t ref_id = p_handle.id();
|
uint32_t ref_id = p_handle.id();
|
||||||
|
|
||||||
BVH_ABB abb;
|
|
||||||
abb.from(p_aabb);
|
|
||||||
|
|
||||||
// get the reference
|
// get the reference
|
||||||
ItemRef &ref = _refs[ref_id];
|
ItemRef &ref = _refs[ref_id];
|
||||||
|
if (!ref.is_active()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BVH_ABB abb;
|
||||||
|
abb.from(p_aabb);
|
||||||
|
|
||||||
BVH_ASSERT(ref.tnode_id != BVHCommon::INVALID);
|
BVH_ASSERT(ref.tnode_id != BVHCommon::INVALID);
|
||||||
TNode &tnode = _nodes[ref.tnode_id];
|
TNode &tnode = _nodes[ref.tnode_id];
|
||||||
|
@ -117,7 +124,14 @@ bool item_move(BVHHandle p_handle, const AABB &p_aabb) {
|
||||||
// for accurate collision detection
|
// for accurate collision detection
|
||||||
TLeaf &leaf = _node_get_leaf(tnode);
|
TLeaf &leaf = _node_get_leaf(tnode);
|
||||||
|
|
||||||
leaf.get_aabb(ref.item_id) = abb;
|
BVH_ABB &leaf_abb = leaf.get_aabb(ref.item_id);
|
||||||
|
|
||||||
|
// no change?
|
||||||
|
if (leaf_abb == abb) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
leaf_abb = abb;
|
||||||
_integrity_check_all();
|
_integrity_check_all();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -168,8 +182,10 @@ void item_remove(BVHHandle p_handle) {
|
||||||
_extra[ref_id_moved_back].active_ref_id = active_ref_id;
|
_extra[ref_id_moved_back].active_ref_id = active_ref_id;
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
||||||
// remove the item from the node
|
// remove the item from the node (only if active)
|
||||||
node_remove_item(ref_id);
|
if (_refs[ref_id].is_active()) {
|
||||||
|
node_remove_item(ref_id);
|
||||||
|
}
|
||||||
|
|
||||||
// remove the item reference
|
// remove the item reference
|
||||||
_refs.free(ref_id);
|
_refs.free(ref_id);
|
||||||
|
@ -186,6 +202,54 @@ void item_remove(BVHHandle p_handle) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns success
|
||||||
|
bool item_activate(BVHHandle p_handle, const AABB &p_aabb) {
|
||||||
|
uint32_t ref_id = p_handle.id();
|
||||||
|
ItemRef &ref = _refs[ref_id];
|
||||||
|
if (ref.is_active()) {
|
||||||
|
// noop
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to tree
|
||||||
|
BVH_ABB abb;
|
||||||
|
abb.from(p_aabb);
|
||||||
|
|
||||||
|
_current_tree = _handle_get_tree_id(p_handle);
|
||||||
|
|
||||||
|
// we must choose where to add to tree
|
||||||
|
ref.tnode_id = _logic_choose_item_add_node(_root_node_id[_current_tree], abb);
|
||||||
|
_node_add_item(ref.tnode_id, ref_id, abb);
|
||||||
|
|
||||||
|
refit_upward_and_balance(ref.tnode_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns success
|
||||||
|
bool item_deactivate(BVHHandle p_handle) {
|
||||||
|
uint32_t ref_id = p_handle.id();
|
||||||
|
ItemRef &ref = _refs[ref_id];
|
||||||
|
if (!ref.is_active()) {
|
||||||
|
// noop
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove from tree
|
||||||
|
BVH_ABB abb;
|
||||||
|
node_remove_item(ref_id, &abb);
|
||||||
|
|
||||||
|
// mark as inactive
|
||||||
|
ref.set_inactive();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool item_get_active(BVHHandle p_handle) const {
|
||||||
|
uint32_t ref_id = p_handle.id();
|
||||||
|
const ItemRef &ref = _refs[ref_id];
|
||||||
|
return ref.is_active();
|
||||||
|
}
|
||||||
|
|
||||||
// during collision testing, we want to set the mask and whether pairable for the item testing from
|
// during collision testing, we want to set the mask and whether pairable for the item testing from
|
||||||
void item_fill_cullparams(BVHHandle p_handle, CullParams &r_params) const {
|
void item_fill_cullparams(BVHHandle p_handle, CullParams &r_params) const {
|
||||||
uint32_t ref_id = p_handle.id();
|
uint32_t ref_id = p_handle.id();
|
||||||
|
@ -226,7 +290,10 @@ void item_set_pairable(const BVHHandle &p_handle, bool p_pairable, uint32_t p_pa
|
||||||
ex.pairable_type = p_pairable_type;
|
ex.pairable_type = p_pairable_type;
|
||||||
ex.pairable_mask = p_pairable_mask;
|
ex.pairable_mask = p_pairable_mask;
|
||||||
|
|
||||||
if ((ex.pairable != 0) != p_pairable) {
|
bool active = ref.is_active();
|
||||||
|
bool pairable_changed = (ex.pairable != 0) != p_pairable;
|
||||||
|
|
||||||
|
if (active && pairable_changed) {
|
||||||
// record abb
|
// record abb
|
||||||
TNode &tnode = _nodes[ref.tnode_id];
|
TNode &tnode = _nodes[ref.tnode_id];
|
||||||
TLeaf &leaf = _node_get_leaf(tnode);
|
TLeaf &leaf = _node_get_leaf(tnode);
|
||||||
|
@ -238,6 +305,8 @@ void item_set_pairable(const BVHHandle &p_handle, bool p_pairable, uint32_t p_pa
|
||||||
// remove from old tree
|
// remove from old tree
|
||||||
node_remove_item(ref_id);
|
node_remove_item(ref_id);
|
||||||
|
|
||||||
|
// we must set the pairable AFTER getting the current tree
|
||||||
|
// because the pairable status determines which tree
|
||||||
ex.pairable = p_pairable;
|
ex.pairable = p_pairable;
|
||||||
|
|
||||||
// add to new tree
|
// add to new tree
|
||||||
|
@ -255,6 +324,9 @@ void item_set_pairable(const BVHHandle &p_handle, bool p_pairable, uint32_t p_pa
|
||||||
if (add_node.parent_id != BVHCommon::INVALID)
|
if (add_node.parent_id != BVHCommon::INVALID)
|
||||||
refit_upward_and_balance(add_node.parent_id);
|
refit_upward_and_balance(add_node.parent_id);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// always keep this up to date
|
||||||
|
ex.pairable = p_pairable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,12 @@ public:
|
||||||
struct ItemRef {
|
struct ItemRef {
|
||||||
uint32_t tnode_id; // -1 is invalid
|
uint32_t tnode_id; // -1 is invalid
|
||||||
uint32_t item_id; // in the leaf
|
uint32_t item_id; // in the leaf
|
||||||
|
|
||||||
|
bool is_active() const { return tnode_id != BVHCommon::INACTIVE; }
|
||||||
|
void set_inactive() {
|
||||||
|
tnode_id = BVHCommon::INACTIVE;
|
||||||
|
item_id = BVHCommon::INACTIVE;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// extra info kept in separate parallel list to the references,
|
// extra info kept in separate parallel list to the references,
|
||||||
|
|
|
@ -73,7 +73,11 @@
|
||||||
|
|
||||||
// really just a namespace
|
// really just a namespace
|
||||||
struct BVHCommon {
|
struct BVHCommon {
|
||||||
|
// these could possibly also be the same constant,
|
||||||
|
// although this may be useful for debugging.
|
||||||
|
// or use zero for invalid and +1 based indices.
|
||||||
static const uint32_t INVALID = (0xffffffff);
|
static const uint32_t INVALID = (0xffffffff);
|
||||||
|
static const uint32_t INACTIVE = (0xfffffffe);
|
||||||
};
|
};
|
||||||
|
|
||||||
// really a handle, can be anything
|
// really a handle, can be anything
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
BroadPhaseSW::ID BroadPhaseBVH::create(CollisionObjectSW *p_object, int p_subindex, const AABB &p_aabb) {
|
BroadPhaseSW::ID BroadPhaseBVH::create(CollisionObjectSW *p_object, int p_subindex, const AABB &p_aabb) {
|
||||||
|
|
||||||
ID oid = bvh.create(p_object, p_aabb, p_subindex, false, 1 << p_object->get_type(), 0);
|
ID oid = bvh.create(p_object, true, p_aabb, p_subindex, false, 1 << p_object->get_type(), 0);
|
||||||
return oid + 1;
|
return oid + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,12 @@ void VisualServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_enab
|
||||||
|
|
||||||
/* SPATIAL PARTITIONING */
|
/* SPATIAL PARTITIONING */
|
||||||
VisualServerScene::SpatialPartitionID VisualServerScene::SpatialPartitioningScene_BVH::create(Instance *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
|
VisualServerScene::SpatialPartitionID VisualServerScene::SpatialPartitioningScene_BVH::create(Instance *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
|
||||||
return _bvh.create(p_userdata, p_aabb, p_subindex, p_pairable, p_pairable_type, p_pairable_mask) + 1;
|
#if defined(DEBUG_ENABLED) && defined(TOOLS_ENABLED)
|
||||||
|
// we are relying on this instance to be valid in order to pass
|
||||||
|
// the visible flag to the bvh.
|
||||||
|
CRASH_COND(!p_userdata);
|
||||||
|
#endif
|
||||||
|
return _bvh.create(p_userdata, p_userdata->visible, p_aabb, p_subindex, p_pairable, p_pairable_type, p_pairable_mask) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualServerScene::SpatialPartitioningScene_BVH::erase(SpatialPartitionID p_handle) {
|
void VisualServerScene::SpatialPartitioningScene_BVH::erase(SpatialPartitionID p_handle) {
|
||||||
|
@ -116,6 +121,17 @@ void VisualServerScene::SpatialPartitioningScene_BVH::move(SpatialPartitionID p_
|
||||||
_bvh.move(p_handle - 1, p_aabb);
|
_bvh.move(p_handle - 1, p_aabb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VisualServerScene::SpatialPartitioningScene_BVH::activate(SpatialPartitionID p_handle, const AABB &p_aabb) {
|
||||||
|
// be very careful here, we are deferring the collision check, expecting a set_pairable to be called
|
||||||
|
// immediately after.
|
||||||
|
// see the notes in the BVH function.
|
||||||
|
_bvh.activate(p_handle - 1, p_aabb, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualServerScene::SpatialPartitioningScene_BVH::deactivate(SpatialPartitionID p_handle) {
|
||||||
|
_bvh.deactivate(p_handle - 1);
|
||||||
|
}
|
||||||
|
|
||||||
void VisualServerScene::SpatialPartitioningScene_BVH::update() {
|
void VisualServerScene::SpatialPartitioningScene_BVH::update() {
|
||||||
_bvh.update();
|
_bvh.update();
|
||||||
}
|
}
|
||||||
|
@ -764,6 +780,16 @@ void VisualServerScene::instance_set_visible(RID p_instance, bool p_visible) {
|
||||||
|
|
||||||
instance->visible = p_visible;
|
instance->visible = p_visible;
|
||||||
|
|
||||||
|
// give the opportunity for the spatial paritioning scene to use a special implementation of visibility
|
||||||
|
// for efficiency (supported in BVH but not octree)
|
||||||
|
if (instance->spatial_partition_id) {
|
||||||
|
if (p_visible) {
|
||||||
|
instance->scenario->sps->activate(instance->spatial_partition_id, instance->transformed_aabb);
|
||||||
|
} else {
|
||||||
|
instance->scenario->sps->deactivate(instance->spatial_partition_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// when showing or hiding geometry, lights must be kept up to date to show / hide shadows
|
// when showing or hiding geometry, lights must be kept up to date to show / hide shadows
|
||||||
if ((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) {
|
if ((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) {
|
||||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
|
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
|
||||||
|
|
|
@ -117,6 +117,8 @@ public:
|
||||||
virtual SpatialPartitionID create(Instance *p_userdata, const AABB &p_aabb = AABB(), int p_subindex = 0, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1) = 0;
|
virtual SpatialPartitionID create(Instance *p_userdata, const AABB &p_aabb = AABB(), int p_subindex = 0, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1) = 0;
|
||||||
virtual void erase(SpatialPartitionID p_handle) = 0;
|
virtual void erase(SpatialPartitionID p_handle) = 0;
|
||||||
virtual void move(SpatialPartitionID p_handle, const AABB &p_aabb) = 0;
|
virtual void move(SpatialPartitionID p_handle, const AABB &p_aabb) = 0;
|
||||||
|
virtual void activate(SpatialPartitionID p_handle, const AABB &p_aabb) {}
|
||||||
|
virtual void deactivate(SpatialPartitionID p_handle) {}
|
||||||
virtual void update() {}
|
virtual void update() {}
|
||||||
virtual void update_collisions() {}
|
virtual void update_collisions() {}
|
||||||
virtual void set_pairable(SpatialPartitionID p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) = 0;
|
virtual void set_pairable(SpatialPartitionID p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) = 0;
|
||||||
|
@ -164,6 +166,8 @@ public:
|
||||||
SpatialPartitionID create(Instance *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);
|
SpatialPartitionID create(Instance *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);
|
||||||
void erase(SpatialPartitionID p_handle);
|
void erase(SpatialPartitionID p_handle);
|
||||||
void move(SpatialPartitionID p_handle, const AABB &p_aabb);
|
void move(SpatialPartitionID p_handle, const AABB &p_aabb);
|
||||||
|
void activate(SpatialPartitionID p_handle, const AABB &p_aabb);
|
||||||
|
void deactivate(SpatialPartitionID p_handle);
|
||||||
void update();
|
void update();
|
||||||
void update_collisions();
|
void update_collisions();
|
||||||
void set_pairable(SpatialPartitionID p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask);
|
void set_pairable(SpatialPartitionID p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask);
|
||||||
|
|
Loading…
Add table
Reference in a new issue