Selaa lähdekoodia

Merge pull request #57186 from lawnjelly/gameplay_fix_ticks

Rémi Verschelde 3 vuotta sitten
vanhempi
commit
d62166f68f

+ 36 - 31
servers/visual/portals/portal_gameplay_monitor.cpp

@@ -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,18 +459,20 @@ void PortalGameplayMonitor::_swap() {
 	_active_rghost_pool_ids_prev = temp;
 	_active_rghost_pool_ids_curr->clear();
 
-	temp = _active_room_ids_curr;
-	_active_room_ids_curr = _active_room_ids_prev;
-	_active_room_ids_prev = temp;
-	_active_room_ids_curr->clear();
-
-	temp = _active_roomgroup_ids_curr;
-	_active_roomgroup_ids_curr = _active_roomgroup_ids_prev;
-	_active_roomgroup_ids_prev = temp;
-	_active_roomgroup_ids_curr->clear();
-
-	temp = _active_sghost_ids_curr;
-	_active_sghost_ids_curr = _active_sghost_ids_prev;
-	_active_sghost_ids_prev = temp;
-	_active_sghost_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;
+		_active_room_ids_curr->clear();
+
+		temp = _active_roomgroup_ids_curr;
+		_active_roomgroup_ids_curr = _active_roomgroup_ids_prev;
+		_active_roomgroup_ids_prev = temp;
+		_active_roomgroup_ids_curr->clear();
+
+		temp = _active_sghost_ids_curr;
+		_active_sghost_ids_curr = _active_sghost_ids_prev;
+		_active_sghost_ids_prev = temp;
+		_active_sghost_ids_curr->clear();
+	}
 }

+ 8 - 1
servers/visual/portals/portal_gameplay_monitor.h

@@ -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;

+ 1 - 1
servers/visual/portals/portal_renderer.h

@@ -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 {

+ 3 - 3
servers/visual/portals/portal_types.h

@@ -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;