Add z distance checking to entity picking. Fixes issue 521
parent
6c2b967790
commit
142252ddf8
10
src/draw.cpp
10
src/draw.cpp
|
@ -342,6 +342,8 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToSelect() {
|
|||
Group *activeGroup = SK.GetGroup(SS.GW.activeGroup);
|
||||
int bestOrder = -1;
|
||||
int bestZIndex = 0;
|
||||
double bestDepth = VERY_POSITIVE;
|
||||
|
||||
for(const Hover &hov : hoverList) {
|
||||
hGroup hg = {};
|
||||
if(hov.selection.entity.v != 0) {
|
||||
|
@ -353,8 +355,11 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToSelect() {
|
|||
Group *g = SK.GetGroup(hg);
|
||||
if(g->order > activeGroup->order) continue;
|
||||
if(bestOrder != -1 && (bestOrder > g->order || bestZIndex > hov.zIndex)) continue;
|
||||
// we have hov.zIndex is >= best and hov.group is >= best (but not > active group)
|
||||
if(hov.depth > bestDepth && bestOrder == g->order && bestZIndex == hov.zIndex) continue;
|
||||
bestOrder = g->order;
|
||||
bestZIndex = hov.zIndex;
|
||||
bestDepth = hov.depth;
|
||||
sel = hov.selection;
|
||||
}
|
||||
return sel;
|
||||
|
@ -370,6 +375,8 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToDrag() {
|
|||
Group *activeGroup = SK.GetGroup(SS.GW.activeGroup);
|
||||
int bestOrder = -1;
|
||||
int bestZIndex = 0;
|
||||
double bestDepth = VERY_POSITIVE;
|
||||
|
||||
for(const Hover &hov : hoverList) {
|
||||
hGroup hg = {};
|
||||
if(hov.selection.entity.v != 0) {
|
||||
|
@ -383,6 +390,8 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToDrag() {
|
|||
Group *g = SK.GetGroup(hg);
|
||||
if(g->order > activeGroup->order) continue;
|
||||
if(bestOrder != -1 && (bestOrder > g->order || bestZIndex > hov.zIndex)) continue;
|
||||
// we have hov.zIndex is >= best and hov.group is >= best (but not > active group)
|
||||
if(hov.depth > bestDepth && bestOrder == g->order && bestZIndex == hov.zIndex) continue;
|
||||
bestOrder = g->order;
|
||||
bestZIndex = hov.zIndex;
|
||||
sel = hov.selection;
|
||||
|
@ -439,6 +448,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
|
|||
Hover hov = {};
|
||||
hov.distance = canvas.minDistance;
|
||||
hov.zIndex = canvas.maxZIndex;
|
||||
hov.depth = canvas.minDepth;
|
||||
hov.selection.entity = e.h;
|
||||
hoverList.Add(&hov);
|
||||
}
|
||||
|
|
|
@ -343,9 +343,10 @@ void UiCanvas::DrawBitmapText(const std::string &str, int x, int y, RgbaColor co
|
|||
// A canvas that performs picking against drawn geometry.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ObjectPicker::DoCompare(double distance, int zIndex, int comparePosition) {
|
||||
void ObjectPicker::DoCompare(double depth, double distance, int zIndex, int comparePosition) {
|
||||
if(distance > selRadius) return;
|
||||
if((zIndex == maxZIndex && distance < minDistance) || (zIndex > maxZIndex)) {
|
||||
minDepth = depth;
|
||||
minDistance = distance;
|
||||
maxZIndex = zIndex;
|
||||
position = comparePosition;
|
||||
|
@ -372,10 +373,10 @@ void ObjectPicker::DoQuad(const Vector &a, const Vector &b, const Vector &c, con
|
|||
|
||||
bool insideQuad = (minNegative == VERY_NEGATIVE || maxPositive == VERY_POSITIVE);
|
||||
if(insideQuad) {
|
||||
DoCompare(0.0, zIndex, comparePosition);
|
||||
DoCompare(0, 0.0, zIndex, comparePosition);
|
||||
} else {
|
||||
double distance = std::min(fabs(minNegative), fabs(maxPositive));
|
||||
DoCompare(distance, zIndex, comparePosition);
|
||||
DoCompare(0, distance, zIndex, comparePosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,7 +385,8 @@ void ObjectPicker::DrawLine(const Vector &a, const Vector &b, hStroke hcs) {
|
|||
Point2d ap = camera.ProjectPoint(a);
|
||||
Point2d bp = camera.ProjectPoint(b);
|
||||
double distance = point.DistanceToLine(ap, bp.Minus(ap), /*asSegment=*/true);
|
||||
DoCompare(distance - stroke->width / 2.0, stroke->zIndex);
|
||||
double depth = 0.5 * (camera.ProjectPoint3(a).z + camera.ProjectPoint3(b).z) ;
|
||||
DoCompare(depth, distance - stroke->width / 2.0, stroke->zIndex);
|
||||
}
|
||||
|
||||
void ObjectPicker::DrawEdges(const SEdgeList &el, hStroke hcs) {
|
||||
|
@ -393,7 +395,8 @@ void ObjectPicker::DrawEdges(const SEdgeList &el, hStroke hcs) {
|
|||
Point2d ap = camera.ProjectPoint(e.a);
|
||||
Point2d bp = camera.ProjectPoint(e.b);
|
||||
double distance = point.DistanceToLine(ap, bp.Minus(ap), /*asSegment=*/true);
|
||||
DoCompare(distance - stroke->width / 2.0, stroke->zIndex, e.auxB);
|
||||
double depth = 0.5 * (camera.ProjectPoint3(e.a).z + camera.ProjectPoint3(e.b).z) ;
|
||||
DoCompare(depth, distance - stroke->width / 2.0, stroke->zIndex, e.auxB);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,7 +426,8 @@ void ObjectPicker::DrawQuad(const Vector &a, const Vector &b, const Vector &c, c
|
|||
void ObjectPicker::DrawPoint(const Vector &o, Canvas::hStroke hcs) {
|
||||
Stroke *stroke = strokes.FindById(hcs);
|
||||
double distance = point.DistanceTo(camera.ProjectPoint(o)) - stroke->width / 2;
|
||||
DoCompare(distance, stroke->zIndex);
|
||||
double depth = camera.ProjectPoint3(o).z;
|
||||
DoCompare(depth, distance, stroke->zIndex);
|
||||
}
|
||||
|
||||
void ObjectPicker::DrawPolygon(const SPolygon &p, hFill hcf) {
|
||||
|
@ -445,6 +449,7 @@ void ObjectPicker::DrawPixmap(std::shared_ptr<const Pixmap> pm,
|
|||
}
|
||||
|
||||
bool ObjectPicker::Pick(const std::function<void()> &drawFn) {
|
||||
minDepth = VERY_POSITIVE;
|
||||
minDistance = VERY_POSITIVE;
|
||||
maxZIndex = INT_MIN;
|
||||
|
||||
|
|
|
@ -232,6 +232,7 @@ public:
|
|||
double selRadius = 0.0;
|
||||
// Picking state.
|
||||
double minDistance = 0.0;
|
||||
double minDepth = 1e10;
|
||||
int maxZIndex = 0;
|
||||
uint32_t position = 0;
|
||||
|
||||
|
@ -257,7 +258,7 @@ public:
|
|||
const Point2d &ta, const Point2d &tb, hFill hcf) override;
|
||||
void InvalidatePixmap(std::shared_ptr<const Pixmap> pm) override {}
|
||||
|
||||
void DoCompare(double distance, int zIndex, int comparePosition = 0);
|
||||
void DoCompare(double depth, double distance, int zIndex, int comparePosition = 0);
|
||||
void DoQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d,
|
||||
int zIndex, int comparePosition = 0);
|
||||
|
||||
|
|
Loading…
Reference in New Issue