| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- --- Creates a rotation with the specified forward and upwards directions.
- -- @param forward vector3 The forward direction.
- -- @param upwards vector3|nil The upwards direction.
- -- @return quat The rotation.
- local function quat_look_rotation(forward, upwards)
- -- If no upwards direction is specified, use the default (0, 1, 0)
- upwards = upwards or vmath.vector3(0, 1, 0)
- -- No zero vectors
- if vmath.length_sqr(forward) < 0.0000000001 or vmath.length_sqr(upwards) < 0.0000000001 then
- return vmath.quat()
- end
- -- Create a rotation matrix from the forward and upwards vectors
- local matrix = vmath.matrix4_look_at(vmath.vector3(0), forward, upwards)
- -- Convert the matrix to a quaternion and return it
- return vmath.conj(vmath.quat_matrix4(matrix))
- end
- local function next_target(self)
- self.target = (self.target or 0) + 1
- if self.target > #self.targets then
- self.target = 1
- end
- local target_id = self.targets[self.target]
- local from = go.get_position("/sword")
- local to = go.get_position(target_id)
- self.target_rotation = quat_look_rotation(to - from)
- end
- function init(self)
- -- Acquire input focus to receive input events
- msg.post(".", "acquire_input_focus")
- -- List of target objects
- self.targets = {
- "/target1",
- "/target2",
- "/target3"
- }
- -- Set the initial target
- next_target(self)
- end
- function update(self, dt)
- -- If a target rotation is set, smoothly rotate the sword to face the target
- if self.target_rotation then
- -- Important: we must use vmath.slerp to animate quaternions
- local q = vmath.slerp(0.15, go.get_rotation("/sword"), self.target_rotation)
- go.set_rotation(q, "/sword")
- end
- end
- function on_input(self, action_id, action)
- -- If the left mouse button (or touch) is pressed, set the next target
- if action_id == hash("mouse_button_left") and action.pressed then
- next_target(self)
- end
- end
|