diff --git a/WickedEngine/wiMath.cpp b/WickedEngine/wiMath.cpp index a5123cdbd..d1ab3920f 100644 --- a/WickedEngine/wiMath.cpp +++ b/WickedEngine/wiMath.cpp @@ -162,4 +162,17 @@ namespace wiMath XMVECTOR Closest = A + AB_ * t; return Closest; } + float GetPointSegmentDistance(const XMVECTOR& point, const XMVECTOR& segmentA, const XMVECTOR& segmentB) + { + // Return minimum distance between line segment vw and point p + const float l2 = XMVectorGetX(XMVector3LengthSq(segmentB - segmentA)); // i.e. |w-v|^2 - avoid a sqrt + if (l2 == 0.0) return Distance(point, segmentA); // v == w case + // Consider the line extending the segment, parameterized as v + t (w - v). + // We find projection of point p onto the line. + // It falls where t = [(p-v) . (w-v)] / |w-v|^2 + // We clamp t from [0,1] to handle points outside the segment vw. + const float t = max(0, min(1, XMVectorGetX(XMVector3Dot(point - segmentA, segmentB-segmentA)) / l2)); + const XMVECTOR projection = segmentA + t * (segmentB - segmentA); // Projection falls on the segment + return Distance(point, projection); + } } diff --git a/WickedEngine/wiMath.h b/WickedEngine/wiMath.h index 1dcf85dcb..4565608ef 100644 --- a/WickedEngine/wiMath.h +++ b/WickedEngine/wiMath.h @@ -30,5 +30,6 @@ namespace wiMath XMFLOAT3 QuaternionToRollPitchYaw(const XMFLOAT4& quaternion); XMVECTOR GetClosestPointToLine(const XMVECTOR& A, const XMVECTOR& B, const XMVECTOR& P, bool segmentClamp = false); + float GetPointSegmentDistance(const XMVECTOR& point, const XMVECTOR& segmentA, const XMVECTOR& segmentB); }; diff --git a/WickedEngine/wiTranslator.cpp b/WickedEngine/wiTranslator.cpp index 1b11f39e6..9bc1087e1 100644 --- a/WickedEngine/wiTranslator.cpp +++ b/WickedEngine/wiTranslator.cpp @@ -168,9 +168,9 @@ void wiTranslator::Update() y = o + XMVectorSet(0, 3, 0, 0) * dist; z = o + XMVectorSet(0, 0, 3, 0) * dist; p = XMLoadFloat4(&pointer); - xy = o + XMVectorSet(1, 1, 0, 0) * dist; - xz = o + XMVectorSet(1, 0, 1, 0) * dist; - yz = o + XMVectorSet(0, 1, 1, 0) * dist; + xy = o + XMVectorSet(0.5f, 0.5f, 0, 0) * dist; + xz = o + XMVectorSet(0.5f, 0, 0.5f, 0) * dist; + yz = o + XMVectorSet(0, 0.5f, 0.5f, 0) * dist; o = XMVector3Project(o, 0, 0, cam->width, cam->height, 0, 1, P, V, W); @@ -181,17 +181,14 @@ void wiTranslator::Update() xz = XMVector3Project(xz, 0, 0, cam->width, cam->height, 0, 1, P, V, W); yz = XMVector3Project(yz, 0, 0, cam->width, cam->height, 0, 1, P, V, W); - XMVECTOR xDisV = XMVector2LinePointDistance(o, x, p); - XMVECTOR yDisV = XMVector2LinePointDistance(o, y, p); - XMVECTOR zDisV = XMVector2LinePointDistance(o, z, p); XMVECTOR oDisV = XMVector3Length(o - p); XMVECTOR xyDisV = XMVector3Length(xy - p); XMVECTOR xzDisV = XMVector3Length(xz - p); XMVECTOR yzDisV = XMVector3Length(yz - p); - float xDis = XMVectorGetX(xDisV); - float yDis = XMVectorGetX(yDisV); - float zDis = XMVectorGetX(zDisV); + float xDis = wiMath::GetPointSegmentDistance(p, o, x); + float yDis = wiMath::GetPointSegmentDistance(p, o, y); + float zDis = wiMath::GetPointSegmentDistance(p, o, z); float oDis = XMVectorGetX(oDisV); float xyDis = XMVectorGetX(xyDisV); float xzDis = XMVectorGetX(xzDisV); @@ -201,15 +198,15 @@ void wiTranslator::Update() { state = TRANSLATOR_XYZ; } - else if (xyDis < 10) + else if (xyDis < 20) { state = TRANSLATOR_XY; } - else if (xzDis < 10) + else if (xzDis < 20) { state = TRANSLATOR_XZ; } - else if (yzDis < 10) + else if (yzDis < 20) { state = TRANSLATOR_YZ; } diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 95d76c6ae..5691a653f 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -7,7 +7,7 @@ namespace wiVersion // minor features, major bug fixes const int minor = 8; // minor bug fixes, alterations, refactors - const int revision = 25; + const int revision = 26; long GetVersion()