look_rotation.script 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. --- Creates a rotation with the specified forward and upwards directions.
  2. -- @param forward vector3 The forward direction.
  3. -- @param upwards vector3|nil The upwards direction.
  4. -- @return quat The rotation.
  5. local function quat_look_rotation(forward, upwards)
  6. -- If no upwards direction is specified, use the default (0, 1, 0)
  7. upwards = upwards or vmath.vector3(0, 1, 0)
  8. -- No zero vectors
  9. if vmath.length_sqr(forward) < 0.0000000001 or vmath.length_sqr(upwards) < 0.0000000001 then
  10. return vmath.quat()
  11. end
  12. -- Create a rotation matrix from the forward and upwards vectors
  13. local matrix = vmath.matrix4_look_at(vmath.vector3(0), forward, upwards)
  14. -- Convert the matrix to a quaternion and return it
  15. return vmath.conj(vmath.quat_matrix4(matrix))
  16. end
  17. local function next_target(self)
  18. self.target = (self.target or 0) + 1
  19. if self.target > #self.targets then
  20. self.target = 1
  21. end
  22. local target_id = self.targets[self.target]
  23. local from = go.get_position("/sword")
  24. local to = go.get_position(target_id)
  25. self.target_rotation = quat_look_rotation(to - from)
  26. end
  27. function init(self)
  28. -- Acquire input focus to receive input events
  29. msg.post(".", "acquire_input_focus")
  30. -- List of target objects
  31. self.targets = {
  32. "/target1",
  33. "/target2",
  34. "/target3"
  35. }
  36. -- Set the initial target
  37. next_target(self)
  38. end
  39. function update(self, dt)
  40. -- If a target rotation is set, smoothly rotate the sword to face the target
  41. if self.target_rotation then
  42. -- Important: we must use vmath.slerp to animate quaternions
  43. local q = vmath.slerp(0.15, go.get_rotation("/sword"), self.target_rotation)
  44. go.set_rotation(q, "/sword")
  45. end
  46. end
  47. function on_input(self, action_id, action)
  48. -- If the left mouse button (or touch) is pressed, set the next target
  49. if action_id == hash("mouse_button_left") and action.pressed then
  50. next_target(self)
  51. end
  52. end