editor: revert self-drawn scale gizmo, clip degenerate axes instead

User feedback: the self-drawn scale handles clash visually with the
ImGuizmo translate/rotate rods (different size/style, clearly not one
widget). Keep the library widget for all three ops for visual
consistency and prevent mis-drags by masking degenerate axes via
SetAxisMask:

- translate: axis ~ parallel to camera-to-object line (sin < 0.25)
- scale: axis ~ perpendicular to camera-to-object line (|dot| < 0.1,
  intersection numerator identically zero -> grab fails/values jump)
  OR axis ~ parallel to view direction (|dot| > 0.98, zero screen
  displacement -> value never changes)
- rotate: screen-space math, no degeneracy, no mask

Masked axes are neither drawn nor activatable; a slight view change
restores them. Center uniform-scale square (MT_SCALE_XYZ, pure screen
space) stays available in any view.
This commit is contained in:
2026-10-03 12:46:07 +08:00
parent c9d4eed043
commit 9ff08651f0
2 changed files with 66 additions and 322 deletions
+1 -15
View File
@@ -35,21 +35,7 @@ struct GizmoState {
int op = 7; // ImGuizmo::TRANSLATE(TRANSLATE_X|Y|Z)
bool localSpace = true; // 操纵空间:true=模型轴(旋转/缩放语义),
// T 键切 world
bool dragging = false; // 拖拽中(IsUsing 或自绘缩放拖拽)→ 鼠标归
// Gizmo 不给游戏侧(Editor::BlockingMouse)
// ---- 自绘缩放 gizmo(op==SCALE 整体不走 ImGuizmo)----
// 库内缩放的 hover/拖拽依赖"法线=轴"平面求交:正对视角(轴⊥
// 相机连线)时求交分子恒 0 → 杆抓不到、数值随机猛变;轴∥视线
// 时又无屏幕位移。submodule 禁改,AxisMask 只能"藏"不能"补"
// → 调用层整体自绘三轴杆 + 中心等比方块(纯屏幕空间数学,任意
// 视角良构),实现见 ViewportPanel.cpp ScaleGizmoSelf
bool scaleDragActive = false; // 自绘缩放拖拽中
int scaleDragAxis = -1; // 拖拽目标:0/1/2 轴;-2 = 中心等比
bool scaleHover = false; // 本帧悬停/拖拽自绘手柄 → 抑制 pick
float scaleStartMouse[2] = {0.0f, 0.0f}; // 拖拽起始鼠标(屏幕系)
float scaleStartDist = 0.0f; // 起始鼠标到杆心距离(径向映射用)
float scaleStartScale[3] = {1.0f, 1.0f, 1.0f}; // 拖拽起始 scale
bool dragging = false; // 拖拽中(IsUsing)→ 鼠标归 Gizmo 不给游戏侧
};
class ViewportPanel {