From a0db182d2beec03775dbaf379a0b9ff797cd73fd Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 5 Jun 2026 14:24:49 +1000 Subject: [PATCH] ifcviewer: move camera + surface-geom state into ViewportCore (#84-g) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the camera/projection/clear-color fields that buildViewProj, updateFrameUniforms, the cull screen-area projector, and the bonsai- side cameraState/setCamera/viewAll surface depend on. Same alias pattern; no method bodies move in this commit — the next one moves the camera math methods now that all their state is in core. State moved (12 fields): int configured_w_, configured_h_ float camera_target_[3], camera_distance_ float camera_yaw_deg_, camera_pitch_deg_, camera_fov_y_deg_ float camera_near_, camera_far_ bool projection_ortho_ Eigen::Vector4f background_color_ ViewportWindow keeps reference aliases for each (including a proper `float (&camera_target_)[3]` reference-to-array binding) so the ~150 call sites that touch camera state stay unchanged. Aliases collapse when their owning methods migrate. Builds: desktop / bonsai / web all green. Tests 100/100. --- src/ifcviewer/ViewportCore.h | 30 ++++++++++++++++++++++++++++++ src/ifcviewer/ViewportWindow.cpp | 13 ++++++++++++- src/ifcviewer/ViewportWindow.h | 31 ++++++++++++------------------- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/ifcviewer/ViewportCore.h b/src/ifcviewer/ViewportCore.h index b99ec6e0a8..62f32a08e1 100644 --- a/src/ifcviewer/ViewportCore.h +++ b/src/ifcviewer/ViewportCore.h @@ -197,6 +197,36 @@ private: // queued setter that runs before init becomes a no-op rather than // crashing on a null device. bool wgpu_initialized_ = false; + + // ---- Surface geometry ---------------------------------------------------- + // + // configured_w_/h_ track the device-pixel framebuffer size as last + // requested through host_->framebufferSize(). depth + MSAA attachments + // are sized against these. + int configured_w_ = 0; + int configured_h_ = 0; + + // ---- Orbit / fly camera state ------------------------------------------- + // + // Mirrors the GL viewport's defaults; the orbit math lives in + // buildViewProj (also in ViewportCore). BIM scenes are +Z up. + float camera_target_[3] = { 0.0f, 0.0f, 0.0f }; + float camera_distance_ = 50.0f; + float camera_yaw_deg_ = 45.0f; + float camera_pitch_deg_ = 30.0f; + float camera_fov_y_deg_ = 45.0f; + float camera_near_ = 0.1f; + float camera_far_ = 10000.0f; + // Perspective by default; toggleProjection (P key) flips this. When + // true, buildViewProj uses an orthographic matrix sized by + // camera_distance_ × tan(fov/2) so toggling looks like a smooth + // swap rather than a jump in apparent size. + bool projection_ortho_ = false; + + // RGBA in linear-space [0..1]. The render-pass clear value applies + // an sRGB-to-linear conversion on top so the on-screen colour + // matches the hex value passed via setBackgroundColor. + Eigen::Vector4f background_color_ = {0.125f, 0.137f, 0.161f, 1.0f}; }; #endif // VIEWPORTCORE_H diff --git a/src/ifcviewer/ViewportWindow.cpp b/src/ifcviewer/ViewportWindow.cpp index 6f941da2b3..5956182689 100644 --- a/src/ifcviewer/ViewportWindow.cpp +++ b/src/ifcviewer/ViewportWindow.cpp @@ -608,7 +608,18 @@ ViewportWindow::ViewportWindow(QWindow* parent) next_model_id_ (core_.next_model_id_), next_object_id_ (core_.next_object_id_), federated_false_origin_meters_(core_.federated_false_origin_meters_), - wgpu_initialized_(core_.wgpu_initialized_) { + wgpu_initialized_(core_.wgpu_initialized_), + configured_w_ (core_.configured_w_), + configured_h_ (core_.configured_h_), + camera_target_ (core_.camera_target_), + camera_distance_(core_.camera_distance_), + projection_ortho_(core_.projection_ortho_), + camera_yaw_deg_ (core_.camera_yaw_deg_), + camera_pitch_deg_(core_.camera_pitch_deg_), + camera_fov_y_deg_(core_.camera_fov_y_deg_), + camera_near_ (core_.camera_near_), + camera_far_ (core_.camera_far_), + background_color_(core_.background_color_) { // wgpu doesn't need a GL context; we just need a real native window // whose backing layer matches the GPU API wgpu will drive. // diff --git a/src/ifcviewer/ViewportWindow.h b/src/ifcviewer/ViewportWindow.h index 916b19d190..f388186c11 100644 --- a/src/ifcviewer/ViewportWindow.h +++ b/src/ifcviewer/ViewportWindow.h @@ -635,8 +635,8 @@ private: void recomposeAndUploadModel(uint32_t model_id); bool& wgpu_initialized_; - int configured_w_ = 0; - int configured_h_ = 0; + int& configured_w_; + int& configured_h_; // ---- wgpu lifecycle state aliases ---------------------------------- // @@ -869,19 +869,12 @@ private: // thread per model. mutable std::atomic hiz_trace_budget_{0}; - // 0x20 / 0xff ≈ 0.125, 0x23 / 0xff ≈ 0.137, 0x29 / 0xff ≈ 0.161. - Eigen::Vector4f background_color_ = {0.125f, 0.137f, 0.161f, 1.0f}; + Eigen::Vector4f& background_color_; - // Camera (orbit, right-handed Y-up world → wait, BIM is +Z up). - // Mirrors the GL viewport's defaults; mouse navigation lands later. - float camera_target_[3] = { 0.0f, 0.0f, 0.0f }; - float camera_distance_ = 50.0f; - - // Perspective by default; toggleProjection() (P key) flips this. When - // true, the per-frame projection builder uses an orthographic matrix - // sized by camera_distance_ × tan(fov/2) so toggling looks like a - // smooth swap rather than a jump in apparent size. - bool projection_ortho_ = false; + // Camera state aliases (storage in core_). + float (&camera_target_)[3]; + float& camera_distance_; + bool& projection_ortho_; // Fly / FPS-mode state. Mirrors GL ViewportWindow::CameraMode::Fps. // While fps_mode_ is true: cursor is hidden, mouse-look uses raw @@ -928,11 +921,11 @@ private: // mouseMoveEvent so mid-drag modifier changes don't switch axes. enum class NavDrag : uint8_t { Inactive, Orbit, Pan }; NavDrag nav_drag_kind_ = NavDrag::Inactive; - float camera_yaw_deg_ = 45.0f; - float camera_pitch_deg_ = 30.0f; - float camera_fov_y_deg_ = 45.0f; - float camera_near_ = 0.1f; - float camera_far_ = 10000.0f; + float& camera_yaw_deg_; + float& camera_pitch_deg_; + float& camera_fov_y_deg_; + float& camera_near_; + float& camera_far_; // Contribution-cull thresholds. Still-frame uses min_pixel_radius_; // when the camera changed since last frame, the bigger motion threshold