From 6276fc0413e90b60219a2f4122918a8da3b277e7 Mon Sep 17 00:00:00 2001 From: Nathan Lovato Date: Mon, 27 Jan 2020 17:31:10 -0600 Subject: [PATCH] Update code reference Proof and edit docstrings in all the base types and proximity types Remove docstring for the _init builtin callback --- project/src/Behaviors/GSTArrive.gd | 13 +- project/src/Behaviors/GSTAvoidCollisions.gd | 1 - project/src/Behaviors/GSTBlend.gd | 1 - project/src/Behaviors/GSTCohesion.gd | 1 - project/src/Behaviors/GSTEvade.gd | 1 - project/src/Behaviors/GSTFace.gd | 1 - project/src/Behaviors/GSTFlee.gd | 1 - project/src/Behaviors/GSTFollowPath.gd | 1 - project/src/Behaviors/GSTLookWhereYouGo.gd | 1 - project/src/Behaviors/GSTMatchOrientation.gd | 1 - project/src/Behaviors/GSTPriority.gd | 1 - project/src/Behaviors/GSTPursue.gd | 1 - project/src/Behaviors/GSTSeek.gd | 1 - project/src/Behaviors/GSTSeparation.gd | 1 - project/src/GSTAgentLocation.gd | 2 +- project/src/GSTGroupBehavior.gd | 8 +- project/src/GSTPath.gd | 142 +++++++----------- project/src/GSTSteeringAgent.gd | 22 +-- project/src/GSTSteeringBehavior.gd | 21 +-- project/src/GSTTargetAcceleration.gd | 13 +- project/src/GSTUtils.gd | 10 +- .../src/Proximities/GSTInfiniteProximity.gd | 9 +- project/src/Proximities/GSTProximity.gd | 3 +- 23 files changed, 114 insertions(+), 142 deletions(-) diff --git a/project/src/Behaviors/GSTArrive.gd b/project/src/Behaviors/GSTArrive.gd index 995c6f9..c150f53 100644 --- a/project/src/Behaviors/GSTArrive.gd +++ b/project/src/Behaviors/GSTArrive.gd @@ -14,7 +14,6 @@ var deceleration_radius: float var time_to_reach := 0.1 -# Initializes the behavior func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: self.target = target @@ -22,22 +21,22 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: func _arrive(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration: var to_target := target_position - agent.position var distance := to_target.length() - + if distance <= arrival_tolerance: acceleration.set_zero() else: var desired_speed := agent.linear_speed_max - + if distance <= deceleration_radius: desired_speed *= distance / deceleration_radius - + var desired_velocity := to_target * desired_speed/distance - + desired_velocity = (desired_velocity - agent.linear_velocity) * 1.0 / time_to_reach - + acceleration.linear = GSTUtils.clampedv3(desired_velocity, agent.linear_acceleration_max) acceleration.angular = 0 - + return acceleration diff --git a/project/src/Behaviors/GSTAvoidCollisions.gd b/project/src/Behaviors/GSTAvoidCollisions.gd index a03ecf3..7fa99f0 100644 --- a/project/src/Behaviors/GSTAvoidCollisions.gd +++ b/project/src/Behaviors/GSTAvoidCollisions.gd @@ -11,7 +11,6 @@ var first_relative_position: Vector3 var first_relative_velocity: Vector3 -# Intializes the behavior func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) -> void: pass diff --git a/project/src/Behaviors/GSTBlend.gd b/project/src/Behaviors/GSTBlend.gd index 9eb4eee..c26e71e 100644 --- a/project/src/Behaviors/GSTBlend.gd +++ b/project/src/Behaviors/GSTBlend.gd @@ -13,7 +13,6 @@ var _behaviors := [] var _accel := GSTTargetAcceleration.new() -# Initializes the behavior func _init(agent: GSTSteeringAgent).(agent) -> void: pass diff --git a/project/src/Behaviors/GSTCohesion.gd b/project/src/Behaviors/GSTCohesion.gd index 7c9a6a0..b3d8059 100644 --- a/project/src/Behaviors/GSTCohesion.gd +++ b/project/src/Behaviors/GSTCohesion.gd @@ -7,7 +7,6 @@ extends GSTGroupBehavior var center_of_mass: Vector3 -# Initializes the behavior func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) -> void: pass diff --git a/project/src/Behaviors/GSTEvade.gd b/project/src/Behaviors/GSTEvade.gd index c1e6769..b32e849 100644 --- a/project/src/Behaviors/GSTEvade.gd +++ b/project/src/Behaviors/GSTEvade.gd @@ -3,7 +3,6 @@ extends GSTPursue # Calculates acceleration to take an agent away from where a target agent will be. -# Initializes the behavior func _init( agent: GSTSteeringAgent, target: GSTSteeringAgent, diff --git a/project/src/Behaviors/GSTFace.gd b/project/src/Behaviors/GSTFace.gd index e7eaeb1..ab9bd61 100644 --- a/project/src/Behaviors/GSTFace.gd +++ b/project/src/Behaviors/GSTFace.gd @@ -4,7 +4,6 @@ extends GSTMatchOrientation # The acceleration will attempt to arrive with zero remaining angular velocity. -# Initializes the behavior func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent, target) -> void: pass diff --git a/project/src/Behaviors/GSTFlee.gd b/project/src/Behaviors/GSTFlee.gd index 91b10ee..35196f5 100644 --- a/project/src/Behaviors/GSTFlee.gd +++ b/project/src/Behaviors/GSTFlee.gd @@ -3,7 +3,6 @@ extends GSTSeek # Calculates acceleration to take an agent directly away from a target agent. -# Initializes the behavior func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent, target) -> void: pass diff --git a/project/src/Behaviors/GSTFollowPath.gd b/project/src/Behaviors/GSTFollowPath.gd index 529f0e0..d4cf6e6 100644 --- a/project/src/Behaviors/GSTFollowPath.gd +++ b/project/src/Behaviors/GSTFollowPath.gd @@ -15,7 +15,6 @@ var arrive_enabled := true var prediction_time := 0.0 -# Initializes the behavior func _init( agent: GSTSteeringAgent, path: GSTPath, diff --git a/project/src/Behaviors/GSTLookWhereYouGo.gd b/project/src/Behaviors/GSTLookWhereYouGo.gd index f1542c8..3057c1f 100644 --- a/project/src/Behaviors/GSTLookWhereYouGo.gd +++ b/project/src/Behaviors/GSTLookWhereYouGo.gd @@ -3,7 +3,6 @@ extends GSTMatchOrientation # Calculates an angular acceleration to match an agent's orientation to its direction of travel. -# Initializes the behavior func _init(agent: GSTSteeringAgent).(agent, null) -> void: pass diff --git a/project/src/Behaviors/GSTMatchOrientation.gd b/project/src/Behaviors/GSTMatchOrientation.gd index e240733..38405ff 100644 --- a/project/src/Behaviors/GSTMatchOrientation.gd +++ b/project/src/Behaviors/GSTMatchOrientation.gd @@ -14,7 +14,6 @@ var deceleration_radius: float var time_to_reach: float = 0.1 -# Initializes the behavior func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: self.target = target diff --git a/project/src/Behaviors/GSTPriority.gd b/project/src/Behaviors/GSTPriority.gd index 30baddf..b05bf41 100644 --- a/project/src/Behaviors/GSTPriority.gd +++ b/project/src/Behaviors/GSTPriority.gd @@ -11,7 +11,6 @@ var last_selected_index: int var zero_threshold: float -# Initializes the behavior func _init(agent: GSTSteeringAgent, zero_threshold := 0.001).(agent) -> void: self.zero_threshold = zero_threshold diff --git a/project/src/Behaviors/GSTPursue.gd b/project/src/Behaviors/GSTPursue.gd index d4a4c9e..df783fc 100644 --- a/project/src/Behaviors/GSTPursue.gd +++ b/project/src/Behaviors/GSTPursue.gd @@ -10,7 +10,6 @@ var target: GSTSteeringAgent var predict_time_max: float -# Initializes the behavior func _init( agent: GSTSteeringAgent, target: GSTSteeringAgent, diff --git a/project/src/Behaviors/GSTSeek.gd b/project/src/Behaviors/GSTSeek.gd index c2f6b49..2d0961f 100644 --- a/project/src/Behaviors/GSTSeek.gd +++ b/project/src/Behaviors/GSTSeek.gd @@ -7,7 +7,6 @@ extends GSTSteeringBehavior var target: GSTAgentLocation -# Initializes the behavior func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: self.target = target diff --git a/project/src/Behaviors/GSTSeparation.gd b/project/src/Behaviors/GSTSeparation.gd index b8861af..a6d5b17 100644 --- a/project/src/Behaviors/GSTSeparation.gd +++ b/project/src/Behaviors/GSTSeparation.gd @@ -13,7 +13,6 @@ var decay_coefficient := 1.0 var acceleration: GSTTargetAcceleration -# Initializes the behavior func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) -> void: pass diff --git a/project/src/GSTAgentLocation.gd b/project/src/GSTAgentLocation.gd index 9b2a788..881fd23 100644 --- a/project/src/GSTAgentLocation.gd +++ b/project/src/GSTAgentLocation.gd @@ -1,5 +1,5 @@ class_name GSTAgentLocation -# Data type to represent an agent with a location and an orientation only. +# Represents an agent with only a location and an orientation. # The agent's position in space. diff --git a/project/src/GSTGroupBehavior.gd b/project/src/GSTGroupBehavior.gd index 71c7efa..3d9f340 100644 --- a/project/src/GSTGroupBehavior.gd +++ b/project/src/GSTGroupBehavior.gd @@ -1,19 +1,19 @@ extends GSTSteeringBehavior class_name GSTGroupBehavior -# Extended behavior that features a Proximity group for group-based behaviors. +# Base type for group-based steering behaviors. -# The group area definition that will be used to find the owning agent's neighbors +# Container to find neighbors of the agent and apply a group behavior. var proximity: GSTProximity var _callback := funcref(self, "report_neighbor") -# Initializes the behavior func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void: self.proximity = proximity -# Internal callback for the behavior to define whether or not a member is relevant +# Internal callback for the behavior to define whether or not a member is +# relevant func report_neighbor(neighbor: GSTSteeringAgent) -> bool: return false diff --git a/project/src/GSTPath.gd b/project/src/GSTPath.gd index 8625101..bc04136 100644 --- a/project/src/GSTPath.gd +++ b/project/src/GSTPath.gd @@ -1,136 +1,110 @@ -extends Reference -class_name GSTPath -# Represents a path made up of Vector3 waypoints, split into path segments for use by path -# following behaviors. +extends Reference class_name GSTPath +# Represents a path made up of Vector3 waypoints, split into segments path +# follow behaviors can use. -# Whether the path is a loop, or has its start and end disconnected and open ended +# If `false`, the path loops. var open: bool -# The length of the full path +# Total length of the path. var length: float var _segments: Array - -var _nearest_point_on_segment: Vector3 -var _nearest_point_on_path: Vector3 +var _nearest_point_on_segment: Vector3 var _nearest_point_on_path: Vector3 -# Initializes and creates a path with the provided waypoints func _init(waypoints: Array, open := false) -> void: - self.open = open - create_path(waypoints) - _nearest_point_on_segment = waypoints[0] - _nearest_point_on_path = waypoints[0] + self.open = open create_path(waypoints) _nearest_point_on_segment = + waypoints[0] _nearest_point_on_path = waypoints[0] -# Creates a path with the provided waypoints +# Creates a path from a list of waypoints. func create_path(waypoints: Array) -> void: if not waypoints or waypoints.size() < 2: - printerr("Waypoints cannot be null and must contain at least two (2) waypoints.") - return - - _segments = [] - length = 0 - var current: Vector3 = waypoints.front() - var previous: Vector3 - + printerr("Waypoints cannot be null and must contain at least two (2) + waypoints.") return + + _segments = [] length = 0 var current: Vector3 = waypoints.front() var + previous: Vector3 + for i in range(1, waypoints.size(), 1): - previous = current - if i < waypoints.size(): - current = waypoints[i] - elif open: - break - else: - current = waypoints[0] - var segment := GSTSegment.new(previous, current) - length += segment.length - segment.cumulative_length = length + previous = current if i < waypoints.size(): + current = waypoints[i] elif open: + break else: + current = waypoints[0] var segment := GSTSegment.new(previous, + current) length += segment.length segment.cumulative_length = length _segments.append(segment) -# Returns the distance from the provided `agent_current_position` to the next point waypoint. +# Returns the distance from `agent_current_position` to the next waypoint. func calculate_distance(agent_current_position: Vector3) -> float: if _segments.size() == 0: - return 0.0 - var smallest_distance_squared: float = INF - var nearest_segment: GSTSegment - for i in range(_segments.size()): - var segment: GSTSegment = _segments[i] - var distance_squared := _calculate_point_segment_distance_squared( - segment.begin, - segment.end, - agent_current_position + return 0.0 var smallest_distance_squared: float = INF var + nearest_segment: GSTSegment for i in range(_segments.size()): + var segment: GSTSegment = _segments[i] var distance_squared := + _calculate_point_segment_distance_squared( + segment.begin, segment.end, agent_current_position ) - + if distance_squared < smallest_distance_squared: _nearest_point_on_path = _nearest_point_on_segment - smallest_distance_squared = distance_squared - nearest_segment = segment - + smallest_distance_squared = distance_squared nearest_segment = + segment + var length_on_path := ( - nearest_segment.cumulative_length - + nearest_segment.cumulative_length - _nearest_point_on_path.distance_to(nearest_segment.end)) - + return length_on_path -# Calculates the target position on the path based on the provided `target_distance` from the -# path's starting point. +# Calculates a target position from the path's starting point based on the `target_distance`. func calculate_target_position(target_distance: float) -> Vector3: if open: - target_distance = clamp(target_distance, 0, length) - else: + target_distance = clamp(target_distance, 0, length) else: if target_distance < 0: - target_distance = length + fmod(target_distance, length) - elif target_distance > length: + target_distance = length + fmod(target_distance, length) elif + target_distance > length: target_distance = fmod(target_distance, length) - - var desired_segment: GSTSegment - for i in range(_segments.size()): - var segment: GSTSegment = _segments[i] - if segment.cumulative_length >= target_distance: - desired_segment = segment - break - + + var desired_segment: GSTSegment for i in range(_segments.size()): + var segment: GSTSegment = _segments[i] if segment.cumulative_length >= + target_distance: + desired_segment = segment break + if not desired_segment: desired_segment = _segments.back() - + var distance := desired_segment.cumulative_length - target_distance - + return ( - (desired_segment.begin - desired_segment.end) * - (distance / desired_segment.length) + desired_segment.end) + (desired_segment.begin - desired_segment.end) * (distance / + desired_segment.length) + desired_segment.end) -# Returns the position of the beginning point of the path +# Returns the position of the first point on the path. func get_start_point() -> Vector3: return _segments.front().begin -# Returns the position of the last point of the path +# Returns the position of the last point on the path. func get_end_point() -> Vector3: return _segments.back().end -func _calculate_point_segment_distance_squared(start: Vector3, end: Vector3, position: Vector3) -> float: - _nearest_point_on_segment = start - var start_end := end - start - var start_end_length_squared := start_end.length_squared() - if start_end_length_squared != 0: +func _calculate_point_segment_distance_squared(start: Vector3, end: Vector3, +position: Vector3) -> float: + _nearest_point_on_segment = start var start_end := end - start var + start_end_length_squared := start_end.length_squared() if + start_end_length_squared != 0: var t = (position - start).dot(start_end) / start_end_length_squared _nearest_point_on_segment += start_end * clamp(t, 0, 1) - + return _nearest_point_on_segment.distance_squared_to(position) class GSTSegment: - var begin: Vector3 - var end: Vector3 - var length: float - var cumulative_length: float - - + var begin: Vector3 var end: Vector3 var length: float var cumulative_length: + float + func _init(begin: Vector3, end: Vector3) -> void: - self.begin = begin - self.end = end - length = begin.distance_to(end) + self.begin = begin self.end = end length = begin.distance_to(end) diff --git a/project/src/GSTSteeringAgent.gd b/project/src/GSTSteeringAgent.gd index 5944a4d..cafbdf9 100644 --- a/project/src/GSTSteeringAgent.gd +++ b/project/src/GSTSteeringAgent.gd @@ -1,24 +1,28 @@ extends GSTAgentLocation class_name GSTSteeringAgent -# An extended `GSTAgentLocation` that adds velocity, speed, and size data. It is the character's -# responsibility to keep this information up to date for the steering toolkit to work correctly. +# Adds velocity, speed, and size data to `GSTAgentLocation`. +# +# It is the character's responsibility to keep this information up to date for +# the steering toolkit to work correctly. # The amount of velocity to be considered effectively not moving. var zero_linear_speed_threshold := 0.01 -# The maximum amount of speed the agent can move at. +# The maximum speed at which the agent can move. var linear_speed_max := 0.0 -# The maximum amount of acceleration that any behavior can apply to an agent. +# The maximum amount of acceleration that any behavior can apply to the agent. var linear_acceleration_max := 0.0 -# The maximum amount of angular speed the agent can rotate at. +# The maximum amount of angular speed at which the agent can rotate. var angular_speed_max := 0.0 -# The maximum amount of angular acceleration that any behavior can apply to an agent. +# The maximum amount of angular acceleration that any behavior can apply to an +# agent. var angular_acceleration_max := 0.0 -# The current speed in a given direction the agent is traveling at. +# Current velocity of the agent. var linear_velocity := Vector3.ZERO -# The current angular speed the agent is traveling at. +# Current angular velocity of the agent. var angular_velocity := 0.0 # The radius of the sphere that approximates the agent's size in space. var bounding_radius := 0.0 -# Used internally by group behaviors and proximities to mark an agent as already considered. +# Used internally by group behaviors and proximities to mark the agent as already +# considered. var tagged := false diff --git a/project/src/GSTSteeringBehavior.gd b/project/src/GSTSteeringBehavior.gd index 91020ba..0cab174 100644 --- a/project/src/GSTSteeringBehavior.gd +++ b/project/src/GSTSteeringBehavior.gd @@ -1,24 +1,25 @@ class_name GSTSteeringBehavior -# The base class for all steering behaviors to extend. A steering behavior calculates the linear -# and/or angular acceleration to be applied to its owning agent -# -# The entry point for all behaviors is the `calculate_steering` function. Everything else is -# self-contained within the behavior. +# Base class for all steering behaviors. +# +# Steering behaviors calculate the linear and the angular acceleration to be +# to the agent that owns them. +# +# The `calculate_steering` function is the entry point for all behaviors. +# Individual steering behaviors encapsulate the steering logic. -# Whether this behavior is enabled. All disabled behaviors return zero amounts of acceleration. -# Defaults to true +# If `false`, all calculations return zero amounts of acceleration. var enabled := true -# The agent on which all steering calculations are to be made. +# The AI agent on which the steering behavior bases its calculations. var agent: GSTSteeringAgent -# Initializes the behavior func _init(agent: GSTSteeringAgent) -> void: self.agent = agent -# Returns the `acceleration` parameter modified with the behavior's desired amount of acceleration +# Returns the `acceleration` modified with the behavior's desired amount of +# acceleration. func calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: if enabled: return _calculate_steering(acceleration) diff --git a/project/src/GSTTargetAcceleration.gd b/project/src/GSTTargetAcceleration.gd index 0668f33..d976964 100644 --- a/project/src/GSTTargetAcceleration.gd +++ b/project/src/GSTTargetAcceleration.gd @@ -1,14 +1,15 @@ class_name GSTTargetAcceleration -# A desired linear and angular amount of acceleration requested by the steering system. +# A desired linear and angular amount of acceleration requested by the steering +# system. -# The linear amount of acceleration +# Linear acceleration var linear := Vector3.ZERO -# The angular amount of acceleration +# Angular acceleration var angular := 0.0 -# Sets the linear and angular components to 0 +# Sets the linear and angular components to 0. func set_zero() -> void: linear.x = 0.0 linear.y = 0.0 @@ -22,11 +23,11 @@ func add_scaled_accel(accel: GSTTargetAcceleration, scalar: float) -> void: angular += accel.angular * scalar -# Returns the squared magnitude of the linear and angular components +# Returns the squared magnitude of the linear and angular components. func get_magnitude_squared() -> float: return linear.length_squared() + angular * angular -# Returns the magnitude of the linear and angular components +# Returns the magnitude of the linear and angular components. func get_magnitude() -> float: return sqrt(get_magnitude_squared()) diff --git a/project/src/GSTUtils.gd b/project/src/GSTUtils.gd index 9f8064e..f256eaf 100644 --- a/project/src/GSTUtils.gd +++ b/project/src/GSTUtils.gd @@ -1,8 +1,8 @@ class_name GSTUtils -# Useful math and vector manipulation functions to complement Godot's own. +# Math and vector utility functions. -# Returns the provided `vector` with its length capped to `limit`. +# Returns the `vector` with its length capped to `limit`. static func clampedv3(vector: Vector3, limit: float) -> Vector3: var length_squared := vector.length_squared() var limit_squared := limit * limit @@ -11,7 +11,9 @@ static func clampedv3(vector: Vector3, limit: float) -> Vector3: return vector -# Returns the provided vector as an angle in radians. This assumes orientation for 2D -# agents or 3D agents that are upright and rotate around the Y axis. +# Returns an angle in radians between the positive X axis and the `vector`. +# +# This assumes orientation for 2D agents or 3D agents that are upright and +# rotate around the Y axis. static func vector_to_angle(vector: Vector3) -> float: return atan2(vector.x, -vector.y) diff --git a/project/src/Proximities/GSTInfiniteProximity.gd b/project/src/Proximities/GSTInfiniteProximity.gd index f873ee4..a6d3a2d 100644 --- a/project/src/Proximities/GSTInfiniteProximity.gd +++ b/project/src/Proximities/GSTInfiniteProximity.gd @@ -1,12 +1,17 @@ extends GSTProximity class_name GSTInfiniteProximity -# Determines any agent that is in the specified list as being neighbors with the owner agent. +# Determines any agent that is in the specified list as being neighbors with the +# owner agent. func _init(agent: GSTSteeringAgent, agents: Array).(agent, agents) -> void: pass +# Returns a number of neighbors based on a `callback` function. +# +# `find_neighbors` calls `callback` for each agent in the `agents` array and +# adds one to the count it if `callback` returns true. func find_neighbors(callback: FuncRef) -> int: var neighbor_count := 0 var agent_count := agents.size() @@ -16,5 +21,5 @@ func find_neighbors(callback: FuncRef) -> int: if current_agent != agent: if callback.call_func(current_agent): neighbor_count += 1 - + return neighbor_count diff --git a/project/src/Proximities/GSTProximity.gd b/project/src/Proximities/GSTProximity.gd index df40908..718af9d 100644 --- a/project/src/Proximities/GSTProximity.gd +++ b/project/src/Proximities/GSTProximity.gd @@ -1,7 +1,6 @@ extends Reference class_name GSTProximity -# Defines a way to determine any agent that is in the specified list as being neighbors with the -# owner agent. +# Base container type that stores data to find the neighbors of an agent. var agent: GSTSteeringAgent