More on Passable/RayTracing.

* Prepare more debugging.
* Move collides flag into RayTracing.
This commit is contained in:
asofold 2016-06-10 08:42:44 +02:00
parent 19312bdbfa
commit 181502cdd4
7 changed files with 94 additions and 54 deletions

View File

@ -30,10 +30,14 @@ import fr.neatmonster.nocheatplus.utilities.BlockProperties;
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
import fr.neatmonster.nocheatplus.utilities.collision.ICollidePassable;
import fr.neatmonster.nocheatplus.utilities.collision.PassableAxisTracing;
import fr.neatmonster.nocheatplus.utilities.collision.PassableRayTracing;
public class Passable extends Check {
/** TESTING RATHER. */
private static boolean preferAxisWise = false;
/**
* Convenience for player moving, to keep a better overview.
*
@ -42,12 +46,10 @@ public class Passable extends Check {
* @return
*/
public static boolean isPassable(Location from, Location to) {
return BlockProperties.isPassable(from, to);
//return BlockProperties.isPassableAxisWise(from, to);
return preferAxisWise ? BlockProperties.isPassableAxisWise(from, to) : BlockProperties.isPassable(from, to);
}
private final ICollidePassable rayTracing = new PassableRayTracing();
//private final ICollidePassable rayTracing = new PassableAxisTracing();
private final ICollidePassable rayTracing = preferAxisWise ? new PassableAxisTracing() : new PassableRayTracing();
public Passable() {
super(CheckType.MOVING_PASSABLE);
@ -80,19 +82,25 @@ public class Passable extends Check {
rayTracing.set(from, to);
rayTracing.loop();
if (rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps()) {
if (data.debug) {
debugExtraCollisionDetails(player, rayTracing, "initial");
}
final int maxBlockDist = manhattan <= 1 ? manhattan : from.maxBlockDist(to);
if (maxBlockDist <= 1 && rayTracing.getStepsDone() == 1 && !from.isPassable()) {
// Redo ray-tracing for moving out of blocks.
if (collidesIgnoreFirst(from, to)) {
toPassable = false;
tags = "raytracing_2x_";
if (data.debug) {
debugExtraCollisionDetails(player, rayTracing, "ingorFirst");
}
}
else if (data.debug) {
debug(player, "Allow moving out of a block.");
}
}
else{
if (!allowsSplitMove(from, to, manhattan)) {
if (!allowsSplitMove(from, to, manhattan, data)) {
toPassable = false;
tags = "raytracing_";
}
@ -218,7 +226,7 @@ public class Passable extends Check {
* @param manhattan
* @return
*/
private boolean allowsSplitMove(final PlayerLocation from, final PlayerLocation to, final int manhattan) {
private boolean allowsSplitMove(final PlayerLocation from, final PlayerLocation to, final int manhattan, final MovingData data) {
if (!rayTracing.mightNeedSplitAxisHandling()) {
return false;
}
@ -252,7 +260,19 @@ public class Passable extends Check {
// }
// }
// }
if (data.debug) {
debug(from.getPlayer(), "Raytracing collision (split move): (no details)");
}
return false;
}
private void debugExtraCollisionDetails(Player player, ICollidePassable rayTracing, String tag) {
if (rayTracing.collides()) {
debug(player, "Raytracing collision (" + tag + "): " + rayTracing.getCollidingAxis());
}
else if (rayTracing.getStepsDone() >= rayTracing.getMaxSteps()) {
debug(player, "Raytracing collision (" + tag + "): max steps exceeded.");
}
}
}

View File

@ -0,0 +1,19 @@
package fr.neatmonster.nocheatplus.utilities.collision;
/**
* Represent an orientation concerning Axes (not necessarily a single one).
*
* @author asofold
*
*/
public enum Axis {
// TODO: name?
X_AXIS,
Y_AXIS,
Z_AXIS,
XZ_AXES,
XYZ_AXES,
NONE;
}

View File

@ -15,13 +15,6 @@ public abstract class AxisTracing implements ICollide, ISetMargins {
// TODO: Consider an extra loop(coordinates + margins...) for convenience.
public static enum Axis {
X_AXIS,
Y_AXIS,
Z_AXIS,
NONE;
}
/** The order of axis to be checked. */
private final Axis[] axisOrder = new Axis[3];
@ -35,6 +28,9 @@ public abstract class AxisTracing implements ICollide, ISetMargins {
/** Result returned with collides() and reset to false on set/loop. */
protected boolean collides;
/** */
protected Axis collidesAxis;
/**
* Number of steps, counting advancing on one axis for all axes. Does not
* count the number of processed blocks. The step is increased before
@ -84,6 +80,11 @@ public abstract class AxisTracing implements ICollide, ISetMargins {
return collides;
}
@Override
public Axis getCollidingAxis() {
return collidesAxis;
}
public void setDefaultAxisOrder() {
setAxisOrder(Axis.Y_AXIS, Axis.X_AXIS, Axis.Z_AXIS);
}
@ -121,28 +122,27 @@ public abstract class AxisTracing implements ICollide, ISetMargins {
double y = this.y0;
double z = this.z0;
for (int i = 0; i < 3; i++) {
switch (axisOrder[i]) {
case Y_AXIS: {
runAxisY(x, y, z);
y = this.y1;
break;
}
case X_AXIS: {
runAxisX(x, y, z);
x = this.x1;
break;
}
case Z_AXIS: {
runAxisZ(x, y, z);
z = this.z1;
break;
}
default: {
// Just skip.
break;
}
final Axis axis = axisOrder[i];
if (axis == Axis.Y_AXIS) {
runAxisY(x, y, z);
y = this.y1;
}
else if (axis == Axis.X_AXIS) {
runAxisX(x, y, z);
x = this.x1;
}
else if (axis == Axis.Z_AXIS) {
runAxisZ(x, y, z);
z = this.z1;
}
else if (axis != Axis.NONE) {
// TODO: Might still just skip these.
// TODO: Should throw IllegalArgumentException with setting to this.
throw new IllegalStateException("Can not ");
}
// NONE = skip
if (collides) {
collidesAxis = axis;
break;
}
}

View File

@ -50,4 +50,12 @@ public interface ICollide {
*/
public boolean collides();
/**
* Optional information about which (sub-) type of checking lead to
* collision. Should only be considered valid, if collides() returns true.
*
* @return
*/
public Axis getCollidingAxis();
}

View File

@ -40,8 +40,6 @@ public class InteractRayTracing extends RayTracing {
protected BlockCache blockCache = null;
protected boolean collides = false;
protected final boolean strict;
protected int lastBx, lastBy, lastBz;
@ -94,10 +92,6 @@ public class InteractRayTracing extends RayTracing {
this.targetZ = targetZ;
}
public boolean collides() {
return collides;
}
/**
* Remove reference to BlockCache.
*/

View File

@ -22,8 +22,6 @@ public class PassableRayTracing extends RayTracing implements ICollidePassable {
protected BlockCache blockCache = null;
protected boolean collides = false;
protected boolean ignorefirst = false;
@Override
@ -52,11 +50,6 @@ public class PassableRayTracing extends RayTracing implements ICollidePassable {
ignorefirst = false;
}
@Override
public boolean collides(){
return collides;
}
@Override
public void setIgnoreFirst(){
this.ignorefirst = true;

View File

@ -64,6 +64,8 @@ public abstract class RayTracing implements ICollide {
/** Maximum steps that will be done. */
private int maxSteps = Integer.MAX_VALUE;
protected boolean collides = false;
public RayTracing(double x0, double y0, double z0, double x1, double y1, double z1) {
set(x0, y0, z0, x1, y1, z1);
}
@ -95,6 +97,7 @@ public abstract class RayTracing implements ICollide {
oZ = z0 - (double) blockZ;
t = 0.0;
step = 0;
collides = false;
}
/**
@ -353,14 +356,14 @@ public abstract class RayTracing implements ICollide {
return true;
}
/**
* Indicate if a collision appeared during loop(). This must be overridden to return a result other than false.
* @return
*/
@Override
public boolean collides() {
// TODO: Switch to using a protected flag right away.
return false;
return collides;
}
@Override
public Axis getCollidingAxis() {
return Axis.XYZ_AXES;
}
/**
@ -419,7 +422,8 @@ public abstract class RayTracing implements ICollide {
}
/**
* One step in the loop.
* One step in the loop. Set the collides flag to indicate a specific
* result.
*
* @param blockX
* The block coordinates regarded in this step.
@ -436,7 +440,9 @@ public abstract class RayTracing implements ICollide {
* If this is along the primary line, for which all transitions
* are done at once. The secondary line would cover all
* combinations of transitions off the primary line.
* @return If to continue processing at all.
* @return If to continue processing at all. Mind that the collides flag is
* not set based on the result, instead has to be set from within
* handling this method.
*/
protected abstract boolean step(int blockX, int blockY, int blockZ, double oX, double oY, double oZ, double dT, boolean isPrimary);