Skip to content

Add camera fly mode + zoom towards cursor#437

Open
tatelax wants to merge 5 commits intoguillaumechereau:masterfrom
tatelax:feature/fps-camera
Open

Add camera fly mode + zoom towards cursor#437
tatelax wants to merge 5 commits intoguillaumechereau:masterfrom
tatelax:feature/fps-camera

Conversation

@tatelax
Copy link
Copy Markdown

@tatelax tatelax commented Jul 7, 2025

This PR adds a completely new way of controlling the camera while maintaining existing camera controls.

If WASD is pressed while holding right-click, the camera enters 'fly mode' where the user is free to fly around the scene. Holding shift doubles the movement speed.

This also refactors zooming to move the camera forward in space instead of adjusting FOV. FOV can now be adjusted in Settings.

This change makes it significantly easier to position the camera in tight spaces, such as the interior of buildings.

Also, this PR adjusts zooming logic to zoom the location of the mouse cursor.

Default Controls
W = Forward
A = Left
S = Backward
D = Right
Space = Up
Left Ctrl = Down

cameracontrols.mp4

tatelax added 3 commits July 7, 2025 16:04
- Remove contaminated snap_offsets[3], snap_units[3], use_brush_size fields from goxel.h
- Remove contaminated initialization code from goxel.c
- Restore goxel_unproject() function to original signature and implementation
- Fix all function calls to use gest3d->snap_offset instead of goxel.snap_offsets
- Keep only pure FPS camera functionality (fly mode, WASD, mouse look, camera_fov)
- Project compiles successfully without errors
- Space bar now moves camera up in world space
- Left Ctrl now moves camera down in world space
- Maintains existing WASD horizontal movement
- Works with existing speed boost (Shift) and mouse look
- Same functionality as added to dev branch

Complete fly mode controls:
- Right-click + WASD: Enter fly mode with movement
- Space: Move up
- Left Ctrl: Move down
- Shift: Double movement speed
- Mouse: Look around (yaw/pitch)
- Mouse wheel: Zoom in/out
@tatelax
Copy link
Copy Markdown
Author

tatelax commented Jul 8, 2025

VS Code automatically reformatted everything without me realizing so you will need to pull the changes and reformat it to your preference before merging.

@tatelax tatelax changed the title Add FPS camera controls similar to Unity and other engines Add camera fly mode + zoom towards cursor Jul 8, 2025
@guillaumechereau
Copy link
Copy Markdown
Owner

Thanks, I just tried but it seems to be broken at the moment no? On my linux when I start goxel the camera is at the wrong position and normal movements are not working anymore.

@tatelax
Copy link
Copy Markdown
Author

tatelax commented Jul 8, 2025

Thanks, I just tried but it seems to be broken at the moment no? On my linux when I start goxel the camera is at the wrong position and normal movements are not working anymore.

Hi, can you try again? Confirmed working on macOS. Haven't tested any other platforms.

@guillaumechereau
Copy link
Copy Markdown
Owner

image
Here is what I see when I start goxel (notice the perspective distortion). The mouse navigation is also not working correctly.

@tatelax
Copy link
Copy Markdown
Author

tatelax commented Jul 8, 2025

Yes this is the expected behavior. This is because I've modified the zoom function to move the camera itself forward, instead of adjusting FOV of the camera. By default I set the FOV to 80 which is quite high and made it configurable in the settings menu.

The reason for this change is that zooming with FOV becomes very cumbersome when working on intricate objects. Such as the interior of a building.

By moving the camera itself, the user can position the camera easier. Similar to how a game engine camera works. Use right click + WASD/Shift/Spacebar to move the camera.

I know this is a large change so if you don't want to merge it that's fine but for me without all of these PR's Goxel has become very difficult to use as my game environment data becomes more complex.

@tatelax
Copy link
Copy Markdown
Author

tatelax commented Jul 8, 2025

Note: I have a fix for zooming to the cursor if there is no voxel present. If you want this PR merged I can migrate the fix from my fork.

@guillaumechereau
Copy link
Copy Markdown
Owner

I'll have to check a bit more, I don't have much time today. As far as I remember the camera is already having a fixed FOV, and 'zooming' just moves it toward the target. Or maybe I miss something? This was written a long time ago maybe I don't remember correctly.

@FelisDiligens
Copy link
Copy Markdown

Hi @guillaumechereau, @tatelax,

I'd love for this PR to be merged if possible/desired. It implements a FOV slider and fly mode, which I feel are missing from Goxel for me.
I built this PR on my Ubuntu machine and noticed a tiny issue. While in fly mode, when the cursor leaves the window's bounds, the camera behaves erratically as can be seen in this screen capture:

Bildschirmaufzeichnung.vom.2025-09-14.21-51-08.webm

The terminal prints:

glfw error 65548 (Wayland: The platform does not support setting the cursor position)

This is because the current code in the PR tries to reset the cursor to the center of the window and fails on GNOME (Wayland).
Looking at the documentation of GLFW, it says:

If you wish to implement mouse motion based camera controls or other input schemes that require unlimited mouse movement, set the cursor mode to GLFW_CURSOR_DISABLED.

I was able to fix the erratic behavior by changing line 1237 in src/goxel.c to set the input mode to GLFW_CURSOR_DISABLED instead:

-   glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
+   glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

This should make setting the cursor position in lines 1387 to 1414 redundant, as GLFW should handle it internally.
I was able to confirm it working on Ubuntu 25.04 and macOS Sequoia 15.6.1.

@guillaumechereau commented:
Here is what I see when I start goxel (notice the perspective distortion).

This could be restored to how it was before by changing these lines back to the previous values:

In src/goxel.c L564, set FOV to 20°:

    // Initialize camera settings
-   goxel.camera_fov = 80.0f; // Default FOV to 80 degrees
+   goxel.camera_fov = 20.0f; // Default FOV to 20 degrees
    goxel.zoom_speed = 1.0f;  // Default zoom speed

In src/camera.c L28, increase distance to 128:

-   cam->dist = 48;
+   cam->dist = 128;

This results in the same view as before without distortion due to the higher FOV:

Bildschirmfoto 2025-09-15 um 12 43 25

Also, the FOV preference in the settings doesn't seem to be loaded correctly right now, because the values are overwritten after the call to settings_load() in the function goxel_reset().

I hope this helps and thank you for your time.

@tatelax
Copy link
Copy Markdown
Author

tatelax commented Sep 15, 2025

@FelisDiligens If you can open a PR on my fork, I can merge it there: https://github.com/tatelax/goxelplusplus

On my fork I have several other QOL improvements. Not all of which I have opened PRs for in the original repo because it became too cumbersome as changes are interdependent upon each other.

@guillaumechereau
Copy link
Copy Markdown
Owner

I'd like to merge something like that, but currently the branch doesn't work at all for me (on ubuntu). It breaks the normal camera controls, and the WASD control don't work either. It also deformed the perspective projection.

@FelisDiligens
Copy link
Copy Markdown

@tatelax Would it be okay if I use some of your code and my proposed fixes to open a new PR here?

@guillaumechereau I'd love to fix the issues and get the WASD control, and FOV setting to work.

@guillaumechereau
Copy link
Copy Markdown
Owner

guillaumechereau commented Sep 16, 2025 via email

@tatelax
Copy link
Copy Markdown
Author

tatelax commented Sep 24, 2025

This feature is now implemented as part of Goxel++

https://github.com/tatelax/goxelplusplus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants