fekalnigtacko/src/gameview/entityview.cpp
2026-02-20 21:29:46 +01:00

137 lines
3.5 KiB
C++

#include "entityview.hpp"
#include <iostream>
#include "worldview.hpp"
#include "assets/cache.hpp"
game::view::EntityView::EntityView(WorldView& world, net::InMessage& msg) :
world_(world),
audioplayer_(world_.GetAudioMaster()),
nametag_text_(assets::CacheManager::GetFont("data/comic32.font"), 0xFFFFFFFF)
{
// read nametag and attachment info
if (!ReadNametag(msg) || !ReadAttach(msg))
throw EntityInitError();
}
bool game::view::EntityView::ProcessMsg(net::EntMsgType type, net::InMessage& msg)
{
switch (type)
{
case net::EMSG_NAMETAG:
return ReadNametag(msg);
case net::EMSG_ATTACH:
return ReadAttach(msg);
default:
return false;
}
}
bool game::view::EntityView::TryUpdate(const UpdateInfo& info)
{
float time = world_.GetTime();
if (time == upd_time_)
return false;
Update(info);
return true;
}
void game::view::EntityView::Update(const UpdateInfo& info)
{
upd_time_ = world_.GetTime();
// ensure parent is updated
parent_ = nullptr;
if (parentnum_)
{
parent_ = world_.GetEntity(parentnum_);
if (parent_)
parent_->TryUpdate(info);
}
// update transform parent
root_.parent = parent_ ? &parent_->GetRoot() : nullptr;
audioplayer_.Update();
}
void game::view::EntityView::Draw(const DrawArgs& args)
{
// std::cout << "TODO draw entity nametag: " << nametag_ << std::endl;
DrawNametag(args);
//DrawAxes(args);
}
bool game::view::EntityView::ReadNametag(net::InMessage& msg)
{
// read nametag
net::NameTag nametag;
if (!msg.Read(nametag))
return false;
nametag_ = nametag;
nametag_text_.SetText(nametag);
return true;
}
bool game::view::EntityView::ReadAttach(net::InMessage& msg)
{
return msg.Read(parentnum_);
}
void game::view::EntityView::DrawNametag(const DrawArgs& args)
{
if (nametag_.empty())
return;
// calc screen position
glm::vec4 world_pos = glm::vec4(root_.local.position + glm::vec3(0.0f, 0.0f, 2.0f), 1.0f);
glm::vec4 clip_pos = args.view_proj * world_pos;
if (clip_pos.w == 0.0f)
return;
glm::vec3 ndc_pos = glm::vec3(clip_pos) / clip_pos.w;
if (ndc_pos.z < -1.0f || ndc_pos.z > 1.0f)
return; // behind camera
nametag_pos_.anchor.x = ndc_pos.x * 0.5f + 0.5f;
nametag_pos_.anchor.y = 1.0f - (ndc_pos.y * 0.5f + 0.5f); // flip y
// center
float scale = 0.7f;
nametag_pos_.scale = glm::vec2(scale, -scale);
nametag_pos_.pos = nametag_text_.GetSize() * glm::vec2(-0.5f, -1.0f) * scale;
// static const glm::vec4 nametag_color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
gfx::DrawHudCmd hudcmd;
hudcmd.va = &nametag_text_.GetVA();
hudcmd.texture = nametag_text_.GetFont()->GetTexture().get();
hudcmd.pos = &nametag_pos_;
// hudcmd.color = &nametag_color;
args.dlist.AddHUD(hudcmd);
// std::cout << "at position: " << root_.local.position.x << ", " << root_.local.position.y << ", " << root_.local.position.z << std::endl;
}
void game::view::EntityView::DrawAxes(const DrawArgs& args)
{
const float len = 5.0f;
static const uint32_t colors[] = {0xFF0000FF, 0xFF00FF00, 0xFFFF0000};
for (size_t i = 0; i < 3; i++)
{
glm::vec3 end(0.0f);
end[i] = len;
glm::vec3 beam_start = glm::vec3(root_.matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
glm::vec3 beam_end = glm::vec3(root_.matrix * glm::vec4(end, 1.0f));
args.dlist.AddBeam(beam_start, beam_end, colors[i], 0.05f);
}
}