mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-18 03:19:53 +00:00
ifcviewer-web: navigation parity — view all, XYZ views, ortho, zoom-to-selected
The camera math already lived in the shared ViewportCore; the desktop just bound keys to it. The web build had no keyboard handler and no camera UI, so none of it was reachable. Wire it up (Tier 1 + 2 of nav parity; fly mode is a separate follow-up). Shared core: - setStandardView(StandardView) — named Front/Back/Left/Right/Top/Bottom wrapper over setStandardView(yaw,pitch), so the axis→angle mapping lives in one place. - frameSelection() — lifts the desktop's "union selected AABBs → frameAabb(1.30)" focus logic out of ViewportWindow into the core. Desktop's focusOnSelectedObject and the X/Y/Z hotkeys now call these (DRY, behaviour unchanged). Web: - main_web gains a keydown handler matching the desktop bindings — Home=view all, F=zoom to selected, P=ortho toggle, X/Y/Z (+Shift=negative)=standard views — plus exported entry points (view_all_c / frame_selection_c / toggle_projection_c / projection_is_ortho_c / standard_view_c) for the toolbar. - shell.html adds a bottom nav toolbar (Fit / Focus / Persp-Ortho / the six views) with the hotkeys in tooltips; the ortho button reflects state. Verified: Z key and Front button both move the camera, ortho toggles render + label, zero GPU errors; 111/111 unit + 6/6 web smoke pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1519,31 +1519,10 @@ bool ViewportWindow::computeObjectAabb(uint32_t id,
|
||||
|
||||
void ViewportWindow::focusOnSelectedObject() {
|
||||
if (fps_mode_) return;
|
||||
if (selection_.count() == 0) {
|
||||
Log::info() << "[wgpu] focus: no object selected";
|
||||
return;
|
||||
// Shared math lives in ViewportCore::frameSelection (also the web path).
|
||||
if (!core_.frameSelection()) {
|
||||
Log::info() << "[wgpu] focus: no object selected / no AABB available";
|
||||
}
|
||||
float lo[3] = { std::numeric_limits<float>::infinity(),
|
||||
std::numeric_limits<float>::infinity(),
|
||||
std::numeric_limits<float>::infinity() };
|
||||
float hi[3] = { -std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity() };
|
||||
bool any = false;
|
||||
for (uint32_t id : selection_.selectionIds()) {
|
||||
float mn[3], mx[3];
|
||||
if (!computeObjectAabb(id, mn, mx)) continue;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
lo[i] = std::min(lo[i], mn[i]);
|
||||
hi[i] = std::max(hi[i], mx[i]);
|
||||
}
|
||||
any = true;
|
||||
}
|
||||
if (!any) {
|
||||
Log::info() << "[wgpu] focus: no AABB available";
|
||||
return;
|
||||
}
|
||||
frameAabb(lo, hi, 1.30f);
|
||||
}
|
||||
|
||||
// setStandardView / toggleProjection / cameraString moved to ViewportCore (#84-i).
|
||||
@@ -2226,10 +2205,11 @@ void ViewportWindow::keyPressEvent(QKeyEvent* event) {
|
||||
&& (mods == Qt::NoModifier || mods == Qt::ShiftModifier)
|
||||
&& !event->isAutoRepeat()) {
|
||||
const bool neg = (mods & Qt::ShiftModifier);
|
||||
using SV = ViewportCore::StandardView;
|
||||
switch (key) {
|
||||
case Qt::Key_X: setStandardView(neg ? 180.0f : 0.0f, 0.0f); break;
|
||||
case Qt::Key_Y: setStandardView(neg ? 270.0f : 90.0f, 0.0f); break;
|
||||
case Qt::Key_Z: setStandardView(camera_yaw_deg_, neg ? -90.0f : 90.0f); break;
|
||||
case Qt::Key_X: core_.setStandardView(neg ? SV::Back : SV::Front); break;
|
||||
case Qt::Key_Y: core_.setStandardView(neg ? SV::Left : SV::Right); break;
|
||||
case Qt::Key_Z: core_.setStandardView(neg ? SV::Bottom : SV::Top); break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user