Merge pull request #60147 from lawnjelly/interpolation_out_of_scenario

This commit is contained in:
Rémi Verschelde 2022-04-13 17:08:08 +02:00 committed by GitHub
commit e1eb3c2fb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 155 additions and 229 deletions

View file

@ -115,10 +115,6 @@ void Camera::_notification(int p_what) {
if (current || first_camera) { if (current || first_camera) {
viewport->_camera_set(this); viewport->_camera_set(this);
} }
ERR_FAIL_COND(get_world().is_null());
VisualServer::get_singleton()->camera_set_scenario(camera, get_world()->get_scenario());
} break; } break;
case NOTIFICATION_TRANSFORM_CHANGED: { case NOTIFICATION_TRANSFORM_CHANGED: {
_request_camera_update(); _request_camera_update();
@ -132,8 +128,6 @@ void Camera::_notification(int p_what) {
} }
} break; } break;
case NOTIFICATION_EXIT_WORLD: { case NOTIFICATION_EXIT_WORLD: {
VisualServer::get_singleton()->camera_set_scenario(camera, RID());
if (!get_tree()->is_node_being_edited(this)) { if (!get_tree()->is_node_being_edited(this)) {
if (is_current()) { if (is_current()) {
clear_current(); clear_current();

View file

@ -507,13 +507,7 @@ void SceneTree::set_physics_interpolation_enabled(bool p_enabled) {
} }
_physics_interpolation_enabled = p_enabled; _physics_interpolation_enabled = p_enabled;
VisualServer::get_singleton()->set_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);
}
}
} }
bool SceneTree::is_physics_interpolation_enabled() const { bool SceneTree::is_physics_interpolation_enabled() const {
@ -535,11 +529,8 @@ bool SceneTree::iteration(float p_time) {
current_frame++; current_frame++;
if (root->get_world().is_valid()) { if (_physics_interpolation_enabled) {
RID scenario = root->get_world()->get_scenario(); VisualServer::get_singleton()->tick();
if (scenario.is_valid()) {
VisualServer::get_singleton()->scenario_tick(scenario);
}
} }
// Any objects performing client physics interpolation // Any objects performing client physics interpolation
@ -686,11 +677,8 @@ bool SceneTree::idle(float p_time) {
#endif #endif
if (root->get_world().is_valid()) { if (_physics_interpolation_enabled) {
RID scenario = root->get_world()->get_scenario(); VisualServer::get_singleton()->pre_draw(true);
if (scenario.is_valid()) {
VisualServer::get_singleton()->scenario_pre_draw(scenario, true);
}
} }
return _quit; return _quit;

View file

@ -94,14 +94,6 @@ void VisualServerRaster::request_frame_drawn_callback(Object *p_where, const Str
frame_drawn_callbacks.push_back(fdc); 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) { 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 //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"); VS::get_singleton()->emit_signal("frame_pre_draw");

View file

@ -116,8 +116,12 @@ public:
#define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ #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); } 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) \ #define BIND1(m_name, m_type1) \
void m_name(m_type1 arg1) { DISPLAY_CHANGED BINDBASE->m_name(arg1); } 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) \ #define BIND2(m_name, m_type1, m_type2) \
void m_name(m_type1 arg1, m_type2 arg2) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2); } void m_name(m_type1 arg1, m_type2 arg2) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2); }
#define BIND2C(m_name, m_type1, m_type2) \ #define BIND2C(m_name, m_type1, m_type2) \
@ -448,10 +452,14 @@ public:
//from now on, calls forwarded to this singleton //from now on, calls forwarded to this singleton
#define BINDBASE VSG::scene #define BINDBASE VSG::scene
/* EVENT QUEUING */
BIND0N(tick)
BIND1N(pre_draw, bool)
/* CAMERA API */ /* CAMERA API */
BIND0R(RID, camera_create) BIND0R(RID, camera_create)
BIND2(camera_set_scenario, RID, RID)
BIND4(camera_set_perspective, RID, float, float, float) BIND4(camera_set_perspective, RID, float, float, float)
BIND4(camera_set_orthogonal, RID, float, float, float) BIND4(camera_set_orthogonal, RID, float, float, float)
BIND5(camera_set_frustum, RID, float, Vector2, float, float) BIND5(camera_set_frustum, RID, float, Vector2, float, float)
@ -548,20 +556,24 @@ public:
BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float)
BIND5(environment_set_fog_height, RID, bool, float, float, float) BIND5(environment_set_fog_height, RID, bool, float, float, float)
/* SCENARIO API */
#undef BINDBASE #undef BINDBASE
#define BINDBASE VSG::scene #define BINDBASE VSG::scene
/* INTERPOLATION */
BIND1(set_physics_interpolation_enabled, bool)
/* SCENARIO API */
BIND0R(RID, scenario_create) BIND0R(RID, scenario_create)
BIND2(scenario_set_debug, RID, ScenarioDebugMode) BIND2(scenario_set_debug, RID, ScenarioDebugMode)
BIND2(scenario_set_environment, RID, RID) BIND2(scenario_set_environment, RID, RID)
BIND3(scenario_set_reflection_atlas_size, RID, int, int) BIND3(scenario_set_reflection_atlas_size, RID, int, int)
BIND2(scenario_set_fallback_environment, RID, RID) BIND2(scenario_set_fallback_environment, RID, RID)
BIND2(scenario_set_physics_interpolation_enabled, RID, bool)
/* INSTANCING API */ /* INSTANCING API */
BIND0R(RID, instance_create) BIND0R(RID, instance_create)
BIND2(instance_set_base, RID, RID) BIND2(instance_set_base, RID, RID)
@ -583,7 +595,8 @@ public:
BIND2(instance_set_extra_visibility_margin, RID, real_t) BIND2(instance_set_extra_visibility_margin, RID, real_t)
// Portals /* PORTALS */
BIND2(instance_set_portal_mode, RID, InstancePortalMode) BIND2(instance_set_portal_mode, RID, InstancePortalMode)
BIND0R(RID, ghost_create) BIND0R(RID, ghost_create)
@ -596,13 +609,15 @@ public:
BIND4(portal_link, RID, RID, RID, bool) BIND4(portal_link, RID, RID, RID, bool)
BIND2(portal_set_active, RID, bool) BIND2(portal_set_active, RID, bool)
// Roomgroups /* ROOMGROUPS */
BIND0R(RID, roomgroup_create) BIND0R(RID, roomgroup_create)
BIND2(roomgroup_prepare, RID, ObjectID) BIND2(roomgroup_prepare, RID, ObjectID)
BIND2(roomgroup_set_scenario, RID, RID) BIND2(roomgroup_set_scenario, RID, RID)
BIND2(roomgroup_add_room, RID, RID) BIND2(roomgroup_add_room, RID, RID)
// Occluders /* OCCLUDERS */
BIND0R(RID, occluder_instance_create) BIND0R(RID, occluder_instance_create)
BIND2(occluder_instance_set_scenario, RID, RID) BIND2(occluder_instance_set_scenario, RID, RID)
BIND2(occluder_instance_link_resource, RID, RID) BIND2(occluder_instance_link_resource, RID, RID)
@ -616,7 +631,8 @@ public:
BIND1(set_use_occlusion_culling, bool) BIND1(set_use_occlusion_culling, bool)
BIND1RC(Geometry::MeshData, occlusion_debug_get_current_polys, RID) BIND1RC(Geometry::MeshData, occlusion_debug_get_current_polys, RID)
// Rooms /* ROOMS */
BIND0R(RID, room_create) BIND0R(RID, room_create)
BIND2(room_set_scenario, RID, RID) BIND2(room_set_scenario, RID, RID)
BIND4(room_add_instance, RID, RID, const AABB &, const Vector<Vector3> &) BIND4(room_add_instance, RID, RID, const AABB &, const Vector<Vector3> &)
@ -764,8 +780,6 @@ public:
virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const; virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const;
virtual void init(); virtual void init();
virtual void finish(); virtual void finish();
virtual void scenario_tick(RID p_scenario);
virtual void scenario_pre_draw(RID p_scenario, bool p_will_draw);
/* STATUS INFORMATION */ /* STATUS INFORMATION */

