mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
refactor(client): extract AABB creation and add collision check on block place
Make ClientPlayer::get_aabb and ClientWorld::get_block_aabb static. Change player size to static constexpr M_SIZE. Use shared_mutex for concurrent reads of other players. Check for collision with other players before placing a block.
This commit is contained in:
@@ -23,7 +23,7 @@ public:
|
|||||||
const ChunkPosSet& get_chunk_pos_set() const;
|
const ChunkPosSet& get_chunk_pos_set() const;
|
||||||
ChunkPosSet& get_chunk_pos_set();
|
ChunkPosSet& get_chunk_pos_set();
|
||||||
|
|
||||||
AABB get_aabb(const glm::vec3& pos) const;
|
static AABB get_aabb(const glm::vec3& pos);
|
||||||
const glm::vec3& get_front() const;
|
const glm::vec3& get_front() const;
|
||||||
const Gait& get_gait() const;
|
const Gait& get_gait() const;
|
||||||
const std::optional<LookBlock>& get_look_block_pos() const;
|
const std::optional<LookBlock>& get_look_block_pos() const;
|
||||||
@@ -97,7 +97,7 @@ private:
|
|||||||
|
|
||||||
glm::vec3 m_front{0, 0, -1};
|
glm::vec3 m_front{0, 0, -1};
|
||||||
glm::vec3 m_right{0, 0, 0};
|
glm::vec3 m_right{0, 0, 0};
|
||||||
glm::vec3 m_size{0.6f, 1.8f, 0.6f};
|
static constexpr glm::vec3 M_SIZE{0.6f, 1.8f, 0.6f};
|
||||||
|
|
||||||
Gait m_gait = Gait::WALK;
|
Gait m_gait = Gait::WALK;
|
||||||
MoveState m_move_state{};
|
MoveState m_move_state{};
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ public:
|
|||||||
void request_exit();
|
void request_exit();
|
||||||
bool is_receive_exit();
|
bool is_receive_exit();
|
||||||
int chunk_size() const;
|
int chunk_size() const;
|
||||||
|
static AABB get_block_aabb(const glm::ivec3& pos);
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
void register_timer(std::string_view id, TickType threshold, Fn&& f) {
|
void register_timer(std::string_view id, TickType threshold, Fn&& f) {
|
||||||
m_timers.emplace(std::piecewise_construct,
|
m_timers.emplace(std::piecewise_construct,
|
||||||
@@ -99,7 +100,7 @@ private:
|
|||||||
|
|
||||||
std::mutex m_delete_vbo_mutex;
|
std::mutex m_delete_vbo_mutex;
|
||||||
std::mutex m_delete_vao_mutex;
|
std::mutex m_delete_vao_mutex;
|
||||||
std::mutex m_other_players_mutex;
|
mutable std::shared_mutex m_other_players_mutex;
|
||||||
|
|
||||||
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
||||||
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ namespace Cubed {
|
|||||||
ClientPlayer::ClientPlayer(ClientWorld& world) : m_world(world) {}
|
ClientPlayer::ClientPlayer(ClientWorld& world) : m_world(world) {}
|
||||||
ClientPlayer::~ClientPlayer() {}
|
ClientPlayer::~ClientPlayer() {}
|
||||||
|
|
||||||
AABB ClientPlayer::get_aabb(const glm::vec3& pos) const {
|
AABB ClientPlayer::get_aabb(const glm::vec3& pos) {
|
||||||
float half_width = m_size.x / 2.0f;
|
float half_width = M_SIZE.x / 2.0f;
|
||||||
float half_depth = m_size.z / 2.0f;
|
float half_depth = M_SIZE.z / 2.0f;
|
||||||
|
|
||||||
glm::vec3 min{pos.x - half_width, pos.y, pos.z - half_depth};
|
glm::vec3 min{pos.x - half_width, pos.y, pos.z - half_depth};
|
||||||
|
|
||||||
glm::vec3 max{pos.x + half_width, pos.y + m_size.y, pos.z + half_depth};
|
glm::vec3 max{pos.x + half_width, pos.y + M_SIZE.y, pos.z + half_depth};
|
||||||
|
|
||||||
return AABB{min, max};
|
return AABB{min, max};
|
||||||
}
|
}
|
||||||
@@ -282,15 +282,7 @@ void ClientPlayer::update_lookup_block() {
|
|||||||
if (Input::get_input_state().mouse_state.right) {
|
if (Input::get_input_state().mouse_state.right) {
|
||||||
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
|
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
|
||||||
if (!m_world.is_solid(near_pos)) {
|
if (!m_world.is_solid(near_pos)) {
|
||||||
auto x = near_pos.x;
|
AABB block_box = ClientWorld::get_block_aabb(near_pos);
|
||||||
auto y = near_pos.y;
|
|
||||||
auto z = near_pos.z;
|
|
||||||
AABB block_box = {glm::vec3{static_cast<float>(x),
|
|
||||||
static_cast<float>(y),
|
|
||||||
static_cast<float>(z)},
|
|
||||||
glm::vec3{static_cast<float>(x + 1),
|
|
||||||
static_cast<float>(y + 1),
|
|
||||||
static_cast<float>(z + 1)}};
|
|
||||||
AABB player_box = get_aabb(get_player_pos());
|
AABB player_box = get_aabb(get_player_pos());
|
||||||
if (!player_box.intersects(block_box)) {
|
if (!player_box.intersects(block_box)) {
|
||||||
m_world.report_block_change(near_pos, m_place_block);
|
m_world.report_block_change(near_pos, m_place_block);
|
||||||
@@ -409,13 +401,9 @@ void ClientPlayer::update_x_move(glm::vec3& player_pos) {
|
|||||||
for (int x = minx; x <= maxx; ++x) {
|
for (int x = minx; x <= maxx; ++x) {
|
||||||
for (int y = miny; y <= maxy; ++y) {
|
for (int y = miny; y <= maxy; ++y) {
|
||||||
for (int z = minz; z <= maxz; ++z) {
|
for (int z = minz; z <= maxz; ++z) {
|
||||||
if (!m_world.can_pass_block(glm::ivec3{x, y, z})) {
|
glm::ivec3 block_pos{x, y, z};
|
||||||
AABB block_box = {glm::vec3{static_cast<float>(x),
|
if (!m_world.can_pass_block(block_pos)) {
|
||||||
static_cast<float>(y),
|
AABB block_box = ClientWorld::get_block_aabb(block_pos);
|
||||||
static_cast<float>(z)},
|
|
||||||
glm::vec3{static_cast<float>(x + 1),
|
|
||||||
static_cast<float>(y + 1),
|
|
||||||
static_cast<float>(z + 1)}};
|
|
||||||
if (player_box.intersects(block_box)) {
|
if (player_box.intersects(block_box)) {
|
||||||
m_gait = Gait::WALK;
|
m_gait = Gait::WALK;
|
||||||
player_pos.x -= move_distance.x;
|
player_pos.x -= move_distance.x;
|
||||||
@@ -443,13 +431,9 @@ void ClientPlayer::update_y_move(glm::vec3& player_pos) {
|
|||||||
for (int x = minx; x <= maxx; ++x) {
|
for (int x = minx; x <= maxx; ++x) {
|
||||||
for (int y = miny; y <= maxy; ++y) {
|
for (int y = miny; y <= maxy; ++y) {
|
||||||
for (int z = minz; z <= maxz; ++z) {
|
for (int z = minz; z <= maxz; ++z) {
|
||||||
if (!m_world.can_pass_block(glm::ivec3{x, y, z})) {
|
glm::ivec3 block_pos{x, y, z};
|
||||||
AABB block_box = {glm::vec3{static_cast<float>(x),
|
if (!m_world.can_pass_block(block_pos)) {
|
||||||
static_cast<float>(y),
|
AABB block_box = ClientWorld::get_block_aabb(block_pos);
|
||||||
static_cast<float>(z)},
|
|
||||||
glm::vec3{static_cast<float>(x + 1),
|
|
||||||
static_cast<float>(y + 1),
|
|
||||||
static_cast<float>(z + 1)}};
|
|
||||||
if (player_box.intersects(block_box)) {
|
if (player_box.intersects(block_box)) {
|
||||||
player_pos.y -= move_distance.y;
|
player_pos.y -= move_distance.y;
|
||||||
m_y_speed = 0.0f;
|
m_y_speed = 0.0f;
|
||||||
@@ -481,13 +465,9 @@ void ClientPlayer::update_z_move(glm::vec3& player_pos) {
|
|||||||
for (int x = minx; x <= maxx; ++x) {
|
for (int x = minx; x <= maxx; ++x) {
|
||||||
for (int y = miny; y <= maxy; ++y) {
|
for (int y = miny; y <= maxy; ++y) {
|
||||||
for (int z = minz; z <= maxz; ++z) {
|
for (int z = minz; z <= maxz; ++z) {
|
||||||
if (!m_world.can_pass_block(glm::ivec3{x, y, z})) {
|
glm::ivec3 block_pos{x, y, z};
|
||||||
AABB block_box = {glm::vec3{static_cast<float>(x),
|
if (!m_world.can_pass_block(block_pos)) {
|
||||||
static_cast<float>(y),
|
AABB block_box = ClientWorld::get_block_aabb(block_pos);
|
||||||
static_cast<float>(z)},
|
|
||||||
glm::vec3{static_cast<float>(x + 1),
|
|
||||||
static_cast<float>(y + 1),
|
|
||||||
static_cast<float>(z + 1)}};
|
|
||||||
if (player_box.intersects(block_box)) {
|
if (player_box.intersects(block_box)) {
|
||||||
m_gait = Gait::WALK;
|
m_gait = Gait::WALK;
|
||||||
player_pos.z -= move_distance.z;
|
player_pos.z -= move_distance.z;
|
||||||
|
|||||||
@@ -262,6 +262,18 @@ void ClientWorld::push_delete_vao(GLuint vao) {
|
|||||||
|
|
||||||
void ClientWorld::report_block_change(const glm::ivec3& pos,
|
void ClientWorld::report_block_change(const glm::ivec3& pos,
|
||||||
unsigned id) const {
|
unsigned id) const {
|
||||||
|
{
|
||||||
|
AABB block_box = get_block_aabb(pos);
|
||||||
|
std::shared_lock lock(m_other_players_mutex);
|
||||||
|
|
||||||
|
for (auto& [uuid, player] : m_other_players) {
|
||||||
|
AABB box = ClientPlayer::get_aabb(player.target_pos);
|
||||||
|
if (box.intersects(block_box)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Arena arena;
|
Arena arena;
|
||||||
auto* req = Arena::Create<BlockChangeReq>(&arena);
|
auto* req = Arena::Create<BlockChangeReq>(&arena);
|
||||||
req->set_uuid(m_player.get_uuid());
|
req->set_uuid(m_player.get_uuid());
|
||||||
@@ -572,6 +584,16 @@ bool ClientWorld::is_receive_exit() { return m_receive_exit; }
|
|||||||
|
|
||||||
int ClientWorld::chunk_size() const { return m_chunks.size(); }
|
int ClientWorld::chunk_size() const { return m_chunks.size(); }
|
||||||
|
|
||||||
|
AABB ClientWorld::get_block_aabb(const glm::ivec3& pos) {
|
||||||
|
auto x = pos.x;
|
||||||
|
auto y = pos.y;
|
||||||
|
auto z = pos.z;
|
||||||
|
return {glm::vec3{static_cast<float>(x), static_cast<float>(y),
|
||||||
|
static_cast<float>(z)},
|
||||||
|
glm::vec3{static_cast<float>(x + 1), static_cast<float>(y + 1),
|
||||||
|
static_cast<float>(z + 1)}};
|
||||||
|
}
|
||||||
|
|
||||||
void ClientWorld::request_exit() {
|
void ClientWorld::request_exit() {
|
||||||
if (m_receive_exit) {
|
if (m_receive_exit) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user