mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-09-27 14:13:11 +02:00
Complete initial draft for ICollideRayVsAABB.
(Blind/untested.)
This commit is contained in:
parent
a38e63d4a9
commit
050760afd2
@ -9,7 +9,7 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
||||
private double minX, minY, minZ, maxX, maxY, maxZ;
|
||||
|
||||
/** Collision or closest point. */
|
||||
private double closestX, closestY, closestZ, closestTime;
|
||||
private double closestX, closestY, closestZ, closestDistanceSquared, closestTime;
|
||||
/**
|
||||
* Indicate a collision occurred. Reset with calling loop only.
|
||||
*/
|
||||
@ -59,6 +59,7 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
||||
closestX = startX;
|
||||
closestY = startY;
|
||||
closestZ = startZ;
|
||||
closestDistanceSquared = 0.0; // Not applicable by default.
|
||||
closestTime = 0.0;
|
||||
// Determine basic orientation and timing.
|
||||
final double tMinX = CollisionUtil.getMinTimeIncludeEdges(startX, dirX, minX, maxX);
|
||||
@ -79,7 +80,7 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
||||
closestZ = startZ + dirZ * tMin;
|
||||
}
|
||||
else if (findNearestPointIfNotCollide) {
|
||||
findNearestPoint(tMinX, tMinY, tMinZ, tMaxX, tMaxY, tMaxZ, tMin, tMax);
|
||||
findNearestPoint(tMinX, tMinY, tMinZ, tMaxX, tMaxY, tMaxZ);
|
||||
}
|
||||
}
|
||||
else if (findNearestPointIfNotCollide) {
|
||||
@ -88,28 +89,10 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the nearest point for the case of not hitting the box, but with
|
||||
* hitting min-max coordinates per axis independently.
|
||||
*
|
||||
* @param tMinX
|
||||
* @param tMinY
|
||||
* @param tMinZ
|
||||
* @param tMaxX
|
||||
* @param tMaxY
|
||||
* @param tMaxZ
|
||||
* @param tMin
|
||||
* @param tMax
|
||||
*/
|
||||
private void findNearestPoint(final double tMinX, final double tMinY, final double tMinZ,
|
||||
final double tMaxX, final double tMaxY, final double tMaxZ,
|
||||
final double tMin, final double tMax) {
|
||||
// TODO: Implement.
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate the nearest point for the case of at least one of the
|
||||
* coordinates not being possible to match at all.
|
||||
* coordinates not being possible to match at all. Asserts closestX|Y|Z to
|
||||
* be set to the start coordinates.
|
||||
*
|
||||
* @param tMinX
|
||||
* @param tMinY
|
||||
@ -118,9 +101,31 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
||||
* @param tMaxY
|
||||
* @param tMaxZ
|
||||
*/
|
||||
private void findNearestPoint(final double tMinX, final double tMinY, final double tMinZ,
|
||||
final double tMaxX, final double tMaxY, final double tMaxZ) {
|
||||
// TODO: Implement.
|
||||
private void findNearestPoint(final double... timeValues) {
|
||||
// TODO: Squared vs. Manhattan vs. maxAxis.
|
||||
// Update squared distance to 'actual'.
|
||||
closestDistanceSquared = CollisionUtil.getSquaredDistAABB(this.startX, this.startY, this.startZ,
|
||||
minX, minY, minZ, maxX, maxY, maxZ);
|
||||
// Find the closest point using set time values.
|
||||
for (int i = 0; i < timeValues.length; i++) {
|
||||
final double time = timeValues[i];
|
||||
if (time == Double.NaN || time == Double.POSITIVE_INFINITY) {
|
||||
// Note that Double.POSITIVE_INFINITY means that we are colliding forever.
|
||||
continue;
|
||||
}
|
||||
final double x = startX + dirX * time;
|
||||
final double y = startY + dirY * time;
|
||||
final double z = startZ + dirZ * time;
|
||||
final double distanceSquared = CollisionUtil.getSquaredDistAABB(x, y, z,
|
||||
minX, minY, minZ, maxX, maxY, maxZ);
|
||||
if (distanceSquared < closestDistanceSquared) {
|
||||
closestX = x;
|
||||
closestY = y;
|
||||
closestZ = z;
|
||||
closestDistanceSquared = distanceSquared;
|
||||
closestTime = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -143,6 +148,11 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
||||
return closestZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getClosestDistanceSquared() {
|
||||
return closestDistanceSquared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTime() {
|
||||
return closestTime;
|
||||
|
@ -386,4 +386,92 @@ public class CollisionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum (closest) distance from the given position towards the
|
||||
* AABB regarding axes independently.
|
||||
*
|
||||
* @param x
|
||||
* Position of the point.
|
||||
* @param y
|
||||
* @param z
|
||||
* @param minX
|
||||
* Minimum coordinates of the AABB.
|
||||
* @param minY
|
||||
* @param minZ
|
||||
* @param maxX
|
||||
* Maximum coordinates of the AABB.
|
||||
* @param maxY
|
||||
* @param maxZ
|
||||
* @return
|
||||
*/
|
||||
public static double getMaxAxisDistAABB(final double x, final double y, final double z,
|
||||
final double minX, final double minY, final double minZ,
|
||||
final double maxX, final double maxY, final double maxZ) {
|
||||
return Math.max(axisDistance(x, minX, maxX), Math.max(axisDistance(y, minY, maxY), axisDistance(z, minZ, maxZ)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum (closest) 'Manhattan' distance from the given position
|
||||
* towards the AABB regarding axes independently.
|
||||
*
|
||||
* @param x
|
||||
* Position of the point.
|
||||
* @param y
|
||||
* @param z
|
||||
* @param minX
|
||||
* Minimum coordinates of the AABB.
|
||||
* @param minY
|
||||
* @param minZ
|
||||
* @param maxX
|
||||
* Maximum coordinates of the AABB.
|
||||
* @param maxY
|
||||
* @param maxZ
|
||||
* @return
|
||||
*/
|
||||
public static double getManhattanDistAABB(final double x, final double y, final double z,
|
||||
final double minX, final double minY, final double minZ,
|
||||
final double maxX, final double maxY, final double maxZ) {
|
||||
return axisDistance(x, minX, maxX)+ axisDistance(y, minY, maxY) + axisDistance(z, minZ, maxZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the squared (closest) distance from the given position towards the
|
||||
* AABB regarding axes independently.
|
||||
*
|
||||
* @param x
|
||||
* Position of the point.
|
||||
* @param y
|
||||
* @param z
|
||||
* @param minX
|
||||
* Minimum coordinates of the AABB.
|
||||
* @param minY
|
||||
* @param minZ
|
||||
* @param maxX
|
||||
* Maximum coordinates of the AABB.
|
||||
* @param maxY
|
||||
* @param maxZ
|
||||
* @return
|
||||
*/
|
||||
public static double getSquaredDistAABB(final double x, final double y, final double z,
|
||||
final double minX, final double minY, final double minZ,
|
||||
final double maxX, final double maxY, final double maxZ) {
|
||||
final double dX = axisDistance(x, minX, maxX);
|
||||
final double dY = axisDistance(y, minY, maxY);
|
||||
final double dZ = axisDistance(z, minZ, maxZ);
|
||||
return dX * dX + dY * dY + dZ * dZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the distance towards a min-max interval (inside and edge count as 0.0
|
||||
* distance).
|
||||
*
|
||||
* @param pos
|
||||
* @param minPos
|
||||
* @param maxPos
|
||||
* @return Positive distance always.
|
||||
*/
|
||||
public static double axisDistance(final double pos, final double minPos, final double maxPos) {
|
||||
return pos < minPos ? Math.abs(pos - minPos) : (pos > maxPos ? Math.abs(pos - maxPos) : 0.0);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ import fr.neatmonster.nocheatplus.components.location.IGetPosition;
|
||||
* Collide a ray with an axis aligned bounding box (AABB). Allow fetching the
|
||||
* point of time, when the ray is closest to the AABB. The methods getX|Y|Z from
|
||||
* IGetPosition will fetch the coordinates of collision or the nearest point (if
|
||||
* set so). By default colliding with the edges of the box would count.
|
||||
* set so). That nearest point may be an estimation, not necessarily consistent
|
||||
* for all cases/directions. By default colliding with the edges of the box
|
||||
* would count.
|
||||
*
|
||||
* @author asofold
|
||||
*
|
||||
@ -90,6 +92,14 @@ public interface ICollideRayVsAABB extends IGetPosition {
|
||||
*/
|
||||
public boolean collides();
|
||||
|
||||
/**
|
||||
* Get some kind of squared distance for the nearest point, in case of not
|
||||
* colliding and findNearestPointIfNotCollid being set.
|
||||
*
|
||||
* @return 0.0 if not applicable.
|
||||
*/
|
||||
public double getClosestDistanceSquared();
|
||||
|
||||
/**
|
||||
* Earliest time of collision if collides() returns true, or of the nearest
|
||||
* point, counted in times of applying the direction.
|
||||
|
Loading…
Reference in New Issue
Block a user