WASD movement
georgewsinger opened this issue · comments
George Singer commented
0cc4078 attempts to bring WASD and FPS-style camera movement into Simula. The core functions are
rotateFPSCamera :: GodotSimulaServer -> GodotInputEventMouseMotion -> IO ()
rotateFPSCamera gss event = do
camera <- getARVRCameraOrPancakeCamera gss
let mouseSensitivity = 0.1
eventRelative <- G.get_relative event
V2 eventRelativeX eventRelativeY <- fromLowLevel eventRelative
V3 rotationX rotationY rotationZ <- G.get_rotation camera >>= fromLowLevel
let newRotationY' = (rotationY - eventRelativeX) * mouseSensitivity
let newRotationX' = (rotationX - eventRelativeY) * mouseSensitivity
let newRotationY = case ((newRotationY' > 1.5708), (newRotationY' < -1.5708)) of
(True, False) -> 1.5708
(False, True) -> -1.5708
_ -> newRotationY'
let newRotationX = case ((newRotationX' > 1.5708), (newRotationX' < -1.5708)) of
(True, False) -> 1.5708
(False, True) -> -1.5708
_ -> newRotationX'
G.set_rotation camera =<< toLowLevel (V3 newRotationX' newRotationY' rotationZ)
processWASDMovement :: GodotSimulaServer -> Float -> IO ()
processWASDMovement gss delta = do
camera <- getARVRCameraOrPancakeCamera gss
input <- getSingleton GodotInput "Input"
moveForward <- toLowLevel "move_forward"
moveBackward <- toLowLevel "move_backward"
moveLeft <- toLowLevel "move_left"
moveRight <- toLowLevel "move_right"
moveUp <- toLowLevel "move_up"
moveDown <- toLowLevel "move_down"
isMoveForward <- G.is_action_pressed input moveForward
isMoveBackward <- G.is_action_pressed input moveBackward
isMoveLeft <- G.is_action_pressed input moveLeft
isMoveRight <- G.is_action_pressed input moveRight
isMoveUp <- G.is_action_pressed input moveUp
isMoveDown <- G.is_action_pressed input moveDown
let motionX = case (isMoveForward, isMoveBackward) of
(True, _) -> -1
(_, True) -> 1
_ -> 0
let motionZ = case (isMoveLeft, isMoveRight) of
(True, _) -> 1
(_, True) -> -1
_ -> 0
let motionY = case (isMoveUp, isMoveDown) of
(True, _) -> 1
(_, True) -> -1
_ -> 0
motion <- Api.godot_vector3_normalized =<< (toLowLevel $ V3 motionX motionY motionZ)
rotation@(V3 rotationX rotationY rotationZ) <- G.get_rotation camera >>= fromLowLevel
initialRotation <- readTVarIO (gss ^. gssInitialRotation)
yVector <- toLowLevel (V3 0 1 0)
xVector <- toLowLevel (V3 1 0 0)
zVector <- toLowLevel (V3 0 0 1)
motion1 <- Api.godot_vector3_rotated motion yVector (realToFrac (rotationY - initialRotation))
motion2 <- Api.godot_vector3_rotated motion1 xVector (realToFrac ((cos rotationY) * rotationX))
motion3 <- Api.godot_vector3_rotated motion2 zVector (realToFrac ((-sin rotationY) * rotationX))
(V3 motionXFinal motionYFinal motionZFinal) <- fromLowLevel motion3
translationFinal <- toLowLevel $ V3 (motionXFinal * 0.9 * delta) (motionYFinal * 0.9 * delta) (motionZFinal * 0.9 * delta)
G.set_translation camera translationFinal
Api.godot_string_destroy moveForward
Api.godot_string_destroy moveBackward
Api.godot_string_destroy moveLeft
Api.godot_string_destroy moveRight
Api.godot_string_destroy moveUp
Api.godot_string_destroy moveDown
...which are crude Haskell re-implementations of functions in godot-sponza's camera.gd.
For some reason WASD and camera movement seem to be "snapped back" each frame: https://www.youtube.com/watch?v=RtJSH0cKPXo&ab_channel=GeorgeSinger This video shows me pressing WASD keys and jerking the mouse around.