From 43f8228e49056fb5879d9fb2038dc770224c423f Mon Sep 17 00:00:00 2001 From: gaozheng Date: Tue, 16 Jun 2026 10:34:11 +0800 Subject: [PATCH] =?UTF-8?q?fix(vtk):=20=E5=88=87=E7=89=87=E5=8D=95?= =?UTF-8?q?=E5=87=BB=E4=BB=85=E9=80=89=E4=B8=AD+=E9=AB=98=E4=BA=AE,?= =?UTF-8?q?=E4=B8=8D=E5=8A=A8=E7=9B=B8=E6=9C=BA(=E7=BB=88=E6=80=81)=20?= =?UTF-8?q?=E2=80=94=20=E5=88=87=E6=8D=A2=E5=88=87=E7=89=87=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E8=B7=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 据用户实测: '按切片中心移焦点'(eb8cb9e)在切换两切片时仍跳(两次焦点跳动), 且切片中心≈体中心 → 与默认绕中心旋转视觉等价、价值低。终态: 单击=仅选中+高亮, 拖动=默认 TrackballCamera 绕 场景/体中心旋转(稳定、永不跳)。spec C38 '以体为中心' 由此满足; 切片本身不自转(符合语义)。 --- src/render/interact/InteractionManager.cpp | 27 +++++----------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/render/interact/InteractionManager.cpp b/src/render/interact/InteractionManager.cpp index bcef9ee..8438cdb 100644 --- a/src/render/interact/InteractionManager.cpp +++ b/src/render/interact/InteractionManager.cpp @@ -131,28 +131,13 @@ int InteractionManager::nearestSlice(const Vec3& worldPoint) const { } void InteractionManager::onPicked(const Vec3& worldPoint) { + // 单击 = 仅选中命中切片 + 高亮,**不动相机** → 切换切片永不跳。 + // 拖动旋转交给默认 TrackballCamera(绕场景/体中心,稳定)。曾试"按切片中心移焦点"以实现 + // spec C38'以切片为中心',但切片中心≈体中心→与默认视觉等价、却引入切换跳动,得不偿失,故去除。 const int idx = nearestSlice(worldPoint); - if (idx < 0) { - safeRender(); // 未命中切片:不动相机(拖动绕当前中心旋转,不甩) - return; - } - selected_ = idx; - updateSelectionVisual(); - - // 旋转中心 = 切片中心(spec C38 "以切片为中心旋转"),**不是点击点**: - // 实测点击点常远离体中心,绕它拖动旋转会大幅摆动(=用户看到的"跳");切片中心≈体中心 → 居中、不甩。 - // 焦点与相机位置同步平移同一 delta → 视向/距离不变、点击瞬间画面不动;之后 TrackballCamera 绕切片中心旋转。 - if (renderer_) { - if (auto* cam = renderer_->GetActiveCamera()) { - const Vec3 c = slices_[static_cast(idx)]->center(); - double f[3], p[3]; - cam->GetFocalPoint(f); - cam->GetPosition(p); - const double d[3] = {c[0] - f[0], c[1] - f[1], c[2] - f[2]}; - cam->SetFocalPoint(c[0], c[1], c[2]); - cam->SetPosition(p[0] + d[0], p[1] + d[1], p[2] + d[2]); - renderer_->ResetCameraClippingRange(); - } + if (idx >= 0) { + selected_ = idx; + updateSelectionVisual(); } safeRender(); }