mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
perf(world): cull distant players from updates and rendering
Add distance2 utility function. On client, skip rendering other players if distance squared exceeds rendering distance. On server, only send player position and block change updates to players in relevant chunks.
This commit is contained in:
@@ -14,6 +14,11 @@ bool is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents,
|
|||||||
float deterministic_random(int x, int z, uint64_t seed);
|
float deterministic_random(int x, int z, uint64_t seed);
|
||||||
glm::vec3 slerp(const glm::vec3& from, const glm::vec3& to, float t);
|
glm::vec3 slerp(const glm::vec3& from, const glm::vec3& to, float t);
|
||||||
|
|
||||||
|
inline float distance2(const glm::vec3& a, const glm::vec3& b) {
|
||||||
|
glm::vec3 diff = a - b;
|
||||||
|
return glm::dot(diff, diff);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Math
|
} // namespace Math
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "Cubed/config.hpp"
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/gameplay/game_time.hpp"
|
#include "Cubed/gameplay/game_time.hpp"
|
||||||
#include "Cubed/gameplay/packet.hpp"
|
#include "Cubed/gameplay/packet.hpp"
|
||||||
|
#include "Cubed/tools/math_tools.hpp"
|
||||||
|
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
|
|
||||||
@@ -608,6 +609,11 @@ void ClientWorld::update(float delta_time) {
|
|||||||
for (auto& [uuid, player] : m_other_players) {
|
for (auto& [uuid, player] : m_other_players) {
|
||||||
player.render_pos =
|
player.render_pos =
|
||||||
glm::mix(player.render_pos, player.target_pos, 0.15f);
|
glm::mix(player.render_pos, player.target_pos, 0.15f);
|
||||||
|
if (Math::distance2(player.render_pos, m_player.get_player_pos()) >
|
||||||
|
m_rendering_distance * CHUNK_SIZE * m_rendering_distance *
|
||||||
|
CHUNK_SIZE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
m_render_player_data.emplace_back(player.name, player.render_pos);
|
m_render_player_data.emplace_back(player.name, player.render_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -585,7 +585,7 @@ void ServerWorld::sync_player_pos(const std::string& uuid, float x, float y,
|
|||||||
it->second.update_sync_gametick(m_game_ticks);
|
it->second.update_sync_gametick(m_game_ticks);
|
||||||
name = it->second.get_name();
|
name = it->second.get_name();
|
||||||
}
|
}
|
||||||
|
ChunkPos pos = get_chunk_pos(x, z);
|
||||||
// update other player pos;
|
// update other player pos;
|
||||||
std::vector<std::shared_ptr<Session>> other;
|
std::vector<std::shared_ptr<Session>> other;
|
||||||
{
|
{
|
||||||
@@ -594,11 +594,16 @@ void ServerWorld::sync_player_pos(const std::string& uuid, float x, float y,
|
|||||||
if (o_uuid == uuid) {
|
if (o_uuid == uuid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (player.has_player(pos)) {
|
||||||
other.emplace_back(player.get_session());
|
other.emplace_back(player.get_session());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& session : other) {
|
for (auto& session : other) {
|
||||||
|
if (!session) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Arena arena;
|
Arena arena;
|
||||||
auto* rsp = Arena::Create<PlayerInfoRsp>(&arena);
|
auto* rsp = Arena::Create<PlayerInfoRsp>(&arena);
|
||||||
rsp->set_uuid(uuid);
|
rsp->set_uuid(uuid);
|
||||||
@@ -694,9 +699,11 @@ void ServerWorld::handle_player_exit(const std::string& uuid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto& s : sessions) {
|
for (auto& s : sessions) {
|
||||||
|
if (s) {
|
||||||
s->send(make_packet(*rsp));
|
s->send(make_packet(*rsp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 ServerWorld::get_player_pos(const std::string& uuid) const {
|
glm::vec3 ServerWorld::get_player_pos(const std::string& uuid) const {
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_player_mutex);
|
||||||
@@ -741,15 +748,23 @@ void ServerWorld::handle_block_change(const BlockChangeReq& req) {
|
|||||||
pos->set_y(y);
|
pos->set_y(y);
|
||||||
pos->set_z(z);
|
pos->set_z(z);
|
||||||
rsp->set_block(req.block());
|
rsp->set_block(req.block());
|
||||||
|
std::vector<std::shared_ptr<Session>> sessions;
|
||||||
|
auto chunk_pos = get_chunk_pos(x, z);
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_player_mutex);
|
||||||
for (auto& [uuid, player] : m_players) {
|
for (auto& [uuid, player] : m_players) {
|
||||||
|
if (player.has_player(chunk_pos)) {
|
||||||
auto session = player.get_session();
|
auto session = player.get_session();
|
||||||
if (session) {
|
sessions.emplace_back(std::move(session));
|
||||||
session->send(make_packet(*rsp));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& x : sessions) {
|
||||||
|
if (x) {
|
||||||
|
x->send(make_packet(*rsp));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ServerWorld::rendering_distance() const {
|
int ServerWorld::rendering_distance() const {
|
||||||
|
|||||||
Reference in New Issue
Block a user