import Vector from '../../math/Vector'; import Location from '../../utils/Location'; import Limiter from '../Limiter'; import Steerable from '../Steerable'; import SteeringAcceleration from '../SteeringAcceleration'; import ReachOrientation from './ReachOrientation'; /** * {@code Face} behavior makes the owner look at its target. It delegates to the {@link ReachOrientation} behavior to perform the * rotation but calculates the target orientation first based on target and owner position. * * @param Type of vector, either 2D or 3D, implementing the {@link Vector} interface * * @author davebaol */ class Face> extends ReachOrientation { /** * Creates a {@code Face} behavior for the specified owner and target. * @param owner the owner of this behavior * @param target the target of this behavior. */ constructor(owner: Steerable, target: Location = null) { super(owner, target); } // // Setters overridden in order to fix the correct return type for chaining // public setOwner(owner: Steerable): Face { this.owner = owner; return this; } public setEnabled (enabled: boolean): Face { 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. */ public setLimiter(limiter: Limiter): Face { this.limiter = limiter; return this; } public setTarget(target: Location): Face { this.target = target; return this; } public setAlignTolerance(alignTolerance: number): Face { this.alignTolerance = alignTolerance; return this; } public setDecelerationRadius(decelerationRadius: number): Face { this.decelerationRadius = decelerationRadius; return this; } public setTimeToTarget(timeToTarget: number): Face { this.timeToTarget = timeToTarget; return this; } protected calculateRealSteering (steering: SteeringAcceleration): SteeringAcceleration { return this.face(steering, this.target.getPosition()); } protected face(steering: SteeringAcceleration, targetPosition: T): SteeringAcceleration { // Get the direction to target const toTarget = steering.linear.copy(targetPosition).sub(this.owner.getPosition()); // Check for a zero direction, and return no steering if so if (toTarget.sqrLen() < this.getActualLimiter().getZeroLinearSpeedThreshold()) { return steering.setZero(); } // Calculate the orientation to face the target const orientation = this.owner.vectorToAngle(toTarget); // Delegate to ReachOrientation return this.reachOrientation(steering, orientation); } } export default Face;