Skip to content

Commit

Permalink
Added want_to_occupy_mouse, begin_wanting_to_occupy_mouse, and end_wa…
Browse files Browse the repository at this point in the history
…nting_to_occupy_mouse to imgui_manager,

tweaked orbit_camera (I have no idea what I'm doing)
  • Loading branch information
johannesugb committed Jun 2, 2023
1 parent c75a9e5 commit 3383bb2
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 38 deletions.
25 changes: 25 additions & 0 deletions auto_vk_toolkit/include/imgui_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,29 @@ namespace avk
mUsingSemaphoreInsteadOfFenceForFontUpload = true;
}

/** Indicates whether or not ImGui wants to occupy the mouse.
* This could be because the mouse is over a window, or currently dragging
* some ImGui control.
* \return True if ImGui wants to occupy the mouse in the current frame.
*/
bool want_to_occupy_mouse() const {
return mOccupyMouse;
}

/** Indicates whether or not ImGui wants to START occupying the mouse.
* \return True if ImGui wants to occupy the mouse in the current frame, but didn't in the previous frame.
*/
bool begin_wanting_to_occupy_mouse() const {
return mOccupyMouse && !mOccupyMouseLastFrame;
}

/** Indicates whether or not ImGui ENDS its desire for occupying the mouse.
* \return True if ImGui wanted to occupy the mouse in the previous frame, but doesn't want anymore.
*/
bool end_wanting_to_occupy_mouse() const {
return !mOccupyMouse && mOccupyMouseLastFrame;
}

private:
void upload_fonts();
void construct_render_pass();
Expand All @@ -113,6 +136,8 @@ namespace avk
bool mUserInteractionEnabled;
bool mAlreadyRendered;
bool mUsingSemaphoreInsteadOfFenceForFontUpload;
bool mOccupyMouse = false;
bool mOccupyMouseLastFrame = false;
};

}
14 changes: 13 additions & 1 deletion auto_vk_toolkit/include/orbit_camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ namespace avk
// Invoked every frame to handle input and update the camera's position
void update() override;

/** Sets the pivot distance, which is the distance along the front vector
* of the camera which this camera orbits around.
* Note: The passed value might get clamped to min/max bounds.
* @param aDistanceFromCamera The desired distance along the front vector.
*/
void set_pivot_distance(float aDistanceFromCamera);

/** Gets the current pivot distance
* @return The currently used pivot distance.
*/
float pivot_distance() const;

private:
void calculate_lateral_speed();

Expand All @@ -40,7 +52,7 @@ namespace avk
float mMinPivotDistance;
float mMaxPivotDistance;
float mPivotDistanceSlowDownRange;
float mLateralSpeed;
glm::vec2 mLateralSpeed;
float mFastMultiplier;
float mSlowMultiplier;
};
Expand Down
7 changes: 7 additions & 0 deletions auto_vk_toolkit/src/imgui_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,10 @@ namespace avk
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f); // TODO: If the framebuffer has a different resolution as the window
io.DeltaTime = avk::time().delta_time();

mOccupyMouseLastFrame = mOccupyMouse;
if (mUserInteractionEnabled) {
mOccupyMouse = io.WantCaptureMouse || ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow);

// Cursor position:
static const auto input = []() -> input_buffer& { return composition_interface::current()->input(); };

Expand Down Expand Up @@ -255,6 +258,10 @@ namespace avk
io.AddInputCharacter(c);
}
}
else {
mOccupyMouse = false;
}

// start of new frame and callback invocations have to be in the update() call of the invokee,
// ... to give the updater an opportunity to clean up (callbacks themselves may cause update events)
mAlreadyRendered = false;
Expand Down
22 changes: 17 additions & 5 deletions auto_vk_toolkit/src/orbit_camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ namespace avk
look_along(-newPos);
}
if (input().mouse_button_down(RMB)) {
const auto latSpeed = mLateralSpeed * 0.1f
const auto latSpeed = mLateralSpeed
* ((input().key_down(key_code::left_shift) || input().key_down(key_code::right_shift)) ? mFastMultiplier : 1.f)
* ((input().key_down(key_code::left_control) || input().key_down(key_code::right_control)) ? mSlowMultiplier : 1.f);

const auto t
= down(*this) * static_cast<float>(deltaCursor.y) * latSpeed
+ right(*this) * static_cast<float>(deltaCursor.x) * latSpeed;
= down(*this) * static_cast<float>(deltaCursor.y) * latSpeed.x
+ right(*this) * static_cast<float>(deltaCursor.x) * latSpeed.x;
translate(*this, t);
}

Expand Down Expand Up @@ -103,10 +103,22 @@ namespace avk
}
}

