2020-01-08 18:46:42 +01:00
|
|
|
class_name GSTSeparation
|
2020-01-16 23:14:50 +01:00
|
|
|
extends GSTGroupBehavior
|
2020-01-08 18:46:42 +01:00
|
|
|
# Group behavior that produces acceleration repelling from the other neighbors that are in the
|
|
|
|
# immediate area defined by the given `GSTProximity`.
|
|
|
|
|
|
|
|
# # The produced acceleration is an average of all agents under consideration, multiplied by a
|
|
|
|
# # strength decreasing by the inverse square law in relation to distance, and accumulated.
|
|
|
|
# # In effect, all neighbors produce a single repelling force.
|
|
|
|
|
|
|
|
|
2020-01-16 09:44:44 +01:00
|
|
|
var decay_coefficient := 1.0
|
2020-01-08 18:46:42 +01:00
|
|
|
|
|
|
|
var acceleration: GSTTargetAcceleration
|
|
|
|
|
|
|
|
|
2020-01-10 18:15:50 +01:00
|
|
|
func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) -> void:
|
|
|
|
pass
|
2020-01-08 18:46:42 +01:00
|
|
|
|
|
|
|
|
|
|
|
func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration:
|
|
|
|
acceleration.set_zero()
|
|
|
|
self.acceleration = acceleration
|
2020-01-10 18:15:50 +01:00
|
|
|
proximity.find_neighbors(_callback)
|
2020-01-08 18:46:42 +01:00
|
|
|
return acceleration
|
|
|
|
|
|
|
|
|
2020-01-10 18:15:50 +01:00
|
|
|
func report_neighbor(neighbor: GSTSteeringAgent) -> bool:
|
2020-01-16 09:44:44 +01:00
|
|
|
var to_agent := agent.position - neighbor.position
|
2020-01-08 18:46:42 +01:00
|
|
|
|
2020-01-16 09:44:44 +01:00
|
|
|
var distance_squared := to_agent.length_squared()
|
|
|
|
var max_acceleration := agent.max_linear_acceleration
|
2020-01-08 18:46:42 +01:00
|
|
|
|
2020-01-16 09:44:44 +01:00
|
|
|
var strength := decay_coefficient / distance_squared
|
2020-01-08 18:46:42 +01:00
|
|
|
if strength > max_acceleration:
|
|
|
|
strength = max_acceleration
|
|
|
|
|
|
|
|
acceleration.linear += to_agent * (strength / sqrt(distance_squared))
|
|
|
|
|
|
|
|
return true
|