summaryrefslogtreecommitdiff
path: root/servers/visual/visual_server_scene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/visual/visual_server_scene.cpp')
-rw-r--r--servers/visual/visual_server_scene.cpp93
1 files changed, 45 insertions, 48 deletions
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 69ab4a6b9b..e2fb0a6351 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -304,12 +304,12 @@ void VisualServerScene::scenario_set_reflection_atlas_size(RID p_scenario, int p
/* INSTANCING API */
-void VisualServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_materials) {
+void VisualServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) {
if (p_update_aabb)
p_instance->update_aabb = true;
- if (p_update_materials)
- p_instance->update_materials = true;
+ if (p_update_dependencies)
+ p_instance->update_dependencies = true;
if (p_instance->update_item.in_list())
return;
@@ -338,8 +338,6 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
if (instance->base_type != VS::INSTANCE_NONE) {
//free anything related to that base
- VSG::storage->instance_remove_dependency(instance->base, instance);
-
if (instance->base_type == VS::INSTANCE_GI_PROBE) {
//if gi probe is baking, wait until done baking, else race condition may happen when removing it
//from octree
@@ -421,12 +419,6 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
}
instance->blend_values.clear();
-
- for (int i = 0; i < instance->materials.size(); i++) {
- if (instance->materials[i].is_valid()) {
- VSG::storage->material_remove_instance_owner(instance->materials[i], instance);
- }
- }
instance->materials.clear();
}
@@ -493,13 +485,13 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
}
}
- VSG::storage->instance_add_dependency(p_base, instance);
-
instance->base = p_base;
- if (scenario)
- _instance_queue_update(instance, true, true);
+ //forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it
+ VSG::storage->base_update_dependency(p_base, instance);
}
+
+ _instance_queue_update(instance, true, true);
}
void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) {
@@ -635,21 +627,15 @@ void VisualServerScene::instance_set_surface_material(RID p_instance, int p_surf
ERR_FAIL_COND(!instance);
if (instance->base_type == VS::INSTANCE_MESH) {
- //may not have been updated yet
- instance->materials.resize(VSG::storage->mesh_get_surface_count(instance->base));
+ //may not have been updated yet, may also have not been set yet. When updated will be correcte, worst case
+ instance->materials.resize(MAX(p_surface + 1, VSG::storage->mesh_get_surface_count(instance->base)));
}
ERR_FAIL_INDEX(p_surface, instance->materials.size());
- if (instance->materials[p_surface].is_valid()) {
- VSG::storage->material_remove_instance_owner(instance->materials[p_surface], instance);
- }
instance->materials.write[p_surface] = p_material;
- instance->base_changed(false, true);
- if (instance->materials[p_surface].is_valid()) {
- VSG::storage->material_add_instance_owner(instance->materials[p_surface], instance);
- }
+ _instance_queue_update(instance, false, true);
}
void VisualServerScene::instance_set_visible(RID p_instance, bool p_visible) {
@@ -753,17 +739,13 @@ void VisualServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton)
if (instance->skeleton == p_skeleton)
return;
- if (instance->skeleton.is_valid()) {
- VSG::storage->instance_remove_skeleton(instance->skeleton, instance);
- }
-
instance->skeleton = p_skeleton;
- if (instance->skeleton.is_valid()) {
- VSG::storage->instance_add_skeleton(instance->skeleton, instance);
+ if (p_skeleton.is_valid()) {
+ //update the dependency now, so if cleared, we remove it
+ VSG::storage->skeleton_update_dependency(p_skeleton, instance);
}
-
- _instance_queue_update(instance, true);
+ _instance_queue_update(instance, true, true);
}
void VisualServerScene::instance_set_exterior(RID p_instance, bool p_enabled) {
@@ -875,22 +857,15 @@ void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instanc
ERR_FAIL_COND(!instance);
instance->cast_shadows = p_shadow_casting_setting;
- instance->base_changed(false, true); // to actually compute if shadows are visible or not
+ _instance_queue_update(instance, false, true);
}
void VisualServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
- if (instance->material_override.is_valid()) {
- VSG::storage->material_remove_instance_owner(instance->material_override, instance);
- }
instance->material_override = p_material;
- instance->base_changed(false, true);
-
- if (instance->material_override.is_valid()) {
- VSG::storage->material_add_instance_owner(instance->material_override, instance);
- }
+ _instance_queue_update(instance, false, true);
}
void VisualServerScene::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) {
@@ -3291,17 +3266,22 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
_update_instance_aabb(p_instance);
}
- if (p_instance->update_materials) {
+ if (p_instance->update_dependencies) {
+
+ p_instance->instance_increase_version();
+
+ if (p_instance->base.is_valid()) {
+ VSG::storage->base_update_dependency(p_instance->base, p_instance);
+ }
+
+ if (p_instance->material_override.is_valid()) {
+ VSG::storage->material_update_dependency(p_instance->material_override, p_instance);
+ }
if (p_instance->base_type == VS::INSTANCE_MESH) {
//remove materials no longer used and un-own them
int new_mat_count = VSG::storage->mesh_get_surface_count(p_instance->base);
- for (int i = p_instance->materials.size() - 1; i >= new_mat_count; i--) {
- if (p_instance->materials[i].is_valid()) {
- VSG::storage->material_remove_instance_owner(p_instance->materials[i], p_instance);
- }
- }
p_instance->materials.resize(new_mat_count);
int new_blend_shape_count = VSG::storage->mesh_get_blend_shape_count(p_instance->base);
@@ -3348,6 +3328,8 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (VSG::storage->material_is_animated(mat)) {
is_animated = true;
}
+
+ VSG::storage->material_update_dependency(mat, p_instance);
}
}
@@ -3378,6 +3360,8 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (VSG::storage->material_is_animated(mat)) {
is_animated = true;
}
+
+ VSG::storage->material_update_dependency(mat, p_instance);
}
}
@@ -3394,6 +3378,11 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (mat.is_valid() && VSG::storage->material_is_animated(mat)) {
is_animated = true;
}
+
+ if (mat.is_valid()) {
+ VSG::storage->material_update_dependency(mat, p_instance);
+ }
+
} else if (p_instance->base_type == VS::INSTANCE_PARTICLES) {
bool cast_shadows = false;
@@ -3422,6 +3411,8 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (VSG::storage->material_is_animated(mat)) {
is_animated = true;
}
+
+ VSG::storage->material_update_dependency(mat, p_instance);
}
}
}
@@ -3444,6 +3435,12 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
geom->material_is_animated = is_animated;
}
+
+ if (p_instance->skeleton.is_valid()) {
+ VSG::storage->skeleton_update_dependency(p_instance->skeleton, p_instance);
+ }
+
+ p_instance->clean_up_dependencies();
}
_instance_update_list.remove(&p_instance->update_item);
@@ -3451,7 +3448,7 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
_update_instance(p_instance);
p_instance->update_aabb = false;
- p_instance->update_materials = false;
+ p_instance->update_dependencies = false;
}
void VisualServerScene::update_dirty_instances() {