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/util/imgui.hpp>
|
||||
#include <scwx/qt/util/maplibre.hpp>
|
||||
#include <scwx/qt/util/texture_atlas.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <execution>
|
||||
|
||||
#include <QUrl>
|
||||
#include <boost/unordered/unordered_flat_map.hpp>
|
||||
|
||||
|
|
@ -54,6 +57,17 @@ struct PlacefileIconInfo
|
|||
class PlacefileIcons::Impl
|
||||
{
|
||||
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) :
|
||||
context_ {context},
|
||||
shaderProgram_ {nullptr},
|
||||
|
|
@ -88,6 +102,8 @@ public:
|
|||
std::vector<std::shared_ptr<const gr::Placefile::IconDrawItem>>
|
||||
newIconList_ {};
|
||||
|
||||
std::vector<IconHoverEntry> hoverIcons_ {};
|
||||
|
||||
std::vector<float> iconBuffer_ {};
|
||||
std::vector<GLint> thresholdBuffer_ {};
|
||||
|
||||
|
|
@ -250,6 +266,7 @@ void PlacefileIcons::Deinitialize()
|
|||
|
||||
p->currentIconList_.clear();
|
||||
p->currentIconFiles_.clear();
|
||||
p->hoverIcons_.clear();
|
||||
p->iconBuffer_.clear();
|
||||
p->thresholdBuffer_.clear();
|
||||
}
|
||||
|
|
@ -337,6 +354,7 @@ void PlacefileIcons::Impl::UpdateBuffers()
|
|||
iconBuffer_.reserve(currentIconList_.size() * kBufferLength);
|
||||
thresholdBuffer_.clear();
|
||||
thresholdBuffer_.reserve(currentIconList_.size() * kVerticesPerRectangle);
|
||||
hoverIcons_.clear();
|
||||
numVertices_ = 0;
|
||||
|
||||
for (auto& di : currentIconList_)
|
||||
|
|
@ -425,6 +443,25 @@ void PlacefileIcons::Impl::UpdateBuffers()
|
|||
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;
|
||||
|
|
@ -467,6 +504,65 @@ void PlacefileIcons::Impl::Update(bool textureAtlasChanged)
|
|||
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 gl
|
||||
} // namespace qt
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ public:
|
|||
bool textureAtlasChanged) 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.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue