camera.lua 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. -- Copyright (c) 2012-2025 Daniele Bartolini et al.
  2. -- SPDX-License-Identifier: MIT
  3. require "core/lua/class"
  4. local wkey = false
  5. local skey = false
  6. local akey = false
  7. local dkey = false
  8. FPSCamera = class(FPSCamera)
  9. function FPSCamera:init(world, unit)
  10. self._world = world
  11. self._unit = unit
  12. self._sg = World.scene_graph(world)
  13. self._movement_speed = 20
  14. self._rotation_speed = 0.14
  15. end
  16. function FPSCamera:unit()
  17. return self._unit;
  18. end
  19. function FPSCamera:camera()
  20. return World.camera_instance(self._world, self._unit)
  21. end
  22. function FPSCamera:update(dt, dx, dy)
  23. if Keyboard.pressed(Keyboard.button_id("w")) then wkey = true end
  24. if Keyboard.pressed(Keyboard.button_id("s")) then skey = true end
  25. if Keyboard.pressed(Keyboard.button_id("a")) then akey = true end
  26. if Keyboard.pressed(Keyboard.button_id("d")) then dkey = true end
  27. if Keyboard.released(Keyboard.button_id("w")) then wkey = false end
  28. if Keyboard.released(Keyboard.button_id("s")) then skey = false end
  29. if Keyboard.released(Keyboard.button_id("a")) then akey = false end
  30. if Keyboard.released(Keyboard.button_id("d")) then dkey = false end
  31. local camera = self:camera()
  32. local tr = SceneGraph.instance(self._sg, self._unit)
  33. local camera_local_pose = SceneGraph.local_pose(self._sg, tr)
  34. local camera_right_vector = Matrix4x4.x(camera_local_pose)
  35. local camera_position = Matrix4x4.translation(camera_local_pose)
  36. local camera_rotation = Matrix4x4.rotation(camera_local_pose)
  37. local view_dir = Matrix4x4.y(camera_local_pose)
  38. -- Rotation
  39. if dx ~= 0 or dy ~= 0 then
  40. local rotation_speed = self._rotation_speed * dt
  41. local rotation_around_world_up = Quaternion(Vector3(0, 0, 1), -dx * rotation_speed)
  42. local rotation_around_camera_right = Quaternion(camera_right_vector, -dy * rotation_speed)
  43. local rotation = Quaternion.multiply(rotation_around_world_up, rotation_around_camera_right)
  44. local old_rotation = Matrix4x4.from_quaternion(camera_rotation)
  45. local delta_rotation = Matrix4x4.from_quaternion(rotation)
  46. local new_rotation = Matrix4x4.multiply(old_rotation, delta_rotation)
  47. Matrix4x4.set_translation(new_rotation, camera_position)
  48. -- Fixme
  49. SceneGraph.set_local_pose(self._sg, tr, new_rotation)
  50. end
  51. -- Translation
  52. local translation_speed = self._movement_speed * dt
  53. if wkey then camera_position = camera_position + view_dir * translation_speed end
  54. if skey then camera_position = camera_position - view_dir * translation_speed end
  55. if akey then camera_position = camera_position - camera_right_vector * translation_speed end
  56. if dkey then camera_position = camera_position + camera_right_vector * translation_speed end
  57. SceneGraph.set_local_position(self._sg, tr, camera_position)
  58. end