Merge pull request #57489 from akien-mga/3.4-cherrypicks

This commit is contained in:
Rémi Verschelde 2022-01-31 22:54:02 +01:00 committed by GitHub
commit caaa648e86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 157 additions and 83 deletions

View File

@ -8,8 +8,8 @@
See also [AudioStreamGenerator] for procedurally generating sounds.
</description>
<tutorials>
<link title="https://godotengine.org/asset-library/asset/528">Audio Spectrum Demo</link>
<link title="https://godotengine.org/article/godot-32-will-get-new-audio-features">Godot 3.2 will get new audio features</link>
<link title="Audio Spectrum Demo">https://godotengine.org/asset-library/asset/528</link>
<link title="Godot 3.2 will get new audio features">https://godotengine.org/article/godot-32-will-get-new-audio-features</link>
</tutorials>
<methods>
</methods>

View File

@ -10,7 +10,7 @@
</description>
<tutorials>
<link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link>
<link title="https://godotengine.org/article/godot-32-will-get-new-audio-features">Godot 3.2 will get new audio features</link>
<link title="Godot 3.2 will get new audio features">https://godotengine.org/article/godot-32-will-get-new-audio-features</link>
</tutorials>
<methods>
</methods>

View File

@ -8,7 +8,7 @@
</description>
<tutorials>
<link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link>
<link title="https://godotengine.org/article/godot-32-will-get-new-audio-features">Godot 3.2 will get new audio features</link>
<link title="Godot 3.2 will get new audio features">https://godotengine.org/article/godot-32-will-get-new-audio-features</link>
</tutorials>
<methods>
<method name="can_push_buffer" qualifiers="const">

View File

@ -47,6 +47,7 @@
</member>
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="0.0">
The maximum distance away from the [ReflectionProbe] an object can be before it is culled. Decrease this to improve performance, especially when using the [constant UPDATE_ALWAYS] [member update_mode].
[b]Note:[/b] The maximum reflection distance is always at least equal to the [member extents]. This means that decreasing [member max_distance] will not always cull objects from reflections, especially if the reflection probe's [member extents] are already large.
</member>
<member name="origin_offset" type="Vector3" setter="set_origin_offset" getter="get_origin_offset" default="Vector3( 0, 0, 0 )">
Sets the origin offset to be used when this [ReflectionProbe] is in [member box_projection] mode. This can be set to a non-zero value to ensure a reflection fits a rectangle-shaped room, while reducing the amount of objects that "get in the way" of the reflection.

View File

