BVH render tree new updating scheme

Change render BVH update scheme from once per update_dirty_instances to a new update_scenarios function called once per draw.

Fix lights not being properly unpaired.
Fixed bug in add_changed_item where AABBs were not being updated due to more than one update per tick.
This commit is contained in:
lawnjelly
2021-01-19 14:24:32 +00:00
parent 544f0bfff1
commit 4954a869bb
6 changed files with 102 additions and 32 deletions
+30 -3
View File
@@ -120,6 +120,10 @@ void VisualServerScene::SpatialPartitioningScene_BVH::update() {
_bvh.update();
}
void VisualServerScene::SpatialPartitioningScene_BVH::update_collisions() {
_bvh.update_collisions();
}
void VisualServerScene::SpatialPartitioningScene_BVH::set_pairable(SpatialPartitionID p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
_bvh.set_pairable(p_handle - 1, p_pairable, p_pairable_type, p_pairable_mask);
}
@@ -191,7 +195,7 @@ void VisualServerScene::SpatialPartitioningScene_Octree::set_balance(float p_bal
VisualServerScene::Scenario::Scenario() {
debug = VS::SCENARIO_DEBUG_DISABLED;
bool use_bvh_or_octree = GLOBAL_DEF("rendering/quality/spatial_partitioning/use_bvh", true);
bool use_bvh_or_octree = GLOBAL_GET("rendering/quality/spatial_partitioning/use_bvh");
if (use_bvh_or_octree) {
sps = memnew(SpatialPartitioningScene_BVH);
@@ -3574,24 +3578,47 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
p_instance->update_materials = false;
}
void VisualServerScene::update_scenarios() {
// go through all scenarios and update BVH in each
if (!_use_bvh) {
return;
}
List<RID> owned;
scenario_owner.get_owned_list(&owned);
for (List<RID>::Element *E = owned.front(); E; E = E->next()) {
RID rid = E->get();
Scenario *scenario = scenario_owner.get(rid);
scenario->sps->update();
}
}
void VisualServerScene::update_dirty_instances() {
VSG::storage->update_dirty_resources();
// only define this if you run into problems with missed pairing collisions for debugging
//#define GODOT_RENDER_SPS_EXTRA_COLLISION_CHECKS
#ifdef GODOT_RENDER_SPS_EXTRA_COLLISION_CHECKS
// this is just to get access to scenario so we can update the spatial partitioning scheme
Scenario *scenario = nullptr;
if (_instance_update_list.first()) {
scenario = _instance_update_list.first()->self()->scenario;
}
#endif
while (_instance_update_list.first()) {
_update_dirty_instance(_instance_update_list.first()->self());
}
#ifdef GODOT_RENDER_SPS_EXTRA_COLLISION_CHECKS
if (scenario) {
scenario->sps->update();
scenario->sps->update_collisions();
}
#endif
}
bool VisualServerScene::free(RID p_rid) {
@@ -3652,7 +3679,7 @@ VisualServerScene::VisualServerScene() {
render_pass = 1;
singleton = this;
_use_bvh = false;
_use_bvh = GLOBAL_DEF("rendering/quality/spatial_partitioning/use_bvh", true);
}
VisualServerScene::~VisualServerScene() {