Fixing Mouse Behavior in the Path Tracer

Welcome back to another code review! Today, we will continue our exploration of the path tracer made by a talented 15-year-old programmer using C++ and OpenGL. In our previous review, we scratched the surface of this project and found it quite exciting. In fact, it motivated me to work on Hazel’s path tracer during the holiday break. But today, we have a specific issue to address – the mouse behavior.

Currently, I noticed that the mouse isn’t locked when moved around the window. This can be quite annoying, especially when you want to keep spinning the camera but your mouse reaches the edge of the window. To fix this, we will implement a simple solution that locks the mouse to the window and provides a smooth and uninterrupted experience.

Fixing Mouse Behavior in the Path Tracer
Fixing Mouse Behavior in the Path Tracer

Fixing the Mouse Behavior

To lock the mouse to the window, we will use the glfwSetInputMode function from the GLFW library. By setting the input mode to GLFW_CURSOR_DISABLED, we can capture the mouse and allow for virtual and unlimited cursor movement, perfect for implementing smooth camera controls.

Here’s the code snippet that achieves this:

glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

Now, when we click on the viewport, the mouse will be locked to the window, allowing for continuous camera movement. But we need a way to release the mouse as well. We can do this by capturing the Escape key press event and setting the input mode back to GLFW_CURSOR_NORMAL, which releases the mouse.

Here’s the code snippet for releasing the mouse:

if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
}

Improving User Experience

To enhance the user experience, we can prevent the Escape key from closing the application. Often, users are accustomed to using the Escape key to release the mouse in first-person camera scenarios. Let’s keep that expectation consistent.

Further reading:  Deserializing Fields, Strings, and Arrays: A Comprehensive Guide

By modifying the code snippet above, we can prevent the application from closing when Escape is pressed:

if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
    if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) {
        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
    }
}

Now pressing Escape will release the mouse, but it won’t close the application.

Handling UI Interactions

One additional improvement we can make is to prevent camera movement if the mouse is hovering over the UI elements. We want the camera to move only when the mouse is not interacting with any UI element.

To achieve this, we can use the ImGui::IsWindowHovered() function from the ImGui library. By checking if the UI window is not hovered, we can determine whether to capture the mouse or not.

Here’s an example of how we can implement this:

bool isUIHovered = ImGui::IsWindowHovered();
if (isUIHovered) {
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
} else {
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}

With this code, when the mouse hovers over any UI element, the camera movement will be disabled, allowing users to interact with the UI without interference. But once the mouse moves away from the UI, the camera movement will be enabled again.

Conclusion

By implementing these changes, we have significantly improved the mouse behavior in the path tracer project. Now, users can enjoy a smooth and uninterrupted experience while navigating the 3D scene. Additionally, the UI interactions are better handled, ensuring that camera movement only occurs when the mouse is not interacting with any UI elements.

I hope you found this code review helpful and insightful. Let me know your thoughts in the comments below. As always, stay tuned for more exciting technology content from Techal!

Further reading:  Making Our Launcher Work: A Step-by-Step Guide

Image Source: Unsplash

YouTube video
Fixing Mouse Behavior in the Path Tracer