2019-12-19 20:04:08 +01:00
|
|
|
extends GSTSteeringBehavior
|
|
|
|
class_name GSTMatchOrientation
|
2019-12-17 05:12:18 +01:00
|
|
|
"""
|
|
|
|
Calculates an angular acceleration to match an agent's orientation to its target's.
|
|
|
|
The calculation will attempt to arrive with zero remaining angular velocity.
|
|
|
|
"""
|
2019-12-16 17:22:03 +01:00
|
|
|
|
|
|
|
|
2019-12-19 20:04:08 +01:00
|
|
|
var target: GSTAgentLocation
|
2019-12-16 17:22:03 +01:00
|
|
|
var alignment_tolerance: float
|
|
|
|
var deceleration_radius: float
|
2019-12-19 20:04:08 +01:00
|
|
|
var time_to_reach: float = 0.1
|
2019-12-16 17:22:03 +01:00
|
|
|
|
|
|
|
|
2019-12-19 20:04:08 +01:00
|
|
|
func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void:
|
2019-12-16 17:22:03 +01:00
|
|
|
self.target = target
|
|
|
|
|
|
|
|
|
2019-12-19 20:04:08 +01:00
|
|
|
func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation: float) -> GSTTargetAcceleration:
|
|
|
|
var rotation: = wrapf(desired_orientation - agent.orientation, -PI, PI)
|
2019-12-16 17:22:03 +01:00
|
|
|
|
|
|
|
var rotation_size: = -rotation if rotation < 0 else rotation
|
|
|
|
|
|
|
|
if rotation_size <= alignment_tolerance:
|
|
|
|
return acceleration.set_zero()
|
|
|
|
|
2019-12-19 20:04:08 +01:00
|
|
|
var desired_rotation: = agent.max_angular_speed
|
2019-12-16 17:22:03 +01:00
|
|
|
|
|
|
|
if rotation_size <= deceleration_radius:
|
2019-12-19 20:04:08 +01:00
|
|
|
desired_rotation *= rotation_size / deceleration_radius
|
2019-12-16 17:22:03 +01:00
|
|
|
|
2019-12-19 20:04:08 +01:00
|
|
|
desired_rotation *= rotation / rotation_size
|
2019-12-16 17:22:03 +01:00
|
|
|
|
2019-12-19 20:04:08 +01:00
|
|
|
acceleration.angular = (desired_rotation - agent.angular_velocity) / time_to_reach
|
2019-12-16 17:22:03 +01:00
|
|
|
|
|
|
|
var limited_acceleration: = -acceleration.angular if acceleration.angular < 0 else acceleration.angular
|
|
|
|
if limited_acceleration > agent.max_angular_acceleration:
|
|
|
|
acceleration.angular *= agent.max_angular_acceleration / limited_acceleration
|
|
|
|
|
|
|
|
acceleration.linear = Vector3.ZERO
|
|
|
|
|
|
|
|
return acceleration
|
|
|
|
|
|
|
|
|
2019-12-19 20:04:08 +01:00
|
|
|
func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration:
|
2019-12-16 17:22:03 +01:00
|
|
|
return _match_orientation(acceleration, target.orientation)
|