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;
|
private double minX, minY, minZ, maxX, maxY, maxZ;
|
||||||
|
|
||||||
/** Collision or closest point. */
|
/** 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.
|
* Indicate a collision occurred. Reset with calling loop only.
|
||||||
*/
|
*/
|
||||||
@ -59,6 +59,7 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
|||||||
closestX = startX;
|
closestX = startX;
|
||||||
closestY = startY;
|
closestY = startY;
|
||||||
closestZ = startZ;
|
closestZ = startZ;
|
||||||
|
closestDistanceSquared = 0.0; // Not applicable by default.
|
||||||
closestTime = 0.0;
|
closestTime = 0.0;
|
||||||
// Determine basic orientation and timing.
|
// Determine basic orientation and timing.
|
||||||
final double tMinX = CollisionUtil.getMinTimeIncludeEdges(startX, dirX, minX, maxX);
|
final double tMinX = CollisionUtil.getMinTimeIncludeEdges(startX, dirX, minX, maxX);
|
||||||
@ -79,7 +80,7 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
|||||||
closestZ = startZ + dirZ * tMin;
|
closestZ = startZ + dirZ * tMin;
|
||||||
}
|
}
|
||||||
else if (findNearestPointIfNotCollide) {
|
else if (findNearestPointIfNotCollide) {
|
||||||
findNearestPoint(tMinX, tMinY, tMinZ, tMaxX, tMaxY, tMaxZ, tMin, tMax);
|
findNearestPoint(tMinX, tMinY, tMinZ, tMaxX, tMaxY, tMaxZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (findNearestPointIfNotCollide) {
|
else if (findNearestPointIfNotCollide) {
|
||||||
@ -88,28 +89,10 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
|||||||
return this;
|
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
|
* 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 tMinX
|
||||||
* @param tMinY
|
* @param tMinY
|
||||||
@ -118,9 +101,31 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
|||||||
* @param tMaxY
|
* @param tMaxY
|
||||||
* @param tMaxZ
|
* @param tMaxZ
|
||||||
*/
|
*/
|
||||||
private void findNearestPoint(final double tMinX, final double tMinY, final double tMinZ,
|
private void findNearestPoint(final double... timeValues) {
|
||||||
final double tMaxX, final double tMaxY, final double tMaxZ) {
|
// TODO: Squared vs. Manhattan vs. maxAxis.
|
||||||
// TODO: Implement.
|
// 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
|
@Override
|
||||||
@ -143,6 +148,11 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
|
|||||||
return closestZ;
|
return closestZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getClosestDistanceSquared() {
|
||||||
|
return closestDistanceSquared;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getTime() {
|
public double getTime() {
|
||||||
return closestTime;
|
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
|
* 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
|
* 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
|
* 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
|
* @author asofold
|
||||||
*
|
*
|
||||||
@ -90,6 +92,14 @@ public interface ICollideRayVsAABB extends IGetPosition {
|
|||||||
*/
|
*/
|
||||||
public boolean collides();
|
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
|
* Earliest time of collision if collides() returns true, or of the nearest
|
||||||
* point, counted in times of applying the direction.
|
* point, counted in times of applying the direction.
|
||||||
|
Loading…
Reference in New Issue
Block a user