This commit is contained in:
Anuken
2020-05-02 14:54:01 -04:00
parent b9aa8edf78
commit 3e87fff9db
42 changed files with 102 additions and 1904 deletions

View File

@@ -80,7 +80,7 @@ public class Formation{
this.motionModerator = motionModerator;
this.slotAssignments = new Array<>();
this.driftOffset = anchor.newLocation();
this.driftOffset = new VecLocation();
this.positionOffset = anchor.getPosition().cpy();
}

View File

@@ -35,7 +35,7 @@ public abstract class FormationMotionModerator{
float centerOfMassOrientation = 0;
// Make sure tempLocation is instantiated
if(tempLocation == null) tempLocation = centerOfMass.newLocation();
if(tempLocation == null) tempLocation = new VecLocation();
Vec2 centerOfMassPos = centerOfMass.getPosition();
Vec2 tempLocationPos = tempLocation.getPosition();

View File

@@ -9,7 +9,6 @@ import mindustry.ai.ai.steer.Proximity.*;
* @author davebaol
*/
public abstract class GroupBehavior extends SteeringBehavior{
/** The proximity decides which agents are considered neighbors. */
protected Proximity proximity;

View File

@@ -10,35 +10,27 @@ public interface Limiter{
* Returns the threshold below which the linear speed can be considered zero. It must be a small positive value near to zero.
* Usually it is used to avoid updating the orientation when the velocity vector has a negligible length.
*/
float getZeroLinearSpeedThreshold();
/**
* Sets the threshold below which the linear speed can be considered zero. It must be a small positive value near to zero.
* Usually it is used to avoid updating the orientation when the velocity vector has a negligible length.
*/
void setZeroLinearSpeedThreshold(float value);
default float getZeroLinearSpeedThreshold(){
return 0.001f;
}
/** Returns the maximum linear speed. */
float getMaxLinearSpeed();
/** Sets the maximum linear speed. */
void setMaxLinearSpeed(float maxLinearSpeed);
default float getMaxLinearSpeed(){
return Float.MAX_VALUE;
}
/** Returns the maximum linear acceleration. */
float getMaxLinearAcceleration();
/** Sets the maximum linear acceleration. */
void setMaxLinearAcceleration(float maxLinearAcceleration);
default float getMaxLinearAcceleration(){
return Float.MAX_VALUE;
}
/** Returns the maximum angular speed. */
float getMaxAngularSpeed();
/** Sets the maximum angular speed. */
void setMaxAngularSpeed(float maxAngularSpeed);
default float getMaxAngularSpeed(){
return Float.MAX_VALUE;
}
/** Returns the maximum angular acceleration. */
float getMaxAngularAcceleration();
/** Sets the maximum angular acceleration. */
void setMaxAngularAcceleration(float maxAngularAcceleration);
default float getMaxAngularAcceleration(){
return Float.MAX_VALUE;
}
}

View File

@@ -36,7 +36,7 @@ import mindustry.ai.ai.utils.Timepiece;
* </li>
* <li>If you want to make sure a Proximity doesn't use as a neighbor a given agent from the list, for example the evader or the
* owner itself, you have to implement a callback that prevents it from being considered by returning {@code false} from the method
* {@link ProximityCallback#reportNeighbor(Steerable) reportNeighbor}.</li>
* {@link ProximityCallback#report(Steerable) reportNeighbor}.</li>
* <li>If there is some efficient way of pruning potential neighbors before they are processed, the overall performance in time
* will improve. Spatial data structures such as multi-resolution maps, quad-trees, oct-trees, and binary space partition (BSP)
* trees can be used to get potential neighbors more efficiently. Spatial partitioning techniques are crucial when you have to
@@ -55,7 +55,7 @@ public interface Proximity{
/**
* Finds the agents that are within the immediate area of the owner. Each of those agents is passed to the
* {@link ProximityCallback#reportNeighbor(Steerable) reportNeighbor} method of the specified callback.
* {@link ProximityCallback#report(Steerable) reportNeighbor} method of the specified callback.
* @return the number of neighbors found.
*/
int findNeighbors(ProximityCallback callback);
@@ -71,7 +71,7 @@ public interface Proximity{
* @param neighbor the reported neighbor.
* @return {@code true} if the given neighbor is valid; {@code false} otherwise.
*/
boolean reportNeighbor(Steerable neighbor);
boolean report(Steerable neighbor);
}
}

View File

@@ -1,7 +1,6 @@
package mindustry.ai.ai.steer;
import arc.math.geom.*;
import mindustry.ai.ai.utils.*;
/**
* An adapter class for {@link Steerable}. You can derive from this and only override what you are interested in. For example,
@@ -10,15 +9,6 @@ import mindustry.ai.ai.utils.*;
*/
public class SteerableAdapter implements Steerable{
@Override
public float getZeroLinearSpeedThreshold(){
return 0.001f;
}
@Override
public void setZeroLinearSpeedThreshold(float value){
}
@Override
public float getMaxLinearSpeed(){
return 0;
@@ -93,19 +83,4 @@ public class SteerableAdapter implements Steerable{
public void setTagged(boolean tagged){
}
@Override
public Location newLocation(){
return null;
}
@Override
public float vectorToAngle(Vec2 vector){
return 0;
}
@Override
public Vec2 angleToVector(Vec2 outVector, float angle){
return null;
}
}

View File

@@ -15,7 +15,6 @@ import mindustry.ai.ai.steer.Proximity.*;
* @author davebaol
*/
public class Alignment extends GroupBehavior implements ProximityCallback{
private Vec2 averageVelocity;
/**
@@ -48,36 +47,9 @@ public class Alignment extends GroupBehavior implements ProximityCallback{
}
@Override
public boolean reportNeighbor(Steerable neighbor){
public boolean report(Steerable neighbor){
// Accumulate neighbor velocity
averageVelocity.add(neighbor.getLinearVelocity());
return true;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Alignment setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Alignment setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public Alignment setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -22,21 +22,17 @@ import mindustry.ai.ai.utils.*;
* @author davebaol
*/
public class Arrive extends SteeringBehavior{
/** The target to arrive to. */
protected Location target;
public Location target;
/**
* The tolerance for arriving at the target. It lets the owner get near enough to the target without letting small errors keep
* it in motion.
*/
protected float arrivalTolerance;
public float arrivalTolerance;
/** The radius for beginning to slow down */
protected float decelerationRadius;
public float decelerationRadius;
/** The time over which to achieve target speed */
protected float timeToTarget = 0.1f;
public float timeToTarget = 0.1f;
/**
* Creates an {@code Arrive} behavior for the specified owner.
@@ -89,92 +85,4 @@ public class Arrive extends SteeringBehavior{
// Output the steering
return steering;
}
/** Returns the target to arrive to. */
public Location getTarget(){
return target;
}
/**
* Sets the target to arrive to.
* @return this behavior for chaining.
*/
public Arrive setTarget(Location target){
this.target = target;
return this;
}
/**
* Returns the tolerance for arriving at the target. It lets the owner get near enough to the target without letting small
* errors keep it in motion.
*/
public float getArrivalTolerance(){
return arrivalTolerance;
}
/**
* Sets the tolerance for arriving at the target. It lets the owner get near enough to the target without letting small errors
* keep it in motion.
* @return this behavior for chaining.
*/
public Arrive setArrivalTolerance(float arrivalTolerance){
this.arrivalTolerance = arrivalTolerance;
return this;
}
/** Returns the radius for beginning to slow down. */
public float getDecelerationRadius(){
return decelerationRadius;
}
/**
* Sets the radius for beginning to slow down.
* @return this behavior for chaining.
*/
public Arrive setDecelerationRadius(float decelerationRadius){
this.decelerationRadius = decelerationRadius;
return this;
}
/** Returns the time over which to achieve target speed. */
public float getTimeToTarget(){
return timeToTarget;
}
/**
* Sets the time over which to achieve target speed.
* @return this behavior for chaining.
*/
public Arrive setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Arrive setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Arrive setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear speed and
* acceleration.
* @return this behavior for chaining.
*/
@Override
public Arrive setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -2,7 +2,6 @@ package mindustry.ai.ai.steer.behaviors;
import arc.struct.*;
import mindustry.ai.ai.steer.*;
import mindustry.ai.ai.steer.limiters.*;
/**
* This combination behavior simply sums up all the behaviors, applies their weights, and truncates the result before returning.
@@ -27,7 +26,7 @@ import mindustry.ai.ai.steer.limiters.*;
public class BlendedSteering extends SteeringBehavior{
/** The list of behaviors and their corresponding blending weights. */
protected Array<BehaviorAndWeight> list;
protected Array<BehaviorAndWeight> list = new Array<>();
private SteeringAcceleration steering;
@@ -120,33 +119,6 @@ public class BlendedSteering extends SteeringBehavior{
return blendedSteering;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public BlendedSteering setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public BlendedSteering setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear and angular
* accelerations. You can use {@link NullLimiter#NEUTRAL_LIMITER} to avoid all truncations.
* @return this behavior for chaining.
*/
@Override
public BlendedSteering setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
//
// Nested classes
//

View File

@@ -48,35 +48,9 @@ public class Cohesion extends GroupBehavior implements ProximityCallback{
}
@Override
public boolean reportNeighbor(Steerable neighbor){
public boolean report(Steerable neighbor){
// Accumulate neighbor position
centerOfMass.add(neighbor.getPosition());
return true;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Cohesion setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Cohesion setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public Cohesion setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -19,7 +19,6 @@ import mindustry.ai.ai.steer.Proximity.*;
* @author davebaol
*/
public class CollisionAvoidance extends GroupBehavior implements ProximityCallback{
private float shortestTime;
private Steerable firstNeighbor;
private float firstMinSeparation;
@@ -83,7 +82,7 @@ public class CollisionAvoidance extends GroupBehavior implements ProximityCallba
}
@Override
public boolean reportNeighbor(Steerable neighbor){
public boolean report(Steerable neighbor){
// Calculate the time to collision
relativePosition.set(neighbor.getPosition()).sub(owner.getPosition());
relativeVelocity.set(neighbor.getLinearVelocity()).sub(owner.getLinearVelocity());
@@ -117,30 +116,4 @@ public class CollisionAvoidance extends GroupBehavior implements ProximityCallba
return true;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public CollisionAvoidance setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public CollisionAvoidance setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public CollisionAvoidance setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -35,36 +35,4 @@ public class Evade extends Pursue{
return -getActualLimiter().getMaxLinearAcceleration();
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Evade setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Evade setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public Evade setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
@Override
public Evade setTarget(Steerable target){
this.target = target;
return this;
}
}

View File

@@ -46,56 +46,4 @@ public class Face extends ReachOrientation{
// Delegate to ReachOrientation
return reachOrientation(steering, orientation);
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Face setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Face setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum angular speed and
* acceleration.
* @return this behavior for chaining.
*/
@Override
public Face setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
@Override
public Face setTarget(Location target){
this.target = target;
return this;
}
@Override
public Face setAlignTolerance(float alignTolerance){
this.alignTolerance = alignTolerance;
return this;
}
@Override
public Face setDecelerationRadius(float decelerationRadius){
this.decelerationRadius = decelerationRadius;
return this;
}
@Override
public Face setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
}

View File

@@ -40,36 +40,4 @@ public class Flee extends Seek{
return steering;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Flee setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Flee setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public Flee setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
@Override
public Flee setTarget(Location target){
this.target = target;
return this;
}
}

View File

@@ -16,12 +16,10 @@ import mindustry.ai.ai.steer.*;
* @author davebaol
*/
public class FollowFlowField extends SteeringBehavior{
/** The flow field to follow. */
protected FlowField flowField;
public FlowField flowField;
/** The time in the future to predict the owner's position. Set it to 0 for non-predictive flow field following. */
protected float predictionTime;
public float predictionTime;
/**
* Creates a non-predictive {@code FollowFlowField} for the specified owner.
@@ -81,63 +79,6 @@ public class FollowFlowField extends SteeringBehavior{
return steering;
}
/** Returns the flow field of this behavior */
public FlowField getFlowField(){
return flowField;
}
/**
* Sets the flow field of this behavior
* @param flowField the flow field to set
* @return this behavior for chaining
*/
public FollowFlowField setFlowField(FlowField flowField){
this.flowField = flowField;
return this;
}
/** Returns the prediction time. */
public float getPredictionTime(){
return predictionTime;
}
/**
* Sets the prediction time. Set it to 0 for non-predictive flow field following.
* @param predictionTime the predictionTime to set
* @return this behavior for chaining.
*/
public FollowFlowField setPredictionTime(float predictionTime){
this.predictionTime = predictionTime;
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public FollowFlowField setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public FollowFlowField setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear speed and
* acceleration.
* @return this behavior for chaining.
*/
@Override
public FollowFlowField setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
/**
* A {@code FlowField} defines a mapping from a location in space to a flow vector. Typically flow fields are implemented as a
* multidimensional array representing a grid of cells. In each cell of the grid lives a flow vector.

View File

@@ -4,7 +4,6 @@ import arc.math.geom.*;
import mindustry.ai.ai.steer.*;
import mindustry.ai.ai.steer.utils.Path;
import mindustry.ai.ai.steer.utils.Path.*;
import mindustry.ai.ai.utils.*;
/**
* {@code FollowPath} behavior produces a linear acceleration that moves the agent along the given path. First it calculates the
@@ -22,21 +21,16 @@ import mindustry.ai.ai.utils.*;
* @author davebaol
*/
public class FollowPath<P extends PathParam> extends Arrive{
/** The path to follow */
protected Path<P> path;
public Path<P> path;
/** The distance along the path to generate the target. Can be negative if the owner has to move along the reverse direction. */
protected float pathOffset;
public float pathOffset;
/** The current position on the path */
protected P pathParam;
public P pathParam;
/** The flag indicating whether to use {@link Arrive} behavior to approach the end of an open path. It defaults to {@code true}. */
protected boolean arriveEnabled;
public boolean arriveEnabled;
/** The time in the future to predict the owner's position. Set it to 0 for non-predictive path following. */
protected float predictionTime;
public float predictionTime;
private Vec2 internalTargetPosition;
@@ -122,126 +116,9 @@ public class FollowPath<P extends PathParam> extends Arrive{
return steering;
}
/** Returns the path to follow */
public Path<P> getPath(){
return path;
}
/**
* Sets the path followed by this behavior.
* @param path the path to set
* @return this behavior for chaining.
*/
public FollowPath<P> setPath(Path<P> path){
this.path = path;
return this;
}
/** Returns the path offset. */
public float getPathOffset(){
return pathOffset;
}
/** Returns the flag indicating whether to use {@link Arrive} behavior to approach the end of an open path. */
public boolean isArriveEnabled(){
return arriveEnabled;
}
/** Returns the prediction time. */
public float getPredictionTime(){
return predictionTime;
}
/**
* Sets the prediction time. Set it to 0 for non-predictive path following.
* @param predictionTime the predictionTime to set
* @return this behavior for chaining.
*/
public FollowPath<P> setPredictionTime(float predictionTime){
this.predictionTime = predictionTime;
return this;
}
/**
* Sets the flag indicating whether to use {@link Arrive} behavior to approach the end of an open path. It defaults to
* {@code true}.
* @param arriveEnabled the flag value to set
* @return this behavior for chaining.
*/
public FollowPath<P> setArriveEnabled(boolean arriveEnabled){
this.arriveEnabled = arriveEnabled;
return this;
}
/**
* Sets the path offset to generate the target. Can be negative if the owner has to move along the reverse direction.
* @param pathOffset the pathOffset to set
* @return this behavior for chaining.
*/
public FollowPath<P> setPathOffset(float pathOffset){
this.pathOffset = pathOffset;
return this;
}
/** Returns the current path parameter. */
public P getPathParam(){
return pathParam;
}
/** Returns the current position of the internal target. This method is useful for debug purpose. */
public Vec2 getInternalTargetPosition(){
return internalTargetPosition;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public FollowPath<P> setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public FollowPath<P> setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear speed and
* acceleration. However the maximum linear speed is not required for a closed path.
* @return this behavior for chaining.
*/
@Override
public FollowPath<P> setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
@Override
public FollowPath<P> setTarget(Location target){
this.target = target;
return this;
}
@Override
public FollowPath<P> setArrivalTolerance(float arrivalTolerance){
this.arrivalTolerance = arrivalTolerance;
return this;
}
@Override
public FollowPath<P> setDecelerationRadius(float decelerationRadius){
this.decelerationRadius = decelerationRadius;
return this;
}
@Override
public FollowPath<P> setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
}

View File

@@ -38,12 +38,10 @@ import mindustry.ai.ai.utils.*;
* @author davebaol
*/
public class Hide extends Arrive implements ProximityCallback{
/** The proximity to find nearby obstacles. */
protected Proximity proximity;
public Proximity proximity;
/** The distance from the boundary of the obstacle behind which to hide. */
protected float distanceFromBoundary;
public float distanceFromBoundary;
private Vec2 toObstacle;
private Vec2 bestHidingSpot;
@@ -94,7 +92,7 @@ public class Hide extends Arrive implements ProximityCallback{
}
@Override
public boolean reportNeighbor(Steerable neighbor){
public boolean report(Steerable neighbor){
// Calculate the position of the hiding spot for this obstacle
Vec2 hidingSpot = getHidingPosition(neighbor.getPosition(), neighbor.getBoundingRadius(), target.getPosition());
@@ -110,36 +108,6 @@ public class Hide extends Arrive implements ProximityCallback{
return false;
}
/** Returns the proximity used to find nearby obstacles. */
public Proximity getProximity(){
return proximity;
}
/**
* Sets the proximity used to find nearby obstacles.
* @param proximity the proximity to set
* @return this behavior for chaining.
*/
public Hide setProximity(Proximity proximity){
this.proximity = proximity;
return this;
}
/** Returns the distance from the boundary of the obstacle behind which to hide. */
public float getDistanceFromBoundary(){
return distanceFromBoundary;
}
/**
* Sets the distance from the boundary of the obstacle behind which to hide.
* @param distanceFromBoundary the distance to set
* @return this behavior for chaining.
*/
public Hide setDistanceFromBoundary(float distanceFromBoundary){
this.distanceFromBoundary = distanceFromBoundary;
return this;
}
/**
* Given the position of a target and the position and radius of an obstacle, this method calculates a position
* {@code distanceFromBoundary} away from the object's bounding radius and directly opposite the target. It does this by scaling
@@ -160,50 +128,4 @@ public class Hide extends Arrive implements ProximityCallback{
return toObstacle.scl(distanceAway).add(obstaclePosition);
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Hide setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Hide setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
@Override
public Hide setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
@Override
public Hide setTarget(Location target){
this.target = target;
return this;
}
@Override
public Hide setArrivalTolerance(float arrivalTolerance){
this.arrivalTolerance = arrivalTolerance;
return this;
}
@Override
public Hide setDecelerationRadius(float decelerationRadius){
this.decelerationRadius = decelerationRadius;
return this;
}
@Override
public Hide setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
}

View File

@@ -2,7 +2,6 @@ package mindustry.ai.ai.steer.behaviors;
import arc.math.geom.*;
import mindustry.ai.ai.steer.*;
import mindustry.ai.ai.utils.*;
/**
* {@code Interpose} behavior produces a steering force that moves the owner to a point along the imaginary line connecting two
@@ -24,10 +23,9 @@ import mindustry.ai.ai.utils.*;
* @author davebaol
*/
public class Interpose extends Arrive{
protected Steerable agentA;
protected Steerable agentB;
protected float interpositionRatio;
public Steerable agentA;
public Steerable agentB;
public float interpositionRatio;
private Vec2 internalTargetPosition;
@@ -58,50 +56,6 @@ public class Interpose extends Arrive{
this.internalTargetPosition = newVector(owner);
}
/** Returns the first agent. */
public Steerable getAgentA(){
return agentA;
}
/**
* Sets the first agent.
* @return this behavior for chaining.
*/
public Interpose setAgentA(Steerable agentA){
this.agentA = agentA;
return this;
}
/** Returns the second agent. */
public Steerable getAgentB(){
return agentB;
}
/**
* Sets the second agent.
* @return this behavior for chaining.
*/
public Interpose setAgentB(Steerable agentB){
this.agentB = agentB;
return this;
}
/** Returns the interposition ratio. */
public float getInterpositionRatio(){
return interpositionRatio;
}
/**
* Sets the interposition ratio.
* @param interpositionRatio a number between 0 and 1 indicating the percentage of the distance between the 2 agents that the
* owner should reach. Especially, 0 is the position of agentA and 1 is the position of agentB.
* @return this behavior for chaining.
*/
public Interpose setInterpositionRatio(float interpositionRatio){
this.interpositionRatio = interpositionRatio;
return this;
}
@Override
protected SteeringAcceleration calculateRealSteering(SteeringAcceleration steering){
// First we need to figure out where the two agents are going to be at
@@ -132,51 +86,4 @@ public class Interpose extends Arrive{
public Vec2 getInternalTargetPosition(){
return internalTargetPosition;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Interpose setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Interpose setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
@Override
public Interpose setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
@Override
public Interpose setTarget(Location target){
this.target = target;
return this;
}
@Override
public Interpose setArrivalTolerance(float arrivalTolerance){
this.arrivalTolerance = arrivalTolerance;
return this;
}
@Override
public Interpose setDecelerationRadius(float decelerationRadius){
this.decelerationRadius = decelerationRadius;
return this;
}
@Override
public Interpose setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
}

View File

@@ -233,55 +233,6 @@ public class Jump extends MatchVelocity{
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Jump setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Jump setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration and
* speed.
* @return this behavior for chaining.
*/
@Override
public Jump setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
/**
* Sets the target whose velocity should be matched. Notice that this method is inherited from {@link MatchVelocity}. Usually
* with {@code Jump} you should never call it because a specialized internal target has already been created implicitly.
* @param target the target to set
* @return this behavior for chaining.
*/
@Override
public Jump setTarget(Steerable target){
this.target = target;
return this;
}
@Override
public Jump setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
//
// Nested classes and interfaces
//
private static class JumpTarget extends SteerableAdapter{
Vec2 position;

View File

@@ -1,7 +1,6 @@
package mindustry.ai.ai.steer.behaviors;
import mindustry.ai.ai.steer.*;
import mindustry.ai.ai.utils.*;
/**
* The entire steering framework assumes that the direction a character is facing does not have to be its direction of motion. In
@@ -40,60 +39,4 @@ public class LookWhereYouAreGoing extends ReachOrientation{
return reachOrientation(steering, orientation);
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public LookWhereYouAreGoing setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public LookWhereYouAreGoing setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum angular speed and
* acceleration.
* @return this behavior for chaining.
*/
@Override
public LookWhereYouAreGoing setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
/**
* Sets the target to align to. Notice that this method is inherited from {@link ReachOrientation}, but is completely useless
* for {@code LookWhereYouAreGoing} because the target orientation is determined by the velocity of the owner itself.
* @return this behavior for chaining.
*/
@Override
public LookWhereYouAreGoing setTarget(Location target){
this.target = target;
return this;
}
@Override
public LookWhereYouAreGoing setAlignTolerance(float alignTolerance){
this.alignTolerance = alignTolerance;
return this;
}
@Override
public LookWhereYouAreGoing setDecelerationRadius(float decelerationRadius){
this.decelerationRadius = decelerationRadius;
return this;
}
@Override
public LookWhereYouAreGoing setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
}

View File

@@ -8,12 +8,10 @@ import mindustry.ai.ai.steer.*;
* @author davebaol
*/
public class MatchVelocity extends SteeringBehavior{
/** The target of this behavior */
protected Steerable target;
public Steerable target;
/** The time over which to achieve target speed */
protected float timeToTarget;
public float timeToTarget;
/**
* Creates a {@code MatchVelocity} behavior for the given owner. No target is set. The maxLinearAcceleration is set to 100. The
@@ -57,61 +55,4 @@ public class MatchVelocity extends SteeringBehavior{
// Output steering acceleration
return steering;
}
/** Returns the target whose velocity should be matched. */
public Steerable getTarget(){
return target;
}
/**
* Sets the target whose velocity should be matched.
* @param target the target to set
* @return this behavior for chaining.
*/
public MatchVelocity setTarget(Steerable target){
this.target = target;
return this;
}
/** Returns the time over which to achieve target speed. */
public float getTimeToTarget(){
return timeToTarget;
}
/**
* Sets the time over which to achieve target speed.
* @param timeToTarget the time to set
* @return this behavior for chaining.
*/
public MatchVelocity setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public MatchVelocity setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public MatchVelocity setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public MatchVelocity setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -39,18 +39,15 @@ import mindustry.ai.ai.steer.*;
* @author davebaol
*/
public class PrioritySteering extends SteeringBehavior{
/** The threshold of the steering acceleration magnitude below which a steering behavior is considered to have given no output. */
protected float epsilon;
public float epsilon;
/**
* The list of steering behaviors in priority order. The first item in the list is tried first, the subsequent entries are only
* considered if the first one does not return a result.
*/
protected Array<SteeringBehavior> behaviors = new Array<>();
public Array<SteeringBehavior> behaviors = new Array<>();
/** The index of the behavior whose acceleration has been returned by the last evaluation of this priority steering. */
protected int selectedBehaviorIndex;
public int selectedBehaviorIndex;
/**
* Creates a {@code PrioritySteering} behavior for the specified owner. The threshold is set to 0.001.
@@ -107,57 +104,4 @@ public class PrioritySteering extends SteeringBehavior{
return n > 0 ? steering : steering.setZero();
}
/**
* Returns the index of the behavior whose acceleration has been returned by the last evaluation of this priority steering; -1
* otherwise.
*/
public int getSelectedBehaviorIndex(){
return selectedBehaviorIndex;
}
/**
* Returns the threshold of the steering acceleration magnitude below which a steering behavior is considered to have given no
* output.
*/
public float getEpsilon(){
return epsilon;
}
/**
* Sets the threshold of the steering acceleration magnitude below which a steering behavior is considered to have given no
* output.
* @param epsilon the epsilon to set
* @return this behavior for chaining.
*/
public PrioritySteering setEpsilon(float epsilon){
this.epsilon = epsilon;
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public PrioritySteering setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public PrioritySteering setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. However, {@code PrioritySteering} needs no limiter at all as it simply returns
* the first non zero steering acceleration.
* @return this behavior for chaining.
*/
@Override
public PrioritySteering setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -20,12 +20,10 @@ import mindustry.ai.ai.steer.*;
* @author davebaol
*/
public class Pursue extends SteeringBehavior{
/** The target */
protected Steerable target;
public Steerable target;
/** The maximum prediction time */
protected float maxPredictionTime;
public float maxPredictionTime;
/**
* Creates a {@code Pursue} behavior for the specified owner and target. Maximum prediction time defaults to 1 second.
@@ -87,58 +85,4 @@ public class Pursue extends SteeringBehavior{
return steering;
}
/** Returns the target. */
public Steerable getTarget(){
return target;
}
/**
* Sets the target.
* @return this behavior for chaining.
*/
public Pursue setTarget(Steerable target){
this.target = target;
return this;
}
/** Returns the maximum prediction time. */
public float getMaxPredictionTime(){
return maxPredictionTime;
}
/**
* Sets the maximum prediction time.
* @return this behavior for chaining.
*/
public Pursue setMaxPredictionTime(float maxPredictionTime){
this.maxPredictionTime = maxPredictionTime;
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Pursue setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Pursue setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public Pursue setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -48,15 +48,12 @@ import mindustry.ai.ai.utils.*;
* @author davebaol
*/
public class RaycastObstacleAvoidance extends SteeringBehavior{
/** The inputRay configuration */
protected RayConfiguration rayConfiguration;
public RayConfiguration rayConfiguration;
/** The collision detector */
protected RaycastCollisionDetector raycastCollisionDetector;
public RaycastCollisionDetector raycastCollisionDetector;
/** The minimum distance to a wall, i.e. how far to avoid collision. */
protected float distanceFromBoundary;
public float distanceFromBoundary;
private Collision outputCollision;
private Collision minOutputCollision;
@@ -147,75 +144,4 @@ public class RaycastObstacleAvoidance extends SteeringBehavior{
return steering;
}
/** Returns the ray configuration of this behavior. */
public RayConfiguration getRayConfiguration(){
return rayConfiguration;
}
/**
* Sets the ray configuration of this behavior.
* @param rayConfiguration the ray configuration to set
* @return this behavior for chaining.
*/
public RaycastObstacleAvoidance setRayConfiguration(RayConfiguration rayConfiguration){
this.rayConfiguration = rayConfiguration;
return this;
}
/** Returns the raycast collision detector of this behavior. */
public RaycastCollisionDetector getRaycastCollisionDetector(){
return raycastCollisionDetector;
}
/**
* Sets the raycast collision detector of this behavior.
* @param raycastCollisionDetector the raycast collision detector to set
* @return this behavior for chaining.
*/
public RaycastObstacleAvoidance setRaycastCollisionDetector(RaycastCollisionDetector raycastCollisionDetector){
this.raycastCollisionDetector = raycastCollisionDetector;
return this;
}
/** Returns the distance from boundary, i.e. the minimum distance to an obstacle. */
public float getDistanceFromBoundary(){
return distanceFromBoundary;
}
/**
* Sets the distance from boundary, i.e. the minimum distance to an obstacle.
* @param distanceFromBoundary the distanceFromBoundary to set
* @return this behavior for chaining.
*/
public RaycastObstacleAvoidance setDistanceFromBoundary(float distanceFromBoundary){
this.distanceFromBoundary = distanceFromBoundary;
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public RaycastObstacleAvoidance setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public RaycastObstacleAvoidance setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public RaycastObstacleAvoidance setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -17,18 +17,14 @@ import mindustry.ai.ai.utils.*;
* @author davebaol
*/
public class ReachOrientation extends SteeringBehavior{
/** The target to align to. */
protected Location target;
public Location target;
/** The tolerance for aligning to the target without letting small errors keep the owner swinging. */
protected float alignTolerance;
public float alignTolerance;
/** The radius for beginning to slow down */
protected float decelerationRadius;
public float decelerationRadius;
/** The time over which to achieve target rotation speed */
protected float timeToTarget = 0.1f;
public float timeToTarget = 0.1f;
/**
* Creates a {@code ReachOrientation} behavior for the specified owner.
@@ -97,87 +93,4 @@ public class ReachOrientation extends SteeringBehavior{
return steering;
}
/** Returns the target to align to. */
public Location getTarget(){
return target;
}
/**
* Sets the target to align to.
* @return this behavior for chaining.
*/
public ReachOrientation setTarget(Location target){
this.target = target;
return this;
}
/** Returns the tolerance for aligning to the target without letting small errors keep the owner swinging. */
public float getAlignTolerance(){
return alignTolerance;
}
/**
* Sets the tolerance for aligning to the target without letting small errors keep the owner swinging.
* @return this behavior for chaining.
*/
public ReachOrientation setAlignTolerance(float alignTolerance){
this.alignTolerance = alignTolerance;
return this;
}
/** Returns the radius for beginning to slow down */
public float getDecelerationRadius(){
return decelerationRadius;
}
/**
* Sets the radius for beginning to slow down
* @return this behavior for chaining.
*/
public ReachOrientation setDecelerationRadius(float decelerationRadius){
this.decelerationRadius = decelerationRadius;
return this;
}
/** Returns the time over which to achieve target rotation speed */
public float getTimeToTarget(){
return timeToTarget;
}
/**
* Sets the time over which to achieve target rotation speed
* @return this behavior for chaining.
*/
public ReachOrientation setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public ReachOrientation setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public ReachOrientation setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum angular speed and
* acceleration.
* @return this behavior for chaining.
*/
@Override
public ReachOrientation setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -9,9 +9,8 @@ import mindustry.ai.ai.utils.*;
* @author davebaol
*/
public class Seek extends SteeringBehavior{
/** The target to seek */
protected Location target;
public Location target;
/**
* Creates a {@code Seek} behavior for the specified owner.
@@ -43,45 +42,4 @@ public class Seek extends SteeringBehavior{
// Output steering acceleration
return steering;
}
/** Returns the target to seek. */
public Location getTarget(){
return target;
}
/**
* Sets the target to seek.
* @return this behavior for chaining.
*/
public Seek setTarget(Location target){
this.target = target;
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Seek setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Seek setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public Seek setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -12,12 +12,11 @@ import mindustry.ai.ai.steer.Proximity.*;
* @author davebaol
*/
public class Separation extends GroupBehavior implements ProximityCallback{
/**
* The constant coefficient of decay for the inverse square law force. It controls how fast the separation strength decays with
* distance.
*/
float decayCoefficient = 1f;
public float decayCoefficient = 1f;
private Vec2 toAgent;
private Vec2 linear;
@@ -45,7 +44,7 @@ public class Separation extends GroupBehavior implements ProximityCallback{
}
@Override
public boolean reportNeighbor(Steerable neighbor){
public boolean report(Steerable neighbor){
toAgent.set(owner.getPosition()).sub(neighbor.getPosition());
float distanceSqr = toAgent.len2();
@@ -55,7 +54,7 @@ public class Separation extends GroupBehavior implements ProximityCallback{
float maxAcceleration = getActualLimiter().getMaxLinearAcceleration();
// Calculate the strength of repulsion through inverse square law decay
float strength = getDecayCoefficient() / distanceSqr;
float strength = decayCoefficient / distanceSqr;
if(strength > maxAcceleration) strength = maxAcceleration;
// Add the acceleration
@@ -64,45 +63,4 @@ public class Separation extends GroupBehavior implements ProximityCallback{
return true;
}
/** Returns the coefficient of decay for the inverse square law force. */
public float getDecayCoefficient(){
return decayCoefficient;
}
/**
* Sets the coefficient of decay for the inverse square law force. It controls how fast the separation strength decays with
* distance.
* @param decayCoefficient the coefficient of decay to set
*/
public Separation setDecayCoefficient(float decayCoefficient){
this.decayCoefficient = decayCoefficient;
return this;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Separation setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Separation setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration.
* @return this behavior for chaining.
*/
@Override
public Separation setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
}

View File

@@ -4,7 +4,6 @@ import arc.math.*;
import arc.math.geom.*;
import mindustry.ai.ai.steer.*;
import mindustry.ai.ai.utils.*;
import mindustry.ai.ai.utils.Timepiece;
/**
* {@code Wander} behavior is designed to produce a steering acceleration that will give the impression of a random walk through
@@ -42,27 +41,21 @@ import mindustry.ai.ai.utils.Timepiece;
* @author davebaol
*/
public class Wander extends Face{
/** The forward offset of the wander circle */
protected float wanderOffset;
public float wanderOffset;
/** The radius of the wander circle */
protected float wanderRadius;
public float wanderRadius;
/** The rate, expressed in radian per second, at which the wander orientation can change */
protected float wanderRate;
public float wanderRate;
/** The last time the orientation of the wander target has been updated */
protected float lastTime;
public float lastTime;
/** The current orientation of the wander target */
protected float wanderOrientation;
public float wanderOrientation;
/**
* The flag indicating whether to use {@link Face} behavior or not. This should be set to {@code true} when independent facing
* is used.
*/
protected boolean faceEnabled;
public boolean faceEnabled;
private Vec2 internalTargetPosition;
private Vec2 wanderCenter;
@@ -118,142 +111,4 @@ public class Wander extends Face{
return steering;
}
/** Returns the forward offset of the wander circle. */
public float getWanderOffset(){
return wanderOffset;
}
/**
* Sets the forward offset of the wander circle.
* @return this behavior for chaining.
*/
public Wander setWanderOffset(float wanderOffset){
this.wanderOffset = wanderOffset;
return this;
}
/** Returns the radius of the wander circle. */
public float getWanderRadius(){
return wanderRadius;
}
/**
* Sets the radius of the wander circle.
* @return this behavior for chaining.
*/
public Wander setWanderRadius(float wanderRadius){
this.wanderRadius = wanderRadius;
return this;
}
/** Returns the rate, expressed in radian per second, at which the wander orientation can change. */
public float getWanderRate(){
return wanderRate;
}
/**
* Sets the rate, expressed in radian per second, at which the wander orientation can change.
* @return this behavior for chaining.
*/
public Wander setWanderRate(float wanderRate){
this.wanderRate = wanderRate;
return this;
}
/** Returns the current orientation of the wander target. */
public float getWanderOrientation(){
return wanderOrientation;
}
/**
* Sets the current orientation of the wander target.
* @return this behavior for chaining.
*/
public Wander setWanderOrientation(float wanderOrientation){
this.wanderOrientation = wanderOrientation;
return this;
}
/** Returns the flag indicating whether to use {@link Face} behavior or not. */
public boolean isFaceEnabled(){
return faceEnabled;
}
/**
* Sets the flag indicating whether to use {@link Face} behavior or not. This should be set to {@code true} when independent
* facing is used.
* @return this behavior for chaining.
*/
public Wander setFaceEnabled(boolean faceEnabled){
this.faceEnabled = faceEnabled;
return this;
}
/** Returns the current position of the wander target. This method is useful for debug purpose. */
public Vec2 getInternalTargetPosition(){
return internalTargetPosition;
}
/** Returns the current center of the wander circle. This method is useful for debug purpose. */
public Vec2 getWanderCenter(){
return wanderCenter;
}
//
// Setters overridden in order to fix the correct return type for chaining
//
@Override
public Wander setOwner(Steerable owner){
this.owner = owner;
return this;
}
@Override
public Wander setEnabled(boolean enabled){
this.enabled = enabled;
return this;
}
/**
* Sets the limiter of this steering behavior. The given limiter must at least take care of the maximum linear acceleration;
* additionally, if the flag {@code faceEnabled} is true, it must take care of the maximum angular speed and acceleration.
* @return this behavior for chaining.
*/
@Override
public Wander setLimiter(Limiter limiter){
this.limiter = limiter;
return this;
}
/**
* Sets the target to align to. Notice that this method is inherited from {@link ReachOrientation}, but is completely useless
* for {@code Wander} because owner's orientation is determined by the internal target, which is moving on the wander circle.
* @return this behavior for chaining.
*/
@Override
public Wander setTarget(Location target){
this.target = target;
return this;
}
@Override
public Wander setAlignTolerance(float alignTolerance){
this.alignTolerance = alignTolerance;
return this;
}
@Override
public Wander setDecelerationRadius(float decelerationRadius){
this.decelerationRadius = decelerationRadius;
return this;
}
@Override
public Wander setTimeToTarget(float timeToTarget){
this.timeToTarget = timeToTarget;
return this;
}
}

View File

@@ -1,32 +0,0 @@
package mindustry.ai.ai.steer.limiters;
/**
* An {@code AngularAccelerationLimiter} provides the maximum magnitude of angular acceleration. All other methods throw an
* {@link UnsupportedOperationException}.
* @author davebaol
*/
public class AngularAccelerationLimiter extends NullLimiter{
private float maxAngularAcceleration;
/**
* Creates an {@code AngularAccelerationLimiter}.
* @param maxAngularAcceleration the maximum angular acceleration
*/
public AngularAccelerationLimiter(float maxAngularAcceleration){
this.maxAngularAcceleration = maxAngularAcceleration;
}
/** Returns the maximum angular acceleration. */
@Override
public float getMaxAngularAcceleration(){
return maxAngularAcceleration;
}
/** Sets the maximum angular acceleration. */
@Override
public void setMaxAngularAcceleration(float maxAngularAcceleration){
this.maxAngularAcceleration = maxAngularAcceleration;
}
}

View File

@@ -1,47 +0,0 @@
package mindustry.ai.ai.steer.limiters;
/**
* An {@code AngularLimiter} provides the maximum magnitudes of angular speed and angular acceleration. Linear methods throw an
* {@link UnsupportedOperationException}.
* @author davebaol
*/
public class AngularLimiter extends NullLimiter{
private float maxAngularAcceleration;
private float maxAngularSpeed;
/**
* Creates an {@code AngularLimiter}.
* @param maxAngularAcceleration the maximum angular acceleration
* @param maxAngularSpeed the maximum angular speed
*/
public AngularLimiter(float maxAngularAcceleration, float maxAngularSpeed){
this.maxAngularAcceleration = maxAngularAcceleration;
this.maxAngularSpeed = maxAngularSpeed;
}
/** Returns the maximum angular speed. */
@Override
public float getMaxAngularSpeed(){
return maxAngularSpeed;
}
/** Sets the maximum angular speed. */
@Override
public void setMaxAngularSpeed(float maxAngularSpeed){
this.maxAngularSpeed = maxAngularSpeed;
}
/** Returns the maximum angular acceleration. */
@Override
public float getMaxAngularAcceleration(){
return maxAngularAcceleration;
}
/** Sets the maximum angular acceleration. */
@Override
public void setMaxAngularAcceleration(float maxAngularAcceleration){
this.maxAngularAcceleration = maxAngularAcceleration;
}
}

View File

@@ -1,32 +0,0 @@
package mindustry.ai.ai.steer.limiters;
/**
* An {@code AngularSpeedLimiter} provides the maximum magnitudes of angular speed. All other methods throw an
* {@link UnsupportedOperationException}.
* @author davebaol
*/
public class AngularSpeedLimiter extends NullLimiter{
private float maxAngularSpeed;
/**
* Creates an {@code AngularSpeedLimiter}.
* @param maxAngularSpeed the maximum angular speed
*/
public AngularSpeedLimiter(float maxAngularSpeed){
this.maxAngularSpeed = maxAngularSpeed;
}
/** Returns the maximum angular speed. */
@Override
public float getMaxAngularSpeed(){
return maxAngularSpeed;
}
/** Sets the maximum angular speed. */
@Override
public void setMaxAngularSpeed(float maxAngularSpeed){
this.maxAngularSpeed = maxAngularSpeed;
}
}

View File

@@ -1,80 +0,0 @@
package mindustry.ai.ai.steer.limiters;
import mindustry.ai.ai.steer.*;
/**
* A {@code FullLimiter} provides the maximum magnitudes of speed and acceleration for both linear and angular components.
* @author davebaol
*/
public class FullLimiter implements Limiter{
private float maxLinearAcceleration;
private float maxLinearSpeed;
private float maxAngularAcceleration;
private float maxAngularSpeed;
private float zeroLinearSpeedThreshold;
/**
* Creates a {@code FullLimiter}.
* @param maxLinearAcceleration the maximum linear acceleration
* @param maxLinearSpeed the maximum linear speed
* @param maxAngularAcceleration the maximum angular acceleration
* @param maxAngularSpeed the maximum angular speed
*/
public FullLimiter(float maxLinearAcceleration, float maxLinearSpeed, float maxAngularAcceleration, float maxAngularSpeed){
this.maxLinearAcceleration = maxLinearAcceleration;
this.maxLinearSpeed = maxLinearSpeed;
this.maxAngularAcceleration = maxAngularAcceleration;
this.maxAngularSpeed = maxAngularSpeed;
}
@Override
public float getMaxLinearSpeed(){
return maxLinearSpeed;
}
@Override
public void setMaxLinearSpeed(float maxLinearSpeed){
this.maxLinearSpeed = maxLinearSpeed;
}
@Override
public float getMaxLinearAcceleration(){
return maxLinearAcceleration;
}
@Override
public void setMaxLinearAcceleration(float maxLinearAcceleration){
this.maxLinearAcceleration = maxLinearAcceleration;
}
@Override
public float getMaxAngularSpeed(){
return maxAngularSpeed;
}
@Override
public void setMaxAngularSpeed(float maxAngularSpeed){
this.maxAngularSpeed = maxAngularSpeed;
}
@Override
public float getMaxAngularAcceleration(){
return maxAngularAcceleration;
}
@Override
public void setMaxAngularAcceleration(float maxAngularAcceleration){
this.maxAngularAcceleration = maxAngularAcceleration;
}
@Override
public float getZeroLinearSpeedThreshold(){
return zeroLinearSpeedThreshold;
}
@Override
public void setZeroLinearSpeedThreshold(float zeroLinearSpeedThreshold){
this.zeroLinearSpeedThreshold = zeroLinearSpeedThreshold;
}
}

View File

@@ -1,32 +0,0 @@
package mindustry.ai.ai.steer.limiters;
/**
* A {@code LinearAccelerationLimiter} provides the maximum magnitude of linear acceleration. All other methods throw an
* {@link UnsupportedOperationException}.
* @author davebaol
*/
public class LinearAccelerationLimiter extends NullLimiter{
private float maxLinearAcceleration;
/**
* Creates a {@code LinearAccelerationLimiter}.
* @param maxLinearAcceleration the maximum linear acceleration
*/
public LinearAccelerationLimiter(float maxLinearAcceleration){
this.maxLinearAcceleration = maxLinearAcceleration;
}
/** Returns the maximum linear acceleration. */
@Override
public float getMaxLinearAcceleration(){
return maxLinearAcceleration;
}
/** Sets the maximum linear acceleration. */
@Override
public void setMaxLinearAcceleration(float maxLinearAcceleration){
this.maxLinearAcceleration = maxLinearAcceleration;
}
}

View File

@@ -1,47 +0,0 @@
package mindustry.ai.ai.steer.limiters;
/**
* A {@code LinearLimiter} provides the maximum magnitudes of linear speed and linear acceleration. Angular methods throw an
* {@link UnsupportedOperationException}.
* @author davebaol
*/
public class LinearLimiter extends NullLimiter{
private float maxLinearAcceleration;
private float maxLinearSpeed;
/**
* Creates a {@code LinearLimiter}.
* @param maxLinearAcceleration the maximum linear acceleration
* @param maxLinearSpeed the maximum linear speed
*/
public LinearLimiter(float maxLinearAcceleration, float maxLinearSpeed){
this.maxLinearAcceleration = maxLinearAcceleration;
this.maxLinearSpeed = maxLinearSpeed;
}
/** Returns the maximum linear speed. */
@Override
public float getMaxLinearSpeed(){
return maxLinearSpeed;
}
/** Sets the maximum linear speed. */
@Override
public void setMaxLinearSpeed(float maxLinearSpeed){
this.maxLinearSpeed = maxLinearSpeed;
}
/** Returns the maximum linear acceleration. */
@Override
public float getMaxLinearAcceleration(){
return maxLinearAcceleration;
}
/** Sets the maximum linear acceleration. */
@Override
public void setMaxLinearAcceleration(float maxLinearAcceleration){
this.maxLinearAcceleration = maxLinearAcceleration;
}
}

View File

@@ -1,32 +0,0 @@
package mindustry.ai.ai.steer.limiters;
/**
* A {@code LinearSpeedLimiter} provides the maximum magnitudes of linear speed. All other methods throw an
* {@link UnsupportedOperationException}.
* @author davebaol
*/
public class LinearSpeedLimiter extends NullLimiter{
private float maxLinearSpeed;
/**
* Creates a {@code LinearSpeedLimiter}.
* @param maxLinearSpeed the maximum linear speed
*/
public LinearSpeedLimiter(float maxLinearSpeed){
this.maxLinearSpeed = maxLinearSpeed;
}
/** Returns the maximum linear speed. */
@Override
public float getMaxLinearSpeed(){
return maxLinearSpeed;
}
/** Sets the maximum linear speed. */
@Override
public void setMaxLinearSpeed(float maxLinearSpeed){
this.maxLinearSpeed = maxLinearSpeed;
}
}

View File

@@ -1,129 +0,0 @@
package mindustry.ai.ai.steer.limiters;
import mindustry.ai.ai.steer.*;
/**
* A {@code NullLimiter} always throws {@link UnsupportedOperationException}. Typically it's used as the base class of partial or
* immutable limiters.
* @author davebaol
*/
public class NullLimiter implements Limiter{
/**
* An immutable limiter whose getters return {@link Float#POSITIVE_INFINITY} and setters throw
* {@link UnsupportedOperationException}.
*/
public static final NullLimiter NEUTRAL_LIMITER = new NullLimiter(){
@Override
public float getMaxLinearSpeed(){
return Float.POSITIVE_INFINITY;
}
@Override
public float getMaxLinearAcceleration(){
return Float.POSITIVE_INFINITY;
}
@Override
public float getMaxAngularSpeed(){
return Float.POSITIVE_INFINITY;
}
@Override
public float getMaxAngularAcceleration(){
return Float.POSITIVE_INFINITY;
}
};
/** Creates a {@code NullLimiter}. */
public NullLimiter(){
}
/**
* Guaranteed to throw UnsupportedOperationException.
* @throws UnsupportedOperationException always
*/
@Override
public float getMaxLinearSpeed(){
throw new UnsupportedOperationException();
}
/**
* Guaranteed to throw UnsupportedOperationException.
* @throws UnsupportedOperationException always
*/
@Override
public void setMaxLinearSpeed(float maxLinearSpeed){
throw new UnsupportedOperationException();
}
/**
* Guaranteed to throw UnsupportedOperationException.
* @throws UnsupportedOperationException always
*/
@Override
public float getMaxLinearAcceleration(){
throw new UnsupportedOperationException();
}
/**
* Guaranteed to throw UnsupportedOperationException.
* @throws UnsupportedOperationException always
*/
@Override
public void setMaxLinearAcceleration(float maxLinearAcceleration){
throw new UnsupportedOperationException();
}
/**
* Guaranteed to throw UnsupportedOperationException.
* @throws UnsupportedOperationException always
*/
@Override
public float getMaxAngularSpeed(){
throw new UnsupportedOperationException();
}
/**
* Guaranteed to throw UnsupportedOperationException.
* @throws UnsupportedOperationException always
*/
@Override
public void setMaxAngularSpeed(float maxAngularSpeed){
throw new UnsupportedOperationException();
}
/**
* Guaranteed to throw UnsupportedOperationException.
* @throws UnsupportedOperationException always
*/
@Override
public float getMaxAngularAcceleration(){
throw new UnsupportedOperationException();
}
/**
* Guaranteed to throw UnsupportedOperationException.
* @throws UnsupportedOperationException always
*/
@Override
public void setMaxAngularAcceleration(float maxAngularAcceleration){
throw new UnsupportedOperationException();
}
@Override
public float getZeroLinearSpeedThreshold(){
return 0.001f;
}
/**
* Guaranteed to throw UnsupportedOperationException.
* @throws UnsupportedOperationException always
*/
@Override
public void setZeroLinearSpeedThreshold(float zeroLinearSpeedThreshold){
throw new UnsupportedOperationException();
}
}

View File

@@ -108,7 +108,7 @@ public class FieldOfViewProximity extends ProximityBase{
// If the current agent is within the field of view of the owner,
// report it to the callback and tag it for further consideration.
if(ownerOrientation.dot(toAgent) > coneThreshold){
if(callback.reportNeighbor(currentAgent)){
if(callback.report(currentAgent)){
currentAgent.setTagged(true);
neighborCount++;
continue;
@@ -128,7 +128,7 @@ public class FieldOfViewProximity extends ProximityBase{
// it's tagged.
if(currentAgent != owner && currentAgent.isTagged()){
if(callback.reportNeighbor(currentAgent)){
if(callback.report(currentAgent)){
neighborCount++;
}
}

View File

@@ -24,7 +24,7 @@ public class InfiniteProximity extends ProximityBase{
for(Steerable currentAgent : agents){
// Make sure the agent being examined isn't the owner
if(currentAgent != owner){
if(callback.reportNeighbor(currentAgent)){
if(callback.report(currentAgent)){
neighborCount++;
}
}

View File

@@ -7,17 +7,10 @@ import mindustry.ai.ai.steer.*;
* @author davebaol
*/
public abstract class ProximityBase implements Proximity{
/** The owner of this proximity. */
protected Steerable owner;
/**
* The collection of the agents handled by this proximity.
* <p>
* Note that, being this field of type {@code Iterable}, you can either use java or libgdx collections. See
* https://github.com/libgdx/gdx-ai/issues/65
*/
protected Iterable<? extends Steerable> agents;
/** The collection of the agents handled by this proximity. */
public Iterable<? extends Steerable> agents;
/**
* Creates a {@code ProximityBase} for the specified owner and list of agents.
@@ -38,15 +31,4 @@ public abstract class ProximityBase implements Proximity{
public void setOwner(Steerable owner){
this.owner = owner;
}
/** Returns the the agents that represent potential neighbors. */
public Iterable<? extends Steerable> getAgents(){
return agents;
}
/** Sets the agents that represent potential neighbors. */
public void setAgents(Iterable<Steerable> agents){
this.agents = agents;
}
}

View File

@@ -19,7 +19,6 @@ import mindustry.ai.ai.utils.Timepiece;
* @author davebaol
*/
public class RadiusProximity extends ProximityBase{
/** The radius of this proximity. */
protected float radius;
@@ -73,7 +72,7 @@ public class RadiusProximity extends ProximityBase{
// If the current agent is within the range, report it to the callback
// and tag it for further consideration.
if(squareDistance < range * range){
if(callback.reportNeighbor(currentAgent)){
if(callback.report(currentAgent)){
currentAgent.setTagged(true);
neighborCount++;
continue;
@@ -91,7 +90,7 @@ public class RadiusProximity extends ProximityBase{
// it's tagged.
if(currentAgent != owner && currentAgent.isTagged()){
if(callback.reportNeighbor(currentAgent)){
if(callback.report(currentAgent)){
neighborCount++;
}
}

View File

@@ -1,6 +1,7 @@
package mindustry.ai.ai.utils;
import arc.math.*;
import arc.math.geom.*;
/**
@@ -28,7 +29,9 @@ public interface Location{
* Returns the angle in radians pointing along the specified vector.
* @param vector the vector
*/
float vectorToAngle(Vec2 vector);
default float vectorToAngle(Vec2 vector){
return Mathf.atan2(-vector.x, vector.y);
}
/**
* Returns the unit vector in the direction of the specified angle expressed in radians.
@@ -36,14 +39,7 @@ public interface Location{
* @param angle the angle in radians.
* @return the output vector for chaining.
*/
Vec2 angleToVector(Vec2 outVector, float angle);
/**
* Creates a new location.
* <p>
* This method is used internally to instantiate locations of the correct type parameter {@code T}. This technique keeps the API
* simple and makes the API easier to use with the GWVec2 backend because avoids the use of reflection.
* @return the newly created location.
*/
Location newLocation();
default Vec2 angleToVector(Vec2 outVector, float angle){
return outVector.set(-Mathf.sin(angle), Mathf.cos(angle));
}
}

View File

@@ -0,0 +1,23 @@
package mindustry.ai.ai.utils;
import arc.math.geom.*;
public class VecLocation implements Location{
float orientation;
Vec2 position = new Vec2();
@Override
public Vec2 getPosition(){
return position;
}
@Override
public float getOrientation(){
return orientation;
}
@Override
public void setOrientation(float orientation){
this.orientation = orientation;
}
}