diff --git a/Editor/Translator.cpp b/Editor/Translator.cpp index 4c8296546..c603855ae 100644 --- a/Editor/Translator.cpp +++ b/Editor/Translator.cpp @@ -212,7 +212,7 @@ void Translator::Update(const CameraComponent& camera, const XMFLOAT4& currentMo state = TRANSLATOR_XYZ; XMStoreFloat3(&axis, screen_normal); } - + } else { @@ -386,11 +386,26 @@ void Translator::Update(const CameraComponent& camera, const XMFLOAT4& currentMo // xyz planeNormal = camera.GetAt(); } - plane = XMPlaneFromPointNormal(pos, XMVector3Normalize(planeNormal)); - if (XMVectorGetX(XMVectorAbs(XMVector3Dot(planeNormal, rayDir))) < 0.001f) + // Use stored plane from drag start to avoid drift + if (dragging) { - state = TRANSLATOR_IDLE; + plane = XMLoadFloat4(&drag_plane); + } + else + { + plane = XMPlaneFromPointNormal(pos, XMVector3Normalize(planeNormal)); + } + + // Check if ray is nearly parallel to plane - only abort if not already dragging + if (XMVectorGetX(XMVectorAbs(XMVector3Dot(XMPlaneNormalize(plane), rayDir))) < 0.001f) + { + if (!dragging) + { + state = TRANSLATOR_IDLE; + return; + } + // If already dragging, skip this frame's update but maintain state return; } XMVECTOR intersection = XMPlaneIntersectLine(plane, rayOrigin, rayOrigin + rayDir * camera.zFarP); @@ -400,28 +415,30 @@ void Translator::Update(const CameraComponent& camera, const XMFLOAT4& currentMo dragStarted = true; transform_start = transform; XMStoreFloat3(&intersection_start, intersection); + XMStoreFloat4(&drag_plane, plane); matrices_start = matrices_current; } XMVECTOR intersectionPrev = XMLoadFloat3(&intersection_start); + XMVECTOR startPosition = transform_start.GetPositionV(); XMVECTOR deltaV; if (state == TRANSLATOR_X) { - XMVECTOR A = pos, B = pos + XMVectorSet(1, 0, 0, 0); + XMVECTOR A = startPosition, B = startPosition + XMVectorSet(1, 0, 0, 0); XMVECTOR P = wi::math::ClosestPointOnLine(A, B, intersection); XMVECTOR PPrev = wi::math::ClosestPointOnLine(A, B, intersectionPrev); deltaV = P - PPrev; } else if (state == TRANSLATOR_Y) { - XMVECTOR A = pos, B = pos + XMVectorSet(0, 1, 0, 0); + XMVECTOR A = startPosition, B = startPosition + XMVectorSet(0, 1, 0, 0); XMVECTOR P = wi::math::ClosestPointOnLine(A, B, intersection); XMVECTOR PPrev = wi::math::ClosestPointOnLine(A, B, intersectionPrev); deltaV = P - PPrev; } else if (state == TRANSLATOR_Z) { - XMVECTOR A = pos, B = pos + XMVectorSet(0, 0, 1, 0); + XMVECTOR A = startPosition, B = startPosition + XMVectorSet(0, 0, 1, 0); XMVECTOR P = wi::math::ClosestPointOnLine(A, B, intersection); XMVECTOR PPrev = wi::math::ClosestPointOnLine(A, B, intersectionPrev); deltaV = P - PPrev; @@ -534,7 +551,7 @@ void Translator::Update(const CameraComponent& camera, const XMFLOAT4& currentMo PostTranslate(); } } - + if (!wi::input::Down(wi::input::MOUSE_BUTTON_LEFT)) { if (dragging) diff --git a/Editor/Translator.h b/Editor/Translator.h index 16af5e55c..50d447a93 100644 --- a/Editor/Translator.h +++ b/Editor/Translator.h @@ -8,6 +8,7 @@ private: bool dragEnded = false; XMFLOAT3 intersection_start = XMFLOAT3(0, 0, 0); XMFLOAT3 axis = XMFLOAT3(1, 0, 0); + XMFLOAT4 drag_plane = XMFLOAT4(0, 0, 0, 0); float angle = 0; float angle_start = 0; bool has_selected_transform = false;