View file

@ -39,8 +39,8 @@
/* CAMERA API */ /* CAMERA API */
Transform VisualServerScene::Camera::get_transform() const { Transform VisualServerScene::Camera::get_transform_interpolated() const {
if (!is_currently_interpolated()) { if (!interpolated) {
return transform; return transform;
} }
@ -54,25 +54,6 @@ RID VisualServerScene::camera_create() {
return camera_owner.make_rid(camera); 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) { 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); Camera *camera = camera_owner.get(p_camera);
ERR_FAIL_COND(!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); Camera *camera = camera_owner.get(p_camera);
ERR_FAIL_COND(!camera); ERR_FAIL_COND(!camera);
if (camera->is_currently_interpolated()) { if (_interpolation_data.interpolation_enabled && camera->interpolated) {
camera->scenario->_interpolation_data.camera_teleport_list.push_back(p_camera); _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(); camera->transform = p_transform.orthonormalized();
if (camera->is_currently_interpolated()) { if (_interpolation_data.interpolation_enabled && camera->interpolated) {
if (!camera->on_interpolate_transform_list) { 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; camera->on_interpolate_transform_list = true;
} }
@ -302,7 +283,6 @@ void VisualServerScene::SpatialPartitioningScene_Octree::set_balance(float p_bal
VisualServerScene::Scenario::Scenario() { VisualServerScene::Scenario::Scenario() {
debug = VS::SCENARIO_DEBUG_DISABLED; debug = VS::SCENARIO_DEBUG_DISABLED;
_interpolation_data.interpolation_enabled = false;
bool use_bvh_or_octree = GLOBAL_GET("rendering/quality/spatial_partitioning/use_bvh"); bool use_bvh_or_octree = GLOBAL_GET("rendering/quality/spatial_partitioning/use_bvh");
@ -470,30 +450,22 @@ RID VisualServerScene::scenario_create() {
return scenario_rid; return scenario_rid;
} }
void VisualServerScene::scenario_set_physics_interpolation_enabled(RID p_scenario, bool p_enabled) { void VisualServerScene::set_physics_interpolation_enabled(bool p_enabled) {
Scenario *scenario = scenario_owner.get(p_scenario); _interpolation_data.interpolation_enabled = p_enabled;
ERR_FAIL_COND(!scenario);
scenario->_interpolation_data.interpolation_enabled = p_enabled;
} }
void VisualServerScene::_scenario_tick(RID p_scenario) { void VisualServerScene::tick() {
Scenario *scenario = scenario_owner.get(p_scenario); if (_interpolation_data.interpolation_enabled) {
ERR_FAIL_COND(!scenario); update_interpolation_tick(true);
if (scenario->is_physics_interpolation_enabled()) {
update_interpolation_tick(scenario->_interpolation_data, true);
} }
} }
void VisualServerScene::_scenario_pre_draw(RID p_scenario, bool p_will_draw) { void VisualServerScene::pre_draw(bool p_will_draw) {
Scenario *scenario = scenario_owner.get(p_scenario);
ERR_FAIL_COND(!scenario);
// even when running and not drawing scenes, we still need to clear intermediate per frame // 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 // interpolation data .. hence the p_will_draw flag (so we can reduce the processing if the frame
// will not be drawn) // will not be drawn)
if (scenario->is_physics_interpolation_enabled()) { if (_interpolation_data.interpolation_enabled) {
update_interpolation_frame(scenario->_interpolation_data, p_will_draw); 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 // 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) { switch (instance->base_type) {
case VS::INSTANCE_LIGHT: { case VS::INSTANCE_LIGHT: {
@ -801,8 +773,8 @@ void VisualServerScene::instance_reset_physics_interpolation(RID p_instance) {
Instance *instance = instance_owner.get(p_instance); Instance *instance = instance_owner.get(p_instance);
ERR_FAIL_COND(!instance); ERR_FAIL_COND(!instance);
if (instance->is_currently_interpolated()) { if (_interpolation_data.interpolation_enabled && instance->interpolated) {
instance->scenario->_interpolation_data.instance_teleport_list.push_back(p_instance); _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); Instance *instance = instance_owner.get(p_instance);
ERR_FAIL_COND(!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) { if (instance->transform == p_transform) {
return; //must be checked to avoid worst evil 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 #ifdef DEBUG_ENABLED
for (int i = 0; i < 4; i++) { 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; instance->transform_checksum_curr = new_checksum;
if (!instance->on_interpolate_transform_list) { 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; instance->on_interpolate_transform_list = true;
} else { } 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) { 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; instance->on_interpolate_list = true;
} else { } 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); _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; r_camera.on_interpolate_transform_list = false;
if (!interpolation_enabled) { 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); 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_list = false;
r_instance.on_interpolate_transform_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); 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 // update interpolation in storage
VSG::storage->update_interpolation_tick(p_process); VSG::storage->update_interpolation_tick(p_process);
// detect any that were on the previous transform list that are no longer active, // detect any that were on the previous transform list that are no longer active,
// we should remove them from the interpolate list // we should remove them from the interpolate list
for (unsigned int n = 0; n < r_interpolation_data.instance_transform_update_list_prev->size(); n++) { for (unsigned int n = 0; n < _interpolation_data.instance_transform_update_list_prev->size(); n++) {
const RID &rid = (*r_interpolation_data.instance_transform_update_list_prev)[n]; const RID &rid = (*_interpolation_data.instance_transform_update_list_prev)[n];
Instance *instance = instance_owner.getornull(rid); Instance *instance = instance_owner.getornull(rid);
bool active = true; bool active = true;
@ -960,15 +924,15 @@ void VisualServerScene::update_interpolation_tick(Scenario::InterpolationData &r
} }
if (!active) { 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 // and now for any in the transform list (being actively interpolated), keep the previous transform
// value up to date ready for the next tick // value up to date ready for the next tick
if (p_process) { if (p_process) {
for (unsigned int n = 0; n < r_interpolation_data.instance_transform_update_list_curr->size(); n++) { for (unsigned int n = 0; n < _interpolation_data.instance_transform_update_list_curr->size(); n++) {
const RID &rid = (*r_interpolation_data.instance_transform_update_list_curr)[n]; const RID &rid = (*_interpolation_data.instance_transform_update_list_curr)[n];
Instance *instance = instance_owner.getornull(rid); Instance *instance = instance_owner.getornull(rid);
if (instance) { if (instance) {
instance->transform_prev = instance->transform_curr; 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 // 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 // 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 // prepare for the next iteration
r_interpolation_data.instance_transform_update_list_curr->clear(); _interpolation_data.instance_transform_update_list_curr->clear();
// CAMERAS // CAMERAS
// detect any that were on the previous transform list that are no longer active, // 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++) { for (unsigned int n = 0; n < _interpolation_data.camera_transform_update_list_prev->size(); n++) {
const RID &rid = (*r_interpolation_data.camera_transform_update_list_prev)[n]; const RID &rid = (*_interpolation_data.camera_transform_update_list_prev)[n];
Camera *camera = camera_owner.getornull(rid); Camera *camera = camera_owner.getornull(rid);
// no longer active? (either the instance deleted or no longer being transformed) // 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 // cameras , swap any current with previous
for (unsigned int n = 0; n < r_interpolation_data.camera_transform_update_list_curr->size(); n++) { for (unsigned int n = 0; n < _interpolation_data.camera_transform_update_list_curr->size(); n++) {
const RID &rid = (*r_interpolation_data.camera_transform_update_list_curr)[n]; const RID &rid = (*_interpolation_data.camera_transform_update_list_curr)[n];
Camera *camera = camera_owner.getornull(rid); Camera *camera = camera_owner.getornull(rid);
if (camera) { if (camera) {
camera->transform_prev = camera->transform; 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 // 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 // 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 // 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 // update interpolation in storage
VSG::storage->update_interpolation_frame(p_process); VSG::storage->update_interpolation_frame(p_process);
// teleported instances // teleported instances
for (unsigned int n = 0; n < r_interpolation_data.instance_teleport_list.size(); n++) { for (unsigned int n = 0; n < _interpolation_data.instance_teleport_list.size(); n++) {
const RID &rid = r_interpolation_data.instance_teleport_list[n]; const RID &rid = _interpolation_data.instance_teleport_list[n];
Instance *instance = instance_owner.getornull(rid); Instance *instance = instance_owner.getornull(rid);
if (instance) { if (instance) {
instance->transform_prev = instance->transform_curr; 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 // camera teleports
for (unsigned int n = 0; n < r_interpolation_data.camera_teleport_list.size(); n++) { for (unsigned int n = 0; n < _interpolation_data.camera_teleport_list.size(); n++) {
const RID &rid = r_interpolation_data.camera_teleport_list[n]; const RID &rid = _interpolation_data.camera_teleport_list[n];
Camera *camera = camera_owner.getornull(rid); Camera *camera = camera_owner.getornull(rid);
if (camera) { if (camera) {
camera->transform_prev = camera->transform; camera->transform_prev = camera->transform;
} }
} }
r_interpolation_data.camera_teleport_list.clear(); _interpolation_data.camera_teleport_list.clear();
if (p_process) { if (p_process) {
real_t f = Engine::get_singleton()->get_physics_interpolation_fraction(); 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++) { for (unsigned int i = 0; i < _interpolation_data.instance_interpolate_update_list.size(); i++) {
const RID &rid = r_interpolation_data.instance_interpolate_update_list[i]; const RID &rid = _interpolation_data.instance_interpolate_update_list[i];
Instance *instance = instance_owner.getornull(rid); Instance *instance = instance_owner.getornull(rid);
if (instance) { if (instance) {
TransformInterpolator::interpolate_transform_via_method(instance->transform_prev, instance->transform_curr, instance->transform, f, instance->interpolation_method); 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; } break;
} }
// This getter allows optional fixed timestep interpolation for the camera. Transform camera_transform = _interpolation_data.interpolation_enabled ? camera->get_transform_interpolated() : camera->transform;
Transform camera_transform = camera->get_transform();
_prepare_scene(camera_transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), camera->previous_room_id_hint); _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); _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) { bool VisualServerScene::free(RID p_rid) {
if (camera_owner.owns(p_rid)) { if (camera_owner.owns(p_rid)) {
Camera *camera = camera_owner.get(p_rid); Camera *camera = camera_owner.get(p_rid);
_interpolation_data.notify_free_camera(p_rid, *camera);
if (camera->scenario) {
camera->scenario->_interpolation_data.notify_free_camera(p_rid, *camera);
}
camera_owner.free(p_rid); camera_owner.free(p_rid);
memdelete(camera); memdelete(camera);
@ -4490,15 +4450,7 @@ bool VisualServerScene::free(RID p_rid) {
update_dirty_instances(); update_dirty_instances();
Instance *instance = instance_owner.get(p_rid); Instance *instance = instance_owner.get(p_rid);
_interpolation_data.notify_free_instance(p_rid, *instance);
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.");
}
}
instance_set_use_lightmap(p_rid, RID(), RID(), -1, Rect2(0, 0, 1, 1)); instance_set_use_lightmap(p_rid, RID(), RID(), -1, Rect2(0, 0, 1, 1));
instance_set_scenario(p_rid, RID()); instance_set_scenario(p_rid, RID());

View file

@ -57,6 +57,11 @@ public:
uint64_t render_pass; uint64_t render_pass;
static VisualServerScene *singleton; static VisualServerScene *singleton;
/* EVENT QUEUING */
void tick();
void pre_draw(bool p_will_draw);
/* CAMERA API */ /* CAMERA API */
struct Scenario; struct Scenario;
@ -78,8 +83,6 @@ public:
Transform transform; Transform transform;
Transform transform_prev; Transform transform_prev;
Scenario *scenario;
bool interpolated : 1; bool interpolated : 1;
bool on_interpolate_transform_list : 1; bool on_interpolate_transform_list : 1;
@ -88,10 +91,7 @@ public:
int32_t previous_room_id_hint; int32_t previous_room_id_hint;
// call get transform to get either the transform straight, Transform get_transform_interpolated() const;
// 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; }
Camera() { Camera() {
visible_layers = 0xFFFFFFFF; visible_layers = 0xFFFFFFFF;
@ -102,7 +102,6 @@ public:
size = 1.0; size = 1.0;
offset = Vector2(); offset = Vector2();
vaspect = false; vaspect = false;
scenario = nullptr;
previous_room_id_hint = -1; previous_room_id_hint = -1;
interpolated = true; interpolated = true;
on_interpolate_transform_list = false; on_interpolate_transform_list = false;
@ -113,7 +112,6 @@ public:
mutable RID_Owner<Camera> camera_owner; mutable RID_Owner<Camera> camera_owner;
virtual RID camera_create(); 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_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_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); 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 @@ public:
SelfList<Instance>::List instances; SelfList<Instance>::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<RID> instance_interpolate_update_list;
LocalVector<RID> instance_transform_update_lists[2];
LocalVector<RID> *instance_transform_update_list_curr = &instance_transform_update_lists[0];
LocalVector<RID> *instance_transform_update_list_prev = &instance_transform_update_lists[1];
LocalVector<RID> instance_teleport_list;
LocalVector<RID> camera_transform_update_lists[2];
LocalVector<RID> *camera_transform_update_list_curr = &camera_transform_update_lists[0];
LocalVector<RID> *camera_transform_update_list_prev = &camera_transform_update_lists[1];
LocalVector<RID> camera_teleport_list;
bool interpolation_enabled;
} _interpolation_data;
Scenario(); Scenario();
~Scenario() { memdelete(sps); } ~Scenario() { memdelete(sps); }
}; };
@ -305,9 +283,6 @@ public:
virtual void scenario_set_environment(RID p_scenario, RID p_environment); 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_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_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 */ /* INSTANCING API */
@ -365,8 +340,6 @@ public:
singleton->_instance_queue_update(this, p_aabb, p_materials); singleton->_instance_queue_update(this, p_aabb, p_materials);
} }
bool is_currently_interpolated() const { return scenario && scenario->is_physics_interpolation_enabled() && interpolated; }
Instance() : Instance() :
scenario_item(this), scenario_item(this),
update_item(this) { update_item(this) {
@ -412,6 +385,26 @@ public:
SelfList<Instance>::List _instance_update_list; SelfList<Instance>::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<RID> instance_interpolate_update_list;
LocalVector<RID> instance_transform_update_lists[2];
LocalVector<RID> *instance_transform_update_list_curr = &instance_transform_update_lists[0];
LocalVector<RID> *instance_transform_update_list_prev = &instance_transform_update_lists[1];
LocalVector<RID> instance_teleport_list;
LocalVector<RID> camera_transform_update_lists[2];
LocalVector<RID> *camera_transform_update_list_curr = &camera_transform_update_lists[0];
LocalVector<RID> *camera_transform_update_list_prev = &camera_transform_update_lists[1];
LocalVector<RID> 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); void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_materials = false);
struct InstanceGeometryData : public InstanceBaseData { struct InstanceGeometryData : public InstanceBaseData {
@ -688,6 +681,8 @@ private:
void _ghost_destroy_occlusion_rep(Ghost *p_ghost); void _ghost_destroy_occlusion_rep(Ghost *p_ghost);
public: public:
/* PORTALS API */
struct Portal : RID_Data { struct Portal : RID_Data {
// all interactions with actual portals are indirect, as the portal is part of the scenario // all interactions with actual portals are indirect, as the portal is part of the scenario
uint32_t scenario_portal_id = 0; uint32_t scenario_portal_id = 0;
@ -708,7 +703,8 @@ public:
virtual void portal_link(RID p_portal, RID p_room_from, RID p_room_to, bool p_two_way); 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); virtual void portal_set_active(RID p_portal, bool p_active);
// RoomGroups /* ROOMGROUPS API */
struct RoomGroup : RID_Data { struct RoomGroup : RID_Data {
// all interactions with actual roomgroups are indirect, as the roomgroup is part of the scenario // all interactions with actual roomgroups are indirect, as the roomgroup is part of the scenario
uint32_t scenario_roomgroup_id = 0; uint32_t scenario_roomgroup_id = 0;
@ -728,7 +724,8 @@ public:
virtual void roomgroup_set_scenario(RID p_roomgroup, RID p_scenario); virtual void roomgroup_set_scenario(RID p_roomgroup, RID p_scenario);
virtual void roomgroup_add_room(RID p_roomgroup, RID p_room); virtual void roomgroup_add_room(RID p_roomgroup, RID p_room);
// Occluders /* OCCLUDERS API */
struct OccluderInstance : RID_Data { struct OccluderInstance : RID_Data {
uint32_t scenario_occluder_id = 0; uint32_t scenario_occluder_id = 0;
Scenario *scenario = nullptr; Scenario *scenario = nullptr;
@ -768,10 +765,15 @@ public:
// editor only .. slow // editor only .. slow
virtual Geometry::MeshData occlusion_debug_get_current_polys(RID p_scenario) const; virtual Geometry::MeshData occlusion_debug_get_current_polys(RID p_scenario) const;
const PortalResources &get_portal_resources() const { return _portal_resources; } const PortalResources &get_portal_resources() const {
PortalResources &get_portal_resources() { return _portal_resources; } return _portal_resources;
}
PortalResources &get_portal_resources() {
return _portal_resources;
}
/* ROOMS API */
// Rooms
struct Room : RID_Data { struct Room : RID_Data {
// all interactions with actual rooms are indirect, as the room is part of the scenario // all interactions with actual rooms are indirect, as the room is part of the scenario
uint32_t scenario_room_id = 0; uint32_t scenario_room_id = 0;
@ -805,7 +807,9 @@ public:
virtual bool rooms_is_loaded(RID p_scenario) const; virtual bool rooms_is_loaded(RID p_scenario) const;
virtual void callbacks_register(VisualServerCallbacks *p_callbacks); 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! // don't use these in a game!
virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const; virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const;
@ -840,8 +844,8 @@ public:
void update_dirty_instances(); void update_dirty_instances();
// interpolation // interpolation
void update_interpolation_tick(Scenario::InterpolationData &r_interpolation_data, bool p_process = true); void update_interpolation_tick(bool p_process = true);
void update_interpolation_frame(Scenario::InterpolationData &r_interpolation_data, bool p_process = true); void update_interpolation_frame(bool p_process = true);
//probes //probes
struct GIProbeDataHeader { struct GIProbeDataHeader {

View file

@ -36,18 +36,6 @@ void VisualServerWrapMT::thread_exit() {
exit.set(); 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) { void VisualServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) {
if (!draw_pending.decrement()) { if (!draw_pending.decrement()) {
visual_server->draw(p_swap_buffers, frame_step); 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) { void VisualServerWrapMT::draw(bool p_swap_buffers, double frame_step) {
if (create_thread) { if (create_thread) {
draw_pending.increment(); draw_pending.increment();

View file

@ -54,8 +54,6 @@ class VisualServerWrapMT : public VisualServer {
SafeNumeric<uint64_t> draw_pending; SafeNumeric<uint64_t> draw_pending;
void thread_draw(bool p_swap_buffers, double frame_step); void thread_draw(bool p_swap_buffers, double frame_step);
void thread_flush(); 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(); void thread_exit();
@ -374,7 +372,6 @@ public:
/* CAMERA API */ /* CAMERA API */
FUNCRID(camera) FUNCRID(camera)
FUNC2(camera_set_scenario, RID, RID)
FUNC4(camera_set_perspective, RID, float, float, float) FUNC4(camera_set_perspective, RID, float, float, float)
FUNC4(camera_set_orthogonal, RID, float, float, float) FUNC4(camera_set_orthogonal, RID, float, float, float)
FUNC5(camera_set_frustum, RID, float, Vector2, float, float) FUNC5(camera_set_frustum, RID, float, Vector2, float, float)
@ -468,15 +465,21 @@ public:
FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float)
FUNC5(environment_set_fog_height, RID, bool, float, float, float) FUNC5(environment_set_fog_height, RID, bool, float, float, float)
/* INTERPOLATION API */
FUNC1(set_physics_interpolation_enabled, bool)
/* SCENARIO API */
FUNCRID(scenario) FUNCRID(scenario)
FUNC2(scenario_set_debug, RID, ScenarioDebugMode) FUNC2(scenario_set_debug, RID, ScenarioDebugMode)
FUNC2(scenario_set_environment, RID, RID) FUNC2(scenario_set_environment, RID, RID)
FUNC3(scenario_set_reflection_atlas_size, RID, int, int) FUNC3(scenario_set_reflection_atlas_size, RID, int, int)
FUNC2(scenario_set_fallback_environment, RID, RID) FUNC2(scenario_set_fallback_environment, RID, RID)
FUNC2(scenario_set_physics_interpolation_enabled, RID, bool)
/* INSTANCING API */ /* INSTANCING API */
FUNCRID(instance) FUNCRID(instance)
FUNC2(instance_set_base, RID, RID) FUNC2(instance_set_base, RID, RID)
@ -498,7 +501,8 @@ public:
FUNC2(instance_set_extra_visibility_margin, RID, real_t) FUNC2(instance_set_extra_visibility_margin, RID, real_t)
// Portals /* PORTALS API */
FUNC2(instance_set_portal_mode, RID, InstancePortalMode) FUNC2(instance_set_portal_mode, RID, InstancePortalMode)
FUNCRID(ghost) FUNCRID(ghost)
@ -511,13 +515,15 @@ public:
FUNC4(portal_link, RID, RID, RID, bool) FUNC4(portal_link, RID, RID, RID, bool)
FUNC2(portal_set_active, RID, bool) FUNC2(portal_set_active, RID, bool)
// Roomgroups /* ROOMGROUPS API */
FUNCRID(roomgroup) FUNCRID(roomgroup)
FUNC2(roomgroup_prepare, RID, ObjectID) FUNC2(roomgroup_prepare, RID, ObjectID)
FUNC2(roomgroup_set_scenario, RID, RID) FUNC2(roomgroup_set_scenario, RID, RID)
FUNC2(roomgroup_add_room, RID, RID) FUNC2(roomgroup_add_room, RID, RID)
// Occluders /* OCCLUDERS API */
FUNCRID(occluder_instance) FUNCRID(occluder_instance)
FUNC2(occluder_instance_set_scenario, RID, RID) FUNC2(occluder_instance_set_scenario, RID, RID)
FUNC2(occluder_instance_link_resource, RID, RID) FUNC2(occluder_instance_link_resource, RID, RID)
@ -531,7 +537,8 @@ public:
FUNC1(set_use_occlusion_culling, bool) FUNC1(set_use_occlusion_culling, bool)
FUNC1RC(Geometry::MeshData, occlusion_debug_get_current_polys, RID) FUNC1RC(Geometry::MeshData, occlusion_debug_get_current_polys, RID)
// Rooms /* ROOMS API */
FUNCRID(room) FUNCRID(room)
FUNC2(room_set_scenario, RID, RID) FUNC2(room_set_scenario, RID, RID)
FUNC4(room_add_instance, RID, RID, const AABB &, const Vector<Vector3> &) FUNC4(room_add_instance, RID, RID, const AABB &, const Vector<Vector3> &)
@ -674,8 +681,8 @@ public:
virtual void finish(); virtual void finish();
virtual void draw(bool p_swap_buffers, double frame_step); virtual void draw(bool p_swap_buffers, double frame_step);
virtual void sync(); virtual void sync();
virtual void scenario_tick(RID p_scenario); FUNC0(tick)
virtual void scenario_pre_draw(RID p_scenario, bool p_will_draw); FUNC1(pre_draw, bool)
FUNC1RC(bool, has_changed, ChangedPriority) FUNC1RC(bool, has_changed, ChangedPriority)
/* RENDER INFO */ /* RENDER INFO */

View file

@ -619,7 +619,6 @@ public:
/* CAMERA API */ /* CAMERA API */
virtual RID camera_create() = 0; 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_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_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; 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 @@ 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_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; 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 */ /* SCENARIO API */
virtual RID scenario_create() = 0; virtual RID scenario_create() = 0;
@ -837,7 +840,6 @@ public:
virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0; 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_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_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 */ /* INSTANCING API */
@ -881,8 +883,8 @@ public:
virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) = 0; virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) = 0;
/* ROOMS AND PORTALS API */ /* PORTALS API */
// Portals
enum InstancePortalMode { enum InstancePortalMode {
INSTANCE_PORTAL_MODE_STATIC, // not moving within a room INSTANCE_PORTAL_MODE_STATIC, // not moving within a room
INSTANCE_PORTAL_MODE_DYNAMIC, // moving within room INSTANCE_PORTAL_MODE_DYNAMIC, // moving within room
@ -903,13 +905,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_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; virtual void portal_set_active(RID p_portal, bool p_active) = 0;
// Roomgroups /* ROOMGROUPS API */
virtual RID roomgroup_create() = 0; virtual RID roomgroup_create() = 0;
virtual void roomgroup_prepare(RID p_roomgroup, ObjectID p_roomgroup_object_id) = 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_set_scenario(RID p_roomgroup, RID p_scenario) = 0;
virtual void roomgroup_add_room(RID p_roomgroup, RID p_room) = 0; virtual void roomgroup_add_room(RID p_roomgroup, RID p_room) = 0;
// Occluders /* OCCLUDERS API */
enum OccluderType { enum OccluderType {
OCCLUDER_TYPE_UNDEFINED, OCCLUDER_TYPE_UNDEFINED,
OCCLUDER_TYPE_SPHERE, OCCLUDER_TYPE_SPHERE,
@ -931,7 +935,8 @@ public:
virtual void set_use_occlusion_culling(bool p_enable) = 0; virtual void set_use_occlusion_culling(bool p_enable) = 0;
virtual Geometry::MeshData occlusion_debug_get_current_polys(RID p_scenario) const = 0; virtual Geometry::MeshData occlusion_debug_get_current_polys(RID p_scenario) const = 0;
// Rooms /* ROOMS API */
enum RoomsDebugFeature { enum RoomsDebugFeature {
ROOMS_DEBUG_SPRAWL, ROOMS_DEBUG_SPRAWL,
}; };
@ -1131,8 +1136,8 @@ public:
virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const = 0; virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const = 0;
virtual void init() = 0; virtual void init() = 0;
virtual void finish() = 0; virtual void finish() = 0;
virtual void scenario_tick(RID p_scenario) = 0; virtual void tick() = 0;
virtual void scenario_pre_draw(RID p_scenario, bool p_will_draw) = 0; virtual void pre_draw(bool p_will_draw) = 0;
/* STATUS INFORMATION */ /* STATUS INFORMATION */