void orbit_camera::set_pivot_distance(float aDistanceFromCamera) {
mPivotDistance = glm::clamp(aDistanceFromCamera, mMinPivotDistance, mMaxPivotDistance);
calculate_lateral_speed();
}

float orbit_camera::pivot_distance() const {
return mPivotDistance;
}

void orbit_camera::calculate_lateral_speed()
{
const auto* wnd = context().main_window();
auto resy = nullptr != wnd ? static_cast<float>(wnd->resolution().y) : 1000.f;
mLateralSpeed = glm::abs(mPivotDistance / projection_matrix()[1][1]) / resy;
auto resi = nullptr != wnd ? wnd->resolution() : glm::uvec2{1920, 1080};
mLateralSpeed = glm::vec2{
(mPivotDistance / (static_cast<float>(resi.x) * 2.f)) / near_plane_distance(),
(mPivotDistance / (static_cast<float>(resi.y) * 2.f)) / near_plane_distance()
};
}
}
11 changes: 3 additions & 8 deletions examples/model_loader/source/model_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,7 @@ class model_loader_app : public avk::invokee

auto imguiManager = avk::current_composition()->element_by_type<avk::imgui_manager>();
if(nullptr != imguiManager) {
imguiManager->add_callback([
this,
windowHoveredLastFrame = false
]() mutable{
imguiManager->add_callback([this, imguiManager] {
bool isEnabled = this->is_enabled();
ImGui::Begin("Info & Settings");
ImGui::SetWindowPos(ImVec2(1.0f, 1.0f), ImGuiCond_FirstUseEver);
Expand All @@ -248,14 +245,12 @@ class model_loader_app : public avk::invokee
mQuakeCam.disable();
}
}
const bool windowHoveredThisFrame = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow);
if (windowHoveredThisFrame && !windowHoveredLastFrame && mOrbitCam.is_enabled()) {
if (imguiManager->begin_wanting_to_occupy_mouse() && mOrbitCam.is_enabled()) {
mOrbitCam.disable();
}
if (windowHoveredLastFrame && !windowHoveredThisFrame && !mQuakeCam.is_enabled()) {
if (imguiManager->end_wanting_to_occupy_mouse() && !mQuakeCam.is_enabled()) {
mOrbitCam.enable();
}
windowHoveredLastFrame = windowHoveredThisFrame;
ImGui::Separator();

ImGui::DragFloat3("Scale", glm::value_ptr(mScale), 0.005f, 0.01f, 10.0f);
Expand Down
11 changes: 3 additions & 8 deletions examples/orca_loader/source/orca_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,7 @@ class orca_loader_app : public avk::invokee

auto imguiManager = avk::current_composition()->element_by_type<avk::imgui_manager>();
if(nullptr != imguiManager) {
imguiManager->add_callback([
this,
windowHoveredLastFrame = false
]() mutable {
imguiManager->add_callback([this, imguiManager] {
ImGui::Begin("Info & Settings");
ImGui::SetWindowPos(ImVec2(1.0f, 1.0f), ImGuiCond_FirstUseEver);
ImGui::Text("%.3f ms/frame", 1000.0f / ImGui::GetIO().Framerate);
Expand All @@ -459,14 +456,12 @@ class orca_loader_app : public avk::invokee
mQuakeCam.disable();
}
}
const bool windowHoveredThisFrame = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow);
if (windowHoveredThisFrame && !windowHoveredLastFrame && mOrbitCam.is_enabled()) {
if (imguiManager->begin_wanting_to_occupy_mouse() && mOrbitCam.is_enabled()) {
mOrbitCam.disable();
}
if (windowHoveredLastFrame && !windowHoveredThisFrame && !mQuakeCam.is_enabled()) {
if (imguiManager->end_wanting_to_occupy_mouse() && !mQuakeCam.is_enabled()) {
mOrbitCam.enable();
}
windowHoveredLastFrame = windowHoveredThisFrame;
ImGui::Separator();

ImGui::DragFloat3("Rotate Objects", glm::value_ptr(mRotateObjects), 0.005f, -glm::pi<float>(), glm::pi<float>());
Expand Down
12 changes: 5 additions & 7 deletions examples/skinned_meshlets/source/skinned_meshlets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ class skinned_meshlets_app : public avk::invokee

// Add the camera to the composition (and let it handle the updates)
mOrbitCam.set_translation({ 0.0f, -1.0f, 8.0f });
mOrbitCam.set_pivot_distance(8.0f);
mQuakeCam.set_translation({ 0.0f, -1.0f, 8.0f });
mOrbitCam.set_perspective_projection(glm::radians(60.0f), avk::context().main_window()->aspect_ratio(), 0.3f, 1000.0f);
mQuakeCam.set_perspective_projection(glm::radians(60.0f), avk::context().main_window()->aspect_ratio(), 0.3f, 1000.0f);
Expand All @@ -464,15 +465,14 @@ class skinned_meshlets_app : public avk::invokee
auto imguiManager = avk::current_composition()->element_by_type<avk::imgui_manager>();
if (nullptr != imguiManager) {
imguiManager->add_callback([
this,
this, imguiManager,
timestampPeriod = std::invoke([]() {
// get timestamp period from physical device, could be different for other GPUs
auto props = avk::context().physical_device().getProperties();
return static_cast<double>(props.limits.timestampPeriod);
}),
lastFrameDurationMs = 0.0,
lastDrawMeshTasksDurationMs = 0.0,
windowHoveredLastFrame = false
lastDrawMeshTasksDurationMs = 0.0
]() mutable {
ImGui::Begin("Info & Settings");
ImGui::SetWindowPos(ImVec2(1.0f, 1.0f), ImGuiCond_FirstUseEver);
Expand Down Expand Up @@ -505,14 +505,12 @@ class skinned_meshlets_app : public avk::invokee
mQuakeCam.disable();
}
}
const bool windowHoveredThisFrame = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow);
if (windowHoveredThisFrame && !windowHoveredLastFrame && mOrbitCam.is_enabled()) {
if (imguiManager->begin_wanting_to_occupy_mouse() && mOrbitCam.is_enabled()) {
mOrbitCam.disable();
}
if (windowHoveredLastFrame && !windowHoveredThisFrame && !mQuakeCam.is_enabled()) {
if (imguiManager->end_wanting_to_occupy_mouse() && !mQuakeCam.is_enabled()) {
mOrbitCam.enable();
}
windowHoveredLastFrame = windowHoveredThisFrame;
ImGui::Separator();

ImGui::Separator();
Expand Down
16 changes: 7 additions & 9 deletions examples/static_meshlets/source/static_meshlets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,9 @@ class static_meshlets_app : public avk::invokee
});

// Add the camera to the composition (and let it handle the updates)
mOrbitCam.set_translation({ 0.0f, 0.0f, 8.0f });
mQuakeCam.set_translation({ 0.0f, 0.0f, 8.0f });
mOrbitCam.set_translation({ 0.0f, 0.0f, 0.0f });
mOrbitCam.set_pivot_distance(3.0f);
mQuakeCam.set_translation({ 0.0f, 0.0f, 5.0f });
mOrbitCam.set_perspective_projection(glm::radians(45.0f), avk::context().main_window()->aspect_ratio(), 0.3f, 1000.0f);
mQuakeCam.set_perspective_projection(glm::radians(45.0f), avk::context().main_window()->aspect_ratio(), 0.3f, 1000.0f);
avk::current_composition()->add_element(mOrbitCam);
Expand All @@ -327,15 +328,14 @@ class static_meshlets_app : public avk::invokee
auto imguiManager = avk::current_composition()->element_by_type<avk::imgui_manager>();
if (nullptr != imguiManager) {
imguiManager->add_callback([
this,
this, imguiManager,
timestampPeriod = std::invoke([]() {
// get timestamp period from physical device, could be different for other GPUs
auto props = avk::context().physical_device().getProperties();
return static_cast<double>(props.limits.timestampPeriod);
}),
lastFrameDurationMs = 0.0,
lastDrawMeshTasksDurationMs = 0.0,
windowHoveredLastFrame = false
lastDrawMeshTasksDurationMs = 0.0
]() mutable {
ImGui::Begin("Info & Settings");
ImGui::SetWindowPos(ImVec2(1.0f, 1.0f), ImGuiCond_FirstUseEver);
Expand Down Expand Up @@ -368,14 +368,12 @@ class static_meshlets_app : public avk::invokee
mQuakeCam.disable();
}
}
const bool windowHoveredThisFrame = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow);
if (windowHoveredThisFrame && !windowHoveredLastFrame && mOrbitCam.is_enabled()) {
if (imguiManager->begin_wanting_to_occupy_mouse() && mOrbitCam.is_enabled()) {
mOrbitCam.disable();
}
if (windowHoveredLastFrame && !windowHoveredThisFrame && !mQuakeCam.is_enabled()) {
if (imguiManager->end_wanting_to_occupy_mouse() && !mQuakeCam.is_enabled()) {
mOrbitCam.enable();
}
windowHoveredLastFrame = windowHoveredThisFrame;
ImGui::Separator();

ImGui::Separator();
Expand Down

0 comments on commit 3383bb2

Please sign in to comment.