From d2b1d296340bb514b16af037c7ad6ed19e7b4a3f Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Mon, 4 Apr 2022 15:18:44 +0100 Subject: [PATCH] Physics interpolation - Move out of Scenario Move VisualServer interpolation data out of Scenario and into VisualServerScene, so the interpolation data and enabled status is now common to all Scenarios. Fix physics interpolation in multithreaded mode by ensuring tick and pre-draw are called. --- scene/3d/camera.cpp | 6 - scene/main/scene_tree.cpp | 22 +--- servers/visual/visual_server_raster.cpp | 8 -- servers/visual/visual_server_raster.h | 34 ++++-- servers/visual/visual_server_scene.cpp | 148 ++++++++--------------- servers/visual/visual_server_scene.h | 86 ++++++------- servers/visual/visual_server_wrap_mt.cpp | 30 ----- servers/visual/visual_server_wrap_mt.h | 27 +++-- servers/visual_server.h | 23 ++-- 9 files changed, 155 insertions(+), 229 deletions(-) diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index f8dc631293c2..afafeac837cb 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -115,10 +115,6 @@ void Camera::_notification(int p_what) { if (current || first_camera) { viewport->_camera_set(this); } - - ERR_FAIL_COND(get_world().is_null()); - VisualServer::get_singleton()->camera_set_scenario(camera, get_world()->get_scenario()); - } break; case NOTIFICATION_TRANSFORM_CHANGED: { _request_camera_update(); @@ -132,8 +128,6 @@ void Camera::_notification(int p_what) { } } break; case NOTIFICATION_EXIT_WORLD: { - VisualServer::get_singleton()->camera_set_scenario(camera, RID()); - if (!get_tree()->is_node_being_edited(this)) { if (is_current()) { clear_current(); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 1f38926c21fc..0948fc6cc768 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -507,13 +507,7 @@ void SceneTree::set_physics_interpolation_enabled(bool p_enabled) { } _physics_interpolation_enabled = p_enabled; - - if (root->get_world().is_valid()) { - RID scenario = root->get_world()->get_scenario(); - if (scenario.is_valid()) { - VisualServer::get_singleton()->scenario_set_physics_interpolation_enabled(scenario, p_enabled); - } - } + VisualServer::get_singleton()->set_physics_interpolation_enabled(p_enabled); } bool SceneTree::is_physics_interpolation_enabled() const { @@ -535,11 +529,8 @@ bool SceneTree::iteration(float p_time) { current_frame++; - if (root->get_world().is_valid()) { - RID scenario = root->get_world()->get_scenario(); - if (scenario.is_valid()) { - VisualServer::get_singleton()->scenario_tick(scenario); - } + if (_physics_interpolation_enabled) { + VisualServer::get_singleton()->tick(); } // Any objects performing client physics interpolation @@ -686,11 +677,8 @@ bool SceneTree::idle(float p_time) { #endif - if (root->get_world().is_valid()) { - RID scenario = root->get_world()->get_scenario(); - if (scenario.is_valid()) { - VisualServer::get_singleton()->scenario_pre_draw(scenario, true); - } + if (_physics_interpolation_enabled) { + VisualServer::get_singleton()->pre_draw(true); } return _quit; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 1dc1263b9958..d0e7b76bb610 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -94,14 +94,6 @@ void VisualServerRaster::request_frame_drawn_callback(Object *p_where, const Str frame_drawn_callbacks.push_back(fdc); } -void VisualServerRaster::scenario_tick(RID p_scenario) { - VSG::scene->_scenario_tick(p_scenario); -} - -void VisualServerRaster::scenario_pre_draw(RID p_scenario, bool p_will_draw) { - VSG::scene->_scenario_pre_draw(p_scenario, p_will_draw); -} - void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) { //needs to be done before changes is reset to 0, to not force the editor to redraw VS::get_singleton()->emit_signal("frame_pre_draw"); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 56a643c7f4bd..7cec95877de9 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -116,8 +116,12 @@ class VisualServerRaster : public VisualServer { #define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } +#define BIND0N(m_name) \ + void m_name() { BINDBASE->m_name(); } #define BIND1(m_name, m_type1) \ void m_name(m_type1 arg1) { DISPLAY_CHANGED BINDBASE->m_name(arg1); } +#define BIND1N(m_name, m_type1) \ + void m_name(m_type1 arg1) { BINDBASE->m_name(arg1); } #define BIND2(m_name, m_type1, m_type2) \ void m_name(m_type1 arg1, m_type2 arg2) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2); } #define BIND2C(m_name, m_type1, m_type2) \ @@ -448,10 +452,14 @@ class VisualServerRaster : public VisualServer { //from now on, calls forwarded to this singleton #define BINDBASE VSG::scene + /* EVENT QUEUING */ + + BIND0N(tick) + BIND1N(pre_draw, bool) + /* CAMERA API */ BIND0R(RID, camera_create) - BIND2(camera_set_scenario, RID, RID) BIND4(camera_set_perspective, RID, float, float, float) BIND4(camera_set_orthogonal, RID, float, float, float) BIND5(camera_set_frustum, RID, float, Vector2, float, float) @@ -548,20 +556,24 @@ class VisualServerRaster : public VisualServer { BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) BIND5(environment_set_fog_height, RID, bool, float, float, float) - /* SCENARIO API */ - #undef BINDBASE #define BINDBASE VSG::scene + /* INTERPOLATION */ + + BIND1(set_physics_interpolation_enabled, bool) + + /* SCENARIO API */ + BIND0R(RID, scenario_create) BIND2(scenario_set_debug, RID, ScenarioDebugMode) BIND2(scenario_set_environment, RID, RID) BIND3(scenario_set_reflection_atlas_size, RID, int, int) BIND2(scenario_set_fallback_environment, RID, RID) - BIND2(scenario_set_physics_interpolation_enabled, RID, bool) /* INSTANCING API */ + BIND0R(RID, instance_create) BIND2(instance_set_base, RID, RID) @@ -583,7 +595,8 @@ class VisualServerRaster : public VisualServer { BIND2(instance_set_extra_visibility_margin, RID, real_t) - // Portals + /* PORTALS */ + BIND2(instance_set_portal_mode, RID, InstancePortalMode) BIND0R(RID, ghost_create) @@ -596,13 +609,15 @@ class VisualServerRaster : public VisualServer { BIND4(portal_link, RID, RID, RID, bool) BIND2(portal_set_active, RID, bool) - // Roomgroups + /* ROOMGROUPS */ + BIND0R(RID, roomgroup_create) BIND2(roomgroup_prepare, RID, ObjectID) BIND2(roomgroup_set_scenario, RID, RID) BIND2(roomgroup_add_room, RID, RID) - // Occluders + /* OCCLUDERS */ + BIND0R(RID, occluder_instance_create) BIND2(occluder_instance_set_scenario, RID, RID) BIND2(occluder_instance_link_resource, RID, RID) @@ -616,7 +631,8 @@ class VisualServerRaster : public VisualServer { BIND1(set_use_occlusion_culling, bool) BIND1RC(Geometry::MeshData, occlusion_debug_get_current_polys, RID) - // Rooms + /* ROOMS */ + BIND0R(RID, room_create) BIND2(room_set_scenario, RID, RID) BIND4(room_add_instance, RID, RID, const AABB &, const Vector &) @@ -764,8 +780,6 @@ class VisualServerRaster : public VisualServer { virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const; virtual void init(); virtual void finish(); - virtual void scenario_tick(RID p_scenario); - virtual void scenario_pre_draw(RID p_scenario, bool p_will_draw); /* STATUS INFORMATION */ diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 138fb2c164f6..fd1bdc87d82c 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -39,8 +39,8 @@ /* CAMERA API */ -Transform VisualServerScene::Camera::get_transform() const { - if (!is_currently_interpolated()) { +Transform VisualServerScene::Camera::get_transform_interpolated() const { + if (!interpolated) { return transform; } @@ -54,25 +54,6 @@ RID VisualServerScene::camera_create() { return camera_owner.make_rid(camera); } -void VisualServerScene::camera_set_scenario(RID p_camera, RID p_scenario) { - Camera *camera = camera_owner.get(p_camera); - ERR_FAIL_COND(!camera); - - Scenario *old_scenario = camera->scenario; - - if (p_scenario.is_valid()) { - camera->scenario = scenario_owner.get(p_scenario); - ERR_FAIL_COND(!camera->scenario); - } else { - camera->scenario = nullptr; - } - - if (old_scenario && (old_scenario != camera->scenario)) { - // remove any interpolation data associated with the camera in this scenario - old_scenario->_interpolation_data.notify_free_camera(p_camera, *camera); - } -} - void VisualServerScene::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) { Camera *camera = camera_owner.get(p_camera); ERR_FAIL_COND(!camera); @@ -105,8 +86,8 @@ void VisualServerScene::camera_reset_physics_interpolation(RID p_camera) { Camera *camera = camera_owner.get(p_camera); ERR_FAIL_COND(!camera); - if (camera->is_currently_interpolated()) { - camera->scenario->_interpolation_data.camera_teleport_list.push_back(p_camera); + if (_interpolation_data.interpolation_enabled && camera->interpolated) { + _interpolation_data.camera_teleport_list.push_back(p_camera); } } @@ -122,9 +103,9 @@ void VisualServerScene::camera_set_transform(RID p_camera, const Transform &p_tr camera->transform = p_transform.orthonormalized(); - if (camera->is_currently_interpolated()) { + if (_interpolation_data.interpolation_enabled && camera->interpolated) { if (!camera->on_interpolate_transform_list) { - camera->scenario->_interpolation_data.camera_transform_update_list_curr->push_back(p_camera); + _interpolation_data.camera_transform_update_list_curr->push_back(p_camera); camera->on_interpolate_transform_list = true; } @@ -302,7 +283,6 @@ void VisualServerScene::SpatialPartitioningScene_Octree::set_balance(float p_bal VisualServerScene::Scenario::Scenario() { debug = VS::SCENARIO_DEBUG_DISABLED; - _interpolation_data.interpolation_enabled = false; bool use_bvh_or_octree = GLOBAL_GET("rendering/quality/spatial_partitioning/use_bvh"); @@ -470,30 +450,22 @@ RID VisualServerScene::scenario_create() { return scenario_rid; } -void VisualServerScene::scenario_set_physics_interpolation_enabled(RID p_scenario, bool p_enabled) { - Scenario *scenario = scenario_owner.get(p_scenario); - ERR_FAIL_COND(!scenario); - scenario->_interpolation_data.interpolation_enabled = p_enabled; +void VisualServerScene::set_physics_interpolation_enabled(bool p_enabled) { + _interpolation_data.interpolation_enabled = p_enabled; } -void VisualServerScene::_scenario_tick(RID p_scenario) { - Scenario *scenario = scenario_owner.get(p_scenario); - ERR_FAIL_COND(!scenario); - - if (scenario->is_physics_interpolation_enabled()) { - update_interpolation_tick(scenario->_interpolation_data, true); +void VisualServerScene::tick() { + if (_interpolation_data.interpolation_enabled) { + update_interpolation_tick(true); } } -void VisualServerScene::_scenario_pre_draw(RID p_scenario, bool p_will_draw) { - Scenario *scenario = scenario_owner.get(p_scenario); - ERR_FAIL_COND(!scenario); - +void VisualServerScene::pre_draw(bool p_will_draw) { // even when running and not drawing scenes, we still need to clear intermediate per frame // interpolation data .. hence the p_will_draw flag (so we can reduce the processing if the frame // will not be drawn) - if (scenario->is_physics_interpolation_enabled()) { - update_interpolation_frame(scenario->_interpolation_data, p_will_draw); + if (_interpolation_data.interpolation_enabled) { + update_interpolation_frame(p_will_draw); } } @@ -730,7 +702,7 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { } // remove any interpolation data associated with the instance in this scenario - instance->scenario->_interpolation_data.notify_free_instance(p_instance, *instance); + _interpolation_data.notify_free_instance(p_instance, *instance); switch (instance->base_type) { case VS::INSTANCE_LIGHT: { @@ -801,8 +773,8 @@ void VisualServerScene::instance_reset_physics_interpolation(RID p_instance) { Instance *instance = instance_owner.get(p_instance); ERR_FAIL_COND(!instance); - if (instance->is_currently_interpolated()) { - instance->scenario->_interpolation_data.instance_teleport_list.push_back(p_instance); + if (_interpolation_data.interpolation_enabled && instance->interpolated) { + _interpolation_data.instance_teleport_list.push_back(p_instance); } } @@ -816,19 +788,11 @@ void VisualServerScene::instance_set_transform(RID p_instance, const Transform & Instance *instance = instance_owner.get(p_instance); ERR_FAIL_COND(!instance); - if (!instance->is_currently_interpolated() || !instance->scenario) { + if (!(_interpolation_data.interpolation_enabled && instance->interpolated) || !instance->scenario) { if (instance->transform == p_transform) { return; //must be checked to avoid worst evil } -#ifdef DEV_ENABLED - // If we are interpolated but without a scenario, unsure whether - // this should be supported... - if (instance->is_currently_interpolated()) { - WARN_PRINT_ONCE("Instance interpolated without a scenario."); - } -#endif - #ifdef DEBUG_ENABLED for (int i = 0; i < 4; i++) { @@ -883,23 +847,23 @@ void VisualServerScene::instance_set_transform(RID p_instance, const Transform & instance->transform_checksum_curr = new_checksum; if (!instance->on_interpolate_transform_list) { - instance->scenario->_interpolation_data.instance_transform_update_list_curr->push_back(p_instance); + _interpolation_data.instance_transform_update_list_curr->push_back(p_instance); instance->on_interpolate_transform_list = true; } else { - DEV_ASSERT(instance->scenario->_interpolation_data.instance_transform_update_list_curr->size()); + DEV_ASSERT(_interpolation_data.instance_transform_update_list_curr->size()); } if (!instance->on_interpolate_list) { - instance->scenario->_interpolation_data.instance_interpolate_update_list.push_back(p_instance); + _interpolation_data.instance_interpolate_update_list.push_back(p_instance); instance->on_interpolate_list = true; } else { - DEV_ASSERT(instance->scenario->_interpolation_data.instance_interpolate_update_list.size()); + DEV_ASSERT(_interpolation_data.instance_interpolate_update_list.size()); } _instance_queue_update(instance, true); } -void VisualServerScene::Scenario::InterpolationData::notify_free_camera(RID p_rid, Camera &r_camera) { +void VisualServerScene::InterpolationData::notify_free_camera(RID p_rid, Camera &r_camera) { r_camera.on_interpolate_transform_list = false; if (!interpolation_enabled) { @@ -912,7 +876,7 @@ void VisualServerScene::Scenario::InterpolationData::notify_free_camera(RID p_ri camera_teleport_list.erase_multiple_unordered(p_rid); } -void VisualServerScene::Scenario::InterpolationData::notify_free_instance(RID p_rid, Instance &r_instance) { +void VisualServerScene::InterpolationData::notify_free_instance(RID p_rid, Instance &r_instance) { r_instance.on_interpolate_list = false; r_instance.on_interpolate_transform_list = false; @@ -927,15 +891,15 @@ void VisualServerScene::Scenario::InterpolationData::notify_free_instance(RID p_ instance_teleport_list.erase_multiple_unordered(p_rid); } -void VisualServerScene::update_interpolation_tick(Scenario::InterpolationData &r_interpolation_data, bool p_process) { +void VisualServerScene::update_interpolation_tick(bool p_process) { // update interpolation in storage VSG::storage->update_interpolation_tick(p_process); // detect any that were on the previous transform list that are no longer active, // we should remove them from the interpolate list - for (unsigned int n = 0; n < r_interpolation_data.instance_transform_update_list_prev->size(); n++) { - const RID &rid = (*r_interpolation_data.instance_transform_update_list_prev)[n]; + for (unsigned int n = 0; n < _interpolation_data.instance_transform_update_list_prev->size(); n++) { + const RID &rid = (*_interpolation_data.instance_transform_update_list_prev)[n]; Instance *instance = instance_owner.getornull(rid); bool active = true; @@ -960,15 +924,15 @@ void VisualServerScene::update_interpolation_tick(Scenario::InterpolationData &r } if (!active) { - r_interpolation_data.instance_interpolate_update_list.erase(rid); + _interpolation_data.instance_interpolate_update_list.erase(rid); } } // and now for any in the transform list (being actively interpolated), keep the previous transform // value up to date ready for the next tick if (p_process) { - for (unsigned int n = 0; n < r_interpolation_data.instance_transform_update_list_curr->size(); n++) { - const RID &rid = (*r_interpolation_data.instance_transform_update_list_curr)[n]; + for (unsigned int n = 0; n < _interpolation_data.instance_transform_update_list_curr->size(); n++) { + const RID &rid = (*_interpolation_data.instance_transform_update_list_curr)[n]; Instance *instance = instance_owner.getornull(rid); if (instance) { instance->transform_prev = instance->transform_curr; @@ -980,15 +944,15 @@ void VisualServerScene::update_interpolation_tick(Scenario::InterpolationData &r // we maintain a mirror list for the transform updates, so we can detect when an instance // is no longer being transformed, and remove it from the interpolate list - SWAP(r_interpolation_data.instance_transform_update_list_curr, r_interpolation_data.instance_transform_update_list_prev); + SWAP(_interpolation_data.instance_transform_update_list_curr, _interpolation_data.instance_transform_update_list_prev); // prepare for the next iteration - r_interpolation_data.instance_transform_update_list_curr->clear(); + _interpolation_data.instance_transform_update_list_curr->clear(); // CAMERAS // detect any that were on the previous transform list that are no longer active, - for (unsigned int n = 0; n < r_interpolation_data.camera_transform_update_list_prev->size(); n++) { - const RID &rid = (*r_interpolation_data.camera_transform_update_list_prev)[n]; + for (unsigned int n = 0; n < _interpolation_data.camera_transform_update_list_prev->size(); n++) { + const RID &rid = (*_interpolation_data.camera_transform_update_list_prev)[n]; Camera *camera = camera_owner.getornull(rid); // no longer active? (either the instance deleted or no longer being transformed) @@ -998,8 +962,8 @@ void VisualServerScene::update_interpolation_tick(Scenario::InterpolationData &r } // cameras , swap any current with previous - for (unsigned int n = 0; n < r_interpolation_data.camera_transform_update_list_curr->size(); n++) { - const RID &rid = (*r_interpolation_data.camera_transform_update_list_curr)[n]; + for (unsigned int n = 0; n < _interpolation_data.camera_transform_update_list_curr->size(); n++) { + const RID &rid = (*_interpolation_data.camera_transform_update_list_curr)[n]; Camera *camera = camera_owner.getornull(rid); if (camera) { camera->transform_prev = camera->transform; @@ -1009,19 +973,19 @@ void VisualServerScene::update_interpolation_tick(Scenario::InterpolationData &r // we maintain a mirror list for the transform updates, so we can detect when an instance // is no longer being transformed, and remove it from the interpolate list - SWAP(r_interpolation_data.camera_transform_update_list_curr, r_interpolation_data.camera_transform_update_list_prev); + SWAP(_interpolation_data.camera_transform_update_list_curr, _interpolation_data.camera_transform_update_list_prev); // prepare for the next iteration - r_interpolation_data.camera_transform_update_list_curr->clear(); + _interpolation_data.camera_transform_update_list_curr->clear(); } -void VisualServerScene::update_interpolation_frame(Scenario::InterpolationData &r_interpolation_data, bool p_process) { +void VisualServerScene::update_interpolation_frame(bool p_process) { // update interpolation in storage VSG::storage->update_interpolation_frame(p_process); // teleported instances - for (unsigned int n = 0; n < r_interpolation_data.instance_teleport_list.size(); n++) { - const RID &rid = r_interpolation_data.instance_teleport_list[n]; + for (unsigned int n = 0; n < _interpolation_data.instance_teleport_list.size(); n++) { + const RID &rid = _interpolation_data.instance_teleport_list[n]; Instance *instance = instance_owner.getornull(rid); if (instance) { instance->transform_prev = instance->transform_curr; @@ -1029,24 +993,24 @@ void VisualServerScene::update_interpolation_frame(Scenario::InterpolationData & } } - r_interpolation_data.instance_teleport_list.clear(); + _interpolation_data.instance_teleport_list.clear(); // camera teleports - for (unsigned int n = 0; n < r_interpolation_data.camera_teleport_list.size(); n++) { - const RID &rid = r_interpolation_data.camera_teleport_list[n]; + for (unsigned int n = 0; n < _interpolation_data.camera_teleport_list.size(); n++) { + const RID &rid = _interpolation_data.camera_teleport_list[n]; Camera *camera = camera_owner.getornull(rid); if (camera) { camera->transform_prev = camera->transform; } } - r_interpolation_data.camera_teleport_list.clear(); + _interpolation_data.camera_teleport_list.clear(); if (p_process) { real_t f = Engine::get_singleton()->get_physics_interpolation_fraction(); - for (unsigned int i = 0; i < r_interpolation_data.instance_interpolate_update_list.size(); i++) { - const RID &rid = r_interpolation_data.instance_interpolate_update_list[i]; + for (unsigned int i = 0; i < _interpolation_data.instance_interpolate_update_list.size(); i++) { + const RID &rid = _interpolation_data.instance_interpolate_update_list[i]; Instance *instance = instance_owner.getornull(rid); if (instance) { TransformInterpolator::interpolate_transform_via_method(instance->transform_prev, instance->transform_curr, instance->transform, f, instance->interpolation_method); @@ -2803,8 +2767,7 @@ void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_view } break; } - // This getter allows optional fixed timestep interpolation for the camera. - Transform camera_transform = camera->get_transform(); + Transform camera_transform = _interpolation_data.interpolation_enabled ? camera->get_transform_interpolated() : camera->transform; _prepare_scene(camera_transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), camera->previous_room_id_hint); _render_scene(camera_transform, camera_matrix, 0, ortho, camera->env, p_scenario, p_shadow_atlas, RID(), -1); @@ -4466,10 +4429,7 @@ void VisualServerScene::update_dirty_instances() { bool VisualServerScene::free(RID p_rid) { if (camera_owner.owns(p_rid)) { Camera *camera = camera_owner.get(p_rid); - - if (camera->scenario) { - camera->scenario->_interpolation_data.notify_free_camera(p_rid, *camera); - } + _interpolation_data.notify_free_camera(p_rid, *camera); camera_owner.free(p_rid); memdelete(camera); @@ -4490,15 +4450,7 @@ bool VisualServerScene::free(RID p_rid) { update_dirty_instances(); Instance *instance = instance_owner.get(p_rid); - - if (instance->scenario) { - instance->scenario->_interpolation_data.notify_free_instance(p_rid, *instance); - } else { - if (instance->on_interpolate_list || instance->on_interpolate_transform_list) { - // These flags should be set to false when removing the scenario. - WARN_PRINT_ONCE("Instance delete without scenario and on interpolate lists."); - } - } + _interpolation_data.notify_free_instance(p_rid, *instance); instance_set_use_lightmap(p_rid, RID(), RID(), -1, Rect2(0, 0, 1, 1)); instance_set_scenario(p_rid, RID()); diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index f1a9040791f9..06fc94825d2a 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -57,6 +57,11 @@ class VisualServerScene { uint64_t render_pass; static VisualServerScene *singleton; + /* EVENT QUEUING */ + + void tick(); + void pre_draw(bool p_will_draw); + /* CAMERA API */ struct Scenario; @@ -78,8 +83,6 @@ class VisualServerScene { Transform transform; Transform transform_prev; - Scenario *scenario; - bool interpolated : 1; bool on_interpolate_transform_list : 1; @@ -88,10 +91,7 @@ class VisualServerScene { int32_t previous_room_id_hint; - // call get transform to get either the transform straight, - // or the interpolated transform if using fixed timestep interpolation - Transform get_transform() const; - bool is_currently_interpolated() const { return scenario && scenario->is_physics_interpolation_enabled() && interpolated; } + Transform get_transform_interpolated() const; Camera() { visible_layers = 0xFFFFFFFF; @@ -102,7 +102,6 @@ class VisualServerScene { size = 1.0; offset = Vector2(); vaspect = false; - scenario = nullptr; previous_room_id_hint = -1; interpolated = true; on_interpolate_transform_list = false; @@ -113,7 +112,6 @@ class VisualServerScene { mutable RID_Owner camera_owner; virtual RID camera_create(); - virtual void camera_set_scenario(RID p_camera, RID p_scenario); virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far); virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far); virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far); @@ -270,26 +268,6 @@ class VisualServerScene { SelfList::List instances; - bool is_physics_interpolation_enabled() const { return _interpolation_data.interpolation_enabled; } - - // fixed timestep interpolation - struct InterpolationData { - void notify_free_camera(RID p_rid, Camera &r_camera); - void notify_free_instance(RID p_rid, Instance &r_instance); - LocalVector instance_interpolate_update_list; - LocalVector instance_transform_update_lists[2]; - LocalVector *instance_transform_update_list_curr = &instance_transform_update_lists[0]; - LocalVector *instance_transform_update_list_prev = &instance_transform_update_lists[1]; - LocalVector instance_teleport_list; - - LocalVector camera_transform_update_lists[2]; - LocalVector *camera_transform_update_list_curr = &camera_transform_update_lists[0]; - LocalVector *camera_transform_update_list_prev = &camera_transform_update_lists[1]; - LocalVector camera_teleport_list; - - bool interpolation_enabled; - } _interpolation_data; - Scenario(); ~Scenario() { memdelete(sps); } }; @@ -305,9 +283,6 @@ class VisualServerScene { virtual void scenario_set_environment(RID p_scenario, RID p_environment); virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment); virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_size, int p_subdiv); - virtual void scenario_set_physics_interpolation_enabled(RID p_scenario, bool p_enabled); - void _scenario_tick(RID p_scenario); - void _scenario_pre_draw(RID p_scenario, bool p_will_draw); /* INSTANCING API */ @@ -365,8 +340,6 @@ class VisualServerScene { singleton->_instance_queue_update(this, p_aabb, p_materials); } - bool is_currently_interpolated() const { return scenario && scenario->is_physics_interpolation_enabled() && interpolated; } - Instance() : scenario_item(this), update_item(this) { @@ -412,6 +385,26 @@ class VisualServerScene { SelfList::List _instance_update_list; + // fixed timestep interpolation + virtual void set_physics_interpolation_enabled(bool p_enabled); + + struct InterpolationData { + void notify_free_camera(RID p_rid, Camera &r_camera); + void notify_free_instance(RID p_rid, Instance &r_instance); + LocalVector instance_interpolate_update_list; + LocalVector instance_transform_update_lists[2]; + LocalVector *instance_transform_update_list_curr = &instance_transform_update_lists[0]; + LocalVector *instance_transform_update_list_prev = &instance_transform_update_lists[1]; + LocalVector instance_teleport_list; + + LocalVector camera_transform_update_lists[2]; + LocalVector *camera_transform_update_list_curr = &camera_transform_update_lists[0]; + LocalVector *camera_transform_update_list_prev = &camera_transform_update_lists[1]; + LocalVector camera_teleport_list; + + bool interpolation_enabled = false; + } _interpolation_data; + void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_materials = false); struct InstanceGeometryData : public InstanceBaseData { @@ -688,6 +681,8 @@ class VisualServerScene { void _ghost_destroy_occlusion_rep(Ghost *p_ghost); public: + /* PORTALS API */ + struct Portal : RID_Data { // all interactions with actual portals are indirect, as the portal is part of the scenario uint32_t scenario_portal_id = 0; @@ -708,7 +703,8 @@ class VisualServerScene { virtual void portal_link(RID p_portal, RID p_room_from, RID p_room_to, bool p_two_way); virtual void portal_set_active(RID p_portal, bool p_active); - // RoomGroups + /* ROOMGROUPS API */ + struct RoomGroup : RID_Data { // all interactions with actual roomgroups are indirect, as the roomgroup is part of the scenario uint32_t scenario_roomgroup_id = 0; @@ -728,7 +724,8 @@ class VisualServerScene { virtual void roomgroup_set_scenario(RID p_roomgroup, RID p_scenario); virtual void roomgroup_add_room(RID p_roomgroup, RID p_room); - // Occluders + /* OCCLUDERS API */ + struct OccluderInstance : RID_Data { uint32_t scenario_occluder_id = 0; Scenario *scenario = nullptr; @@ -768,10 +765,15 @@ class VisualServerScene { // editor only .. slow virtual Geometry::MeshData occlusion_debug_get_current_polys(RID p_scenario) const; - const PortalResources &get_portal_resources() const { return _portal_resources; } - PortalResources &get_portal_resources() { return _portal_resources; } + const PortalResources &get_portal_resources() const { + return _portal_resources; + } + PortalResources &get_portal_resources() { + return _portal_resources; + } + + /* ROOMS API */ - // Rooms struct Room : RID_Data { // all interactions with actual rooms are indirect, as the room is part of the scenario uint32_t scenario_room_id = 0; @@ -805,7 +807,9 @@ class VisualServerScene { virtual bool rooms_is_loaded(RID p_scenario) const; virtual void callbacks_register(VisualServerCallbacks *p_callbacks); - VisualServerCallbacks *get_callbacks() const { return _visual_server_callbacks; } + VisualServerCallbacks *get_callbacks() const { + return _visual_server_callbacks; + } // don't use these in a game! virtual Vector instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const; @@ -840,8 +844,8 @@ class VisualServerScene { void update_dirty_instances(); // interpolation - void update_interpolation_tick(Scenario::InterpolationData &r_interpolation_data, bool p_process = true); - void update_interpolation_frame(Scenario::InterpolationData &r_interpolation_data, bool p_process = true); + void update_interpolation_tick(bool p_process = true); + void update_interpolation_frame(bool p_process = true); //probes struct GIProbeDataHeader { diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp index 54102875e8f8..ec8bbc5e33c3 100644 --- a/servers/visual/visual_server_wrap_mt.cpp +++ b/servers/visual/visual_server_wrap_mt.cpp @@ -36,18 +36,6 @@ void VisualServerWrapMT::thread_exit() { exit.set(); } -void VisualServerWrapMT::thread_scenario_tick(RID p_scenario) { - if (!draw_pending.decrement()) { - visual_server->scenario_tick(p_scenario); - } -} - -void VisualServerWrapMT::thread_scenario_pre_draw(RID p_scenario, bool p_will_draw) { - if (!draw_pending.decrement()) { - visual_server->scenario_pre_draw(p_scenario, p_will_draw); - } -} - void VisualServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) { if (!draw_pending.decrement()) { visual_server->draw(p_swap_buffers, frame_step); @@ -94,24 +82,6 @@ void VisualServerWrapMT::sync() { } } -void VisualServerWrapMT::scenario_tick(RID p_scenario) { - if (create_thread) { - draw_pending.increment(); - command_queue.push(this, &VisualServerWrapMT::thread_scenario_tick, p_scenario); - } else { - visual_server->scenario_tick(p_scenario); - } -} - -void VisualServerWrapMT::scenario_pre_draw(RID p_scenario, bool p_will_draw) { - if (create_thread) { - draw_pending.increment(); - command_queue.push(this, &VisualServerWrapMT::thread_scenario_pre_draw, p_scenario, p_will_draw); - } else { - visual_server->scenario_pre_draw(p_scenario, p_will_draw); - } -} - void VisualServerWrapMT::draw(bool p_swap_buffers, double frame_step) { if (create_thread) { draw_pending.increment(); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index e2c97cab3ba4..de097369b419 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -54,8 +54,6 @@ class VisualServerWrapMT : public VisualServer { SafeNumeric draw_pending; void thread_draw(bool p_swap_buffers, double frame_step); void thread_flush(); - void thread_scenario_tick(RID p_scenario); - void thread_scenario_pre_draw(RID p_scenario, bool p_will_draw); void thread_exit(); @@ -374,7 +372,6 @@ class VisualServerWrapMT : public VisualServer { /* CAMERA API */ FUNCRID(camera) - FUNC2(camera_set_scenario, RID, RID) FUNC4(camera_set_perspective, RID, float, float, float) FUNC4(camera_set_orthogonal, RID, float, float, float) FUNC5(camera_set_frustum, RID, float, Vector2, float, float) @@ -468,15 +465,21 @@ class VisualServerWrapMT : public VisualServer { FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) FUNC5(environment_set_fog_height, RID, bool, float, float, float) + /* INTERPOLATION API */ + + FUNC1(set_physics_interpolation_enabled, bool) + + /* SCENARIO API */ + FUNCRID(scenario) FUNC2(scenario_set_debug, RID, ScenarioDebugMode) FUNC2(scenario_set_environment, RID, RID) FUNC3(scenario_set_reflection_atlas_size, RID, int, int) FUNC2(scenario_set_fallback_environment, RID, RID) - FUNC2(scenario_set_physics_interpolation_enabled, RID, bool) /* INSTANCING API */ + FUNCRID(instance) FUNC2(instance_set_base, RID, RID) @@ -498,7 +501,8 @@ class VisualServerWrapMT : public VisualServer { FUNC2(instance_set_extra_visibility_margin, RID, real_t) - // Portals + /* PORTALS API */ + FUNC2(instance_set_portal_mode, RID, InstancePortalMode) FUNCRID(ghost) @@ -511,13 +515,15 @@ class VisualServerWrapMT : public VisualServer { FUNC4(portal_link, RID, RID, RID, bool) FUNC2(portal_set_active, RID, bool) - // Roomgroups + /* ROOMGROUPS API */ + FUNCRID(roomgroup) FUNC2(roomgroup_prepare, RID, ObjectID) FUNC2(roomgroup_set_scenario, RID, RID) FUNC2(roomgroup_add_room, RID, RID) - // Occluders + /* OCCLUDERS API */ + FUNCRID(occluder_instance) FUNC2(occluder_instance_set_scenario, RID, RID) FUNC2(occluder_instance_link_resource, RID, RID) @@ -531,7 +537,8 @@ class VisualServerWrapMT : public VisualServer { FUNC1(set_use_occlusion_culling, bool) FUNC1RC(Geometry::MeshData, occlusion_debug_get_current_polys, RID) - // Rooms + /* ROOMS API */ + FUNCRID(room) FUNC2(room_set_scenario, RID, RID) FUNC4(room_add_instance, RID, RID, const AABB &, const Vector &) @@ -674,8 +681,8 @@ class VisualServerWrapMT : public VisualServer { virtual void finish(); virtual void draw(bool p_swap_buffers, double frame_step); virtual void sync(); - virtual void scenario_tick(RID p_scenario); - virtual void scenario_pre_draw(RID p_scenario, bool p_will_draw); + FUNC0(tick) + FUNC1(pre_draw, bool) FUNC1RC(bool, has_changed, ChangedPriority) /* RENDER INFO */ diff --git a/servers/visual_server.h b/servers/visual_server.h index 356e7148e5f9..832bae020060 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -619,7 +619,6 @@ class VisualServer : public Object { /* CAMERA API */ virtual RID camera_create() = 0; - virtual void camera_set_scenario(RID p_camera, RID p_scenario) = 0; virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0; virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0; virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) = 0; @@ -821,6 +820,10 @@ class VisualServer : public Object { virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0; virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0; + /* INTERPOLATION API */ + + virtual void set_physics_interpolation_enabled(bool p_enabled) = 0; + /* SCENARIO API */ virtual RID scenario_create() = 0; @@ -837,7 +840,6 @@ class VisualServer : public Object { virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0; virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_size, int p_subdiv) = 0; virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment) = 0; - virtual void scenario_set_physics_interpolation_enabled(RID p_scenario, bool p_enabled) = 0; /* INSTANCING API */ @@ -881,8 +883,8 @@ class VisualServer : public Object { virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) = 0; - /* ROOMS AND PORTALS API */ - // Portals + /* PORTALS API */ + enum InstancePortalMode { INSTANCE_PORTAL_MODE_STATIC, // not moving within a room INSTANCE_PORTAL_MODE_DYNAMIC, // moving within room @@ -903,13 +905,15 @@ class VisualServer : public Object { virtual void portal_link(RID p_portal, RID p_room_from, RID p_room_to, bool p_two_way) = 0; virtual void portal_set_active(RID p_portal, bool p_active) = 0; - // Roomgroups + /* ROOMGROUPS API */ + virtual RID roomgroup_create() = 0; virtual void roomgroup_prepare(RID p_roomgroup, ObjectID p_roomgroup_object_id) = 0; virtual void roomgroup_set_scenario(RID p_roomgroup, RID p_scenario) = 0; virtual void roomgroup_add_room(RID p_roomgroup, RID p_room) = 0; - // Occluders + /* OCCLUDERS API */ + enum OccluderType { OCCLUDER_TYPE_UNDEFINED, OCCLUDER_TYPE_SPHERE, @@ -931,7 +935,8 @@ class VisualServer : public Object { virtual void set_use_occlusion_culling(bool p_enable) = 0; virtual Geometry::MeshData occlusion_debug_get_current_polys(RID p_scenario) const = 0; - // Rooms + /* ROOMS API */ + enum RoomsDebugFeature { ROOMS_DEBUG_SPRAWL, }; @@ -1131,8 +1136,8 @@ class VisualServer : public Object { virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const = 0; virtual void init() = 0; virtual void finish() = 0; - virtual void scenario_tick(RID p_scenario) = 0; - virtual void scenario_pre_draw(RID p_scenario, bool p_will_draw) = 0; + virtual void tick() = 0; + virtual void pre_draw(bool p_will_draw) = 0; /* STATUS INFORMATION */