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.cpp121
1 files changed, 86 insertions, 35 deletions
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 1e255591f0..1deca7bc66 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "visual_server_scene.h"
-#include "os/os.h"
+#include "core/os/os.h"
#include "visual_server_global.h"
#include "visual_server_raster.h"
/* CAMERA API */
@@ -398,6 +398,7 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
VSG::scene_render->free(gi_probe->probe_instance);
} break;
+ default: {}
}
if (instance->base_data) {
@@ -471,6 +472,7 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
gi_probe->probe_instance = VSG::scene_render->gi_probe_instance_create();
} break;
+ default: {}
}
VSG::storage->instance_add_dependency(p_base, instance);
@@ -518,6 +520,7 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) {
gi_probe_update_list.remove(&gi_probe->update_element);
}
} break;
+ default: {}
}
instance->scenario = NULL;
@@ -549,6 +552,7 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) {
gi_probe_update_list.add(&gi_probe->update_element);
}
} break;
+ default: {}
}
_instance_queue_update(instance, true, true);
@@ -597,8 +601,9 @@ void VisualServerScene::instance_set_surface_material(RID p_instance, int p_surf
Instance *instance = instance_owner.get(p_instance);
ERR_FAIL_COND(!instance);
- if (instance->update_item.in_list()) {
- _update_dirty_instance(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));
}
ERR_FAIL_INDEX(p_surface, instance->materials.size());
@@ -607,7 +612,7 @@ void VisualServerScene::instance_set_surface_material(RID p_instance, int p_surf
VSG::storage->material_remove_instance_owner(instance->materials[p_surface], instance);
}
instance->materials.write[p_surface] = p_material;
- instance->base_material_changed();
+ instance->base_changed(false, true);
if (instance->materials[p_surface].is_valid()) {
VSG::storage->material_add_instance_owner(instance->materials[p_surface], instance);
@@ -649,6 +654,7 @@ void VisualServerScene::instance_set_visible(RID p_instance, bool p_visible) {
}
} break;
+ default: {}
}
}
inline bool is_geometry_instance(VisualServer::InstanceType p_type) {
@@ -825,6 +831,7 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF
instance->redraw_if_visible = p_enabled;
} break;
+ default: {}
}
}
void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting) {
@@ -833,7 +840,7 @@ void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instanc
ERR_FAIL_COND(!instance);
instance->cast_shadows = p_shadow_casting_setting;
- instance->base_material_changed(); // to actually compute if shadows are visible or not
+ instance->base_changed(false, true); // to actually compute if shadows are visible or not
}
void VisualServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) {
@@ -844,7 +851,7 @@ void VisualServerScene::instance_geometry_set_material_override(RID p_instance,
VSG::storage->material_remove_instance_owner(instance->material_override, instance);
}
instance->material_override = p_material;
- instance->base_material_changed();
+ instance->base_changed(false, true);
if (instance->material_override.is_valid()) {
VSG::storage->material_add_instance_owner(instance->material_override, instance);
@@ -902,7 +909,7 @@ void VisualServerScene::_update_instance(Instance *p_instance) {
_update_instance_lightmap_captures(p_instance);
} else {
if (!p_instance->lightmap_capture_data.empty()) {
- !p_instance->lightmap_capture_data.resize(0); //not in use, clear capture data
+ p_instance->lightmap_capture_data.resize(0); //not in use, clear capture data
}
}
}
@@ -1016,7 +1023,6 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) {
new_aabb = VSG::storage->lightmap_capture_get_bounds(p_instance->base);
} break;
-
default: {}
}
@@ -1258,13 +1264,15 @@ void VisualServerScene::_update_instance_lightmap_captures(Instance *p_instance)
}
}
-void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario) {
+bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario) {
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
Transform light_transform = p_instance->transform;
light_transform.orthonormalize(); //scale does not count on lights
+ bool animated_material_found = false;
+
switch (VSG::storage->light_get_type(p_instance->base)) {
case VS::LIGHT_DIRECTIONAL: {
@@ -1297,6 +1305,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
continue;
}
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
+
float max, min;
instance->transformed_aabb.project_range_in_plane(base, min, max);
@@ -1378,9 +1390,12 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
float y_min = 0.f, y_max = 0.f;
float z_min = 0.f, z_max = 0.f;
+ // FIXME: z_max_cam is defined, computed, but not used below when setting up
+ // ortho_camera. Commented out for now to fix warnings but should be investigated.
float x_min_cam = 0.f, x_max_cam = 0.f;
float y_min_cam = 0.f, y_max_cam = 0.f;
- float z_min_cam = 0.f, z_max_cam = 0.f;
+ float z_min_cam = 0.f;
+ //float z_max_cam = 0.f;
float bias_scale = 1.0;
@@ -1442,7 +1457,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
x_min_cam = x_vec.dot(center) - radius;
y_max_cam = y_vec.dot(center) + radius;
y_min_cam = y_vec.dot(center) - radius;
- z_max_cam = z_vec.dot(center) + radius;
+ //z_max_cam = z_vec.dot(center) + radius;
z_min_cam = z_vec.dot(center) - radius;
if (depth_range_mode == VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) {
@@ -1549,6 +1564,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
} else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
+
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
}
@@ -1600,6 +1619,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
} else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
}
@@ -1636,6 +1658,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
} else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
}
@@ -1646,6 +1671,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
} break;
}
+
+ return animated_material_found;
}
void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
@@ -1885,9 +1912,14 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
if (ins->base_type == VS::INSTANCE_PARTICLES) {
//particles visible? process them
- VSG::storage->particles_request_process(ins->base);
- //particles visible? request redraw
- VisualServerRaster::redraw_request();
+ if (VSG::storage->particles_is_inactive(ins->base)) {
+ //but if nothing is going on, don't do it.
+ keep = false;
+ } else {
+ VSG::storage->particles_request_process(ins->base);
+ //particles visible? request redraw
+ VisualServerRaster::redraw_request();
+ }
}
if (geom->lighting_dirty) {
@@ -2087,7 +2119,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
if (redraw) {
//must redraw!
- _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
+ light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
}
}
}
@@ -2133,6 +2165,8 @@ bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int
Scenario *scenario = p_instance->scenario;
ERR_FAIL_COND_V(!scenario, true);
+ VisualServerRaster::redraw_request(); //update, so it updates in editor
+
if (p_step == 0) {
if (!VSG::scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) {
@@ -2821,7 +2855,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
RID rid = E->key();
const InstanceGIProbeData::LightCache &lc = E->get();
- if ((!probe_data->dynamic.light_cache_changes.has(rid) || !(probe_data->dynamic.light_cache_changes[rid] == lc)) && lc.visible) {
+ if ((!probe_data->dynamic.light_cache_changes.has(rid) || probe_data->dynamic.light_cache_changes[rid] != lc) && lc.visible) {
//erase light data
_bake_gi_probe_light(header, cells, local_data, leaves, leaf_count, lc, -1);
@@ -2834,7 +2868,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
RID rid = E->key();
const InstanceGIProbeData::LightCache &lc = E->get();
- if ((!probe_data->dynamic.light_cache.has(rid) || !(probe_data->dynamic.light_cache[rid] == lc)) && lc.visible) {
+ if ((!probe_data->dynamic.light_cache.has(rid) || probe_data->dynamic.light_cache[rid] != lc) && lc.visible) {
//add light data
_bake_gi_probe_light(header, cells, local_data, leaves, leaf_count, lc, 1);
@@ -3051,7 +3085,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) {
lc.transform = probe_data->dynamic.light_to_cell_xform * E->get()->transform;
lc.visible = E->get()->visible;
- if (!probe_data->dynamic.light_cache.has(E->get()->self) || !(probe_data->dynamic.light_cache[E->get()->self] == lc)) {
+ if (!probe_data->dynamic.light_cache.has(E->get()->self) || probe_data->dynamic.light_cache[E->get()->self] != lc) {
all_equal = false;
}
@@ -3071,7 +3105,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) {
lc.transform = probe_data->dynamic.light_to_cell_xform * E->get()->transform;
lc.visible = E->get()->visible;
- if (!probe_data->dynamic.light_cache.has(E->get()->self) || !(probe_data->dynamic.light_cache[E->get()->self] == lc)) {
+ if (!probe_data->dynamic.light_cache.has(E->get()->self) || probe_data->dynamic.light_cache[E->get()->self] != lc) {
all_equal = false;
}
@@ -3154,7 +3188,7 @@ void VisualServerScene::render_probes() {
force_lighting = true;
}
- if (probe->invalid == false && probe->dynamic.enabled) {
+ if (!probe->invalid && probe->dynamic.enabled) {
switch (probe->dynamic.updating_stage) {
case GI_UPDATE_STAGE_CHECK: {
@@ -3233,11 +3267,13 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
bool can_cast_shadows = true;
+ bool is_animated = false;
if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_OFF) {
can_cast_shadows = false;
} else if (p_instance->material_override.is_valid()) {
can_cast_shadows = VSG::storage->material_casts_shadows(p_instance->material_override);
+ is_animated = VSG::storage->material_is_animated(p_instance->material_override);
} else {
if (p_instance->base_type == VS::INSTANCE_MESH) {
@@ -3252,12 +3288,15 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
- break;
- }
+ } else {
- if (VSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- break;
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+
+ if (VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
}
}
@@ -3279,12 +3318,15 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
- break;
- }
- if (VSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- break;
+ } else {
+
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+ if (VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
}
}
@@ -3301,6 +3343,10 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
} else {
can_cast_shadows = false;
}
+
+ if (mat.is_valid() && VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
} else if (p_instance->base_type == VS::INSTANCE_PARTICLES) {
bool cast_shadows = false;
@@ -3320,12 +3366,15 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
- break;
- }
+ } else {
- if (VSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- break;
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+
+ if (VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
}
}
}
@@ -3345,6 +3394,8 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
geom->can_cast_shadows = can_cast_shadows;
}
+
+ geom->material_is_animated = is_animated;
}
}