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 {
|
struct UpdateInfo {
|
||||||
EntityID id;
|
EntityID id;
|
||||||
glm::vec3 pos;
|
glm::vec3 pos;
|
||||||
|
glm::vec3 direction;
|
||||||
};
|
};
|
||||||
|
|
||||||
using EntityMap = tbb::concurrent_hash_map<EntityID, entt::entity>;
|
using EntityMap = tbb::concurrent_hash_map<EntityID, entt::entity>;
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ struct BaseServerCreature {
|
|||||||
|
|
||||||
Movement movement{};
|
Movement movement{};
|
||||||
|
|
||||||
Direction direction{};
|
|
||||||
|
|
||||||
Gravity gravity{};
|
Gravity gravity{};
|
||||||
|
|
||||||
Health health{};
|
Health health{};
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ class Camera;
|
|||||||
class ModelRender {
|
class ModelRender {
|
||||||
public:
|
public:
|
||||||
ModelRender(Renderer& renderer);
|
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:
|
private:
|
||||||
Renderer& m_renderer;
|
Renderer& m_renderer;
|
||||||
|
|||||||
@@ -5,16 +5,19 @@
|
|||||||
#include "glm/ext/vector_float3.hpp"
|
#include "glm/ext/vector_float3.hpp"
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
namespace Tools {
|
namespace Tools {
|
||||||
template <Ptr T> void set_net_pos(T ptr, const glm::vec3& pos) {
|
inline void set_net_vec3(Vec3* p, const glm::vec3& pos) {
|
||||||
Vec3* p = ptr->mutable_pos();
|
|
||||||
p->set_x(pos.x);
|
p->set_x(pos.x);
|
||||||
p->set_y(pos.y);
|
p->set_y(pos.y);
|
||||||
p->set_z(pos.z);
|
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()};
|
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()};
|
return glm::vec3{p.x(), p.y(), p.z()};
|
||||||
}
|
}
|
||||||
} // namespace Tools
|
} // namespace Tools
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ void ClientEntityManager::handle_entity_update(UpdateInfo& info) {
|
|||||||
auto creature = m_registry.try_get<BaseClientCreature>(e);
|
auto creature = m_registry.try_get<BaseClientCreature>(e);
|
||||||
ASSERT(creature);
|
ASSERT(creature);
|
||||||
creature->transform.position.value = info.pos;
|
creature->transform.position.value = info.pos;
|
||||||
|
creature->transform.direction.value = info.direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientEntityManager::receive_entity_create(S2CEntityCreate& s2c) {
|
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) {
|
void ClientEntityManager::receive_entity_update(S2CEntityUpdate& msg) {
|
||||||
UpdateInfo e;
|
UpdateInfo e;
|
||||||
e.id = msg.id();
|
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));
|
m_tasks.emplace(Command::UPDATE, std::move(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ void ServerEntityManager::update_send() {
|
|||||||
p->set_id(entity.id);
|
p->set_id(entity.id);
|
||||||
Tools::set_net_pos(p, creature.transform.position.value);
|
Tools::set_net_pos(p, creature.transform.position.value);
|
||||||
|
|
||||||
|
Tools::set_net_vec3(p->mutable_direction(),
|
||||||
|
creature.transform.direction.value);
|
||||||
|
|
||||||
for (auto& s : sessions) {
|
for (auto& s : sessions) {
|
||||||
s->send(make_packet(p));
|
s->send(make_packet(p));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -875,7 +875,7 @@ void ServerWorld::handle_block_change(const BlockChangeReq& req) {
|
|||||||
|
|
||||||
void ServerWorld::handle_entity_create(C2SEntityCreateRequest& 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) {
|
void ServerWorld::handle_entity_destory(C2SEntityDestoryRequest& req) {
|
||||||
m_entity_manager.destory(req.id());
|
m_entity_manager.destory(req.id());
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ void SpeedSystem::update(float dt, entt::registry& registry) {
|
|||||||
auto& v = creature.velocity.value;
|
auto& v = creature.velocity.value;
|
||||||
if (moveboost.count <= moveboost.duration) {
|
if (moveboost.count <= moveboost.duration) {
|
||||||
++moveboost.count;
|
++moveboost.count;
|
||||||
v += creature.direction.value * creature.movement.acceleration;
|
v += creature.transform.direction.value *
|
||||||
|
creature.movement.acceleration;
|
||||||
} else {
|
} else {
|
||||||
// Decelerated by friction in all directions
|
// Decelerated by friction in all directions
|
||||||
auto decay = [](float& c, float d) {
|
auto decay = [](float& c, float d) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ void WanderAISystem::do_ai(BaseServerCreature& creature,
|
|||||||
MoveBoost& move_boost) {
|
MoveBoost& move_boost) {
|
||||||
thread_local Random r{std::random_device()()};
|
thread_local Random r{std::random_device()()};
|
||||||
if (r.random_bool(DIRECTION_PROBABILITY)) {
|
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)) {
|
if (r.random_bool(MOVE_PROBABILITY)) {
|
||||||
|
|
||||||
|
|||||||
@@ -26,4 +26,5 @@ message C2SEntityCreateRequest {
|
|||||||
message S2CEntityUpdate {
|
message S2CEntityUpdate {
|
||||||
uint64 id = 1;
|
uint64 id = 1;
|
||||||
Vec3 pos = 2;
|
Vec3 pos = 2;
|
||||||
|
Vec3 direction = 3;
|
||||||
}
|
}
|
||||||
@@ -6,20 +6,23 @@
|
|||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
ModelRender::ModelRender(Renderer& renderer) : m_renderer(renderer) {}
|
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) {
|
Camera& camera) {
|
||||||
auto& root = ModelManager::model(id).node;
|
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");
|
auto& shader = m_renderer.get_shader("model_shader");
|
||||||
glm::mat4 view = camera.get_camera_lookat();
|
glm::mat4 view = camera.get_camera_lookat();
|
||||||
shader.set_loc("proj_matrix", m_renderer.p_mat());
|
shader.set_loc("proj_matrix", m_renderer.p_mat());
|
||||||
render_node(root, transform, view, shader, false);
|
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) {
|
Camera& camera) {
|
||||||
auto& root = ModelManager::model(id).node;
|
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");
|
auto& shader = m_renderer.get_shader("depth_model");
|
||||||
glm::mat4 view = camera.get_camera_lookat();
|
glm::mat4 view = camera.get_camera_lookat();
|
||||||
|
|
||||||
|
|||||||
@@ -300,8 +300,11 @@ void WorldRenderer::shadow_entity(ClientWorld& world,
|
|||||||
auto view = registry.view<BaseClientCreature>();
|
auto view = registry.view<BaseClientCreature>();
|
||||||
for (auto entity : view) {
|
for (auto entity : view) {
|
||||||
auto& creature = view.get<BaseClientCreature>(entity);
|
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(
|
m_renderer.model_renderer().shadow_pass(
|
||||||
creature.model, creature.transform.position.value,
|
creature.model, creature.transform.position.value, yaw,
|
||||||
world.world_scene().camera());
|
world.world_scene().camera());
|
||||||
}
|
}
|
||||||
m_player_renderer.render(shader, world, true);
|
m_player_renderer.render(shader, world, true);
|
||||||
@@ -721,8 +724,10 @@ void WorldRenderer::render_entity(ClientWorld& world) {
|
|||||||
auto view = registry.view<BaseClientCreature>();
|
auto view = registry.view<BaseClientCreature>();
|
||||||
for (auto entity : view) {
|
for (auto entity : view) {
|
||||||
auto& creature = view.get<BaseClientCreature>(entity);
|
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(
|
m_renderer.model_renderer().render_model(
|
||||||
creature.model, creature.transform.position.value,
|
creature.model, creature.transform.position.value, yaw,
|
||||||
world.world_scene().camera());
|
world.world_scene().camera());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user