|
@@ -132,6 +132,10 @@ void VisualServerScene::SpatialPartitioningScene_BVH::deactivate(SpatialPartitio
|
|
|
_bvh.deactivate(p_handle - 1);
|
|
|
}
|
|
|
|
|
|
+void VisualServerScene::SpatialPartitioningScene_BVH::force_collision_check(SpatialPartitionID p_handle) {
|
|
|
+ _bvh.force_collision_check(p_handle - 1);
|
|
|
+}
|
|
|
+
|
|
|
void VisualServerScene::SpatialPartitioningScene_BVH::update() {
|
|
|
_bvh.update();
|
|
|
}
|
|
@@ -782,7 +786,13 @@ void VisualServerScene::instance_set_visible(RID p_instance, bool 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) {
|
|
|
+
|
|
|
+ // slightly bug prone optimization here - we want to avoid doing a collision check twice
|
|
|
+ // once when activating, and once when calling set_pairable. We do this by deferring the collision check.
|
|
|
+ // However, in some cases (notably meshes), set_pairable never gets called. So we want to catch this case
|
|
|
+ // and force a collision check (see later in this function).
|
|
|
+ // This is only done in two stages to maintain compatibility with the octree.
|
|
|
+ if (instance->spatial_partition_id && instance->scenario) {
|
|
|
if (p_visible) {
|
|
|
instance->scenario->sps->activate(instance->spatial_partition_id, instance->transformed_aabb);
|
|
|
} else {
|
|
@@ -828,6 +838,11 @@ void VisualServerScene::instance_set_visible(RID p_instance, bool p_visible) {
|
|
|
|
|
|
} break;
|
|
|
default: {
|
|
|
+ // if we haven't called set_pairable, we STILL need to do a collision check
|
|
|
+ // for activated items because we deferred it earlier in the call to activate.
|
|
|
+ if (instance->spatial_partition_id && instance->scenario && p_visible) {
|
|
|
+ instance->scenario->sps->force_collision_check(instance->spatial_partition_id);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|