mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-06-26 06:14:42 +02:00
Simple and incomplete implementation for ICollideRayVsAABB.
This commit is contained in:
parent
de2db16d08
commit
3bdb5414ae
|
@ -229,6 +229,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
}
|
||||
|
||||
// 1.9: sweep attack.
|
||||
// TODO: Account for charge/meter thing?
|
||||
final int locHashCode = LocUtil.hashCode(loc);
|
||||
if (originalDamage == 1.0) {
|
||||
// Might be a sweep attack.
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
package fr.neatmonster.nocheatplus.utilities.collision;
|
||||
|
||||
public class CollideRayVsAABB implements ICollideRayVsAABB {
|
||||
|
||||
private boolean findNearestPointIfNotCollide = false;
|
||||
/** Start point and direction. */
|
||||
private double startX, startY, startZ, dirX, dirY, dirZ;
|
||||
/** Target box (AABB). */
|
||||
private double minX, minY, minZ, maxX, maxY, maxZ;
|
||||
|
||||
/** Collision or closest point. */
|
||||
private double closestX, closestY, closestZ, closestTime;
|
||||
/**
|
||||
* Indicate a collision occurred. Reset with calling loop only.
|
||||
*/
|
||||
private boolean collides;
|
||||
|
||||
@Override
|
||||
public ICollideRayVsAABB setRay(double startX, double startY, double startZ,
|
||||
double dirX, double dirY, double dirZ) {
|
||||
// Set from parameters.
|
||||
this.startX = startX;
|
||||
this.startY = startY;
|
||||
this.startZ = startZ;
|
||||
this.dirX = dirX;
|
||||
this.dirY = dirY;
|
||||
this.dirZ = dirZ;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICollideRayVsAABB setAABB(double targetX, double targetY, double targetZ,
|
||||
double boxMarginHorizontal, double boxMarginVertical) {
|
||||
// Set from parameters.
|
||||
this.minX = targetX - boxMarginHorizontal;
|
||||
this.minY = targetY;
|
||||
this.minZ = targetZ - boxMarginHorizontal;
|
||||
this.maxX = targetX + boxMarginHorizontal;
|
||||
this.maxY = targetY + boxMarginVertical;
|
||||
this.maxZ = targetZ + boxMarginHorizontal;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICollideRayVsAABB setFindNearestPointIfNotCollide(boolean findNearestPointIfNotCollide) {
|
||||
this.findNearestPointIfNotCollide = findNearestPointIfNotCollide;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFindNearestPointIfNotCollide() {
|
||||
return findNearestPointIfNotCollide;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICollideRayVsAABB loop() {
|
||||
// Reset results.
|
||||
collides = false;
|
||||
closestX = startX;
|
||||
closestY = startY;
|
||||
closestZ = startZ;
|
||||
closestTime = 0.0;
|
||||
// Determine basic orientation and timing.
|
||||
final double tMinX = CollisionUtil.getMinTimeIncludeEdges(startX, dirX, minX, maxX);
|
||||
final double tMinY = CollisionUtil.getMinTimeIncludeEdges(startY, dirY, minY, maxY);
|
||||
final double tMinZ = CollisionUtil.getMinTimeIncludeEdges(startZ, dirZ, minZ, maxZ);
|
||||
final double tMaxX = CollisionUtil.getMaxTimeIncludeEdges(startX, dirX, minX, maxX, tMinX);
|
||||
final double tMaxY = CollisionUtil.getMaxTimeIncludeEdges(startY, dirY, minY, maxY, tMinY);
|
||||
final double tMaxZ = CollisionUtil.getMaxTimeIncludeEdges(startZ, dirZ, minZ, maxZ, tMinZ);
|
||||
if (tMaxX != Double.NaN && tMaxY != Double.NaN && tMaxZ != Double.NaN) {
|
||||
// (Excludes any tMin value to be Double.MAX_VALUE.)
|
||||
// Determine if there is overlapping intervals.
|
||||
final double tMin = Math.max(tMinX, Math.max(tMinY, tMinZ));
|
||||
final double tMax = Math.min(tMaxX, Math.min(tMaxY, tMaxZ));
|
||||
if (tMin <= tMax) {
|
||||
collides = true;
|
||||
closestX = startX + dirX * tMin;
|
||||
closestY = startY + dirY * tMin;
|
||||
closestZ = startZ + dirZ * tMin;
|
||||
}
|
||||
else if (findNearestPointIfNotCollide) {
|
||||
findNearestPoint(tMinX, tMinY, tMinZ, tMaxX, tMaxY, tMaxZ, tMin, tMax);
|
||||
}
|
||||
}
|
||||
else if (findNearestPointIfNotCollide) {
|
||||
findNearestPoint(tMinX, tMinY, tMinZ, tMaxX, tMaxY, tMaxZ);
|
||||
}
|
||||
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.
|
||||
*
|
||||
* @param tMinX
|
||||
* @param tMinY
|
||||
* @param tMinZ
|
||||
* @param tMaxX
|
||||
* @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.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides() {
|
||||
return collides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return closestX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return closestY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getZ() {
|
||||
return closestZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTime() {
|
||||
return closestTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -302,4 +302,88 @@ public class CollisionUtil {
|
|||
return db + 1.0 > min && db < max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a point is inside an AABB, including the edges.
|
||||
*
|
||||
* @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 boolean isInsideAABBIncludeEdges(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 !(x < minX || x > maxX || z < minZ || z > maxZ || y < minY || y > maxY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the earliest time a collision with the min-max coordinates can occur,
|
||||
* in multiples of dir, including edges.
|
||||
*
|
||||
* @param pos
|
||||
* @param dir
|
||||
* @param minPos
|
||||
* @param maxPos
|
||||
* @return The multiple of dir to hit the min-max coordinates, or
|
||||
* Double.POSITIVE_INFINITY if not possible to hit.
|
||||
*/
|
||||
public static double getMinTimeIncludeEdges(final double pos, final double dir,
|
||||
final double minPos, final double maxPos) {
|
||||
if (pos >= minPos && pos <= maxPos) {
|
||||
return 0.0;
|
||||
}
|
||||
else if (dir == 0.0) {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
else if (dir < 0.0) {
|
||||
return pos < minPos ? Double.POSITIVE_INFINITY : (Math.abs(pos - maxPos) / Math.abs(dir));
|
||||
}
|
||||
else {
|
||||
// dir > 0.0
|
||||
return pos > maxPos ? Double.POSITIVE_INFINITY : (Math.abs(pos - minPos) / dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum time for which the min-max coordinates still are hit.
|
||||
*
|
||||
* @param pos
|
||||
* @param dir
|
||||
* @param minPos
|
||||
* @param maxPos
|
||||
* @param minTime
|
||||
* The earliest time of collision with the min-max coordinates,
|
||||
* as returned by getMinTimeIncludeEdges.
|
||||
* @return The maximum time for which the min-max coordinates still are hit.
|
||||
* If no hit is possible, Double.NaN is returned. If minTime is
|
||||
* Double.POSITIVE_INFINITY, Double.NaN is returned directly.
|
||||
* Double.POSITIVE_INFINITY may be returned, if coordinates are
|
||||
* colliding always.
|
||||
*/
|
||||
public static double getMaxTimeIncludeEdges(final double pos, final double dir,
|
||||
final double minPos, final double maxPos, final double minTime) {
|
||||
if (minTime == Double.POSITIVE_INFINITY) {
|
||||
return Double.NaN;
|
||||
}
|
||||
else if (dir == 0.0) {
|
||||
return pos < maxPos || pos > maxPos ? Double.NaN : Double.POSITIVE_INFINITY;
|
||||
}
|
||||
else if (dir < 0.0) {
|
||||
return pos < minPos ? Double.NaN : (Math.abs(pos - minPos) / dir);
|
||||
}
|
||||
else {
|
||||
// dir > 0.0
|
||||
return pos > maxPos ? Double.NaN : (Math.abs(pos - maxPos) / dir);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,13 +6,15 @@ 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).
|
||||
* set so). By default colliding with the edges of the box would count.
|
||||
*
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public interface ICollideRayVsAABB extends IGetPosition {
|
||||
|
||||
// TODO: Control of counting in colliding with the edge?
|
||||
// TODO: Method to get the maximum per-axis distance in case of not colliding and findNearest... set.
|
||||
// TODO: Convenience methods to retrieve distances (especially in case of not colliding).
|
||||
// TODO: Convenience methods for other argument types (vector, IGet..., double[], setAABB(block/ints).
|
||||
// TODO: Implement fight.visible, use in BlockBreak.direction/visible.
|
||||
|
@ -89,8 +91,8 @@ public interface ICollideRayVsAABB extends IGetPosition {
|
|||
public boolean collides();
|
||||
|
||||
/**
|
||||
* Time of collision if collides() returns true, or of the nearest point,
|
||||
* counted in times of applying the direction.
|
||||
* Earliest time of collision if collides() returns true, or of the nearest
|
||||
* point, counted in times of applying the direction.
|
||||
*
|
||||
* @return Time in multiples of the initial direction vector. In case it's
|
||||
* not possible at all, 0.0 might be returned.
|
||||
|
|
Loading…
Reference in New Issue
Block a user