How to do free 3d rotation around the center using mouse movement?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By gurubm

I am in space. In the point of origin, I put a model of my starship and a Node3D called CameraPivot. 100m above the origin (x = 0, y = 100, z = 0), I put a Camera3D as a child node of CameraPivot. I rotate the Camera3D by -90° around the x axis and my camera looks at my starship in the point of origin.

My goal: move the mouse to the right/left to rotate right/left. Move the mouse up/down to rotate up/down. I am not on any surface, so my up/down rotation is not clamped. Also, any new mouse movement causes a rotation relative to any previous mouse movements/rotations. Basically, I want to rotate around my spaceship in the center freely using mouse movement.

My approach:

# CameraPivot.gd
func _input(event):
    var mm = event as InputEventMouseMotion
    if mm:
        view_rotate(mm)

func view_rotate(mm : InputEventMouseMotion) -> void:
    
    # get the last mouse movement as vector in world space
    # i.e. the movement vector
    var vec_mm : Vector3 = $CameraMain.project_position(mm.relative, $CameraMain.position.y)
    
    # get the vector that points from the CameraPivot in the point of origin
    # to the camera, i.e. the y vector of the basis
    # the cross product with the movement vector is the desired rotation axis
    var vec_rot : Vector3 = basis.y.cross(vec_mm)
    
    # normalize and use the length of the vector (equal to the length of
    # the movement vector) as the amount by which to rotate
    rotate(vec_rot.normalized(), vec_rot.length() * mouse_sensitivity)

I thought this approach is straightforward enough but I don’t understand the result. Instead of rotation depending on mouse movement, the resulting rotation vector points in an almost constant direction and the rotation doesn’t even change its sign, when I move the mouse down instead of up.

I looked already on the values of the vectors using print, but it’s difficult to infer the problem of my code from there. I might want to display the resulting rotation vector to get an idea of what’s going on.

use screen drag

func _input(event):
if event is InputEventScreenDrag:
	print(event.position)
	pass

ramazan | 2022-03-19 11:12

“only available on mobile devices”

InputEventScreenDrag — Godot Engine (stable) documentation in English

gurubm | 2022-03-20 17:35

i’m having similar issues, have you found a solution?

Andrea | 2023-02-23 08:59