SimulaVR / Simula

Linux VR Desktop

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WASD movement

georgewsinger opened this issue · comments

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.