AIDEBUG: extracted code into own class
parent
fcde5df93a
commit
9ca8fc1bd3
|
@ -577,22 +577,6 @@ void AIDebug::dbgTree() {
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
bool AIDebug::dbgMapIsVisible(const ImVec2& pos, const ImVec2& mapMins, const ImVec2& mapMaxs) const {
|
||||
return pos.x > mapMins.x && pos.y > mapMins.y && pos.x < mapMaxs.x && pos.y < mapMaxs.y;
|
||||
}
|
||||
|
||||
float AIDebug::dbgMapZoom() const {
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
ImVec2 AIDebug::dbgMapCalculateOffsetPos(float x, float y) const {
|
||||
return ImVec2(-x * dbgMapZoom() + _frameBufferDimension.x / 2.0f, -y * dbgMapZoom() + _frameBufferDimension.y / 2.0f);
|
||||
}
|
||||
|
||||
ImVec2 AIDebug::dbgMapConvertEntPos(float x, float y) const {
|
||||
return ImVec2(dbgMapZoom() * (_dbgMapOffset.x + x), dbgMapZoom() * (_dbgMapOffset.y + y));
|
||||
}
|
||||
|
||||
void AIDebug::dbgMap() {
|
||||
if (_stateWorldMsg == nullptr || _stateWorldMsg->states() == nullptr) {
|
||||
return;
|
||||
|
@ -601,7 +585,7 @@ void AIDebug::dbgMap() {
|
|||
for (const auto &e : *_stateWorldMsg->states()) {
|
||||
const bool selected = isSelected(e->character_id());
|
||||
if (selected) {
|
||||
_dbgMapOffset = dbgMapCalculateOffsetPos(e->position()->x(), e->position()->z());
|
||||
_map.centerAtEntPos(e->position()->x(), e->position()->z());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -621,15 +605,15 @@ void AIDebug::dbgMap() {
|
|||
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f));
|
||||
const ImVec2 mapMins(0.0f, 0.0f);
|
||||
const ImVec2 mapMaxs(_frameBufferDimension.x, _frameBufferDimension.y);
|
||||
_map.setMinsMaxs(mapMins, mapMaxs);
|
||||
if (ImGui::Begin("##map", nullptr, ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoSavedSettings)) {
|
||||
dbgBar();
|
||||
|
||||
if (ImGui::IsMouseDragging(ImGuiMouseButton_Right, 0)) {
|
||||
_dbgMapOffset.x += _mouseRelativePos.x;
|
||||
_dbgMapOffset.y += _mouseRelativePos.y;
|
||||
_map.scroll(_mouseRelativePos);
|
||||
}
|
||||
|
||||
const float radius = 10.0f * dbgMapZoom();
|
||||
const float radius = 10.0f * _map.zoom();
|
||||
const ImVec2 entSize(radius * 2.0f);
|
||||
ImDrawList *draw = ImGui::GetWindowDrawList();
|
||||
const ImVec2& clipRectMins = ImGui::GetCursorPos();
|
||||
|
@ -638,8 +622,8 @@ void AIDebug::dbgMap() {
|
|||
clipRectMaxs.y += clipRectMins.y;
|
||||
draw->PushClipRect(clipRectMins, clipRectMaxs, true);
|
||||
for (const auto &e : *_stateWorldMsg->states()) {
|
||||
const ImVec2& entPos = dbgMapConvertEntPos(e->position()->x(), e->position()->z());
|
||||
if (!dbgMapIsVisible(entPos, mapMins, mapMaxs)) {
|
||||
const ImVec2& entPos = _map.entPosToMap(e->position()->x(), e->position()->z());
|
||||
if (!_map.isVisible(entPos, mapMins, mapMaxs)) {
|
||||
continue;
|
||||
}
|
||||
const float orientation = e->orientation();
|
||||
|
@ -684,18 +668,18 @@ void AIDebug::dbgMap() {
|
|||
draw->AddCircle(entPos, radius, col, 12, 1.0f);
|
||||
draw->AddLine(entPos, {entPos.x + dir.x * radius * 2.0f, entPos.y + dir.y * radius * 2.0f}, col, 1.0f);
|
||||
if (selected) {
|
||||
const ImVec2& homePos = dbgMapConvertEntPos(e->home_position()->x(), e->home_position()->z());
|
||||
const ImVec2& targetPos = dbgMapConvertEntPos(e->target_position()->x(), e->target_position()->z());
|
||||
const ImVec2& homePos = _map.entPosToMap(e->home_position()->x(), e->home_position()->z());
|
||||
const ImVec2& targetPos = _map.entPosToMap(e->target_position()->x(), e->target_position()->z());
|
||||
draw->AddLine(entPos, homePos, homecol, 1.0f);
|
||||
draw->AddLine(entPos, targetPos, targetcol, 1.0f);
|
||||
}
|
||||
|
||||
const float viewRadius = (float)attribCurrent[core::enumVal(attrib::Type::VIEWDISTANCE)] * dbgMapZoom();
|
||||
const float viewRadius = (float)attribCurrent[core::enumVal(attrib::Type::VIEWDISTANCE)] * _map.zoom();
|
||||
if (viewRadius > radius) {
|
||||
draw->AddCircle(entPos, (float)viewRadius, viewRadiusColor, 18, 1.0f);
|
||||
}
|
||||
|
||||
const float attackRadius = (float)attribCurrent[core::enumVal(attrib::Type::ATTACKRANGE)] * dbgMapZoom();
|
||||
const float attackRadius = (float)attribCurrent[core::enumVal(attrib::Type::ATTACKRANGE)] * _map.zoom();
|
||||
if (attackRadius > 0.0) {
|
||||
draw->AddCircle(entPos, (float)attackRadius, attackRadiusColor, 12, 1.0f);
|
||||
}
|
||||
|
@ -720,9 +704,12 @@ void AIDebug::dbgMap() {
|
|||
draw->PopClipRect();
|
||||
}
|
||||
if (ImGui::IsWindowHovered()) {
|
||||
_zoom = core_max(0.01f, dbgMapZoom() + ImGui::GetIO().MouseWheel * 0.1f);
|
||||
// TODO: don't center on selection - but on the relative position in the map view
|
||||
//_centerOnSelection = true;
|
||||
const float deltaZoom = ImGui::GetIO().MouseWheel * 0.1f;
|
||||
if (glm::abs(deltaZoom) > glm::epsilon<float>()) {
|
||||
const ImVec2 mousePos = ImGui::GetMousePos();
|
||||
const ImVec2 mouseMapPos(mousePos.x - mapMins.x, mousePos.y - mapMins.y);
|
||||
_map.zoomAtMapPos(mouseMapPos.x, mouseMapPos.y, deltaZoom);
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
@ -809,11 +796,10 @@ void AIDebug::onEvent(const network::DisconnectEvent &event) {
|
|||
_chrStaticMsg = nullptr;
|
||||
_stateWorldMsg = nullptr;
|
||||
_namesMsg = nullptr;
|
||||
_dbgMapOffset = { 0.0f, 0.0f };
|
||||
_map.reset();
|
||||
_pause = false;
|
||||
_centerOnSelection = false;
|
||||
_zoneId = "";
|
||||
_zoom = 1.0f;
|
||||
_entityListFilter[0] = '\0';
|
||||
_stateWorldSize = 0u;
|
||||
_characterDetailsSize = 0u;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "network/MessageSender.h"
|
||||
#include "network/NetworkEvents.h"
|
||||
#include "ui/imgui/IMGUIApp.h"
|
||||
#include "Map.h"
|
||||
|
||||
/**
|
||||
* @ingroup Tools
|
||||
|
@ -25,7 +26,6 @@ private:
|
|||
using Super = ui::imgui::IMGUIApp;
|
||||
char _aiServer[1024] = "127.0.0.1";
|
||||
int _port = _defaultPort;
|
||||
ImVec2 _dbgMapOffset { 0.0f, 0.0f };
|
||||
|
||||
int _dbgTreeIdAdd = -1;
|
||||
int _dbgTreeIdEdit = -1;
|
||||
|
@ -36,10 +36,10 @@ private:
|
|||
Max
|
||||
};
|
||||
|
||||
Map _map;
|
||||
State _state = State::Connect;
|
||||
bool _pause = false;
|
||||
bool _centerOnSelection = false;
|
||||
float _zoom = 1.0f;
|
||||
char _entityListFilter[64] = "";
|
||||
size_t _stateWorldSize = 0u;
|
||||
size_t _characterDetailsSize = 0u;
|
||||
|
@ -95,10 +95,6 @@ private:
|
|||
|
||||
bool dbgConnect();
|
||||
void dbgBar();
|
||||
float dbgMapZoom() const;
|
||||
ImVec2 dbgMapConvertEntPos(float x, float y) const;
|
||||
ImVec2 dbgMapCalculateOffsetPos(float x, float y) const;
|
||||
bool dbgMapIsVisible(const ImVec2& pos, const ImVec2& mapMins, const ImVec2& mapMaxs) const;
|
||||
void dbgMap();
|
||||
void dbgStats();
|
||||
void dbgEntities();
|
||||
|
|
|
@ -4,7 +4,22 @@ set(SRCS
|
|||
network/MessageSender.h network/MessageSender.cpp
|
||||
|
||||
AIDebug.h AIDebug.cpp
|
||||
Map.h Map.cpp
|
||||
)
|
||||
|
||||
engine_add_executable(TARGET ${PROJECT_NAME} SRCS ${SRCS} WINDOWED)
|
||||
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES imgui ai-shared network attrib)
|
||||
|
||||
set(TEST_SRCS
|
||||
tests/MapTest.cpp
|
||||
Map.h Map.cpp
|
||||
)
|
||||
|
||||
gtest_suite_sources(tests
|
||||
${TEST_SRCS}
|
||||
)
|
||||
|
||||
gtest_suite_begin(tests-${PROJECT_NAME} TEMPLATE ${ROOT_DIR}/src/modules/core/tests/main.cpp.in)
|
||||
gtest_suite_sources(tests-${PROJECT_NAME} ${TEST_SRCS})
|
||||
gtest_suite_deps(tests-${PROJECT_NAME} test-app)
|
||||
gtest_suite_end(tests-${PROJECT_NAME})
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
#include "Map.h"
|
||||
#include "core/Common.h"
|
||||
|
||||
void Map::setMinsMaxs(const glm::ivec2& mins, const glm::ivec2& maxs) {
|
||||
_mins = mins;
|
||||
_maxs = maxs;
|
||||
}
|
||||
|
||||
void Map::reset() {
|
||||
_dbgMapOffset = { 0.0f, 0.0f };
|
||||
_zoom = 1.0f;
|
||||
}
|
||||
|
||||
void Map::centerAtEntPos(float x, float y) {
|
||||
_dbgMapOffset = calculateOffsetPos(x, y, (_maxs - _mins) / 2);
|
||||
}
|
||||
|
||||
void Map::zoomAtMapPos(float x, float y, float deltaZoom) {
|
||||
const glm::ivec2 entPos = mapToEntPos(x, y);
|
||||
_zoom = core_max(0.01f, zoom() + deltaZoom);
|
||||
_dbgMapOffset = calculateOffsetPos(entPos.x, entPos.y, glm::ivec2(x, y));
|
||||
}
|
||||
|
||||
void Map::scroll(const glm::ivec2& amount) {
|
||||
_dbgMapOffset += amount;
|
||||
}
|
||||
|
||||
float Map::zoom() const {
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
glm::ivec2 Map::calculateOffsetPos(float x, float y, const glm::ivec2& center) const {
|
||||
return glm::ivec2(-x * zoom() + (float)center.x, -y * zoom() + (float)center.y);
|
||||
}
|
||||
|
||||
glm::ivec2 Map::entPosToMap(float x, float y) const {
|
||||
return glm::ivec2(zoom() * (_dbgMapOffset.x + x), zoom() * (_dbgMapOffset.y + y));
|
||||
}
|
||||
|
||||
glm::ivec2 Map::mapToEntPos(float x, float y) const {
|
||||
return glm::ivec2((x - _dbgMapOffset.x) / zoom(), (y - _dbgMapOffset.y) / zoom());
|
||||
}
|
||||
|
||||
bool Map::isVisible(const glm::ivec2& pos, const glm::ivec2& mapMins, const glm::ivec2& mapMaxs) const {
|
||||
return pos.x > mapMins.x && pos.y > mapMins.y && pos.x < mapMaxs.x && pos.y < mapMaxs.y;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
class Map {
|
||||
private:
|
||||
float _zoom = 1.0f;
|
||||
glm::vec2 _dbgMapOffset { 0.0f, 0.0f };
|
||||
glm::ivec2 _mins {0};
|
||||
glm::ivec2 _maxs {0};
|
||||
glm::ivec2 calculateOffsetPos(float x, float y, const glm::ivec2& center) const;
|
||||
|
||||
public:
|
||||
void scroll(const glm::ivec2& amount);
|
||||
void setMinsMaxs(const glm::ivec2& mins, const glm::ivec2& maxs);
|
||||
void reset();
|
||||
void centerAtEntPos(float x, float y);
|
||||
void zoomAtMapPos(float x, float y, float deltaZoom);
|
||||
float zoom() const;
|
||||
glm::ivec2 entPosToMap(float x, float y) const;
|
||||
glm::ivec2 mapToEntPos(float x, float y) const;
|
||||
bool isVisible(const glm::ivec2& pos, const glm::ivec2& mapMins, const glm::ivec2& mapMaxs) const;
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
#include "app/tests/AbstractTest.h"
|
||||
#include "../Map.h"
|
||||
|
||||
class MapTest: public app::AbstractTest {
|
||||
private:
|
||||
using Super = app::AbstractTest;
|
||||
public:
|
||||
Map _map;
|
||||
|
||||
void SetUp() override {
|
||||
Super::SetUp();
|
||||
_map = Map();
|
||||
_map.setMinsMaxs(glm::ivec2(0), glm::ivec2(200, 100));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(MapTest, testConvertCoordinatesNoScroll) {
|
||||
EXPECT_EQ(glm::ivec2(0), _map.entPosToMap(0.0f, 0.0f));
|
||||
EXPECT_EQ(glm::ivec2(500), _map.entPosToMap(500.0f, 500.0f));
|
||||
}
|
||||
|
||||
TEST_F(MapTest, testConvertCoordinatesNoScrollNeeded) {
|
||||
_map.centerAtEntPos(100.0f, 50.0f);
|
||||
EXPECT_EQ(glm::ivec2(0), _map.entPosToMap(0.0f, 0.0f));
|
||||
}
|
||||
|
||||
TEST_F(MapTest, testConvertCoordinatesScrolled) {
|
||||
_map.centerAtEntPos(200.0f, 100.0f);
|
||||
EXPECT_EQ(glm::ivec2(-100, -50), _map.entPosToMap(0.0f, 0.0f));
|
||||
}
|
Loading…
Reference in New Issue