Fix rotate manipulator axis and gizmo pivot placement
Rotate manipulator — correct axis bug: - Object-space delta axis was set to initRot.GetRow3(axis) (a parent-space vector) then applied in the prim's local frame via deltaM * initRot. These frames are mismatched: the axis must be the canonical e_a so that Rot(e_a) fixes e_a and the prim rotates purely about its own axis. Fixed to use the canonical axis for both spaces; only composition order differs (deltaM * initRot for object, initRot * deltaM for world). Gizmo pivot placement: - ComputeGizmoPivot() used the bounding-box centre (geometry centroid), placing the gizmo at the wrong location for any non-centred prim. Replaced with parentToWorld.Transform(translate + pivot) from XformCommonAPI::GetXformVectors — the authored pivot point in world space. Fallback for incompatible op stacks uses worldMatrix.ExtractTranslation(). Property panel: - Show pivot (X/Y/Z) as read-only row below Scale, populated from XformCommonAPI::GetXformVectors each frame. - Removed active-rotate-axis display (was added and then removed per request). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -108,19 +108,15 @@ private:
|
||||
//
|
||||
// Ring plane: world-space ring normal (for mouse-ray intersection + sign).
|
||||
//
|
||||
// Delta-rotation axis differs by TransformSpace:
|
||||
// Object => initRot.GetRow3(axis) -- local axis in PARENT space
|
||||
// (exact usdtweak localPlaneNormal convention)
|
||||
// World => world unit vector
|
||||
// (correct for root-level / simple hierarchies)
|
||||
//
|
||||
// resultingRotation formula:
|
||||
// Object => GfMatrix4d(1).SetRotate(delta) * initRot
|
||||
// (usdtweak: delta applied in local frame before initRot)
|
||||
// World => initRot * GfMatrix4d(1).SetRotate(delta)
|
||||
// (USD row-vector: initRot maps local->parent, then world delta)
|
||||
// Delta-rotation axis is the canonical axis e_a for the dragged ring in
|
||||
// BOTH spaces; only the composition order differs:
|
||||
// Object => SetRotate(delta) * initRot
|
||||
// delta applied in the prim's own local frame, so the dragged
|
||||
// local axis stays fixed -> rotates purely about its own axis.
|
||||
// World => initRot * SetRotate(delta)
|
||||
// initRot maps local->parent, then delta about the world axis.
|
||||
pxr::GfVec3d m_dragRotatePlaneNormal; // world-space
|
||||
pxr::GfVec3d m_dragRotateDeltaAxis; // space-dependent (see above)
|
||||
pxr::GfVec3d m_dragRotateDeltaAxis; // canonical axis e_a for ring
|
||||
pxr::GfVec3d m_dragRotateFrom; // clock-hand at drag start
|
||||
pxr::GfMatrix4d m_dragRotateInitialRotMat; // local->parent rot at drag start
|
||||
bool m_dragRotateObjectSpace = true;
|
||||
|
||||
Reference in New Issue
Block a user