From 65e50633261b22ce866f62f6c585a21aadfb832f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 23 Nov 2024 07:41:44 +0300 Subject: [PATCH] add player names display --- src/frontend/screens/LevelScreen.cpp | 2 +- src/graphics/render/Decorator.cpp | 55 ++++++++++++++++++++-- src/graphics/render/Decorator.hpp | 11 +++-- src/graphics/render/TextsRenderer.cpp | 4 ++ src/logic/PlayerController.cpp | 2 +- src/logic/scripting/lua/libs/libblock.cpp | 4 +- src/logic/scripting/lua/libs/libplayer.cpp | 2 +- src/objects/Players.cpp | 2 +- src/objects/Players.hpp | 10 +++- src/window/Events.cpp | 4 +- 10 files changed, 80 insertions(+), 16 deletions(-) diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index 1acd9200..b77268ff 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -50,7 +50,7 @@ LevelScreen::LevelScreen(Engine* engine, std::unique_ptr levelPtr) hud = std::make_unique(engine, *frontend, controller->getPlayer()); decorator = std::make_unique( - *controller, *worldRenderer->particles, assets + *controller, *worldRenderer, assets ); keepAlive(settings.graphics.backlight.observe([=](bool) { diff --git a/src/graphics/render/Decorator.cpp b/src/graphics/render/Decorator.cpp index 4bac77af..2cc10d73 100644 --- a/src/graphics/render/Decorator.cpp +++ b/src/graphics/render/Decorator.cpp @@ -1,13 +1,19 @@ #include "Decorator.hpp" #include "ParticlesRenderer.hpp" +#include "WorldRenderer.hpp" +#include "TextsRenderer.hpp" +#include "TextNote.hpp" #include "assets/assets_util.hpp" #include "content/Content.hpp" #include "voxels/Chunks.hpp" #include "voxels/Block.hpp" #include "world/Level.hpp" #include "window/Camera.hpp" +#include "objects/Players.hpp" #include "logic/LevelController.hpp" +#include "util/stringutil.hpp" +#include "presets/NotePreset.hpp" /// @brief Not greather than 64 for this BIG_PRIME value inline constexpr int UPDATE_AREA_DIAMETER = 32; @@ -19,16 +25,37 @@ inline constexpr int ITERATIONS = 512; /// @brief Big prime number used for pseudo-random 3d array iteration inline constexpr int BIG_PRIME = 666667; +static u64id_t create_player_name_note( + const WorldRenderer& renderer, const Player& player +) { + NotePreset preset {}; + preset.displayMode = NoteDisplayMode::PROJECTED; + preset.xrayOpacity = 0.3f; + preset.renderDistance = 128.0f; + return renderer.texts->add(std::make_unique( + util::str2wstr_utf8(player.getName()), preset, player.getPosition() + )); +} + Decorator::Decorator( - LevelController& controller, ParticlesRenderer& particles, const Assets& assets + LevelController& controller, WorldRenderer& renderer, const Assets& assets ) - : level(*controller.getLevel()), particles(particles), assets(assets) { + : level(*controller.getLevel()), + renderer(renderer), + assets(assets), + player(*controller.getPlayer()) { controller.getBlocksController()->listenBlockInteraction( [this](auto player, const auto& pos, const auto& def, BlockInteraction type) { if (type == BlockInteraction::placing && def.particles) { addParticles(def, pos); } }); + for (const auto& [id, player] : *level.players) { + if (id == controller.getPlayer()->getId()) { + continue; + } + playerTexts[id] = create_player_name_note(renderer, *player); + } } void Decorator::addParticles(const Block& def, const glm::ivec3& pos) { @@ -37,7 +64,7 @@ void Decorator::addParticles(const Block& def, const glm::ivec3& pos) { auto treg = util::get_texture_region( assets, def.particles->texture, "" ); - blockEmitters[pos] = particles.add(std::make_unique( + blockEmitters[pos] = renderer.particles->add(std::make_unique( level, glm::vec3{pos.x + 0.5, pos.y + 0.5, pos.z + 0.5}, *def.particles, @@ -81,7 +108,7 @@ void Decorator::update(float delta, const Camera& camera) { const auto& indices = *level.content->getIndices(); auto iter = blockEmitters.begin(); while (iter != blockEmitters.end()) { - auto emitter = particles.getEmitter(iter->second); + auto emitter = renderer.particles->getEmitter(iter->second); if (emitter == nullptr) { iter = blockEmitters.erase(iter); continue; @@ -108,4 +135,24 @@ void Decorator::update(float delta, const Camera& camera) { } iter++; } + + for (const auto& [id, player] : *level.players) { + if (id == this->player.getId() || + playerTexts.find(id) != playerTexts.end()) { + continue; + } + playerTexts[id] = create_player_name_note(renderer, *player); + } + + auto textsIter = playerTexts.begin(); + while (textsIter != playerTexts.end()) { + auto note = renderer.texts->get(textsIter->second); + auto player = level.players->get(textsIter->first); + if (player == nullptr) { + textsIter = playerTexts.erase(textsIter); + } else { + note->setPosition(player->getPosition() + glm::vec3(0, 1, 0)); + ++textsIter; + } + } } diff --git a/src/graphics/render/Decorator.hpp b/src/graphics/render/Decorator.hpp index 32f9540a..bb4202f7 100644 --- a/src/graphics/render/Decorator.hpp +++ b/src/graphics/render/Decorator.hpp @@ -6,19 +6,24 @@ #include +#include "typedefs.hpp" + class Level; class Chunks; class Camera; class Assets; +class Player; struct Block; class LevelController; -class ParticlesRenderer; +class WorldRenderer; class Decorator { const Level& level; const Assets& assets; - ParticlesRenderer& particles; + Player& player; + WorldRenderer& renderer; std::unordered_map blockEmitters; + std::unordered_map playerTexts; int currentIndex = 0; void update( @@ -27,7 +32,7 @@ class Decorator { void addParticles(const Block& def, const glm::ivec3& pos); public: Decorator( - LevelController& level, ParticlesRenderer& particles, const Assets& assets + LevelController& level, WorldRenderer& renderer, const Assets& assets ); void update(float delta, const Camera& camera); diff --git a/src/graphics/render/TextsRenderer.cpp b/src/graphics/render/TextsRenderer.cpp index 92b628f8..676ca349 100644 --- a/src/graphics/render/TextsRenderer.cpp +++ b/src/graphics/render/TextsRenderer.cpp @@ -61,6 +61,10 @@ void TextsRenderer::renderNote( if (preset.displayMode == NoteDisplayMode::XY_FREE_BILLBOARD) { yvec = camera.up; } + float scale = + (1.0f - preset.perspective) * glm::pow(glm::distance(camera.position, pos), 1.0f-preset.perspective); + xvec *= 1.0f + scale; + yvec *= 1.0f + scale; } if (preset.displayMode != NoteDisplayMode::PROJECTED) { if (!frustum.isBoxVisible(pos - xvec * (width * 0.5f), diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 69cc8422..0b23942e 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -194,7 +194,7 @@ PlayerController::PlayerController( BlocksController* blocksController ) : settings(settings), level(level), - player(level->players->getPlayer(0)), + player(level->players->get(0)), camControl(player, settings.camera), blocksController(blocksController), playerTickClock(20, 3) { diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index d2451940..2f24e0fe 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -351,7 +351,7 @@ static int l_place(lua::State* L) { "there is no block with index " + std::to_string(id) ); } - auto player = level->players->getPlayer(playerid); + auto player = level->players->get(playerid); controller->getBlocksController()->placeBlock( player, *def, int2blockstate(state), x, y, z ); @@ -368,7 +368,7 @@ static int l_destruct(lua::State* L) { return 0; } auto& def = level->content->getIndices()->blocks.require(voxel->id); - auto player = level->players->getPlayer(playerid); + auto player = level->players->get(playerid); controller->getBlocksController()->breakBlock(player, def, x, y, z); return 0; } diff --git a/src/logic/scripting/lua/libs/libplayer.cpp b/src/logic/scripting/lua/libs/libplayer.cpp index ff2d6217..0628c5af 100644 --- a/src/logic/scripting/lua/libs/libplayer.cpp +++ b/src/logic/scripting/lua/libs/libplayer.cpp @@ -13,7 +13,7 @@ using namespace scripting; inline Player* get_player(lua::State* L, int idx) { - return level->players->getPlayer(lua::tointeger(L, idx)); + return level->players->get(lua::tointeger(L, idx)); } static int l_get_pos(lua::State* L) { diff --git a/src/objects/Players.cpp b/src/objects/Players.cpp index 70f0a769..90031991 100644 --- a/src/objects/Players.cpp +++ b/src/objects/Players.cpp @@ -11,7 +11,7 @@ void Players::addPlayer(std::unique_ptr player) { players[player->getId()] = std::move(player); } -Player* Players::getPlayer(int64_t id) const { +Player* Players::get(int64_t id) const { const auto& found = players.find(id); if (found == players.end()) { return nullptr; diff --git a/src/objects/Players.hpp b/src/objects/Players.hpp index e32f4755..f66d181f 100644 --- a/src/objects/Players.hpp +++ b/src/objects/Players.hpp @@ -21,11 +21,19 @@ class Players : public Serializable { public: Players(Level* level); - Player* getPlayer(int64_t id) const; + Player* get(int64_t id) const; Player* create(); dv::value serialize() const override; void deserialize(const dv::value& src) override; + + auto begin() const { + return players.begin(); + } + + auto end() const { + return players.end(); + } }; diff --git a/src/window/Events.cpp b/src/window/Events.cpp index 17b54204..f63431cf 100644 --- a/src/window/Events.cpp +++ b/src/window/Events.cpp @@ -62,9 +62,9 @@ bool Events::jclicked(int button) { void Events::toggleCursor() { cursor_drag = false; _cursor_locked = !_cursor_locked; - /*Window::setCursorMode( + Window::setCursorMode( _cursor_locked ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL - );*/ + ); } void Events::pollEvents() {