@ -77,7 +77,7 @@ void SkeletonEditor::create_physical_skeleton() {
if (!bones_infos[parent].physical_bone) {
bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
ur->create_action(TTR("Create physical bones"));
ur->create_action(TTR("Create physical bones"), UndoRedo::MERGE_ALL);
ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone);
ur->add_do_reference(bones_infos[parent].physical_bone);
ur->add_undo_method(skeleton, "remove_child", bones_infos[parent].physical_bone);

View File

@ -164,11 +164,12 @@ const char *godot_so_name = "libgodot_android.so";
void *mono_dl_handle = NULL;
void *godot_dl_handle = NULL;
void *try_dlopen(const String &p_so_path, int p_flags) {
void *_try_dlopen_file_path(const String &p_so_path, int p_flags) {
if (!FileAccess::exists(p_so_path)) {
if (OS::get_singleton()->is_stdout_verbose())
if (OS::get_singleton()->is_stdout_verbose()) {
OS::get_singleton()->print("Cannot find shared library: '%s'\n", p_so_path.utf8().get_data());
return NULL;
}
return nullptr;
}
int lflags = gd_mono_convert_dl_flags(p_flags);
@ -176,13 +177,48 @@ void *try_dlopen(const String &p_so_path, int p_flags) {
void *handle = dlopen(p_so_path.utf8().get_data(), lflags);
if (!handle) {
if (OS::get_singleton()->is_stdout_verbose())
if (OS::get_singleton()->is_stdout_verbose()) {
OS::get_singleton()->print("Failed to open shared library: '%s'. Error: '%s'\n", p_so_path.utf8().get_data(), dlerror());
return NULL;
}
return nullptr;
}
if (OS::get_singleton()->is_stdout_verbose())
if (OS::get_singleton()->is_stdout_verbose()) {
OS::get_singleton()->print("Successfully loaded shared library: '%s'\n", p_so_path.utf8().get_data());
}
return handle;
}
void *try_dlopen(const String &p_so_path, int p_flags) {
void *handle = _try_dlopen_file_path(p_so_path, p_flags);
if (handle) {
return handle;
}
// Try only with the file name, without specifying the location.
// This is needed when installing from Android App Bundles, as the native
// libraries are not extracted. They are loaded directly from the APK.
// See: https://stackoverflow.com/a/56551499
// If we pass only the file name to dlopen without the location, it should
// search the native libraries in all locations, including inside the apk.
String so_name = p_so_path.get_file();
int lflags = gd_mono_convert_dl_flags(p_flags);
handle = dlopen(so_name.utf8().get_data(), lflags);
if (!handle) {
if (OS::get_singleton()->is_stdout_verbose()) {
OS::get_singleton()->print("Failed to open shared library: '%s'. Error: '%s'\n", so_name.utf8().get_data(), dlerror());
}
return nullptr;
}
if (OS::get_singleton()->is_stdout_verbose()) {
OS::get_singleton()->print("Successfully loaded shared library: '%s'\n", so_name.utf8().get_data());
}
return handle;
}
@ -196,6 +232,7 @@ void *gd_mono_android_dlopen(const char *p_name, int p_flags, char **r_err, void
String so_path = path::join(app_native_lib_dir, mono_so_name);
mono_dl_handle = try_dlopen(so_path, p_flags);
ERR_FAIL_COND_V_MSG(!mono_dl_handle, nullptr, "Failed to load Mono native library from path");
}
return mono_dl_handle;
@ -371,7 +408,7 @@ void initialize() {
String so_path = path::join(app_native_lib_dir, godot_so_name);
godot_dl_handle = try_dlopen(so_path, gd_mono_convert_dl_flags(MONO_DL_LAZY));
ERR_FAIL_COND(!godot_dl_handle);
ERR_FAIL_COND_MSG(!godot_dl_handle, "Failed to load Godot native library");
}
void cleanup() {

View File

@ -185,8 +185,8 @@ void AudioStreamOGGVorbis::set_data(const PoolVector<uint8_t> &p_data) {
w.release();
alloc_try *= 2;
} else {
ERR_FAIL_COND(alloc_try == MAX_TEST_MEM);
ERR_FAIL_COND(ogg_stream == nullptr);
ERR_FAIL_COND_MSG(alloc_try == MAX_TEST_MEM, "Failed allocating memory for OGG Vorbis stream.");
ERR_FAIL_COND_MSG(!ogg_stream, "OGG Vorbis decoding failed. Check that your data is a valid OGG Vorbis audio stream.");
stb_vorbis_info info = stb_vorbis_get_info(ogg_stream);

View File

@ -91,7 +91,7 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin
ogg_stream.instance();
ogg_stream->set_data(data);
ERR_FAIL_COND_V(!ogg_stream->get_data().size(), ERR_FILE_CORRUPT);
ERR_FAIL_COND_V_MSG(!ogg_stream->get_data().size(), ERR_FILE_CORRUPT, "Couldn't import file as AudioStreamOGGVorbis: " + p_source_file);
ogg_stream->set_loop(loop);
ogg_stream->set_loop_offset(loop_offset);

View File

@ -987,14 +987,14 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
if (tname == "meta-data" && attrname == "name" && value == "xr_mode_metadata_name") {
// Update the meta-data 'android:name' attribute based on the selected XR mode.
if (xr_mode_index == XR_MODE_OVR || xr_mode_index == XR_MODE_OPENXR) {
if (xr_mode_index == XR_MODE_OVR) {
string_table.write[attr_value] = "com.samsung.android.vr.application.mode";
}
}
if (tname == "meta-data" && attrname == "value" && value == "xr_mode_metadata_value") {
// Update the meta-data 'android:value' attribute based on the selected XR mode.
if (xr_mode_index == XR_MODE_OVR || xr_mode_index == XR_MODE_OPENXR) {
if (xr_mode_index == XR_MODE_OVR) {
string_table.write[attr_value] = "vr_only";
}
}

View File

@ -287,7 +287,9 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
bool_to_string(p_has_storage_permission));
if (uses_xr) {
if (xr_mode_index == XR_MODE_OVR) {
manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n";
}
bool hand_tracking_enabled = (int)(p_preset->get("xr_features/hand_tracking")) > XR_HAND_TRACKING_NONE;
if (hand_tracking_enabled) {
@ -297,6 +299,8 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
" <meta-data tools:node=\"replace\" android:name=\"com.oculus.handtracking.frequency\" android:value=\"%s\" />\n",
hand_tracking_frequency);
}
} else {
manifest_application_text += " <meta-data tools:node=\"remove\" android:name=\"com.oculus.supportedDevices\" />\n";
}
manifest_application_text += _get_activity_tag(p_preset);
manifest_application_text += " </application>\n";

View File

@ -50,6 +50,12 @@
android:name="xr_hand_tracking_metadata_name"
android:value="xr_hand_tracking_metadata_value"/>
<!-- Supported Meta devices -->
<!-- This is removed by the exporter if the xr mode is not VR. -->
<meta-data
android:name="com.oculus.supportedDevices"
android:value="all" />
<activity
android:name=".GodotApp"
android:label="@string/godot_project_name_string"

View File

@ -225,33 +225,34 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
*/
Config.prototype.update = function (opts) {
const config = opts || {};
function parse(key, def) {
const me = this;
function parse(key) {
if (typeof (config[key]) === 'undefined') {
return def;
return me[key];
}
return config[key];
}
// Module config
this.unloadAfterInit = parse('unloadAfterInit', this.unloadAfterInit);
this.onPrintError = parse('onPrintError', this.onPrintError);
this.onPrint = parse('onPrint', this.onPrint);
this.onProgress = parse('onProgress', this.onProgress);
this.unloadAfterInit = parse('unloadAfterInit');
this.onPrintError = parse('onPrintError');
this.onPrint = parse('onPrint');
this.onProgress = parse('onProgress');
// Godot config
this.canvas = parse('canvas', this.canvas);
this.executable = parse('executable', this.executable);
this.mainPack = parse('mainPack', this.mainPack);
this.locale = parse('locale', this.locale);
this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy);
this.persistentPaths = parse('persistentPaths', this.persistentPaths);
this.persistentDrops = parse('persistentDrops', this.persistentDrops);
this.experimentalVK = parse('experimentalVK', this.experimentalVK);
this.focusCanvas = parse('focusCanvas', this.focusCanvas);
this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs);
this.fileSizes = parse('fileSizes', this.fileSizes);
this.args = parse('args', this.args);
this.onExecute = parse('onExecute', this.onExecute);
this.onExit = parse('onExit', this.onExit);
this.canvas = parse('canvas');
this.executable = parse('executable');
this.mainPack = parse('mainPack');
this.locale = parse('locale');
this.canvasResizePolicy = parse('canvasResizePolicy');
this.persistentPaths = parse('persistentPaths');
this.persistentDrops = parse('persistentDrops');
this.experimentalVK = parse('experimentalVK');
this.focusCanvas = parse('focusCanvas');
this.gdnativeLibs = parse('gdnativeLibs');
this.fileSizes = parse('fileSizes');
this.args = parse('args');
this.onExecute = parse('onExecute');
this.onExit = parse('onExit');
};
/**

View File

@ -87,7 +87,7 @@ const GodotInputGamepads = {
},
init: function (onchange) {
GodotEventListeners.samples = [];
GodotInputGamepads.samples = [];
function add(pad) {
const guid = GodotInputGamepads.get_guid(pad);
const c_id = GodotRuntime.allocString(pad.id);

View File

@ -140,6 +140,11 @@ __declspec(dllexport) int widechar_main(int argc, wchar_t **argv) {
setlocale(LC_CTYPE, "");
#ifndef TOOLS_ENABLED
// Workaround to prevent LTCG (MSVC LTO) from removing "pck" section
char *dummy_guard = dummy;
#endif
char **argv_utf8 = new char *[argc];
for (int i = 0; i < argc; ++i) {

View File

@ -170,7 +170,7 @@ uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) {
id = shapes.back()->key() + 1;
}
sd.owner = p_owner;
sd.owner_id = p_owner ? p_owner->get_instance_id() : 0;
shapes[id] = sd;
@ -283,7 +283,7 @@ Transform2D CollisionObject2D::shape_owner_get_transform(uint32_t p_owner) const
Object *CollisionObject2D::shape_owner_get_owner(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), nullptr);
return shapes[p_owner].owner;
return ObjectDB::get_instance(shapes[p_owner].owner_id);
}
void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape) {

View File

@ -45,7 +45,7 @@ class CollisionObject2D : public Node2D {
bool pickable;
struct ShapeData {
Object *owner;
ObjectID owner_id;
Transform2D xform;
struct Shape {
Ref<Shape2D> shape;
@ -61,7 +61,7 @@ class CollisionObject2D : public Node2D {
disabled = false;
one_way_collision = false;
one_way_collision_margin = 0;
owner = nullptr;
owner_id = 0;
}
};

View File

@ -363,7 +363,7 @@ uint32_t CollisionObject::create_shape_owner(Object *p_owner) {
id = shapes.back()->key() + 1;
}
sd.owner = p_owner;
sd.owner_id = p_owner ? p_owner->get_instance_id() : 0;
shapes[id] = sd;
@ -442,7 +442,7 @@ Transform CollisionObject::shape_owner_get_transform(uint32_t p_owner) const {
Object *CollisionObject::shape_owner_get_owner(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), nullptr);
return shapes[p_owner].owner;
return ObjectDB::get_instance(shapes[p_owner].owner_id);
}
void CollisionObject::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape> &p_shape) {

View File

@ -45,7 +45,7 @@ class CollisionObject : public Spatial {
RID rid;
struct ShapeData {
Object *owner;
ObjectID owner_id;
Transform xform;
struct ShapeBase {
RID debug_shape;
@ -58,7 +58,7 @@ class CollisionObject : public Spatial {
ShapeData() {
disabled = false;
owner = nullptr;
owner_id = 0;
}
};

View File

@ -168,6 +168,12 @@ void TextureButton::_notification(int p_what) {
Point2 ofs;
Size2 size;
bool draw_focus = (has_focus() && focused.is_valid());
// If no other texture is valid, try using focused texture.
if (!texdraw.is_valid() && draw_focus) {
texdraw = focused;
}
if (texdraw.is_valid()) {
size = texdraw->get_size();
@ -224,7 +230,9 @@ void TextureButton::_notification(int p_what) {
size.width *= hflip ? -1.0f : 1.0f;
size.height *= vflip ? -1.0f : 1.0f;
if (_tile) {
if (texdraw == focused) {
// Do nothing, we only needed to calculate the rectangle.
} else if (_tile) {
draw_texture_rect(texdraw, Rect2(ofs, size), _tile);
} else {
draw_texture_rect_region(texdraw, Rect2(ofs, size), _texture_region);
@ -233,7 +241,7 @@ void TextureButton::_notification(int p_what) {
_position_rect = Rect2();
}
if (has_focus() && focused.is_valid()) {
if (draw_focus) {
draw_texture_rect(focused, Rect2(ofs, size), false);
};
} break;

View File

@ -109,7 +109,7 @@ void PortalGameplayMonitor::unload(PortalRenderer &p_portal_renderer) {
for (int n = 0; n < _active_room_ids_prev->size(); n++) {
int room_id = (*_active_room_ids_prev)[n];
VSRoom &room = p_portal_renderer.get_room(room_id);
room.last_gameplay_tick_hit = 0;
room.last_room_tick_hit = 0;
VisualServerCallbacks::Message msg;
msg.object_id = room._godot_instance_ID;
@ -121,7 +121,7 @@ void PortalGameplayMonitor::unload(PortalRenderer &p_portal_renderer) {
for (int n = 0; n < _active_roomgroup_ids_prev->size(); n++) {
int roomgroup_id = (*_active_roomgroup_ids_prev)[n];
VSRoomGroup &roomgroup = p_portal_renderer.get_roomgroup(roomgroup_id);
roomgroup.last_gameplay_tick_hit = 0;
roomgroup.last_room_tick_hit = 0;
VisualServerCallbacks::Message msg;
msg.object_id = roomgroup._godot_instance_ID;
@ -133,7 +133,7 @@ void PortalGameplayMonitor::unload(PortalRenderer &p_portal_renderer) {
for (int n = 0; n < _active_sghost_ids_prev->size(); n++) {
int id = (*_active_sghost_ids_prev)[n];
VSStaticGhost &ghost = p_portal_renderer.get_static_ghost(id);
ghost.last_gameplay_tick_hit = 0;
ghost.last_room_tick_hit = 0;
VisualServerCallbacks::Message msg;
msg.object_id = ghost.object_id;
@ -185,6 +185,9 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
// if there is no change in the source room IDs, then we can optimize out a lot of the checks
// (anything not to do with roamers)
bool source_rooms_changed = _source_rooms_changed(p_source_room_ids, p_num_source_rooms);
if (source_rooms_changed) {
_room_tick++;
}
// lock output
VisualServerCallbacks *callbacks = VSG::scene->get_callbacks();
@ -249,7 +252,7 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
const VSRoom &room = p_portal_renderer.get_room(room_id);
// gone out of view
if (room.last_gameplay_tick_hit != _gameplay_tick) {
if (room.last_room_tick_hit != _room_tick) {
VisualServerCallbacks::Message msg;
msg.object_id = room._godot_instance_ID;
msg.type = _exit_callback_type;
@ -264,7 +267,7 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
const VSRoomGroup &roomgroup = p_portal_renderer.get_roomgroup(roomgroup_id);
// gone out of view
if (roomgroup.last_gameplay_tick_hit != _gameplay_tick) {
if (roomgroup.last_room_tick_hit != _room_tick) {
VisualServerCallbacks::Message msg;
msg.object_id = roomgroup._godot_instance_ID;
msg.type = _exit_callback_type;
@ -279,7 +282,7 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
VSStaticGhost &ghost = p_portal_renderer.get_static_ghost(id);
// gone out of view
if (ghost.last_gameplay_tick_hit != _gameplay_tick) {
if (ghost.last_room_tick_hit != _room_tick) {
VisualServerCallbacks::Message msg;
msg.object_id = ghost.object_id;
msg.type = VisualServerCallbacks::CALLBACK_NOTIFICATION_EXIT_GAMEPLAY;
@ -293,7 +296,7 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
callbacks->unlock();
// swap the current and previous lists
_swap();
_swap(source_rooms_changed);
}
void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_renderer, int p_room_id, bool p_source_rooms_changed) {
@ -367,14 +370,14 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
// later tests only relevant if a room has just come into play
bool room_came_into_play = false;
if (room.last_gameplay_tick_hit != _gameplay_tick) {
if (room.last_room_tick_hit != _room_tick) {
room_came_into_play = true;
// add the room to the active list
_active_room_ids_curr->push_back(p_room_id);
// if wasn't present in the tick before, add the notification to enter
if (room.last_gameplay_tick_hit != (_gameplay_tick - 1)) {
if (room.last_room_tick_hit != (_room_tick - 1)) {
VisualServerCallbacks::Message msg;
msg.object_id = room._godot_instance_ID;
msg.type = _enter_callback_type;
@ -383,7 +386,7 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
}
// mark as done
room.last_gameplay_tick_hit = _gameplay_tick;
room.last_room_tick_hit = _room_tick;
}
// no need to do later tests
@ -398,12 +401,12 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
VSRoomGroup &roomgroup = p_portal_renderer.get_roomgroup(roomgroup_id);
if (roomgroup.last_gameplay_tick_hit != _gameplay_tick) {
if (roomgroup.last_room_tick_hit != _room_tick) {
// add the room to the active list
_active_roomgroup_ids_curr->push_back(roomgroup_id);
// if wasn't present in the tick before, add the notification to enter
if (roomgroup.last_gameplay_tick_hit != (_gameplay_tick - 1)) {
if (roomgroup.last_room_tick_hit != (_room_tick - 1)) {
VisualServerCallbacks::Message msg;
msg.object_id = roomgroup._godot_instance_ID;
msg.type = _enter_callback_type;
@ -412,7 +415,7 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
}
// mark as done
roomgroup.last_gameplay_tick_hit = _gameplay_tick;
roomgroup.last_room_tick_hit = _room_tick;
}
} // for through roomgroups
@ -425,14 +428,14 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
VSStaticGhost &ghost = p_portal_renderer.get_static_ghost(id);
// done already?
if (ghost.last_gameplay_tick_hit == _gameplay_tick)
if (ghost.last_room_tick_hit == _room_tick)
continue;
// add to the active list
_active_sghost_ids_curr->push_back(id);
// if wasn't present in the tick before, add the notification to enter
if (ghost.last_gameplay_tick_hit != (_gameplay_tick - 1)) {
if (ghost.last_room_tick_hit != (_room_tick - 1)) {
VisualServerCallbacks::Message msg;
msg.object_id = ghost.object_id;
msg.type = VisualServerCallbacks::CALLBACK_NOTIFICATION_ENTER_GAMEPLAY;
@ -441,11 +444,11 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
}
// mark as done
ghost.last_gameplay_tick_hit = _gameplay_tick;
ghost.last_room_tick_hit = _room_tick;
}
}
void PortalGameplayMonitor::_swap() {
void PortalGameplayMonitor::_swap(bool p_source_rooms_changed) {
LocalVector<uint32_t, int32_t> *temp = _active_moving_pool_ids_curr;
_active_moving_pool_ids_curr = _active_moving_pool_ids_prev;
_active_moving_pool_ids_prev = temp;
@ -456,6 +459,7 @@ void PortalGameplayMonitor::_swap() {
_active_rghost_pool_ids_prev = temp;
_active_rghost_pool_ids_curr->clear();
if (p_source_rooms_changed) {
temp = _active_room_ids_curr;
_active_room_ids_curr = _active_room_ids_prev;
_active_room_ids_prev = temp;
@ -470,4 +474,5 @@ void PortalGameplayMonitor::_swap() {
_active_sghost_ids_curr = _active_sghost_ids_prev;
_active_sghost_ids_prev = temp;
_active_sghost_ids_curr->clear();
}
}

View File

@ -52,10 +52,17 @@ public:
private:
void _update_gameplay_room(PortalRenderer &p_portal_renderer, int p_room_id, bool p_source_rooms_changed);
bool _source_rooms_changed(const int *p_source_room_ids, int p_num_source_rooms);
void _swap();
void _swap(bool p_source_rooms_changed);
// gameplay ticks happen every physics tick
uint32_t _gameplay_tick = 1;
// Room ticks only happen when the rooms the cameras are within change.
// This is an optimization. This tick needs to be maintained separately from _gameplay_tick
// because testing against the previous tick is used to determine whether to send enter or exit
// gameplay notifications, and this must be synchronized differently for rooms, roomgroups and static ghosts.
uint32_t _room_tick = 1;
// we need two version, current and previous
LocalVector<uint32_t, int32_t> _active_moving_pool_ids[2];
LocalVector<uint32_t, int32_t> *_active_moving_pool_ids_curr;

View File

@ -68,7 +68,7 @@ struct VSStaticGhost {
ObjectID object_id;
uint32_t last_tick_hit = 0;
uint32_t last_gameplay_tick_hit = 0;
uint32_t last_room_tick_hit = 0;
};
class PortalRenderer {

View File

@ -227,7 +227,7 @@ struct VSRoomGroup {
}
// used for calculating gameplay notifications
uint32_t last_gameplay_tick_hit = 0;
uint32_t last_room_tick_hit = 0;
ObjectID _godot_instance_ID = 0;
@ -257,7 +257,7 @@ struct VSRoom {
_secondary_pvs_size = 0;
_priority = 0;
_contains_internal_rooms = false;
last_gameplay_tick_hit = 0;
last_room_tick_hit = 0;
}
void cleanup_after_conversion() {
@ -354,7 +354,7 @@ struct VSRoom {
uint16_t _secondary_pvs_size = 0;
// used for calculating gameplay notifications
uint32_t last_gameplay_tick_hit = 0;
uint32_t last_room_tick_hit = 0;
// convex hull of the room, either determined by geometry or manual bound
LocalVector<Plane, int32_t> _planes;