/** Returns the square of the magnitude of this steering acceleration. This includes the angular component. */ public float calculateSquareMagnitude () { return linear.len2() + angular * angular; }
@Override public boolean reportNeighbor (Steerable<T> neighbor) { toAgent.set(owner.getPosition()).sub(neighbor.getPosition()); float distanceSqr = toAgent.len2(); if(distanceSqr == 0) return true; float maxAcceleration = getActualLimiter().getMaxLinearAcceleration(); // Calculate the strength of repulsion through inverse square law decay float strength = getDecayCoefficient() / distanceSqr; if (strength > maxAcceleration) strength = maxAcceleration; // Add the acceleration // Optimized code for linear.mulAdd(toAgent.nor(), strength); linear.mulAdd(toAgent, strength / (float)Math.sqrt(distanceSqr)); return true; }
@Override protected SteeringAcceleration<T> calculateRealSteering (SteeringAcceleration<T> steering) { T targetPosition = target.getPosition(); // Get the square distance to the evader (the target) float squareDistance = steering.linear.set(targetPosition).sub(owner.getPosition()).len2(); // Work out our current square speed float squareSpeed = owner.getLinearVelocity().len2(); float predictionTime = maxPredictionTime; if (squareSpeed > 0) { // Calculate prediction time if speed is not too small to give a reasonable value float squarePredictionTime = squareDistance / squareSpeed; if (squarePredictionTime < maxPredictionTime * maxPredictionTime) predictionTime = (float)Math.sqrt(squarePredictionTime); } // Calculate and seek/flee the predicted position of the target steering.linear.set(targetPosition).mulAdd(target.getLinearVelocity(), predictionTime).sub(owner.getPosition()).nor() .scl(getActualMaxLinearAcceleration()); // No angular acceleration steering.angular = 0; // Output steering acceleration return steering; }
/** Returns the square of the magnitude of this steering acceleration. This includes the angular component. */ public float calculateSquareMagnitude () { return linear.len2() + angular * angular; }
private boolean checkAirborneTimeAndCalculateVelocity (T outVelocity, float time, JumpDescriptor<T> jumpDescriptor, float maxLinearSpeed) { // Calculate the planar velocity planarVelocity.set(jumpDescriptor.delta).scl(1f / time); gravityComponentHandler.setComponent(planarVelocity, 0f); // Check the planar linear speed if (planarVelocity.len2() < maxLinearSpeed * maxLinearSpeed) { // We have a valid solution, so store it by merging vertical and non-vertical axes float verticalValue = gravityComponentHandler.getComponent(outVelocity); gravityComponentHandler.setComponent(outVelocity.set(planarVelocity), verticalValue); if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "targetLinearVelocity = " + outVelocity + "; targetLinearSpeed = " + outVelocity.len()); return true; } return false; }
/** Returns the square distance of the nearest point on line segment {@code a-b}, from point {@code c}. Also, the {@code out} * vector is assigned to the nearest point. * @param out the output vector that contains the nearest point on return * @param a the start point of the line segment * @param b the end point of the line segment * @param c the point to calculate the distance from */ public float calculatePointSegmentSquareDistance (T out, T a, T b, T c) { out.set(a); tmpB.set(b); tmpC.set(c); T ab = tmpB.sub(a); float abLen2 = ab.len2(); if (abLen2 != 0) { float t = (tmpC.sub(a)).dot(ab) / abLen2; out.mulAdd(ab, MathUtils.clamp(t, 0, 1)); } return out.dst2(c); }
@Override public boolean reportNeighbor (Steerable<T> neighbor) { // Calculate the time to collision relativePosition.set(neighbor.getPosition()).sub(owner.getPosition()); relativeVelocity.set(neighbor.getLinearVelocity()).sub(owner.getLinearVelocity()); float relativeSpeed2 = relativeVelocity.len2(); // Collision can't happen when the agents have the same linear velocity. // Also, note that timeToCollision would be NaN due to the indeterminate form 0/0 and, // since any comparison involving NaN returns false, it would become the shortestTime, // so defeating the algorithm. if (relativeSpeed2 == 0) return false; float timeToCollision = -relativePosition.dot(relativeVelocity) / relativeSpeed2; // If timeToCollision is negative, i.e. the owner is already moving away from the the neighbor, // or it's not the most imminent collision then no action needs to be taken. if (timeToCollision <= 0 || timeToCollision >= shortestTime) return false; // Check if it is going to be a collision at all float distance = relativePosition.len(); float minSeparation = distance - (float)Math.sqrt(relativeSpeed2) * timeToCollision /* shortestTime */; if (minSeparation > owner.getBoundingRadius() + neighbor.getBoundingRadius()) return false; // Store most imminent collision data shortestTime = timeToCollision; firstNeighbor = neighbor; firstMinSeparation = minSeparation; firstDistance = distance; firstRelativePosition.set(relativePosition); firstRelativeVelocity.set(relativeVelocity); return true; }
float toAgentLen2 = toAgent.len2();
@Override public boolean reportNeighbor (Steerable<T> neighbor) { toAgent.set(owner.getPosition()).sub(neighbor.getPosition()); float distanceSqr = toAgent.len2(); if(distanceSqr == 0) return true; float maxAcceleration = getActualLimiter().getMaxLinearAcceleration(); // Calculate the strength of repulsion through inverse square law decay float strength = getDecayCoefficient() / distanceSqr; if (strength > maxAcceleration) strength = maxAcceleration; // Add the acceleration // Optimized code for linear.mulAdd(toAgent.nor(), strength); linear.mulAdd(toAgent, strength / (float)Math.sqrt(distanceSqr)); return true; }
@Override protected SteeringAcceleration<T> calculateRealSteering (SteeringAcceleration<T> steering) { T targetPosition = target.getPosition(); // Get the square distance to the evader (the target) float squareDistance = steering.linear.set(targetPosition).sub(owner.getPosition()).len2(); // Work out our current square speed float squareSpeed = owner.getLinearVelocity().len2(); float predictionTime = maxPredictionTime; if (squareSpeed > 0) { // Calculate prediction time if speed is not too small to give a reasonable value float squarePredictionTime = squareDistance / squareSpeed; if (squarePredictionTime < maxPredictionTime * maxPredictionTime) predictionTime = (float)Math.sqrt(squarePredictionTime); } // Calculate and seek/flee the predicted position of the target steering.linear.set(targetPosition).mulAdd(target.getLinearVelocity(), predictionTime).sub(owner.getPosition()).nor() .scl(getActualMaxLinearAcceleration()); // No angular acceleration steering.angular = 0; // Output steering acceleration return steering; }
private boolean checkAirborneTimeAndCalculateVelocity (T outVelocity, float time, JumpDescriptor<T> jumpDescriptor, float maxLinearSpeed) { // Calculate the planar velocity planarVelocity.set(jumpDescriptor.delta).scl(1f / time); gravityComponentHandler.setComponent(planarVelocity, 0f); // Check the planar linear speed if (planarVelocity.len2() < maxLinearSpeed * maxLinearSpeed) { // We have a valid solution, so store it by merging vertical and non-vertical axes float verticalValue = gravityComponentHandler.getComponent(outVelocity); gravityComponentHandler.setComponent(outVelocity.set(planarVelocity), verticalValue); if (DEBUG_ENABLED) GdxAI.getLogger().info("Jump", "targetLinearVelocity = " + outVelocity + "; targetLinearSpeed = " + outVelocity.len()); return true; } return false; }
/** Returns the square distance of the nearest point on line segment {@code a-b}, from point {@code c}. Also, the {@code out} * vector is assigned to the nearest point. * @param out the output vector that contains the nearest point on return * @param a the start point of the line segment * @param b the end point of the line segment * @param c the point to calculate the distance from */ public float calculatePointSegmentSquareDistance (T out, T a, T b, T c) { out.set(a); tmpB.set(b); tmpC.set(c); T ab = tmpB.sub(a); float abLen2 = ab.len2(); if (abLen2 != 0) { float t = (tmpC.sub(a)).dot(ab) / abLen2; out.mulAdd(ab, MathUtils.clamp(t, 0, 1)); } return out.dst2(c); }
@Override public boolean reportNeighbor (Steerable<T> neighbor) { // Calculate the time to collision relativePosition.set(neighbor.getPosition()).sub(owner.getPosition()); relativeVelocity.set(neighbor.getLinearVelocity()).sub(owner.getLinearVelocity()); float relativeSpeed2 = relativeVelocity.len2(); // Collision can't happen when the agents have the same linear velocity. // Also, note that timeToCollision would be NaN due to the indeterminate form 0/0 and, // since any comparison involving NaN returns false, it would become the shortestTime, // so defeating the algorithm. if (relativeSpeed2 == 0) return false; float timeToCollision = -relativePosition.dot(relativeVelocity) / relativeSpeed2; // If timeToCollision is negative, i.e. the owner is already moving away from the the neighbor, // or it's not the most imminent collision then no action needs to be taken. if (timeToCollision <= 0 || timeToCollision >= shortestTime) return false; // Check if it is going to be a collision at all float distance = relativePosition.len(); float minSeparation = distance - (float)Math.sqrt(relativeSpeed2) * timeToCollision /* shortestTime */; if (minSeparation > owner.getBoundingRadius() + neighbor.getBoundingRadius()) return false; // Store most imminent collision data shortestTime = timeToCollision; firstNeighbor = neighbor; firstMinSeparation = minSeparation; firstDistance = distance; firstRelativePosition.set(relativePosition); firstRelativeVelocity.set(relativeVelocity); return true; }
float toAgentLen2 = toAgent.len2();