mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
refactor(collision): convert AABB to center-half representation and migrate player data to ECS
This commit is contained in:
16
assets/model/creature/collision.json
Normal file
16
assets/model/creature/collision.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"boxes": [
|
||||||
|
{
|
||||||
|
"center": [
|
||||||
|
0,
|
||||||
|
0.78,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"half": [
|
||||||
|
0.53,
|
||||||
|
0.78,
|
||||||
|
0.406
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -4,16 +4,20 @@
|
|||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
struct AABB {
|
struct AABB {
|
||||||
glm::vec3 min{0.0f, 0.0f, 0.0f};
|
glm::vec3 center{0.0f};
|
||||||
glm::vec3 max{0.0f, 0.0f, 0.0f};
|
glm::vec3 half{0.0f};
|
||||||
|
|
||||||
AABB(glm::vec3 min_point, glm::vec3 max_point)
|
AABB(glm::vec3 center_point, glm::vec3 half_size)
|
||||||
: min(min_point), max(max_point) {}
|
: center(center_point), half(half_size) {}
|
||||||
|
|
||||||
|
glm::vec3 min() const { return center - half; }
|
||||||
|
|
||||||
|
glm::vec3 max() const { return center + half; }
|
||||||
|
|
||||||
bool intersects(const AABB& other) const {
|
bool intersects(const AABB& other) const {
|
||||||
return (min.x <= other.max.x && max.x >= other.min.x) &&
|
return (glm::abs(center.x - other.center.x) <= half.x + other.half.x) &&
|
||||||
(min.y <= other.max.y && max.y >= other.min.y) &&
|
(glm::abs(center.y - other.center.y) <= half.y + other.half.y) &&
|
||||||
(min.z <= other.max.z && max.z >= other.min.z);
|
(glm::abs(center.z - other.center.z) <= half.z + other.half.z);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -20,21 +20,6 @@
|
|||||||
#include <tbb/concurrent_unordered_map.h>
|
#include <tbb/concurrent_unordered_map.h>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
struct PlayerInfo {
|
|
||||||
std::string name;
|
|
||||||
std::string uuid;
|
|
||||||
glm::vec3 render_pos;
|
|
||||||
glm::vec3 target_pos;
|
|
||||||
float render_yaw;
|
|
||||||
float yaw;
|
|
||||||
float render_pitch;
|
|
||||||
float pitch;
|
|
||||||
Gait gait;
|
|
||||||
float angle = 0.0f;
|
|
||||||
float walk_time = 0.0f;
|
|
||||||
float moving_time = 0.0f;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PlayerRenderData {
|
struct PlayerRenderData {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string uuid;
|
std::string uuid;
|
||||||
@@ -55,7 +40,8 @@ public:
|
|||||||
~ClientWorld();
|
~ClientWorld();
|
||||||
void init(std::string_view player_name,
|
void init(std::string_view player_name,
|
||||||
std::shared_ptr<NetworkClient> client);
|
std::shared_ptr<NetworkClient> client);
|
||||||
void update(float delta_time);
|
void update(float dt);
|
||||||
|
void update_players(float dt);
|
||||||
bool handle_event(const Event& e);
|
bool handle_event(const Event& e);
|
||||||
const std::optional<LookBlock>& get_look_block_pos() const;
|
const std::optional<LookBlock>& get_look_block_pos() const;
|
||||||
ClientPlayer& get_player();
|
ClientPlayer& get_player();
|
||||||
@@ -123,6 +109,17 @@ public:
|
|||||||
std::forward_as_tuple(threshold, std::forward<Fn>(f)));
|
std::forward_as_tuple(threshold, std::forward<Fn>(f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Components>
|
||||||
|
entt::entity create_entity(Components&&... components) {
|
||||||
|
auto e = m_registry.create();
|
||||||
|
|
||||||
|
(m_registry.emplace<std::remove_cvref_t<Components>>(
|
||||||
|
e, std::forward<Components>(components)),
|
||||||
|
...);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct VoiceMessage {
|
struct VoiceMessage {
|
||||||
std::string data;
|
std::string data;
|
||||||
@@ -141,7 +138,6 @@ private:
|
|||||||
ChunkPos::TBBHash>;
|
ChunkPos::TBBHash>;
|
||||||
using ChunkPosSet = absl::flat_hash_set<ChunkPos, ChunkPos::Hash>;
|
using ChunkPosSet = absl::flat_hash_set<ChunkPos, ChunkPos::Hash>;
|
||||||
using ChunkPosVector = std::vector<ChunkPos>;
|
using ChunkPosVector = std::vector<ChunkPos>;
|
||||||
using OtherPlayerHashMap = std::unordered_map<std::string, PlayerInfo>;
|
|
||||||
using chunk_acc = ChunkHashMap::accessor;
|
using chunk_acc = ChunkHashMap::accessor;
|
||||||
using chunk_cacc = ChunkHashMap::const_accessor;
|
using chunk_cacc = ChunkHashMap::const_accessor;
|
||||||
|
|
||||||
@@ -156,7 +152,7 @@ private:
|
|||||||
entt::registry m_registry;
|
entt::registry m_registry;
|
||||||
|
|
||||||
ClientPlayer m_player;
|
ClientPlayer m_player;
|
||||||
OtherPlayerHashMap m_player_info;
|
std::unordered_map<std::string, entt::entity> m_player_entities;
|
||||||
ChunkHashMap m_chunks;
|
ChunkHashMap m_chunks;
|
||||||
AudioEngine& m_audio;
|
AudioEngine& m_audio;
|
||||||
Config& m_config;
|
Config& m_config;
|
||||||
@@ -164,7 +160,7 @@ private:
|
|||||||
std::vector<glm::vec4> m_planes;
|
std::vector<glm::vec4> m_planes;
|
||||||
std::jthread m_client_thread;
|
std::jthread m_client_thread;
|
||||||
|
|
||||||
mutable std::shared_mutex m_player_info_mutex;
|
mutable std::shared_mutex m_registry_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;
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Cubed/gameplay/player.hpp"
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
struct Transform {
|
struct Transform {
|
||||||
glm::vec3 pos;
|
glm::vec3 pos{0, 0, 0};
|
||||||
|
glm::vec3 render_pos{0, 0, 0};
|
||||||
|
Gait gait = Gait::STOP;
|
||||||
|
float walk_time = 0.0f;
|
||||||
|
float moving_time = 0.0f;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EntityInfo {
|
||||||
|
std::string name;
|
||||||
|
std::string uuid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Model {
|
struct Model {
|
||||||
@@ -15,4 +26,12 @@ struct Health {
|
|||||||
float max_hp = 20;
|
float max_hp = 20;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ViewAngles {
|
||||||
|
float render_yaw = 0.0f;
|
||||||
|
float yaw = 0.0f;
|
||||||
|
float render_pitch = 0.0f;
|
||||||
|
float pitch = 0.0f;
|
||||||
|
float angle = 0.0f;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -12,14 +12,11 @@ ClientPlayer::ClientPlayer(ClientWorld& world) : m_world(world) {}
|
|||||||
ClientPlayer::~ClientPlayer() {}
|
ClientPlayer::~ClientPlayer() {}
|
||||||
|
|
||||||
AABB ClientPlayer::get_aabb(const glm::vec3& pos) {
|
AABB ClientPlayer::get_aabb(const glm::vec3& pos) {
|
||||||
float half_width = M_SIZE.x / 2.0f;
|
glm::vec3 half = M_SIZE * 0.5f;
|
||||||
float half_depth = M_SIZE.z / 2.0f;
|
|
||||||
|
|
||||||
glm::vec3 min{pos.x - half_width, pos.y, pos.z - half_depth};
|
glm::vec3 center{pos.x, pos.y + half.y, pos.z};
|
||||||
|
|
||||||
glm::vec3 max{pos.x + half_width, pos.y + M_SIZE.y, pos.z + half_depth};
|
return AABB{center, half};
|
||||||
|
|
||||||
return AABB{min, max};
|
|
||||||
}
|
}
|
||||||
const glm::vec3& ClientPlayer::get_front() const { return m_front; }
|
const glm::vec3& ClientPlayer::get_front() const { return m_front; }
|
||||||
|
|
||||||
@@ -442,12 +439,15 @@ void ClientPlayer::update_x_move(glm::vec3& player_pos) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AABB player_box = get_aabb(player_pos);
|
AABB player_box = get_aabb(player_pos);
|
||||||
int minx = std::floor(player_box.min.x);
|
glm::vec3 min = player_box.min();
|
||||||
int maxx = std::floor(player_box.max.x);
|
glm::vec3 max = player_box.max();
|
||||||
int miny = std::floor(player_box.min.y);
|
|
||||||
int maxy = std::floor(player_box.max.y);
|
int minx = std::floor(min.x);
|
||||||
int minz = std::floor(player_box.min.z);
|
int maxx = std::floor(max.x);
|
||||||
int maxz = std::floor(player_box.max.z);
|
int miny = std::floor(min.y);
|
||||||
|
int maxy = std::floor(max.y);
|
||||||
|
int minz = std::floor(min.z);
|
||||||
|
int maxz = std::floor(max.z);
|
||||||
|
|
||||||
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) {
|
||||||
@@ -472,12 +472,15 @@ void ClientPlayer::update_y_move(glm::vec3& player_pos) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AABB player_box = get_aabb(player_pos);
|
AABB player_box = get_aabb(player_pos);
|
||||||
int minx = std::floor(player_box.min.x);
|
glm::vec3 min = player_box.min();
|
||||||
int maxx = std::floor(player_box.max.x);
|
glm::vec3 max = player_box.max();
|
||||||
int miny = std::floor(player_box.min.y);
|
|
||||||
int maxy = std::floor(player_box.max.y);
|
int minx = std::floor(min.x);
|
||||||
int minz = std::floor(player_box.min.z);
|
int maxx = std::floor(max.x);
|
||||||
int maxz = std::floor(player_box.max.z);
|
int miny = std::floor(min.y);
|
||||||
|
int maxy = std::floor(max.y);
|
||||||
|
int minz = std::floor(min.z);
|
||||||
|
int maxz = std::floor(max.z);
|
||||||
|
|
||||||
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) {
|
||||||
@@ -506,12 +509,15 @@ void ClientPlayer::update_z_move(glm::vec3& player_pos) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AABB player_box = get_aabb(player_pos);
|
AABB player_box = get_aabb(player_pos);
|
||||||
int minx = std::floor(player_box.min.x);
|
glm::vec3 min = player_box.min();
|
||||||
int maxx = std::floor(player_box.max.x);
|
glm::vec3 max = player_box.max();
|
||||||
int miny = std::floor(player_box.min.y);
|
|
||||||
int maxy = std::floor(player_box.max.y);
|
int minx = std::floor(min.x);
|
||||||
int minz = std::floor(player_box.min.z);
|
int maxx = std::floor(max.x);
|
||||||
int maxz = std::floor(player_box.max.z);
|
int miny = std::floor(min.y);
|
||||||
|
int maxy = std::floor(max.y);
|
||||||
|
int minz = std::floor(min.z);
|
||||||
|
int maxz = std::floor(max.z);
|
||||||
|
|
||||||
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) {
|
||||||
|
|||||||
@@ -296,10 +296,13 @@ void ClientWorld::report_block_change(const glm::ivec3& pos,
|
|||||||
unsigned id) const {
|
unsigned id) const {
|
||||||
if (id != 0) {
|
if (id != 0) {
|
||||||
AABB block_box = get_block_aabb(pos);
|
AABB block_box = get_block_aabb(pos);
|
||||||
std::shared_lock lock(m_player_info_mutex);
|
std::shared_lock lock(m_registry_mutex);
|
||||||
|
|
||||||
for (auto& [uuid, player] : m_player_info) {
|
for (auto& [key, player] : m_player_entities) {
|
||||||
AABB box = ClientPlayer::get_aabb(player.target_pos);
|
auto [transform, entity_info] =
|
||||||
|
m_registry.get<Transform, EntityInfo>(player);
|
||||||
|
|
||||||
|
AABB box = ClientPlayer::get_aabb(transform.pos);
|
||||||
if (box.intersects(block_box)) {
|
if (box.intersects(block_box)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -331,20 +334,22 @@ void ClientWorld::receive_remote_player(const PlayerInfoRsp& rsp) {
|
|||||||
auto pitch = rsp.pitch();
|
auto pitch = rsp.pitch();
|
||||||
auto yaw = rsp.yaw();
|
auto yaw = rsp.yaw();
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_player_info_mutex);
|
std::lock_guard lock(m_registry_mutex);
|
||||||
glm::vec3 pos{rsp.pos().x(), rsp.pos().y(), rsp.pos().z()};
|
glm::vec3 pos{rsp.pos().x(), rsp.pos().y(), rsp.pos().z()};
|
||||||
auto it = m_player_info.find(rsp.uuid());
|
auto it = m_player_entities.find(rsp.uuid());
|
||||||
if (it == m_player_info.end()) {
|
if (it == m_player_entities.end()) {
|
||||||
m_player_info.emplace(
|
auto entity =
|
||||||
std::piecewise_construct, std::forward_as_tuple(rsp.uuid()),
|
create_entity(EntityInfo{rsp.name(), rsp.uuid()},
|
||||||
std::forward_as_tuple(rsp.name(), rsp.uuid(), pos, pos, yaw,
|
Transform{pos, pos, get_gait_from_id(rsp.gait())},
|
||||||
yaw, pitch, pitch,
|
ViewAngles{yaw, yaw, pitch, pitch});
|
||||||
get_gait_from_id(rsp.gait())));
|
m_player_entities.try_emplace(rsp.uuid(), entity);
|
||||||
} else {
|
} else {
|
||||||
it->second.target_pos = pos;
|
auto& transform = m_registry.get<Transform>(it->second);
|
||||||
it->second.yaw = yaw;
|
transform.pos = pos;
|
||||||
it->second.pitch = pitch;
|
transform.gait = get_gait_from_id(rsp.gait());
|
||||||
it->second.gait = get_gait_from_id(rsp.gait());
|
auto& view_angles = m_registry.get<ViewAngles>(it->second);
|
||||||
|
view_angles.yaw = yaw;
|
||||||
|
view_angles.pitch = pitch;
|
||||||
}
|
}
|
||||||
// Logger::info("Player {} pos Update", rsp.name());
|
// Logger::info("Player {} pos Update", rsp.name());
|
||||||
}
|
}
|
||||||
@@ -360,11 +365,13 @@ void ClientWorld::receive_player_logout(const LogoutRsp& rsp) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_player_info_mutex);
|
std::lock_guard lock(m_registry_mutex);
|
||||||
int sum = m_player_info.erase(rsp.uuid());
|
auto it = m_player_entities.find(rsp.uuid());
|
||||||
if (sum == 0) {
|
if (it == m_player_entities.end()) {
|
||||||
Logger::warn("Player {} not find", rsp.uuid());
|
Logger::warn("Player {} not find", rsp.uuid());
|
||||||
} else {
|
} else {
|
||||||
|
m_registry.destroy(it->second);
|
||||||
|
m_player_entities.erase(rsp.uuid());
|
||||||
Logger::info("Player {} erase", rsp.uuid());
|
Logger::info("Player {} erase", rsp.uuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,9 +481,8 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
Logger::info("Send Login Request");
|
Logger::info("Send Login Request");
|
||||||
m_client->send(make_packet(req), 0);
|
m_client->send(make_packet(req), 0);
|
||||||
m_audio.play_bgm();
|
m_audio.play_bgm();
|
||||||
auto pig = m_registry.create();
|
create_entity(Transform{glm::vec3{0.0f, 100.0f, 0.0f}},
|
||||||
m_registry.emplace<Transform>(pig, glm::vec3{0.0f, 100.0f, 0.0f});
|
Model{"model/creature/pig.glb"});
|
||||||
m_registry.emplace<Model>(pig, "model/creature/pig.glb");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::receive_login_rsp(LoginRsp& rsp) {
|
void ClientWorld::receive_login_rsp(LoginRsp& rsp) {
|
||||||
@@ -726,15 +732,11 @@ 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) {
|
AABB ClientWorld::get_block_aabb(const glm::ivec3& pos) {
|
||||||
auto x = pos.x;
|
return {glm::vec3{static_cast<float>(pos.x) + 0.5f,
|
||||||
auto y = pos.y;
|
static_cast<float>(pos.y) + 0.5f,
|
||||||
auto z = pos.z;
|
static_cast<float>(pos.z) + 0.5f},
|
||||||
return {glm::vec3{static_cast<float>(x), static_cast<float>(y),
|
glm::vec3{0.5f, 0.5f, 0.5f}};
|
||||||
static_cast<float>(z)},
|
|
||||||
glm::vec3{static_cast<float>(x + 1), static_cast<float>(y + 1),
|
|
||||||
static_cast<float>(z + 1)}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioEngine& ClientWorld::get_audio() { return m_audio; }
|
AudioEngine& ClientWorld::get_audio() { return m_audio; }
|
||||||
const AudioEngine& ClientWorld::get_audio() const { return m_audio; }
|
const AudioEngine& ClientWorld::get_audio() const { return m_audio; }
|
||||||
Config& ClientWorld::get_config() { return m_config; }
|
Config& ClientWorld::get_config() { return m_config; }
|
||||||
@@ -857,91 +859,7 @@ void ClientWorld::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_render_player_data.clear();
|
m_render_player_data.clear();
|
||||||
{
|
update_players(delta_time);
|
||||||
std::lock_guard lock(m_player_info_mutex);
|
|
||||||
for (auto& [uuid, player] : m_player_info) {
|
|
||||||
player.render_pos =
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
player.render_yaw = glm::mix(player.render_yaw, player.yaw, 0.15);
|
|
||||||
player.render_pitch =
|
|
||||||
glm::mix(player.render_pitch, player.pitch, 0.15);
|
|
||||||
|
|
||||||
if (player.gait == Gait::WALK || player.gait == Gait::RUN) {
|
|
||||||
|
|
||||||
player.walk_time += delta_time;
|
|
||||||
|
|
||||||
float speed = player.gait == Gait::RUN ? 14.0f : 8.0f;
|
|
||||||
float amp = player.gait == Gait::RUN ? 50.0f : 35.0f;
|
|
||||||
// float amp = 90.0f;
|
|
||||||
player.angle =
|
|
||||||
glm::sin(player.walk_time * speed) * glm::radians(amp);
|
|
||||||
} else if (player.gait == Gait::STOP) {
|
|
||||||
float t = glm::clamp(delta_time * 10.0f, 0.0f, 1.0f);
|
|
||||||
player.angle = glm::mix(player.angle, 0.0f, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// walking sound
|
|
||||||
if (player.gait == Gait::STOP) {
|
|
||||||
player.moving_time = 0.0f;
|
|
||||||
} else {
|
|
||||||
player.moving_time += delta_time;
|
|
||||||
}
|
|
||||||
auto play_walk_sound = [&]() {
|
|
||||||
glm::ivec3 block = glm::floor(player.render_pos);
|
|
||||||
block.y -= 1;
|
|
||||||
BlockType id = get_block_tpye(block);
|
|
||||||
if (id == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string name = BlockManager::name_form_id(id);
|
|
||||||
std::string sound = "block/" + name + "/walk.ogg";
|
|
||||||
m_audio.play_3d(sound, player.render_pos);
|
|
||||||
};
|
|
||||||
if (player.gait == Gait::WALK) {
|
|
||||||
if (player.moving_time >= ClientPlayer::WALK_SOUND_INTERVAL) {
|
|
||||||
player.moving_time = 0.0f;
|
|
||||||
play_walk_sound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (player.gait == Gait::RUN) {
|
|
||||||
if (player.moving_time >= ClientPlayer::RUN_SOUND_INTERVAL) {
|
|
||||||
player.moving_time = 0.0f;
|
|
||||||
play_walk_sound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_render_player_data.emplace_back(
|
|
||||||
player.name, player.uuid, player.render_pos, player.render_yaw,
|
|
||||||
player.render_pitch, player.gait, player.angle);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto gait = m_player.get_gait();
|
|
||||||
auto& walk_time = m_player.walk_time();
|
|
||||||
auto& angle = m_player.angle();
|
|
||||||
if (gait == Gait::WALK || gait == Gait::RUN) {
|
|
||||||
|
|
||||||
walk_time += delta_time;
|
|
||||||
|
|
||||||
float speed = gait == Gait::RUN ? 14.0f : 8.0f;
|
|
||||||
float amp = gait == Gait::RUN ? 50.0f : 35.0f;
|
|
||||||
// float amp = 90.0f;
|
|
||||||
angle = glm::sin(walk_time * speed) * glm::radians(amp);
|
|
||||||
} else if (gait == Gait::STOP) {
|
|
||||||
float t = glm::clamp(delta_time * 10.0f, 0.0f, 1.0f);
|
|
||||||
angle = glm::mix(angle, 0.0f, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_render_player_data.emplace_back(
|
|
||||||
m_player.get_name(), m_player.get_uuid(),
|
|
||||||
m_player.get_player_pos(), m_player.yaw(), m_player.pitch(),
|
|
||||||
m_player.get_gait(), m_player.angle());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sound
|
// sound
|
||||||
PendingSound pending_sound;
|
PendingSound pending_sound;
|
||||||
@@ -963,6 +881,104 @@ void ClientWorld::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientWorld::update_players(float dt) {
|
||||||
|
|
||||||
|
auto update_renderinfo = [this, dt](entt::entity player) {
|
||||||
|
auto& transform = m_registry.get<Transform>(player);
|
||||||
|
transform.render_pos =
|
||||||
|
glm::mix(transform.render_pos, transform.pos, 0.15f);
|
||||||
|
if (Math::distance2(transform.render_pos, m_player.get_player_pos()) >
|
||||||
|
m_rendering_distance * CHUNK_SIZE * m_rendering_distance *
|
||||||
|
CHUNK_SIZE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& view_angles = m_registry.get<ViewAngles>(player);
|
||||||
|
view_angles.render_yaw =
|
||||||
|
glm::mix(view_angles.render_yaw, view_angles.yaw, 0.15);
|
||||||
|
view_angles.render_pitch =
|
||||||
|
glm::mix(view_angles.render_pitch, view_angles.pitch, 0.15);
|
||||||
|
|
||||||
|
if (transform.gait == Gait::WALK || transform.gait == Gait::RUN) {
|
||||||
|
|
||||||
|
transform.walk_time += dt;
|
||||||
|
|
||||||
|
float speed = transform.gait == Gait::RUN ? 14.0f : 8.0f;
|
||||||
|
float amp = transform.gait == Gait::RUN ? 50.0f : 35.0f;
|
||||||
|
// float amp = 90.0f;
|
||||||
|
view_angles.angle =
|
||||||
|
glm::sin(transform.walk_time * speed) * glm::radians(amp);
|
||||||
|
} else if (transform.gait == Gait::STOP) {
|
||||||
|
float t = glm::clamp(dt * 10.0f, 0.0f, 1.0f);
|
||||||
|
view_angles.angle = glm::mix(view_angles.angle, 0.0f, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// walking sound
|
||||||
|
if (transform.gait == Gait::STOP) {
|
||||||
|
transform.moving_time = 0.0f;
|
||||||
|
} else {
|
||||||
|
transform.moving_time += dt;
|
||||||
|
}
|
||||||
|
auto play_walk_sound = [&]() {
|
||||||
|
glm::ivec3 block = glm::floor(transform.render_pos);
|
||||||
|
block.y -= 1;
|
||||||
|
BlockType id = get_block_tpye(block);
|
||||||
|
if (id == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string name = BlockManager::name_form_id(id);
|
||||||
|
std::string sound = "block/" + name + "/walk.ogg";
|
||||||
|
m_audio.play_3d(sound, transform.render_pos);
|
||||||
|
};
|
||||||
|
if (transform.gait == Gait::WALK) {
|
||||||
|
if (transform.moving_time >= ClientPlayer::WALK_SOUND_INTERVAL) {
|
||||||
|
transform.moving_time = 0.0f;
|
||||||
|
play_walk_sound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (transform.gait == Gait::RUN) {
|
||||||
|
if (transform.moving_time >= ClientPlayer::RUN_SOUND_INTERVAL) {
|
||||||
|
transform.moving_time = 0.0f;
|
||||||
|
play_walk_sound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto& player_info = m_registry.get<EntityInfo>(player);
|
||||||
|
m_render_player_data.emplace_back(
|
||||||
|
player_info.name, player_info.uuid, transform.render_pos,
|
||||||
|
view_angles.render_yaw, view_angles.render_pitch, transform.gait,
|
||||||
|
view_angles.angle);
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard lock(m_registry_mutex);
|
||||||
|
|
||||||
|
for (auto& [_, player] : m_player_entities) {
|
||||||
|
update_renderinfo(player);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto gait = m_player.get_gait();
|
||||||
|
auto& walk_time = m_player.walk_time();
|
||||||
|
auto& angle = m_player.angle();
|
||||||
|
if (gait == Gait::WALK || gait == Gait::RUN) {
|
||||||
|
|
||||||
|
walk_time += dt;
|
||||||
|
|
||||||
|
float speed = gait == Gait::RUN ? 14.0f : 8.0f;
|
||||||
|
float amp = gait == Gait::RUN ? 50.0f : 35.0f;
|
||||||
|
// float amp = 90.0f;
|
||||||
|
angle = glm::sin(walk_time * speed) * glm::radians(amp);
|
||||||
|
} else if (gait == Gait::STOP) {
|
||||||
|
float t = glm::clamp(dt * 10.0f, 0.0f, 1.0f);
|
||||||
|
angle = glm::mix(angle, 0.0f, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_render_player_data.emplace_back(
|
||||||
|
m_player.get_name(), m_player.get_uuid(),
|
||||||
|
m_player.get_player_pos(), m_player.yaw(), m_player.pitch(),
|
||||||
|
m_player.get_gait(), m_player.angle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ClientWorld::handle_event(const Event& e) {
|
bool ClientWorld::handle_event(const Event& e) {
|
||||||
return std::visit(
|
return std::visit(
|
||||||
Overloaded{[this](const MouseButtonEvent& e) {
|
Overloaded{[this](const MouseButtonEvent& e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user