Fix manipulator translate and rotate problem

This commit is contained in:
indigo 2026-06-03 19:51:20 +08:00
parent 607b36b97d
commit d4b46b438c
1 changed files with 19 additions and 4 deletions

View File

@ -581,10 +581,11 @@ bool TransformManipulator::HandleInput(const pxr::GfMatrix4d& viewProj,
if (axLen > 1e-3f) {
float screenDot = (delta.x*axDx + delta.y*axDy) / axLen;
float worldDelta = screenDot * sf / axLen;
pxr::GfVec3d move(
m_dragAxis == 0 ? worldDelta : 0.f,
m_dragAxis == 1 ? worldDelta : 0.f,
m_dragAxis == 2 ? worldDelta : 0.f);
// Displace along the actual gizmo axis direction (world space).
// Using axes[m_dragAxis] is correct for both World and Object space;
// the old code used hardcoded world X/Y/Z components which broke
// Object-space translation.
pxr::GfVec3d move = axes[m_dragAxis] * static_cast<double>(worldDelta);
ApplyMoveDelta(move);
}
}
@ -606,6 +607,20 @@ bool TransformManipulator::HandleInput(const pxr::GfMatrix4d& viewProj,
while (deltaAngle < -static_cast<float>(M_PI)) deltaAngle += 2.f * static_cast<float>(M_PI);
float angleDeg = deltaAngle * (180.f / static_cast<float>(M_PI));
// Correct sign: the screen-angle approach maps 2-D angular
// motion to 3-D rotation around axes[m_dragAxis]. When the
// ring normal faces the camera (dot < 0) the handedness flips,
// so negate the angle to keep rotation direction consistent.
pxr::GfVec3d ringNormal = axes[m_dragAxis];
pxr::GfVec3d camToScene = pivot - cameraEye;
double camLen = camToScene.GetLength();
if (camLen > 1e-9) camToScene /= camLen;
double axisDotView = ringNormal[0]*camToScene[0]
+ ringNormal[1]*camToScene[1]
+ ringNormal[2]*camToScene[2];
if (axisDotView < 0.0) angleDeg = -angleDeg;
ApplyRotateDelta(m_dragAxis, angleDeg);
m_dragRotateLastAngle = currentAngle;
}