mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 19:10:06 +00:00
Placefile icon mouse picking
This commit is contained in:
parent
0b2a118c42
commit
0421435e97
2 changed files with 99 additions and 0 deletions
|
|
@ -1,8 +1,11 @@
|
||||||
#include <scwx/qt/gl/draw/placefile_icons.hpp>
|
#include <scwx/qt/gl/draw/placefile_icons.hpp>
|
||||||
|
#include <scwx/qt/util/imgui.hpp>
|
||||||
#include <scwx/qt/util/maplibre.hpp>
|
#include <scwx/qt/util/maplibre.hpp>
|
||||||
#include <scwx/qt/util/texture_atlas.hpp>
|
#include <scwx/qt/util/texture_atlas.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
|
#include <execution>
|
||||||
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <boost/unordered/unordered_flat_map.hpp>
|
#include <boost/unordered/unordered_flat_map.hpp>
|
||||||
|
|
||||||
|
|
@ -54,6 +57,17 @@ struct PlacefileIconInfo
|
||||||
class PlacefileIcons::Impl
|
class PlacefileIcons::Impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct IconHoverEntry
|
||||||
|
{
|
||||||
|
std::shared_ptr<const gr::Placefile::IconDrawItem> di_;
|
||||||
|
|
||||||
|
glm::vec2 p_;
|
||||||
|
glm::vec2 otl_;
|
||||||
|
glm::vec2 otr_;
|
||||||
|
glm::vec2 obl_;
|
||||||
|
glm::vec2 obr_;
|
||||||
|
};
|
||||||
|
|
||||||
explicit Impl(const std::shared_ptr<GlContext>& context) :
|
explicit Impl(const std::shared_ptr<GlContext>& context) :
|
||||||
context_ {context},
|
context_ {context},
|
||||||
shaderProgram_ {nullptr},
|
shaderProgram_ {nullptr},
|
||||||
|
|
@ -88,6 +102,8 @@ public:
|
||||||
std::vector<std::shared_ptr<const gr::Placefile::IconDrawItem>>
|
std::vector<std::shared_ptr<const gr::Placefile::IconDrawItem>>
|
||||||
newIconList_ {};
|
newIconList_ {};
|
||||||
|
|
||||||
|
std::vector<IconHoverEntry> hoverIcons_ {};
|
||||||
|
|
||||||
std::vector<float> iconBuffer_ {};
|
std::vector<float> iconBuffer_ {};
|
||||||
std::vector<GLint> thresholdBuffer_ {};
|
std::vector<GLint> thresholdBuffer_ {};
|
||||||
|
|
||||||
|
|
@ -250,6 +266,7 @@ void PlacefileIcons::Deinitialize()
|
||||||
|
|
||||||
p->currentIconList_.clear();
|
p->currentIconList_.clear();
|
||||||
p->currentIconFiles_.clear();
|
p->currentIconFiles_.clear();
|
||||||
|
p->hoverIcons_.clear();
|
||||||
p->iconBuffer_.clear();
|
p->iconBuffer_.clear();
|
||||||
p->thresholdBuffer_.clear();
|
p->thresholdBuffer_.clear();
|
||||||
}
|
}
|
||||||
|
|
@ -337,6 +354,7 @@ void PlacefileIcons::Impl::UpdateBuffers()
|
||||||
iconBuffer_.reserve(currentIconList_.size() * kBufferLength);
|
iconBuffer_.reserve(currentIconList_.size() * kBufferLength);
|
||||||
thresholdBuffer_.clear();
|
thresholdBuffer_.clear();
|
||||||
thresholdBuffer_.reserve(currentIconList_.size() * kVerticesPerRectangle);
|
thresholdBuffer_.reserve(currentIconList_.size() * kVerticesPerRectangle);
|
||||||
|
hoverIcons_.clear();
|
||||||
numVertices_ = 0;
|
numVertices_ = 0;
|
||||||
|
|
||||||
for (auto& di : currentIconList_)
|
for (auto& di : currentIconList_)
|
||||||
|
|
@ -425,6 +443,25 @@ void PlacefileIcons::Impl::UpdateBuffers()
|
||||||
thresholdValue,
|
thresholdValue,
|
||||||
thresholdValue,
|
thresholdValue,
|
||||||
thresholdValue});
|
thresholdValue});
|
||||||
|
|
||||||
|
if (!di->hoverText_.empty())
|
||||||
|
{
|
||||||
|
const units::angle::radians<double> radians = angle;
|
||||||
|
|
||||||
|
const auto sc = util::maplibre::LatLongToScreenCoordinate({lat, lon});
|
||||||
|
|
||||||
|
const float cosAngle = cosf(static_cast<float>(radians.value()));
|
||||||
|
const float sinAngle = sinf(static_cast<float>(radians.value()));
|
||||||
|
|
||||||
|
const glm::mat2 rotate {cosAngle, -sinAngle, sinAngle, cosAngle};
|
||||||
|
|
||||||
|
const glm::vec2 otl = rotate * glm::vec2 {lx, ty};
|
||||||
|
const glm::vec2 otr = rotate * glm::vec2 {rx, ty};
|
||||||
|
const glm::vec2 obl = rotate * glm::vec2 {lx, by};
|
||||||
|
const glm::vec2 obr = rotate * glm::vec2 {rx, by};
|
||||||
|
|
||||||
|
hoverIcons_.emplace_back(IconHoverEntry {di, sc, otl, otr, obl, obr});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dirty_ = true;
|
dirty_ = true;
|
||||||
|
|
@ -467,6 +504,65 @@ void PlacefileIcons::Impl::Update(bool textureAtlasChanged)
|
||||||
dirty_ = false;
|
dirty_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PlacefileIcons::RunMousePicking(
|
||||||
|
const QMapLibreGL::CustomLayerRenderParameters& params,
|
||||||
|
const glm::vec2& mousePos)
|
||||||
|
{
|
||||||
|
std::unique_lock lock {p->iconMutex_};
|
||||||
|
|
||||||
|
bool itemPicked = false;
|
||||||
|
|
||||||
|
// Calculate map scale, remove width and height from original calculation
|
||||||
|
glm::vec2 scale = util::maplibre::GetMapScale(params);
|
||||||
|
scale = 2.0f / glm::vec2 {scale.x * params.width, scale.y * params.height};
|
||||||
|
|
||||||
|
// Scale and rotate the identity matrix to create the map matrix
|
||||||
|
glm::mat4 mapMatrix {1.0f};
|
||||||
|
mapMatrix = glm::scale(mapMatrix, glm::vec3 {scale, 1.0f});
|
||||||
|
mapMatrix = glm::rotate(mapMatrix,
|
||||||
|
glm::radians<float>(params.bearing),
|
||||||
|
glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
// For each pickable icon
|
||||||
|
auto it = std::find_if(
|
||||||
|
std::execution::par_unseq,
|
||||||
|
p->hoverIcons_.crbegin(),
|
||||||
|
p->hoverIcons_.crend(),
|
||||||
|
[&mapMatrix, &mousePos](const auto& icon)
|
||||||
|
{
|
||||||
|
// Initialize vertices
|
||||||
|
glm::vec2 bl = icon.p_;
|
||||||
|
glm::vec2 br = bl;
|
||||||
|
glm::vec2 tl = br;
|
||||||
|
glm::vec2 tr = tl;
|
||||||
|
|
||||||
|
// Calculate offsets
|
||||||
|
// - Rotated offset is based on final X/Y offsets (pixels)
|
||||||
|
// - Multiply the offset by the scaled and rotated map matrix
|
||||||
|
const glm::vec2 otl = mapMatrix * glm::vec4 {icon.otl_, 0.0f, 1.0f};
|
||||||
|
const glm::vec2 obl = mapMatrix * glm::vec4 {icon.obl_, 0.0f, 1.0f};
|
||||||
|
const glm::vec2 obr = mapMatrix * glm::vec4 {icon.obr_, 0.0f, 1.0f};
|
||||||
|
const glm::vec2 otr = mapMatrix * glm::vec4 {icon.otr_, 0.0f, 1.0f};
|
||||||
|
|
||||||
|
// Offset vertices
|
||||||
|
tl += otl;
|
||||||
|
bl += obl;
|
||||||
|
br += obr;
|
||||||
|
tr += otr;
|
||||||
|
|
||||||
|
// Test point against polygon bounds
|
||||||
|
return util::maplibre::IsPointInPolygon({tl, bl, br, tr}, mousePos);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (it != p->hoverIcons_.crend())
|
||||||
|
{
|
||||||
|
itemPicked = true;
|
||||||
|
util::ImGui::Instance().DrawTooltip(it->di_->hoverText_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemPicked;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace draw
|
} // namespace draw
|
||||||
} // namespace gl
|
} // namespace gl
|
||||||
} // namespace qt
|
} // namespace qt
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ public:
|
||||||
bool textureAtlasChanged) override;
|
bool textureAtlasChanged) override;
|
||||||
void Deinitialize() override;
|
void Deinitialize() override;
|
||||||
|
|
||||||
|
bool RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params,
|
||||||
|
const glm::vec2& mousePos) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets and prepares the draw item for adding a new set of icons.
|
* Resets and prepares the draw item for adding a new set of icons.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue