mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat: sync entity direction and rotate models accordingly
Move direction into the transform component and include it in server-to-client entity updates. Client now sets transform direction from the network message and uses it to compute yaw for model rotation, so entities visually face their movement direction. Refactor net_utils to support arbitrary Vec3 fields.
This commit is contained in:
@@ -35,6 +35,7 @@ private:
|
||||
struct UpdateInfo {
|
||||
EntityID id;
|
||||
glm::vec3 pos;
|
||||
glm::vec3 direction;
|
||||
};
|
||||
|
||||
using EntityMap = tbb::concurrent_hash_map<EntityID, entt::entity>;
|
||||
|
||||
@@ -12,8 +12,6 @@ struct BaseServerCreature {
|
||||
|
||||
Movement movement{};
|
||||
|
||||
Direction direction{};
|
||||
|
||||
Gravity gravity{};
|
||||
|
||||
Health health{};
|
||||
|
||||
@@ -11,9 +11,11 @@ class Camera;
|
||||
class ModelRender {
|
||||
public:
|
||||
ModelRender(Renderer& renderer);
|
||||
void render_model(ModelID id, const glm::vec3& pos, Camera& camera);
|
||||
void render_model(ModelID id, const glm::vec3& pos, float yaw,
|
||||
Camera& camera);
|
||||
|
||||
void shadow_pass(ModelID id, const glm::vec3& pos, Camera& camera);
|
||||
void shadow_pass(ModelID id, const glm::vec3& pos, float yaw,
|
||||
Camera& camera);
|
||||
|
||||
private:
|
||||
Renderer& m_renderer;
|
||||
|
||||
@@ -5,16 +5,19 @@
|
||||
#include "glm/ext/vector_float3.hpp"
|
||||
namespace Cubed {
|
||||
namespace Tools {
|
||||
template <Ptr T> void set_net_pos(T ptr, const glm::vec3& pos) {
|
||||
Vec3* p = ptr->mutable_pos();
|
||||
inline void set_net_vec3(Vec3* p, const glm::vec3& pos) {
|
||||
p->set_x(pos.x);
|
||||
p->set_y(pos.y);
|
||||
p->set_z(pos.z);
|
||||
}
|
||||
inline glm::vec3 get_net_pos(const Vec3* p) {
|
||||
template <Ptr T> void set_net_pos(T ptr, const glm::vec3& pos) {
|
||||
set_net_vec3(ptr->mutable_pos(), pos);
|
||||
}
|
||||
|
||||
inline glm::vec3 get_net_vec3(const Vec3* p) {
|
||||
return glm::vec3{p->x(), p->y(), p->z()};
|
||||
}
|
||||
inline glm::vec3 get_net_pos(const Vec3& p) {
|
||||
inline glm::vec3 get_net_vec3(const Vec3& p) {
|
||||
return glm::vec3{p.x(), p.y(), p.z()};
|
||||
}
|
||||
} // namespace Tools
|
||||
|
||||
@@ -49,6 +49,7 @@ void ClientEntityManager::handle_entity_update(UpdateInfo& info) {
|
||||
auto creature = m_registry.try_get<BaseClientCreature>(e);
|
||||
ASSERT(creature);
|
||||
creature->transform.position.value = info.pos;
|
||||
creature->transform.direction.value = info.direction;
|
||||
}
|
||||
|
||||
void ClientEntityManager::receive_entity_create(S2CEntityCreate& s2c) {
|
||||
@@ -66,7 +67,8 @@ void ClientEntityManager::receive_entity_destory(EntityID id) {
|
||||
void ClientEntityManager::receive_entity_update(S2CEntityUpdate& msg) {
|
||||
UpdateInfo e;
|
||||
e.id = msg.id();
|
||||
e.pos = Tools::get_net_pos(msg.pos());
|
||||
e.pos = Tools::get_net_vec3(msg.pos());
|
||||
e.direction = Tools::get_net_vec3(msg.direction());
|
||||
m_tasks.emplace(Command::UPDATE, std::move(e));
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@ void ServerEntityManager::update_send() {
|
||||
p->set_id(entity.id);
|
||||
Tools::set_net_pos(p, creature.transform.position.value);
|
||||
|
||||
Tools::set_net_vec3(p->mutable_direction(),
|
||||
creature.transform.direction.value);
|
||||
|
||||
for (auto& s : sessions) {
|
||||
s->send(make_packet(p));
|
||||
}
|
||||
|
||||
@@ -875,7 +875,7 @@ void ServerWorld::handle_block_change(const BlockChangeReq& req) {
|
||||
|
||||
void ServerWorld::handle_entity_create(C2SEntityCreateRequest& req) {
|
||||
|
||||
m_entity_manager.add_entity(req.name(), Tools::get_net_pos(req.pos()));
|
||||
m_entity_manager.add_entity(req.name(), Tools::get_net_vec3(req.pos()));
|
||||
}
|
||||
void ServerWorld::handle_entity_destory(C2SEntityDestoryRequest& req) {
|
||||
m_entity_manager.destory(req.id());
|
||||
|
||||
@@ -13,7 +13,8 @@ void SpeedSystem::update(float dt, entt::registry& registry) {
|
||||
auto& v = creature.velocity.value;
|
||||
if (moveboost.count <= moveboost.duration) {
|
||||
++moveboost.count;
|
||||
v += creature.direction.value * creature.movement.acceleration;
|
||||
v += creature.transform.direction.value *
|
||||
creature.movement.acceleration;
|
||||
} else {
|
||||
// Decelerated by friction in all directions
|
||||
auto decay = [](float& c, float d) {
|
||||
|
||||
@@ -29,7 +29,7 @@ void WanderAISystem::do_ai(BaseServerCreature& creature,
|
||||
MoveBoost& move_boost) {
|
||||
thread_local Random r{std::random_device()()};
|
||||
if (r.random_bool(DIRECTION_PROBABILITY)) {
|
||||
creature.direction.value = r.random_direction_horizontal();
|
||||
creature.transform.direction.value = r.random_direction_horizontal();
|
||||
}
|
||||
if (r.random_bool(MOVE_PROBABILITY)) {
|
||||
|
||||
|
||||
@@ -26,4 +26,5 @@ message C2SEntityCreateRequest {
|
||||
message S2CEntityUpdate {
|
||||
uint64 id = 1;
|
||||
Vec3 pos = 2;
|
||||
Vec3 direction = 3;
|
||||
}
|
||||
@@ -6,20 +6,23 @@
|
||||
namespace Cubed {
|
||||
ModelRender::ModelRender(Renderer& renderer) : m_renderer(renderer) {}
|
||||
|
||||
void ModelRender::render_model(ModelID id, const glm::vec3& pos,
|
||||
void ModelRender::render_model(ModelID id, const glm::vec3& pos, float yaw,
|
||||
Camera& camera) {
|
||||
auto& root = ModelManager::model(id).node;
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos);
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos) *
|
||||
glm::rotate(glm::mat4(1.0f), yaw, {0, 1, 0});
|
||||
auto& shader = m_renderer.get_shader("model_shader");
|
||||
glm::mat4 view = camera.get_camera_lookat();
|
||||
shader.set_loc("proj_matrix", m_renderer.p_mat());
|
||||
render_node(root, transform, view, shader, false);
|
||||
}
|
||||
|
||||
void ModelRender::shadow_pass(ModelID id, const glm::vec3& pos,
|
||||
void ModelRender::shadow_pass(ModelID id, const glm::vec3& pos, float yaw,
|
||||
Camera& camera) {
|
||||
auto& root = ModelManager::model(id).node;
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos);
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos) *
|
||||
glm::rotate(glm::mat4(1.0f), yaw, {0, 1, 0});
|
||||
|
||||
auto& shader = m_renderer.get_shader("depth_model");
|
||||
glm::mat4 view = camera.get_camera_lookat();
|
||||
|
||||
|
||||
@@ -300,8 +300,11 @@ void WorldRenderer::shadow_entity(ClientWorld& world,
|
||||
auto view = registry.view<BaseClientCreature>();
|
||||
for (auto entity : view) {
|
||||
auto& creature = view.get<BaseClientCreature>(entity);
|
||||
float yaw = std::atan2(creature.transform.direction.value.x,
|
||||
creature.transform.direction.value.z);
|
||||
|
||||
m_renderer.model_renderer().shadow_pass(
|
||||
creature.model, creature.transform.position.value,
|
||||
creature.model, creature.transform.position.value, yaw,
|
||||
world.world_scene().camera());
|
||||
}
|
||||
m_player_renderer.render(shader, world, true);
|
||||
@@ -721,8 +724,10 @@ void WorldRenderer::render_entity(ClientWorld& world) {
|
||||
auto view = registry.view<BaseClientCreature>();
|
||||
for (auto entity : view) {
|
||||
auto& creature = view.get<BaseClientCreature>(entity);
|
||||
float yaw = std::atan2(creature.transform.direction.value.x,
|
||||
creature.transform.direction.value.z);
|
||||
m_renderer.model_renderer().render_model(
|
||||
creature.model, creature.transform.position.value,
|
||||
creature.model, creature.transform.position.value, yaw,
|
||||
world.world_scene().camera());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user