diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 3afdf6504..a81a2875b 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -120,10 +120,6 @@ void Camera::_notification(int p_what) { if (current || first_camera) { world->_camera_set(this); } - - ERR_FAIL_COND(get_world_3d().is_null()); - RenderingServer::get_singleton()->camera_set_scenario(camera, get_world_3d()->get_scenario()); - } break; case NOTIFICATION_TRANSFORM_CHANGED: { _request_camera_update(); @@ -137,8 +133,6 @@ void Camera::_notification(int p_what) { } } break; case NOTIFICATION_EXIT_WORLD: { - RenderingServer::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 84fde2050..a08a83416 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -586,12 +586,7 @@ void SceneTree::set_physics_interpolation_enabled(bool p_enabled) { _physics_interpolation_enabled = p_enabled; - if (root->get_world_3d().is_valid()) { - RID scenario = root->get_world_3d()->get_scenario(); - if (scenario.is_valid()) { - RenderingServer::get_singleton()->scenario_set_physics_interpolation_enabled(scenario, p_enabled); - } - } + RenderingServer::get_singleton()->set_physics_interpolation_enabled(p_enabled); } bool SceneTree::is_physics_interpolation_enabled() const { @@ -621,11 +616,8 @@ bool SceneTree::iteration(float p_time) { current_frame++; - if (root->get_world_3d().is_valid()) { - RID scenario = root->get_world_3d()->get_scenario(); - if (scenario.is_valid()) { - RenderingServer::get_singleton()->scenario_tick(scenario); - } + if (_physics_interpolation_enabled) { + RenderingServer::get_singleton()->tick(); } // Any objects performing client physics interpolation @@ -795,11 +787,8 @@ bool SceneTree::idle(float p_time) { #endif - if (root->get_world_3d().is_valid()) { - RID scenario = root->get_world_3d()->get_scenario(); - if (scenario.is_valid()) { - RenderingServer::get_singleton()->scenario_pre_draw(scenario, true); - } + if (_physics_interpolation_enabled) { + RenderingServer::get_singleton()->pre_draw(true); } return _quit; diff --git a/servers/rendering/rendering_server_raster.cpp b/servers/rendering/rendering_server_raster.cpp index 09e6c0848..9d16d0c46 100644 --- a/servers/rendering/rendering_server_raster.cpp +++ b/servers/rendering/rendering_server_raster.cpp @@ -101,14 +101,6 @@ void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const frame_drawn_callbacks.push_back(fdc); } -void RenderingServerRaster::scenario_tick(RID p_scenario) { - RSG::scene->_scenario_tick(p_scenario); -} - -void RenderingServerRaster::scenario_pre_draw(RID p_scenario, bool p_will_draw) { - RSG::scene->_scenario_pre_draw(p_scenario, p_will_draw); -} - void RenderingServerRaster::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 RS::get_singleton()->emit_signal("frame_pre_draw"); diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index d6fa079b4..9675e5223 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -115,8 +115,12 @@ public: #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) \ @@ -357,10 +361,14 @@ public: //from now on, calls forwarded to this singleton #define BINDBASE RSG::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) @@ -455,20 +463,24 @@ public: 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 RSG::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) @@ -490,7 +502,8 @@ public: BIND2(instance_set_extra_visibility_margin, RID, real_t) - // Portals + /* PORTALS */ + BIND2(instance_set_portal_mode, RID, InstancePortalMode) BIND0R(RID, ghost_create) @@ -503,13 +516,15 @@ public: 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) @@ -523,7 +538,8 @@ public: 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 &) @@ -674,8 +690,6 @@ public: 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/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp index 61fb9898d..d6f8a17e5 100644 --- a/servers/rendering/rendering_server_scene.cpp +++ b/servers/rendering/rendering_server_scene.cpp @@ -40,8 +40,8 @@ /* CAMERA API */ -Transform RenderingServerScene::Camera::get_transform() const { - if (!is_currently_interpolated()) { +Transform RenderingServerScene::Camera::get_transform_interpolated() const { + if (!interpolated) { return transform; } @@ -55,25 +55,6 @@ RID RenderingServerScene::camera_create() { return camera_owner.make_rid(camera); } -void RenderingServerScene::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 RenderingServerScene::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); @@ -106,8 +87,8 @@ void RenderingServerScene::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); } } @@ -123,9 +104,9 @@ void RenderingServerScene::camera_set_transform(RID p_camera, const Transform &p 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; } @@ -303,7 +284,6 @@ void RenderingServerScene::SpatialPartitioningScene_Octree::set_balance(float p_ RenderingServerScene::Scenario::Scenario() { debug = RS::SCENARIO_DEBUG_DISABLED; - _interpolation_data.interpolation_enabled = false; bool use_bvh_or_octree = GLOBAL_GET("rendering/quality/spatial_partitioning/use_bvh"); @@ -416,30 +396,22 @@ RID RenderingServerScene::scenario_create() { return scenario_rid; } -void RenderingServerScene::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 RenderingServerScene::set_physics_interpolation_enabled(bool p_enabled) { + _interpolation_data.interpolation_enabled = p_enabled; } -void RenderingServerScene::_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 RenderingServerScene::tick() { + if (_interpolation_data.interpolation_enabled) { + update_interpolation_tick(true); } } -void RenderingServerScene::_scenario_pre_draw(RID p_scenario, bool p_will_draw) { - Scenario *scenario = scenario_owner.get(p_scenario); - ERR_FAIL_COND(!scenario); - +void RenderingServerScene::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); } } @@ -614,7 +586,7 @@ void RenderingServerScene::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 RS::INSTANCE_LIGHT: { @@ -697,8 +669,8 @@ void RenderingServerScene::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); } } @@ -712,19 +684,11 @@ void RenderingServerScene::instance_set_transform(RID p_instance, const Transfor 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++) { @@ -776,10 +740,10 @@ void RenderingServerScene::instance_set_transform(RID p_instance, const Transfor 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 the instance is invisible, then we are simply updating the data flow, there is no need to calculate the interpolated @@ -794,16 +758,16 @@ void RenderingServerScene::instance_set_transform(RID p_instance, const Transfor instance->interpolation_method = TransformInterpolator::find_method(instance->transform_prev.basis, instance->transform_curr.basis); 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 RenderingServerScene::Scenario::InterpolationData::notify_free_camera(RID p_rid, Camera &r_camera) { +void RenderingServerScene::InterpolationData::notify_free_camera(RID p_rid, Camera &r_camera) { r_camera.on_interpolate_transform_list = false; if (!interpolation_enabled) { @@ -816,7 +780,7 @@ void RenderingServerScene::Scenario::InterpolationData::notify_free_camera(RID p camera_teleport_list.erase_multiple_unordered(p_rid); } -void RenderingServerScene::Scenario::InterpolationData::notify_free_instance(RID p_rid, Instance &r_instance) { +void RenderingServerScene::InterpolationData::notify_free_instance(RID p_rid, Instance &r_instance) { r_instance.on_interpolate_list = false; r_instance.on_interpolate_transform_list = false; @@ -831,15 +795,15 @@ void RenderingServerScene::Scenario::InterpolationData::notify_free_instance(RID instance_teleport_list.erase_multiple_unordered(p_rid); } -void RenderingServerScene::update_interpolation_tick(Scenario::InterpolationData &r_interpolation_data, bool p_process) { +void RenderingServerScene::update_interpolation_tick(bool p_process) { // update interpolation in storage RSG::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; @@ -864,15 +828,15 @@ void RenderingServerScene::update_interpolation_tick(Scenario::InterpolationData } 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; @@ -884,15 +848,15 @@ void RenderingServerScene::update_interpolation_tick(Scenario::InterpolationData // 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) @@ -902,8 +866,8 @@ void RenderingServerScene::update_interpolation_tick(Scenario::InterpolationData } // 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; @@ -913,19 +877,19 @@ void RenderingServerScene::update_interpolation_tick(Scenario::InterpolationData // 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 RenderingServerScene::update_interpolation_frame(Scenario::InterpolationData &r_interpolation_data, bool p_process) { +void RenderingServerScene::update_interpolation_frame(bool p_process) { // update interpolation in storage RSG::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; @@ -933,24 +897,24 @@ void RenderingServerScene::update_interpolation_frame(Scenario::InterpolationDat } } - 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); @@ -1014,11 +978,11 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) instance->visible = p_visible; // Special case for physics interpolation, we want to ensure the interpolated data is up to date - if (instance->scenario && instance->scenario->_interpolation_data.interpolation_enabled && p_visible && instance->interpolated && !instance->on_interpolate_list) { + if (_interpolation_data.interpolation_enabled && p_visible && instance->interpolated && instance->scenario && !instance->on_interpolate_list) { // Do all the extra work we normally do on instance_set_transform(), because this is optimized out for hidden instances. // This prevents a glitch of stale interpolation transform data when unhiding before the next physics tick. instance->interpolation_method = TransformInterpolator::find_method(instance->transform_prev.basis, instance->transform_curr.basis); - 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; _instance_queue_update(instance, true); @@ -1027,7 +991,7 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) // If this step is ignored, an unmoving instance could remain on the interpolate lists indefinitely // (or rather until the object is deleted) and cause unnecessary updates and drawcalls. 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; } } @@ -2527,8 +2491,7 @@ void RenderingServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_v } 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); @@ -2883,9 +2846,7 @@ bool RenderingServerScene::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); @@ -2907,14 +2868,7 @@ bool RenderingServerScene::free(RID p_rid) { 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_scenario(p_rid, RID()); instance_set_base(p_rid, RID()); diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h index 09908d816..23f833b5d 100644 --- a/servers/rendering/rendering_server_scene.h +++ b/servers/rendering/rendering_server_scene.h @@ -55,7 +55,13 @@ public: uint64_t render_pass; static RenderingServerScene *singleton; + /* EVENT QUEUING */ + + void tick(); + void pre_draw(bool p_will_draw); + /* CAMERA API */ + struct Scenario; struct Camera : public RID_Data { @@ -76,8 +82,6 @@ public: Transform transform; Transform transform_prev; - Scenario *scenario; - bool interpolated : 1; bool on_interpolate_transform_list : 1; @@ -86,10 +90,7 @@ public: 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; @@ -100,7 +101,6 @@ public: size = 1.0; offset = Vector2(); vaspect = false; - scenario = nullptr; previous_room_id_hint = -1; interpolated = true; on_interpolate_transform_list = false; @@ -111,7 +111,6 @@ public: 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); @@ -283,26 +282,6 @@ public: 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); } }; @@ -318,9 +297,6 @@ public: 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 */ @@ -380,8 +356,6 @@ public: 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) { @@ -429,6 +403,26 @@ public: 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 { @@ -582,6 +576,8 @@ private: 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; @@ -602,7 +598,8 @@ public: 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; @@ -622,7 +619,8 @@ public: 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; @@ -662,10 +660,15 @@ public: // 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; @@ -699,7 +702,9 @@ public: virtual bool rooms_is_loaded(RID p_scenario) const; virtual void callbacks_register(RenderingServerCallbacks *p_callbacks); - RenderingServerCallbacks *get_callbacks() const { return _rendering_server_callbacks; } + RenderingServerCallbacks *get_callbacks() const { + return _rendering_server_callbacks; + } // don't use these in a game! virtual Vector instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const; @@ -732,8 +737,8 @@ public: 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); bool free(RID p_rid); diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp index ade60b354..c34cdfde5 100644 --- a/servers/rendering/rendering_server_wrap_mt.cpp +++ b/servers/rendering/rendering_server_wrap_mt.cpp @@ -36,18 +36,6 @@ void RenderingServerWrapMT::thread_exit() { exit.set(); } -void RenderingServerWrapMT::thread_scenario_tick(RID p_scenario) { - if (!draw_pending.decrement()) { - rendering_server->scenario_tick(p_scenario); - } -} - -void RenderingServerWrapMT::thread_scenario_pre_draw(RID p_scenario, bool p_will_draw) { - if (!draw_pending.decrement()) { - rendering_server->scenario_pre_draw(p_scenario, p_will_draw); - } -} - void RenderingServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) { if (!draw_pending.decrement()) { rendering_server->draw(p_swap_buffers, frame_step); @@ -94,24 +82,6 @@ void RenderingServerWrapMT::sync() { } } -void RenderingServerWrapMT::scenario_tick(RID p_scenario) { - if (create_thread) { - draw_pending.increment(); - command_queue.push(this, &RenderingServerWrapMT::thread_scenario_tick, p_scenario); - } else { - rendering_server->scenario_tick(p_scenario); - } -} - -void RenderingServerWrapMT::scenario_pre_draw(RID p_scenario, bool p_will_draw) { - if (create_thread) { - draw_pending.increment(); - command_queue.push(this, &RenderingServerWrapMT::thread_scenario_pre_draw, p_scenario, p_will_draw); - } else { - rendering_server->scenario_pre_draw(p_scenario, p_will_draw); - } -} - void RenderingServerWrapMT::draw(bool p_swap_buffers, double frame_step) { if (create_thread) { draw_pending.increment(); diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index 7fbf46e9f..7cfd2f964 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -53,8 +53,6 @@ class RenderingServerWrapMT : public RenderingServer { 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(); @@ -286,7 +284,6 @@ public: /* 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) @@ -377,13 +374,18 @@ public: 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) @@ -407,7 +409,8 @@ public: FUNC2(instance_set_extra_visibility_margin, RID, real_t) - // Portals + /* PORTALS API */ + FUNC2(instance_set_portal_mode, RID, InstancePortalMode) FUNCRID(ghost) @@ -420,13 +423,15 @@ public: 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) @@ -440,7 +445,8 @@ public: 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 &) @@ -586,8 +592,8 @@ public: 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/rendering_server.h b/servers/rendering_server.h index 0c6d62363..6fd666c03 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -523,7 +523,6 @@ public: /* 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; @@ -723,6 +722,10 @@ public: 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; @@ -739,7 +742,6 @@ public: 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 */ @@ -779,8 +781,8 @@ public: 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 @@ -801,13 +803,15 @@ public: 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, @@ -829,7 +833,8 @@ public: 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, }; @@ -1039,8 +1044,8 @@ public: 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 */