2020-01-29 17:04:04 +01:00
|
|
|
# Calculates an acceleration that repels the agent from its neighbors in the
|
2020-02-11 18:33:25 +01:00
|
|
|
# given `GSAIProximity`.
|
2020-01-29 17:04:04 +01:00
|
|
|
#
|
|
|
|
# The acceleration is an average based on all neighbors, multiplied by a
|
|
|
|
# strength decreasing by the inverse square law in relation to distance, and it
|
|
|
|
# accumulates.
|
2020-04-03 02:31:59 +02:00
|
|
|
# @category - Group behaviors
|
2020-02-11 18:33:25 +01:00
|
|
|
class_name GSAISeparation
|
|
|
|
extends GSAIGroupBehavior
|
2020-01-08 18:46:42 +01:00
|
|
|
|
2020-01-29 05:56:10 +01:00
|
|
|
# The coefficient to calculate how fast the separation strength decays with distance.
|
2023-01-13 13:09:18 +01:00
|
|
|
var decay_coefficient : float = 1.0
|
2020-01-30 19:06:35 +01:00
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
var _acceleration : GSAITargetAcceleration
|
2020-01-08 18:46:42 +01:00
|
|
|
|
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
func _init(agent : GSAISteeringAgent, proximity : GSAIProximity).(agent, proximity) -> void:
|
2020-01-10 18:15:50 +01:00
|
|
|
pass
|
2020-01-08 18:46:42 +01:00
|
|
|
|
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
func _calculate_steering(acceleration : GSAITargetAcceleration) -> void:
|
2020-01-08 18:46:42 +01:00
|
|
|
acceleration.set_zero()
|
2020-01-30 19:06:35 +01:00
|
|
|
self._acceleration = acceleration
|
2020-02-11 20:36:06 +01:00
|
|
|
# warning-ignore:return_value_discarded
|
2020-01-29 22:53:57 +01:00
|
|
|
proximity._find_neighbors(_callback)
|
2020-01-08 18:46:42 +01:00
|
|
|
|
|
|
|
|
2020-01-29 05:56:10 +01:00
|
|
|
# Callback for the proximity to call when finding neighbors. Determines the amount of
|
|
|
|
# acceleration that `neighbor` imposes based on its distance from the owner agent.
|
2020-04-03 02:31:59 +02:00
|
|
|
# @tags - virtual
|
2023-01-13 13:09:18 +01:00
|
|
|
func _report_neighbor(neighbor : GSAISteeringAgent) -> bool:
|
|
|
|
var to_agent : Vector3 = agent.position - neighbor.position
|
2020-01-08 18:46:42 +01:00
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
var distance_squared : float = to_agent.length_squared()
|
|
|
|
var acceleration_max : float = agent.linear_acceleration_max
|
2020-01-08 18:46:42 +01:00
|
|
|
|
2020-01-16 09:44:44 +01:00
|
|
|
var strength := decay_coefficient / distance_squared
|
2020-01-22 17:55:49 +01:00
|
|
|
if strength > acceleration_max:
|
|
|
|
strength = acceleration_max
|
2020-01-29 17:04:04 +01:00
|
|
|
|
2020-01-30 19:06:35 +01:00
|
|
|
_acceleration.linear += to_agent * (strength / sqrt(distance_squared))
|
2020-01-08 18:46:42 +01:00
|
|
|
|
|
|
|
return true
|