From 88caa46b92e5a4429915351ad466543ebc1d366d Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sat, 28 Mar 2026 03:42:08 -0400 Subject: [PATCH 01/14] chore(deps): update vneinteraction subproject to latest commit 5a53a72 --- deps/internal/vneinteraction | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/internal/vneinteraction b/deps/internal/vneinteraction index 71c538e..5a53a72 160000 --- a/deps/internal/vneinteraction +++ b/deps/internal/vneinteraction @@ -1 +1 @@ -Subproject commit 71c538e581f915f0803f442f61312f7aed5d5ba8 +Subproject commit 5a53a7234c142c9db5d21b52b8f5d9a1bece293b From 2b93a47173c86473408b20717a453c8c3bb5f317 Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sat, 28 Mar 2026 05:36:16 -0400 Subject: [PATCH 02/14] chore: updated vneinteraction lib --- deps/internal/vneinteraction | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/internal/vneinteraction b/deps/internal/vneinteraction index 5a53a72..e906f9e 160000 --- a/deps/internal/vneinteraction +++ b/deps/internal/vneinteraction @@ -1 +1 @@ -Subproject commit 5a53a7234c142c9db5d21b52b8f5d9a1bece293b +Subproject commit e906f9ed897039cdd416b060b37ab6cbd249b680 From 6f8a33c66a76dffd1bc44e3600ec0c68e63649d5 Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sat, 28 Mar 2026 13:03:36 -0400 Subject: [PATCH 03/14] chore: updated vneinteraction lib --- deps/internal/vneinteraction | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/internal/vneinteraction b/deps/internal/vneinteraction index e906f9e..edd96b0 160000 --- a/deps/internal/vneinteraction +++ b/deps/internal/vneinteraction @@ -1 +1 @@ -Subproject commit e906f9ed897039cdd416b060b37ab6cbd249b680 +Subproject commit edd96b0b66161e50a4bb210b9b2b94541870daa3 From f2e2f893a2d2d3fec89b44a1713bbfc3a857826a Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sat, 28 Mar 2026 16:04:45 -0400 Subject: [PATCH 04/14] chore: update vneinteraction subproject and refine interaction terminology - Updated the vneinteraction subproject to the latest commit. - Revised comments and documentation across multiple demo files to replace "orbit-arcball" with "orbit/trackball" for consistency. - Adjusted controller types and method names to reflect the new Inspect3DController, enhancing clarity in interaction handling. --- deps/internal/vneinteraction | 2 +- .../glfw_opengl/00_hello_testbed/README.md | 6 +- .../00_hello_testbed/demo_hello_testbed.cpp | 2 +- .../01_test_events/demo_test_events.cpp | 2 +- .../02_test_scene/demo_test_scene.cpp | 2 +- .../glfw_opengl/03_test_interaction/README.md | 4 +- .../demo_test_interaction.cpp | 59 +++++++++++-------- .../demo_test_interaction.h | 10 ++-- .../glfw_opengl/common/base_scene_layer.cpp | 6 +- samples/glfw_opengl/common/base_scene_layer.h | 10 ++-- 10 files changed, 56 insertions(+), 47 deletions(-) diff --git a/deps/internal/vneinteraction b/deps/internal/vneinteraction index edd96b0..54384b1 160000 --- a/deps/internal/vneinteraction +++ b/deps/internal/vneinteraction @@ -1 +1 @@ -Subproject commit edd96b0b66161e50a4bb210b9b2b94541870daa3 +Subproject commit 54384b118005f85111fdc59f88021d1bb5ad27a7 diff --git a/samples/glfw_opengl/00_hello_testbed/README.md b/samples/glfw_opengl/00_hello_testbed/README.md index 8cb71fc..a3bf9bf 100644 --- a/samples/glfw_opengl/00_hello_testbed/README.md +++ b/samples/glfw_opengl/00_hello_testbed/README.md @@ -8,7 +8,7 @@ The baseline demo that every subsequent GLFW/OpenGL sample is built on. Proves t 2. **Viewport resize**: Resizing the viewport keeps the image filling the panel (no stretching). 3. **Vsync**: Toggle in the application responds immediately. 4. **Grid and axes**: Spatial reference and confirmation that the camera and scene work. -5. **Orbit-arcball** (when `vne::interaction` is enabled): LMB drag rotates, RMB drag pans, scroll zooms. +5. **Orbit / trackball** (when `vne::interaction` is enabled): LMB drag rotates, RMB drag pans, scroll zooms. 6. **ImGui Settings**: Demo-specific section **Viewport** with controls reference and axis legend. ## Screenshots and Demo @@ -42,7 +42,7 @@ Note: The GIF is frame-skipped and also sped up so it can include the full recor - uncheck **Vsync**, - set **Viewport Layout** to **2**, **3**, or **4** viewports for a multi-pane layout (the combo also offers **1** for a single viewport). 3. Use mouse: - - **LMB** drag: rotate (orbit-arcball), + - **LMB** drag: rotate (orbit / trackball inspect), - **RMB** drag: pan, - **Scroll wheel**: zoom. @@ -108,7 +108,7 @@ Exit with **ESC** or by closing the window. ## Key Concepts - **BaseSceneLayer**: Renders grid, axes, and a perspective camera; shared with other samples via `samples/glfw_opengl/common/base_scene_layer.h`. -- **BaseInteractionLayer**: Orbit-arcball manipulator (optional); LMB orbit, RMB pan, scroll zoom. +- **BaseInteractionLayer**: Orbit / trackball inspect manipulator (optional); LMB rotate, RMB pan, scroll zoom. - **ImGui viewport**: The scene is drawn into an ImGui window; **Viewport Layout** can be set to 1–4 viewports when ImGui docking is enabled. - **Libraries**: vne::testbed, vne::scene, vne::interaction (optional). diff --git a/samples/glfw_opengl/00_hello_testbed/demo_hello_testbed.cpp b/samples/glfw_opengl/00_hello_testbed/demo_hello_testbed.cpp index c39ea03..42b2954 100644 --- a/samples/glfw_opengl/00_hello_testbed/demo_hello_testbed.cpp +++ b/samples/glfw_opengl/00_hello_testbed/demo_hello_testbed.cpp @@ -85,7 +85,7 @@ void registerHelloTestbedDemo(vne::testbed::Application& app) { app.getLayerStack().pushLayer(std::unique_ptr(scene), app.getAppContext()); #ifdef VNE_TESTBED_INTERACTION - // Layer 2: orbit-arcball interaction (per-viewport cameras when using multiple viewports) + // Layer 2: orbit/trackball interaction (per-viewport cameras when using multiple viewports) auto* interaction = new BaseInteractionLayer("HelloInteractionLayer"); interaction->setSceneLayer(scene); app.getLayerStack().pushLayer(std::unique_ptr(interaction), app.getAppContext()); diff --git a/samples/glfw_opengl/01_test_events/demo_test_events.cpp b/samples/glfw_opengl/01_test_events/demo_test_events.cpp index 2aebd89..4e0b2a7 100644 --- a/samples/glfw_opengl/01_test_events/demo_test_events.cpp +++ b/samples/glfw_opengl/01_test_events/demo_test_events.cpp @@ -381,7 +381,7 @@ void registerTestEventsDemo(vne::testbed::Application& app) { app.getLayerStack().pushLayer(std::unique_ptr(scene), app.getAppContext()); #ifdef VNE_TESTBED_INTERACTION - // Layer 2: orbit-arcball interaction (per-viewport cameras when using multiple viewports) + // Layer 2: orbit/trackball interaction (per-viewport cameras when using multiple viewports) auto* interaction = new BaseInteractionLayer("TestEventsInteractionLayer"); interaction->setSceneLayer(scene); app.getLayerStack().pushLayer(std::unique_ptr(interaction), app.getAppContext()); diff --git a/samples/glfw_opengl/02_test_scene/demo_test_scene.cpp b/samples/glfw_opengl/02_test_scene/demo_test_scene.cpp index 6b8d004..a7f9eb7 100644 --- a/samples/glfw_opengl/02_test_scene/demo_test_scene.cpp +++ b/samples/glfw_opengl/02_test_scene/demo_test_scene.cpp @@ -1023,7 +1023,7 @@ void registerTestSceneDemo(vne::testbed::Application& app) { app.getLayerStack().pushLayer(std::unique_ptr(scene), app.getAppContext()); #ifdef VNE_TESTBED_INTERACTION - // Layer 2: orbit-arcball (per-viewport cameras; use active set so ortho/persp switch works) + // Layer 2: orbit/trackball interaction (per-viewport cameras; use active set so ortho/persp switch works) auto* interaction = new BaseInteractionLayer("TestSceneInteractionLayer"); interaction->setCameras(scene->getActiveCameras()); app.getLayerStack().pushLayer(std::unique_ptr(interaction), app.getAppContext()); diff --git a/samples/glfw_opengl/03_test_interaction/README.md b/samples/glfw_opengl/03_test_interaction/README.md index 048e476..5989ac0 100644 --- a/samples/glfw_opengl/03_test_interaction/README.md +++ b/samples/glfw_opengl/03_test_interaction/README.md @@ -1,13 +1,13 @@ # 03 - Test Interaction -Full **interaction** demo on top of [`BaseSceneLayer`](../common/base_scene_layer.h): every high-level controller type (Inspect orbit/arcball, 3D navigation with FPS/Fly/Game modes, orthographic pan/zoom, follow), zoom methods, view-direction presets, and optional mesh loading from testdata when `VNE_TESTBED_VNEIO` is enabled. It shares the same **build / run / IDE** workflow as [`00_hello_testbed`](../00_hello_testbed/README.md) and uses the same Blinn-Phong [`MeshLayer`](../../../include/vertexnova/testbed/utils/mesh_layer.h) path as the scene samples when meshes are available. +Full **interaction** demo on top of [`BaseSceneLayer`](../common/base_scene_layer.h): every high-level controller type (Inspect orbit or virtual trackball with Hyperbolic/Rim projection, 3D navigation with FPS/Fly/Game modes, orthographic pan/zoom, follow), zoom methods, view-direction presets, and optional mesh loading from testdata when `VNE_TESTBED_VNEIO` is enabled. It shares the same **build / run / IDE** workflow as [`00_hello_testbed`](../00_hello_testbed/README.md) and uses the same Blinn-Phong [`MeshLayer`](../../../include/vertexnova/testbed/utils/mesh_layer.h) path as the scene samples when meshes are available. Screenshots are not included yet; they may be added in a later revision. ## What This Sample Shows 1. **Base scene**: Grid, axes, perspective or orthographic camera from `BaseSceneLayer`; settings can toggle grid/axes and switch projection. -2. **Controllers**: Runtime selection among Inspect (orbit or arcball), Navigation (FPS / Fly / Game via `NavigateMode`), Ortho2D, and Follow; per-controller ImGui tuning (pivot mode, speeds, navigation multipliers, ortho/follow options). +2. **Controllers**: Runtime selection among Inspect (Euler orbit or trackball), Navigation (FPS / Fly / Game via `NavigateMode`), Ortho2D, and Follow; per-controller ImGui tuning (trackball projection when in trackball inspect mode, pivot mode, speeds, navigation multipliers, ortho/follow options). 3. **Zoom**: Dolly-to-COI, scene-scale, or FOV change where applicable; matrix readouts for view and projection when enabled. 4. **Mesh browser** (with vneio): Lists mesh files under the configured directory (PLY, OBJ, STL, FBX, glTF), loads on click, drag-and-drop to the viewport, plus lighting and mesh transform panels when a mesh is loaded. 5. **Layer stack**: `BaseSceneLayer` → `InteractionTestLayer` → optional `MeshLayer` → `InteractionSettingsLayer` (ImGui settings). diff --git a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp index ded0aab..58c377e 100644 --- a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp +++ b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp @@ -23,7 +23,7 @@ #include "vertexnova/events/types.h" #include "vertexnova/events/window_event.h" -#include "vertexnova/interaction/orbit_arcball_behavior.h" +#include "vertexnova/interaction/orbital_camera_behavior.h" #include "vertexnova/interaction/free_look_behavior.h" #include "vertexnova/interaction/ortho_pan_zoom_behavior.h" #include "vertexnova/interaction/follow_behavior.h" @@ -64,13 +64,13 @@ const vne::math::Vec3f kDefaultTargetPosition{0.0f, 0.0f, 0.0f}; ControllerVariant makeController(ControllerKind kind, vne::interaction::NavigateMode nav_mode) { switch (kind) { case ControllerKind::eInspectOrbit: { - vne::interaction::InspectController c; + vne::interaction::Inspect3DController c; c.setRotationMode(vne::interaction::OrbitRotationMode::eOrbit); return c; } - case ControllerKind::eInspectArcball: { - vne::interaction::InspectController c; - c.setRotationMode(vne::interaction::OrbitRotationMode::eArcball); + case ControllerKind::eInspectTrackball: { + vne::interaction::Inspect3DController c; + c.setRotationMode(vne::interaction::OrbitRotationMode::eTrackball); return c; } case ControllerKind::eNavigation: { @@ -85,7 +85,7 @@ ControllerVariant makeController(ControllerKind kind, vne::interaction::Navigate return vne::interaction::FollowController{}; } } - return vne::interaction::InspectController{}; + return vne::interaction::Inspect3DController{}; } } // namespace @@ -97,7 +97,7 @@ ControllerVariant makeController(ControllerKind kind, vne::interaction::Navigate InteractionTestLayer::InteractionTestLayer() : vne::testbed::ILayer("InteractionTestLayer") { for (size_t i = 0; i < static_cast(kMaxViewports); ++i) { - controllers_[i] = makeController(ControllerKind::eInspectArcball, navigation_mode_); + controllers_[i] = makeController(ControllerKind::eInspectTrackball, navigation_mode_); } } @@ -234,7 +234,7 @@ void InteractionTestLayer::onUpdate(float dt) { // Apply scene scale from eSceneScale zoom method to the mesh transform each frame if (mesh_layer_) { if (auto* insp = getInspectController(0)) { - mesh_layer_->setUniformScale(insp->orbitArcballBehavior().getZoomScale()); + mesh_layer_->setUniformScale(insp->orbitalCameraBehavior().getZoomScale()); } } #endif @@ -313,8 +313,8 @@ void InteractionTestLayer::setZoomMethod(vne::interaction::ZoomMethod method) { for (auto& v : controllers_) { std::visit( [method](auto& c) { - if constexpr (std::is_same_v, vne::interaction::InspectController>) { - c.orbitArcballBehavior().setZoomMethod(method); + if constexpr (std::is_same_v, vne::interaction::Inspect3DController>) { + c.orbitalCameraBehavior().setZoomMethod(method); } else if constexpr (std::is_same_v, vne::interaction::Navigation3DController>) { c.freeLookBehavior().setZoomMethod(method); @@ -332,8 +332,8 @@ void InteractionTestLayer::setViewDirection(vne::interaction::ViewDirection dir) for (auto& v : controllers_) { std::visit( [dir](auto& c) { - if constexpr (std::is_same_v, vne::interaction::InspectController>) { - c.orbitArcballBehavior().setViewDirection(dir); + if constexpr (std::is_same_v, vne::interaction::Inspect3DController>) { + c.orbitalCameraBehavior().setViewDirection(dir); } }, v); @@ -382,8 +382,8 @@ void InteractionTestLayer::setRotationPivotMode(vne::interaction::OrbitPivotMode for (auto& v : controllers_) { std::visit( [mode](auto& c) { - if constexpr (std::is_same_v, vne::interaction::InspectController>) { - c.orbitArcballBehavior().setPivotMode(mode); + if constexpr (std::is_same_v, vne::interaction::Inspect3DController>) { + c.orbitalCameraBehavior().setPivotMode(mode); } }, v); @@ -440,12 +440,12 @@ vne::math::Vec3f InteractionTestLayer::cameraTarget() const { return camera_ ? camera_->getTarget() : vne::math::Vec3f{}; } -vne::interaction::InspectController* InteractionTestLayer::getInspectController(int index) noexcept { +vne::interaction::Inspect3DController* InteractionTestLayer::getInspectController(int index) noexcept { if (index < 0 || index >= kMaxViewports - || (current_kind_ != ControllerKind::eInspectOrbit && current_kind_ != ControllerKind::eInspectArcball)) { + || (current_kind_ != ControllerKind::eInspectOrbit && current_kind_ != ControllerKind::eInspectTrackball)) { return nullptr; } - return std::get_if(&controllers_[static_cast(index)]); + return std::get_if(&controllers_[static_cast(index)]); } vne::interaction::Navigation3DController* InteractionTestLayer::getNavController(int index) noexcept { @@ -597,7 +597,7 @@ void InteractionSettingsLayer::renderPanel() { const ControllerKind cur = il.getControllerKind(); const bool show_zoom = - (cur == ControllerKind::eInspectOrbit || cur == ControllerKind::eInspectArcball + (cur == ControllerKind::eInspectOrbit || cur == ControllerKind::eInspectTrackball || cur == ControllerKind::eNavigation || cur == ControllerKind::eOrtho || cur == ControllerKind::eFollow); if (show_zoom) { if (ImGui::CollapsingHeader("Zoom Method", ImGuiTreeNodeFlags_DefaultOpen)) { @@ -614,7 +614,7 @@ void InteractionSettingsLayer::renderPanel() { } } - if (cur == ControllerKind::eInspectOrbit || cur == ControllerKind::eInspectArcball) { + if (cur == ControllerKind::eInspectOrbit || cur == ControllerKind::eInspectTrackball) { if (ImGui::CollapsingHeader("View Direction", ImGuiTreeNodeFlags_DefaultOpen)) { using VD = vne::interaction::ViewDirection; struct { @@ -680,7 +680,7 @@ void InteractionSettingsLayer::renderCameraSettings() { sl.syncCameraPositionTargetUp(); sl.setUsePerspective(use_persp); if (!use_persp && !il.isManipulatorCompatibleWithCamera(false)) { - il.setControllerKind(ControllerKind::eInspectArcball); + il.setControllerKind(ControllerKind::eInspectTrackball); } il.setCamerasFromScene(); } @@ -753,9 +753,9 @@ void InteractionSettingsLayer::renderManipulatorSettings() { const ControllerKind cur = il.getControllerKind(); if (ImGui::CollapsingHeader("Controller", ImGuiTreeNodeFlags_DefaultOpen)) { - const char* types[] = {"Inspect (Orbit)", "Inspect (Arcball)", "Navigation", "Ortho", "Follow"}; + const char* types[] = {"Inspect (Orbit)", "Inspect (Trackball)", "Navigation", "Ortho", "Follow"}; const ControllerKind values[] = {ControllerKind::eInspectOrbit, - ControllerKind::eInspectArcball, + ControllerKind::eInspectTrackball, ControllerKind::eNavigation, ControllerKind::eOrtho, ControllerKind::eFollow}; @@ -810,8 +810,8 @@ void InteractionSettingsLayer::renderManipulatorSettings() { case ControllerKind::eInspectOrbit: ImGui::TextDisabled("LMB rotate RMB pan Scroll zoom"); break; - case ControllerKind::eInspectArcball: - ImGui::TextDisabled("LMB rotate RMB pan Scroll zoom (arcball)"); + case ControllerKind::eInspectTrackball: + ImGui::TextDisabled("LMB rotate RMB pan Scroll zoom (trackball)"); break; case ControllerKind::eNavigation: ImGui::TextDisabled("RMB + WASD/QE move Mouse look (Fps/Fly/Game)"); @@ -826,8 +826,17 @@ void InteractionSettingsLayer::renderManipulatorSettings() { // Per-controller settings if (auto* insp = il.getInspectController()) { - auto& orb = insp->orbitArcballBehavior(); + auto& orb = insp->orbitalCameraBehavior(); if (ImGui::TreeNodeEx("Inspect Settings", ImGuiTreeNodeFlags_DefaultOpen)) { + if (cur == ControllerKind::eInspectTrackball) { + using TPM = vne::interaction::TrackballBehavior::ProjectionMode; + int proj_idx = (orb.getTrackballProjectionMode() == TPM::eHyperbolic) ? 0 : 1; + const char* proj_names[] = {"Hyperbolic", "Rim"}; + if (ImGui::Combo("Trackball projection##insp", &proj_idx, proj_names, 2)) { + orb.setTrackballProjectionMode(proj_idx == 0 ? TPM::eHyperbolic : TPM::eRim); + } + ImGui::TextDisabled("Hyperbolic: cap + continuation; Rim: hemisphere + equatorial rim"); + } using OPM = vne::interaction::OrbitPivotMode; int pivot_idx = static_cast(orb.getPivotMode()); const char* pivot_names[] = {"COI (pan moves pivot)", diff --git a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.h b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.h index 4d31f14..06984c3 100644 --- a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.h +++ b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.h @@ -15,7 +15,7 @@ #include "vertexnova/testbed/layer.h" -#include "vertexnova/interaction/inspect_controller.h" +#include "vertexnova/interaction/inspect_3d_controller.h" #include "vertexnova/interaction/navigation_3d_controller.h" #include "vertexnova/interaction/ortho_2d_controller.h" #include "vertexnova/interaction/follow_controller.h" @@ -53,13 +53,13 @@ namespace vne::samples { /** Controller type for the interaction demo; maps to one of the four high-level controllers. */ enum class ControllerKind : int { eInspectOrbit = 0, - eInspectArcball, + eInspectTrackball, eNavigation, // Fps / Fly / Game chosen via setNavigationMode eOrtho, eFollow, }; -using ControllerVariant = std::variant; @@ -116,7 +116,7 @@ class InteractionTestLayer : public vne::testbed::ILayer { [[nodiscard]] vne::math::Vec3f cameraPosition() const; [[nodiscard]] vne::math::Vec3f cameraTarget() const; - [[nodiscard]] vne::interaction::InspectController* getInspectController(int index = 0) noexcept; + [[nodiscard]] vne::interaction::Inspect3DController* getInspectController(int index = 0) noexcept; [[nodiscard]] vne::interaction::Navigation3DController* getNavController(int index = 0) noexcept; [[nodiscard]] vne::interaction::Ortho2DController* getOrthoController(int index = 0) noexcept; [[nodiscard]] vne::interaction::FollowController* getFollowController(int index = 0) noexcept; @@ -131,7 +131,7 @@ class InteractionTestLayer : public vne::testbed::ILayer { BaseSceneLayer* scene_layer_{nullptr}; std::shared_ptr camera_; std::array controllers_; - ControllerKind current_kind_{ControllerKind::eInspectArcball}; + ControllerKind current_kind_{ControllerKind::eInspectTrackball}; #ifdef VNE_TESTBED_IMGUI vne::testbed::MeshLayer* mesh_layer_{nullptr}; #endif diff --git a/samples/glfw_opengl/common/base_scene_layer.cpp b/samples/glfw_opengl/common/base_scene_layer.cpp index 2c5a0ad..4b74e28 100644 --- a/samples/glfw_opengl/common/base_scene_layer.cpp +++ b/samples/glfw_opengl/common/base_scene_layer.cpp @@ -268,7 +268,7 @@ BaseInteractionLayer::BaseInteractionLayer(const char* name) : vne::testbed::ILayer(name) { controllers_.reserve(static_cast(kMaxViewports)); for (int i = 0; i < kMaxViewports; ++i) { - vne::interaction::InspectController c; + vne::interaction::Inspect3DController c; c.setRotationMode(vne::interaction::OrbitRotationMode::eOrbit); controllers_.push_back(std::move(c)); } @@ -400,11 +400,11 @@ void BaseInteractionLayer::onEvent(const vne::events::Event& event) { } } -vne::interaction::InspectController* BaseInteractionLayer::getInspectController() { +vne::interaction::Inspect3DController* BaseInteractionLayer::getInspectController() { return controllers_.empty() ? nullptr : &controllers_[0]; } -vne::interaction::InspectController* BaseInteractionLayer::getInspectController(int index) { +vne::interaction::Inspect3DController* BaseInteractionLayer::getInspectController(int index) { if (index >= 0 && index < static_cast(controllers_.size())) { return &controllers_[static_cast(index)]; } diff --git a/samples/glfw_opengl/common/base_scene_layer.h b/samples/glfw_opengl/common/base_scene_layer.h index 37b2926..87037a0 100644 --- a/samples/glfw_opengl/common/base_scene_layer.h +++ b/samples/glfw_opengl/common/base_scene_layer.h @@ -25,7 +25,7 @@ #ifdef VNE_TESTBED_INTERACTION #include "vertexnova/events/event.h" #include "vertexnova/events/event_listener.h" -#include "vertexnova/interaction/inspect_controller.h" +#include "vertexnova/interaction/inspect_3d_controller.h" #endif #ifdef VNE_TESTBED_IMGUI @@ -102,7 +102,7 @@ class BaseSceneLayer : public vne::testbed::ILayer { }; // --------------------------------------------------------------------------- -// BaseInteractionLayer — orbit-arcball driven by EventManager +// BaseInteractionLayer — orbit / trackball inspect driven by EventManager // Pair with BaseSceneLayer: call setCamera(scene->getActiveCamera()) before attach. // Only compiled when VNE_TESTBED_INTERACTION is defined. // --------------------------------------------------------------------------- @@ -129,11 +129,11 @@ class BaseInteractionLayer : public vne::testbed::ILayer, public vne::events::Ev void onUpdate(float dt) override; void onEvent(const vne::events::Event& event) override; - [[nodiscard]] vne::interaction::InspectController* getInspectController(); - [[nodiscard]] vne::interaction::InspectController* getInspectController(int index); + [[nodiscard]] vne::interaction::Inspect3DController* getInspectController(); + [[nodiscard]] vne::interaction::Inspect3DController* getInspectController(int index); private: - std::vector controllers_; + std::vector controllers_; bool interaction_enabled_{true}; double last_x_{0.0}; double last_y_{0.0}; From db2a7f9280f636b5d0f8b616201f786bc2bf7946 Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sat, 28 Mar 2026 18:46:31 -0400 Subject: [PATCH 05/14] refactor: update interaction behavior references in demo_test_interaction - Removed unused ortho_pan_zoom_behavior include and replaced references with ortho2DBehavior for consistency. - Updated method calls in InteractionTestLayer and InteractionSettingsLayer to align with the new behavior naming, enhancing clarity in interaction handling. --- .../03_test_interaction/demo_test_interaction.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp index 58c377e..c0aca8a 100644 --- a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp +++ b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp @@ -25,7 +25,6 @@ #include "vertexnova/interaction/orbital_camera_behavior.h" #include "vertexnova/interaction/free_look_behavior.h" -#include "vertexnova/interaction/ortho_pan_zoom_behavior.h" #include "vertexnova/interaction/follow_behavior.h" #ifdef VNE_TESTBED_IMGUI @@ -319,7 +318,7 @@ void InteractionTestLayer::setZoomMethod(vne::interaction::ZoomMethod method) { vne::interaction::Navigation3DController>) { c.freeLookBehavior().setZoomMethod(method); } else if constexpr (std::is_same_v, vne::interaction::Ortho2DController>) { - c.orthoPanZoomBehavior().setZoomMethod(method); + c.ortho2DBehavior().setZoomMethod(method); } else if constexpr (std::is_same_v, vne::interaction::FollowController>) { c.followBehavior().setZoomMethod(method); } @@ -901,7 +900,7 @@ void InteractionSettingsLayer::renderManipulatorSettings() { ImGui::TreePop(); } } else if (auto* ortho = il.getOrthoController()) { - auto& opz = ortho->orthoPanZoomBehavior(); + auto& opz = ortho->ortho2DBehavior(); if (ImGui::TreeNodeEx("Ortho Settings", ImGuiTreeNodeFlags_DefaultOpen)) { bool rot_en = ortho->isRotationEnabled(); if (ImGui::Checkbox("Rotation enabled##ortho", &rot_en)) { From 9fe2030cff17b5386285ecf4d9991bc9892f6840 Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sat, 28 Mar 2026 18:49:00 -0400 Subject: [PATCH 06/14] chore(deps): update vneinteraction subproject to latest commit f776506 --- deps/internal/vneinteraction | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/internal/vneinteraction b/deps/internal/vneinteraction index 54384b1..f776506 160000 --- a/deps/internal/vneinteraction +++ b/deps/internal/vneinteraction @@ -1 +1 @@ -Subproject commit 54384b118005f85111fdc59f88021d1bb5ad27a7 +Subproject commit f776506048a328abdd50d8d99396ab5154be805a From 2e314452a36fab2eaa96eeb03d2cb1c185b86dd0 Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sat, 28 Mar 2026 18:52:08 -0400 Subject: [PATCH 07/14] feat: add ortho_2d_behavior include to demo_test_interaction - Included the ortho_2d_behavior header to enhance interaction capabilities in the demo. - This addition supports improved 2D interaction handling within the OpenGL context. --- .../glfw_opengl/03_test_interaction/demo_test_interaction.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp index c0aca8a..498fbe7 100644 --- a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp +++ b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp @@ -24,6 +24,7 @@ #include "vertexnova/events/window_event.h" #include "vertexnova/interaction/orbital_camera_behavior.h" +#include "vertexnova/interaction/ortho_2d_behavior.h" #include "vertexnova/interaction/free_look_behavior.h" #include "vertexnova/interaction/follow_behavior.h" From 4723d7389c89acd753d0bb1b93ce68b9bfc263c2 Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sun, 29 Mar 2026 07:17:55 -0400 Subject: [PATCH 08/14] refactor: remove unused scene scale application in InteractionTestLayer - Eliminated the scene scale application logic from the onUpdate method, streamlining the update process. - This change enhances code clarity by removing unnecessary conditional checks related to the mesh layer's scale. --- .../03_test_interaction/demo_test_interaction.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp index 498fbe7..704f350 100644 --- a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp +++ b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp @@ -230,14 +230,6 @@ void InteractionTestLayer::onUpdate(float dt) { } #endif dispatchUpdate(static_cast(dt)); -#ifdef VNE_TESTBED_IMGUI - // Apply scene scale from eSceneScale zoom method to the mesh transform each frame - if (mesh_layer_) { - if (auto* insp = getInspectController(0)) { - mesh_layer_->setUniformScale(insp->orbitalCameraBehavior().getZoomScale()); - } - } -#endif } void InteractionTestLayer::onEvent(const vne::events::Event& event) { From d1f2ea09f1b507f77b3b70810e95051d63b8f872 Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sun, 29 Mar 2026 07:25:11 -0400 Subject: [PATCH 09/14] chore(deps): update vneinteraction subproject to latest commit 48c505e --- deps/internal/vneinteraction | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/internal/vneinteraction b/deps/internal/vneinteraction index f776506..48c505e 160000 --- a/deps/internal/vneinteraction +++ b/deps/internal/vneinteraction @@ -1 +1 @@ -Subproject commit f776506048a328abdd50d8d99396ab5154be805a +Subproject commit 48c505e9f2574e19c72198683530c2495eb13d6e From e6b6592a5838bd1acb0363b433c65c6c5b282c70 Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sun, 29 Mar 2026 20:34:01 -0400 Subject: [PATCH 10/14] feat: synchronize orthographic projection bounds in onRender - Added logic to check and synchronize orthographic projection bounds based on viewport size and UI settings, preventing unnecessary updates. - Introduced new member variables to track the last applied orthographic projection settings, enhancing performance during rendering. - Updated comments to clarify the purpose of the new synchronization mechanism. --- .../glfw_opengl/common/base_scene_layer.cpp | 32 ++++++++++++++----- samples/glfw_opengl/common/base_scene_layer.h | 8 +++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/samples/glfw_opengl/common/base_scene_layer.cpp b/samples/glfw_opengl/common/base_scene_layer.cpp index 4b74e28..4aacced 100644 --- a/samples/glfw_opengl/common/base_scene_layer.cpp +++ b/samples/glfw_opengl/common/base_scene_layer.cpp @@ -98,14 +98,27 @@ void BaseSceneLayer::onRender(const vne::testbed::RenderContext& render_context) } } else { if (auto* o = dynamic_cast(camera)) { - const float hw = ui_settings_.ortho_half * aspect; - o->setBounds(-hw, - hw, - -ui_settings_.ortho_half, - ui_settings_.ortho_half, - ui_settings_.ortho_near, - ui_settings_.ortho_far); - o->updateProjectionMatrix(); + const int vp_w = render_context.frame_info.width; + const int vp_h = render_context.frame_info.height; + const bool need_ortho_proj_sync = vp_w != ortho_proj_sync_vp_w_ || vp_h != ortho_proj_sync_vp_h_ + || ui_settings_.ortho_half != ortho_proj_sync_half_ + || ui_settings_.ortho_near != ortho_proj_sync_near_ + || ui_settings_.ortho_far != ortho_proj_sync_far_; + if (need_ortho_proj_sync) { + const float hw = ui_settings_.ortho_half * aspect; + o->setBounds(-hw, + hw, + -ui_settings_.ortho_half, + ui_settings_.ortho_half, + ui_settings_.ortho_near, + ui_settings_.ortho_far); + o->updateProjectionMatrix(); + ortho_proj_sync_vp_w_ = vp_w; + ortho_proj_sync_vp_h_ = vp_h; + ortho_proj_sync_half_ = ui_settings_.ortho_half; + ortho_proj_sync_near_ = ui_settings_.ortho_near; + ortho_proj_sync_far_ = ui_settings_.ortho_far; + } } } } @@ -240,6 +253,9 @@ void BaseSceneLayer::buildCameras(int w, int h) { ortho->updateMatrices(); cameras_ortho_[static_cast(i)] = std::move(ortho); } + + // Next `onRender` must re-apply ortho bounds if UI sliders / viewport no longer match the camera. + ortho_proj_sync_vp_w_ = -1; } void BaseSceneLayer::drawGrid() const { diff --git a/samples/glfw_opengl/common/base_scene_layer.h b/samples/glfw_opengl/common/base_scene_layer.h index 87037a0..871c025 100644 --- a/samples/glfw_opengl/common/base_scene_layer.h +++ b/samples/glfw_opengl/common/base_scene_layer.h @@ -99,6 +99,14 @@ class BaseSceneLayer : public vne::testbed::ILayer { std::vector> cameras_ortho_; vne::scene::SceneState scene_state_; vne::testbed::IDebugDraw* debug_draw_{nullptr}; + + /// Last orthographic projection pushed from `ui_settings_` in `onRender`. When unchanged, we skip + /// `setBounds` so interaction-driven frustum changes (ortho zoom) are not reset every frame. + int ortho_proj_sync_vp_w_{-1}; + int ortho_proj_sync_vp_h_{-1}; + float ortho_proj_sync_half_{0.0f}; + float ortho_proj_sync_near_{0.0f}; + float ortho_proj_sync_far_{0.0f}; }; // --------------------------------------------------------------------------- From 5db451ab137607d985486494f46d13ff521637dd Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sun, 29 Mar 2026 22:52:55 -0400 Subject: [PATCH 11/14] chore(deps): update vneinteraction and vnescene subprojects to latest commits --- deps/internal/vneinteraction | 2 +- deps/internal/vnescene | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/internal/vneinteraction b/deps/internal/vneinteraction index 48c505e..fb607b9 160000 --- a/deps/internal/vneinteraction +++ b/deps/internal/vneinteraction @@ -1 +1 @@ -Subproject commit 48c505e9f2574e19c72198683530c2495eb13d6e +Subproject commit fb607b92a3dd0e5d08e2024a61aaa17f0f65a502 diff --git a/deps/internal/vnescene b/deps/internal/vnescene index bf074df..d6600d2 160000 --- a/deps/internal/vnescene +++ b/deps/internal/vnescene @@ -1 +1 @@ -Subproject commit bf074dfea3e6d7a4da9822a46b9943a524020bb2 +Subproject commit d6600d258ab8cffdcc8cbe9159e500c5d9df8d8d From fbfc80ac71b97734c0a1c80dad73bfe90bc4de3c Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sun, 29 Mar 2026 22:58:41 -0400 Subject: [PATCH 12/14] refactor: reorder zoom method options and update descriptions in demo_test_interaction - Changed the order of zoom method options in the UI for better user experience. - Updated descriptions for each zoom method to provide clearer explanations of their functionality. --- .../03_test_interaction/demo_test_interaction.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp index 704f350..d44d3f5 100644 --- a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp +++ b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp @@ -594,15 +594,15 @@ void InteractionSettingsLayer::renderPanel() { if (show_zoom) { if (ImGui::CollapsingHeader("Zoom Method", ImGuiTreeNodeFlags_DefaultOpen)) { using ZM = vne::interaction::ZoomMethod; - const char* znames[] = {"DollyToCoi", "SceneScale", "ChangeFov"}; - const ZM zvals[] = {ZM::eDollyToCoi, ZM::eSceneScale, ZM::eChangeFov}; + const char* znames[] = {"SceneScale", "ChangeFov", "DollyToCoi"}; + const ZM zvals[] = {ZM::eSceneScale, ZM::eChangeFov, ZM::eDollyToCoi}; if (ImGui::Combo("Method##zoom", &ui.zoom_idx, znames, 3)) { il.setZoomMethod(zvals[ui.zoom_idx]); } ImGui::Spacing(); - ImGui::TextDisabled("DollyToCoi: move along ray to pivot"); - ImGui::TextDisabled("SceneScale: virtual scene scale"); - ImGui::TextDisabled("ChangeFov: widen/narrow FOV angle"); + ImGui::TextDisabled("SceneScale: XY scene scale in view (virtual zoom)"); + ImGui::TextDisabled("ChangeFov: widen/narrow FOV (perspective) or ortho extents"); + ImGui::TextDisabled("DollyToCoi: move along view ray toward pivot"); } } From 2351ff6bfb71f21cff6bba49c201c5fe1f05de8e Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sun, 29 Mar 2026 23:03:41 -0400 Subject: [PATCH 13/14] refactor: rename and update references for Ortho2D controller in interaction demo - Renamed instances of the Ortho controller to Ortho2D for consistency across the codebase. - Updated method names and comments to reflect the new controller type, ensuring clarity in interaction handling. - Adjusted UI elements and documentation to accurately describe the Ortho2D controller's requirements and functionality. --- .../glfw_opengl/03_test_interaction/README.md | 2 +- .../demo_test_interaction.cpp | 40 +++++++++---------- .../demo_test_interaction.h | 8 ++-- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/samples/glfw_opengl/03_test_interaction/README.md b/samples/glfw_opengl/03_test_interaction/README.md index 5989ac0..4e7661f 100644 --- a/samples/glfw_opengl/03_test_interaction/README.md +++ b/samples/glfw_opengl/03_test_interaction/README.md @@ -7,7 +7,7 @@ Screenshots are not included yet; they may be added in a later revision. ## What This Sample Shows 1. **Base scene**: Grid, axes, perspective or orthographic camera from `BaseSceneLayer`; settings can toggle grid/axes and switch projection. -2. **Controllers**: Runtime selection among Inspect (Euler orbit or trackball), Navigation (FPS / Fly / Game via `NavigateMode`), Ortho2D, and Follow; per-controller ImGui tuning (trackball projection when in trackball inspect mode, pivot mode, speeds, navigation multipliers, ortho/follow options). +2. **Controllers**: Runtime selection among Inspect (Euler orbit or trackball), Navigation (FPS / Fly / Game via `NavigateMode`), Ortho 2D (`Ortho2DController`), and Follow; per-controller ImGui tuning (trackball projection when in trackball inspect mode, pivot mode, speeds, navigation multipliers, ortho/follow options). 3. **Zoom**: Dolly-to-COI, scene-scale, or FOV change where applicable; matrix readouts for view and projection when enabled. 4. **Mesh browser** (with vneio): Lists mesh files under the configured directory (PLY, OBJ, STL, FBX, glTF), loads on click, drag-and-drop to the viewport, plus lighting and mesh transform panels when a mesh is loaded. 5. **Layer stack**: `BaseSceneLayer` → `InteractionTestLayer` → optional `MeshLayer` → `InteractionSettingsLayer` (ImGui settings). diff --git a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp index d44d3f5..ef8d751 100644 --- a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp +++ b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.cpp @@ -78,7 +78,7 @@ ControllerVariant makeController(ControllerKind kind, vne::interaction::Navigate c.setMode(nav_mode); return c; } - case ControllerKind::eOrtho: { + case ControllerKind::eOrtho2D: { return vne::interaction::Ortho2DController{}; } case ControllerKind::eFollow: { @@ -130,7 +130,7 @@ void InteractionTestLayer::setCamerasFromScene() { } bool InteractionTestLayer::isManipulatorCompatibleWithCamera(bool use_perspective) const { - if (current_kind_ == ControllerKind::eOrtho) { + if (current_kind_ == ControllerKind::eOrtho2D) { return !use_perspective; } return true; @@ -387,7 +387,7 @@ void InteractionTestLayer::setRotationEnabled(bool enabled) { if (insp) { insp->setRotationEnabled(enabled); } - auto* ortho = getOrthoController(0); + auto* ortho = getOrtho2DController(0); if (ortho) { ortho->setRotationEnabled(enabled); } @@ -398,7 +398,7 @@ void InteractionTestLayer::setPanEnabled(bool enabled) { if (insp) { insp->setPanEnabled(enabled); } - auto* ortho = getOrthoController(0); + auto* ortho = getOrtho2DController(0); if (ortho) { ortho->setPanEnabled(enabled); } @@ -409,7 +409,7 @@ void InteractionTestLayer::setZoomEnabled(bool enabled) { if (insp) { insp->setZoomEnabled(enabled); } - auto* ortho = getOrthoController(0); + auto* ortho = getOrtho2DController(0); if (ortho) { ortho->setZoomEnabled(enabled); } @@ -447,8 +447,8 @@ vne::interaction::Navigation3DController* InteractionTestLayer::getNavController return std::get_if(&controllers_[static_cast(index)]); } -vne::interaction::Ortho2DController* InteractionTestLayer::getOrthoController(int index) noexcept { - if (index < 0 || index >= kMaxViewports || current_kind_ != ControllerKind::eOrtho) { +vne::interaction::Ortho2DController* InteractionTestLayer::getOrtho2DController(int index) noexcept { + if (index < 0 || index >= kMaxViewports || current_kind_ != ControllerKind::eOrtho2D) { return nullptr; } return std::get_if(&controllers_[static_cast(index)]); @@ -590,7 +590,7 @@ void InteractionSettingsLayer::renderPanel() { const ControllerKind cur = il.getControllerKind(); const bool show_zoom = (cur == ControllerKind::eInspectOrbit || cur == ControllerKind::eInspectTrackball - || cur == ControllerKind::eNavigation || cur == ControllerKind::eOrtho || cur == ControllerKind::eFollow); + || cur == ControllerKind::eNavigation || cur == ControllerKind::eOrtho2D || cur == ControllerKind::eFollow); if (show_zoom) { if (ImGui::CollapsingHeader("Zoom Method", ImGuiTreeNodeFlags_DefaultOpen)) { using ZM = vne::interaction::ZoomMethod; @@ -678,7 +678,7 @@ void InteractionSettingsLayer::renderCameraSettings() { } } if (ImGui::BeginPopupModal("ManipulatorIncompatible", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::Text("Ortho controller requires Orthographic camera."); + ImGui::Text("Ortho 2D controller requires Orthographic camera."); ImGui::Text("Switch to Perspective first, or change controller to Inspect."); if (ImGui::Button("OK")) { ImGui::CloseCurrentPopup(); @@ -745,11 +745,11 @@ void InteractionSettingsLayer::renderManipulatorSettings() { const ControllerKind cur = il.getControllerKind(); if (ImGui::CollapsingHeader("Controller", ImGuiTreeNodeFlags_DefaultOpen)) { - const char* types[] = {"Inspect (Orbit)", "Inspect (Trackball)", "Navigation", "Ortho", "Follow"}; + const char* types[] = {"Inspect (Orbit)", "Inspect (Trackball)", "Navigation", "Ortho 2D", "Follow"}; const ControllerKind values[] = {ControllerKind::eInspectOrbit, ControllerKind::eInspectTrackball, ControllerKind::eNavigation, - ControllerKind::eOrtho, + ControllerKind::eOrtho2D, ControllerKind::eFollow}; int idx = 0; for (int i = 0; i < 5; ++i) { @@ -758,22 +758,22 @@ void InteractionSettingsLayer::renderManipulatorSettings() { break; } } - const bool ortho_only = (cur == ControllerKind::eOrtho); + const bool ortho_only = (cur == ControllerKind::eOrtho2D); const bool need_ortho = ortho_only && scene_layer_->uiSettings().use_perspective; if (need_ortho) { - ImGui::TextColored(ImVec4(1.f, 0.4f, 0.4f, 1.f), "Ortho requires Orthographic camera"); + ImGui::TextColored(ImVec4(1.f, 0.4f, 0.4f, 1.f), "Ortho 2D requires Orthographic camera"); } if (ImGui::Combo("Type##ctrl", &idx, types, 5)) { const ControllerKind new_kind = values[idx]; - if (new_kind == ControllerKind::eOrtho && scene_layer_->uiSettings().use_perspective) { - ImGui::OpenPopup("OrthoNeedsOrtho"); + if (new_kind == ControllerKind::eOrtho2D && scene_layer_->uiSettings().use_perspective) { + ImGui::OpenPopup("Ortho2DNeedsOrthographicCamera"); } else { il.setControllerKind(new_kind); il.setCamerasFromScene(); } } - if (ImGui::BeginPopupModal("OrthoNeedsOrtho", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::Text("Ortho works only with Orthographic camera."); + if (ImGui::BeginPopupModal("Ortho2DNeedsOrthographicCamera", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("Ortho 2D works only with Orthographic camera."); ImGui::Text("Switch camera to Orthographic first."); if (ImGui::Button("OK")) { ImGui::CloseCurrentPopup(); @@ -808,7 +808,7 @@ void InteractionSettingsLayer::renderManipulatorSettings() { case ControllerKind::eNavigation: ImGui::TextDisabled("RMB + WASD/QE move Mouse look (Fps/Fly/Game)"); break; - case ControllerKind::eOrtho: + case ControllerKind::eOrtho2D: ImGui::TextDisabled("LMB/RMB pan Scroll zoom (no rotate)"); break; case ControllerKind::eFollow: @@ -892,9 +892,9 @@ void InteractionSettingsLayer::renderManipulatorSettings() { } ImGui::TreePop(); } - } else if (auto* ortho = il.getOrthoController()) { + } else if (auto* ortho = il.getOrtho2DController()) { auto& opz = ortho->ortho2DBehavior(); - if (ImGui::TreeNodeEx("Ortho Settings", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::TreeNodeEx("Ortho 2D Settings", ImGuiTreeNodeFlags_DefaultOpen)) { bool rot_en = ortho->isRotationEnabled(); if (ImGui::Checkbox("Rotation enabled##ortho", &rot_en)) { ortho->setRotationEnabled(rot_en); diff --git a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.h b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.h index 06984c3..8ea2296 100644 --- a/samples/glfw_opengl/03_test_interaction/demo_test_interaction.h +++ b/samples/glfw_opengl/03_test_interaction/demo_test_interaction.h @@ -50,12 +50,12 @@ class BaseSceneLayer; namespace vne::samples { -/** Controller type for the interaction demo; maps to one of the four high-level controllers. */ +/** Controller type for the interaction demo; maps to one of the high-level controllers. */ enum class ControllerKind : int { eInspectOrbit = 0, eInspectTrackball, eNavigation, // Fps / Fly / Game chosen via setNavigationMode - eOrtho, + eOrtho2D, eFollow, }; @@ -89,7 +89,7 @@ class InteractionTestLayer : public vne::testbed::ILayer { void setControllerKind(ControllerKind kind); [[nodiscard]] ControllerKind getControllerKind() const noexcept { return current_kind_; } - /** @brief Check if current controller supports the given camera type. Ortho requires orthographic. */ + /** @brief Check if current controller supports the given camera type. Ortho 2D requires orthographic. */ [[nodiscard]] bool isManipulatorCompatibleWithCamera(bool use_perspective) const; /** @brief Set cameras from scene (call after scene camera type or params change). */ @@ -118,7 +118,7 @@ class InteractionTestLayer : public vne::testbed::ILayer { [[nodiscard]] vne::interaction::Inspect3DController* getInspectController(int index = 0) noexcept; [[nodiscard]] vne::interaction::Navigation3DController* getNavController(int index = 0) noexcept; - [[nodiscard]] vne::interaction::Ortho2DController* getOrthoController(int index = 0) noexcept; + [[nodiscard]] vne::interaction::Ortho2DController* getOrtho2DController(int index = 0) noexcept; [[nodiscard]] vne::interaction::FollowController* getFollowController(int index = 0) noexcept; private: From 5032bb2e45bd1a9216996708ca4d15278c3206fb Mon Sep 17 00:00:00 2001 From: ayadav-macOs Date: Sun, 29 Mar 2026 23:08:56 -0400 Subject: [PATCH 14/14] chore(deps): update vneinteraction subproject to latest commit fe614a0 --- deps/internal/vneinteraction | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/internal/vneinteraction b/deps/internal/vneinteraction index fb607b9..fe614a0 160000 --- a/deps/internal/vneinteraction +++ b/deps/internal/vneinteraction @@ -1 +1 @@ -Subproject commit fb607b92a3dd0e5d08e2024a61aaa17f0f65a502 +Subproject commit fe614a0aff5d7e3365eda556e83d49e0fda2ba61