I'm trying to figure out how to make a 3D free look camera without Euler angles. I don't want to use a gimbal, and I'm getting lots of problems with smoothing and interpolation with Euler that I'm not sure I can solve easily. So I started writing code to do it fully with Quaternions. This is how far I got, it basically works except it doesn't clamp/limit on the pitch angle.
extends Camera
export(float, 0, 100) var move_speed = 50
export(float, 0, 100) var look_speed = 50
var move_scale = 0.1
var look_scale = 0.00001
func _process(delta):
var move_dir = check_buttons()
translate(move_dir * move_speed * move_scale * delta)
func _input(event):
if event is InputEventMouseMotion:
var mouse_delta = -event.relative * look_speed * look_scale
var mouse_vector_horz = Vector3(0.0, mouse_delta.x, 0.0)
var mouse_vector_vert = Vector3(mouse_delta.y, 0.0, 0.0)
var look_quat_horz = Quat(transform.basis.xform_inv(mouse_vector_horz))
var look_quat_vert = Quat(mouse_vector_vert)
transform.basis *= Basis(look_quat_horz) * Basis(look_quat_vert)
func check_buttons():
var dir = Vector3.ZERO
if Input.is_action_pressed("forward"):
dir += Vector3.FORWARD
if Input.is_action_pressed("back"):
dir += Vector3.BACK
if Input.is_action_pressed("left"):
dir += Vector3.LEFT
if Input.is_action_pressed("right"):
dir += Vector3.RIGHT
if not dir.is_equal_approx(Vector3.ZERO):
dir = dir.normalized()
return dir
So the code is small and the results look much better than Euler so far. Plus the smoothing should work better (not implemented yet but I'm pretty sure it will work fine). The problem is that I need to detect when looking 90 degrees up or down and then clamp only the pitch (the x-axis of the camera). Detection somewhat works, as you can use angle_to(), however this is just the shortest angle. So it will tell you 0 if you are looking directly down, but if you are looking down and slightly forward it will say 10, but looking down and slightly back is also 10. Additionally, I need to clamp or limit the angle to 90 degrees and I can't seem to figure that out. Anyone have ideas?