Elaborate on ray-tracing with and/or passable.

* Add capability to cut margins opposite to the moving direction for
AxisTracing (extend interface(s)).
This commit is contained in:
asofold 2016-06-10 13:21:28 +02:00
parent 5d0d5d411d
commit f1ffb23686
5 changed files with 58 additions and 12 deletions

View File

@ -45,6 +45,8 @@ public class Passable extends Check {
// TODO: Test bumping head into things.
private static double rt_heightFactor = 1.0;
// TODO: Option to ignore initially colliding blocks in general? (Alternative: interpret ignoreFirst as such.)
/**
* Convenience for player moving, to keep a better overview.
*
@ -86,7 +88,7 @@ public class Passable extends Check {
boolean toPassable = to.isPassable();
// General condition check for using ray-tracing.
if (toPassable && cc.passableRayTracingCheck && (!cc.passableRayTracingBlockChangeOnly || manhattan > 0)) {
rayTracing.setMargins(from.getEyeHeight() * rt_heightFactor, from.getWidth() / 2.0 * rt_xzFactor); // max from/to + resolution ?
setNormalMargins(rayTracing, from);
rayTracing.set(from, to);
rayTracing.loop();
if (rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps()) {
@ -100,7 +102,7 @@ public class Passable extends Check {
toPassable = false;
tags = "raytracing_2x_";
if (data.debug) {
debugExtraCollisionDetails(player, rayTracing, "ingorFirst");
debugExtraCollisionDetails(player, rayTracing, "ingoreFirst");
}
}
else if (data.debug) {
@ -130,6 +132,15 @@ public class Passable extends Check {
}
/**
* Default/normal margins.
* @param rayTracing
* @param from
*/
private void setNormalMargins(final ICollidePassable rayTracing, final PlayerLocation from) {
rayTracing.setMargins(from.getEyeHeight() * rt_heightFactor, from.getWidth() / 2.0 * rt_xzFactor); // max from/to + resolution ?
}
private Location potentialViolation(final Player player, final PlayerLocation from, final PlayerLocation to, final int manhattan, String tags, final MovingData data, final MovingConfig cc) {
// Moving into a block, possibly a violation.
@ -221,9 +232,12 @@ public class Passable extends Check {
* @return
*/
private boolean collidesIgnoreFirst(PlayerLocation from, PlayerLocation to) {
// TODO: Set (and reset?) margins?
rayTracing.set(from, to);
rayTracing.setIgnoreFirst();
rayTracing.setCutOppositeDirectionMargin(true);
rayTracing.loop();
rayTracing.setCutOppositeDirectionMargin(false);
return rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps();
}

View File

@ -4,9 +4,12 @@ import org.bukkit.Location;
/**
* Similar to ray-tracing, attempt to model how the client processes move vs.
* block collision via y-x-z or similar (TODO: xz vs zx). Rough orientation is
* the RayTracing classes or a thinkable interface, to be able to use similar
* test cases later on.
* block collision via y-x-z or similar. Rough orientation is the RayTracing
* classes or a thinkable interface, to be able to use similar test cases later
* on.
* <hr>
* This implementation is meant to provide some optimum of ease of
* implementation and performance, not necessarily elegance.
*
* @author asofold
*
@ -25,6 +28,12 @@ public abstract class AxisTracing implements ICollide, ISetMargins {
/** Margins for the bounding box, seen from center / start coordinates. Positive values. */
private double marginXpos, marginXneg, marginYpos, marginYneg, marginZpos, marginZneg;
/**
* Indicate to cut margins that are opposite the moving direction (for
* runAxis_).
*/
private boolean cutOppositeDirectionMargin = false;
/** Result returned with collides() and reset to false on set/loop. */
protected boolean collides;
@ -102,6 +111,11 @@ public abstract class AxisTracing implements ICollide, ISetMargins {
this.marginYpos = height;
}
@Override
public void setCutOppositeDirectionMargin(final boolean cutOppositeDirectionMargin) {
this.cutOppositeDirectionMargin = cutOppositeDirectionMargin;
}
public void set(double x0, double y0, double z0, double x1, double y1, double z1) {
collides = false;
step = 0;
@ -164,13 +178,13 @@ public abstract class AxisTracing implements ICollide, ISetMargins {
final int iEndY;
if (yIn < this.y1) {
increment = 1;
yStart = yIn - marginYneg;
yStart = cutOppositeDirectionMargin ? yIn : (yIn -marginYneg);
yEnd = this.y1 + marginYpos;
iEndY = Location.locToBlock(yEnd) + 1;
}
else {
increment = -1;
yStart = yIn + marginYpos;
yStart = cutOppositeDirectionMargin ? yIn : (yIn + marginYpos);
yEnd = this.y1 - marginYneg;
iEndY = Location.locToBlock(yEnd) - 1;
}
@ -215,13 +229,13 @@ public abstract class AxisTracing implements ICollide, ISetMargins {
final int iEndX;
if (xIn < this.x1) {
increment = 1;
xStart = xIn - marginXneg;
xStart = cutOppositeDirectionMargin ? xIn : (xIn - marginXneg);
xEnd = this.x1 + marginXpos;
iEndX = Location.locToBlock(xEnd) + 1;
}
else {
increment = -1;
xStart = xIn + marginXpos;
xStart = cutOppositeDirectionMargin ? xIn : (xIn + marginXpos);
xEnd = this.x1 - marginXneg;
iEndX = Location.locToBlock(xEnd) - 1;
}
@ -266,13 +280,13 @@ public abstract class AxisTracing implements ICollide, ISetMargins {
final int iEndZ;
if (zIn < this.z1) {
increment = 1;
zStart = zIn - marginZneg;
zStart = cutOppositeDirectionMargin ? zIn : (zIn - marginZneg);
zEnd = this.z1 + marginZpos;
iEndZ = Location.locToBlock(zEnd + 1);
}
else {
increment = -1;
zStart = zIn + marginZpos;
zStart = cutOppositeDirectionMargin ? zIn : (zIn + marginZpos);
zEnd = this.z1 - marginZneg;
iEndZ = Location.locToBlock(zEnd - 1);
}

View File

@ -29,7 +29,9 @@ public interface ICollidePassable extends ICollide, ISetMargins {
* Ignore the first block. Must be called after set, because set should
* override internal state with false.
*/
// TODO: Switch to ignoreBlock(int, int, int) rather.
// TODO: Switch to ignoreBlock(int, int, int) rather?
// TODO: Remove resetting on set?
// TODO: Consider to imply setCutOppositeDirectionMargin(true) with this (needs not reset with set)?
public void setIgnoreFirst();
/**

View File

@ -12,4 +12,15 @@ public interface ISetMargins {
*/
public void setMargins(final double height, final double xzMargin);
/**
* Allow cutting off the margins opposite to a checking direction. Call
* before loop. MAy or may not have any effect.
*
* @param cutOppositeDirectionMargin
* If set to true, margins that are opposite to the moving
* direction are cut off. This is meant for setups like with
* moving out of blocks.
*/
public void setCutOppositeDirectionMargin(boolean cutOppositeDirectionMargin);
}

View File

@ -90,4 +90,9 @@ public class PassableRayTracing extends RayTracing implements ICollidePassable {
// (No effect.)
}
@Override
public void setCutOppositeDirectionMargin(boolean cutOppositeDirectionMargin) {
// (No effect.)
}
}