Skip to content

Commit

Permalink
Fix PassablRayTracing not respecting block flags.
Browse files Browse the repository at this point in the history
Heavier but more consistent: use BlockProperties.collidesBlock, since we
don't really check the blocks bounding box against a ray anyway, but
collision with the full moves bounding box. Getting a blocks shape
should some day be routed through BlockProperties so the shape is
correct from the start.
  • Loading branch information
asofold committed Mar 14, 2013
1 parent 0e506eb commit b5e8ee7
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 52 deletions.
Expand Up @@ -2177,5 +2177,75 @@ public static void cleanup() {
blockCache = null;
// TODO: might empty mappings...
}

/**
*
* @param access
* @param blockX Block location.
* @param blockY
* @param blockZ
* @param oX Origin / offset from block location.
* @param oY
* @param oZ
* @param dX Direction (multiplied by dT to get end point of move).
* @param dY
* @param dZ
* @param dT
* @return
*/
public static final boolean isPassableRay(final BlockCache access, final int blockX, final int blockY, final int blockZ, final double oX, final double oY, final double oZ, final double dX, final double dY, final double dZ, final double dT) {
final int id = access.getTypeId(blockX, blockY, blockZ);
if (BlockProperties.isPassable(id)) return true;
double[] bounds = access.getBounds(blockX, blockY, blockZ);
if (bounds == null) return true;

// Simplified check: Only collision of bounds of the full move is checked.
final double minX, maxX;
if (dX < 0){
minX = dX * dT + oX + blockX;
maxX = oX + blockX;
}
else{
maxX = dX * dT + oX + blockX;
minX = oX + blockX;
}
final double minY, maxY;
if (dY < 0){
minY = dY * dT + oY + blockY;
maxY = oY + blockY;
}
else{
maxY = dY * dT + oY + blockY;
minY = oY + blockY;
}
final double minZ, maxZ;
if (dX < 0){
minZ = dZ * dT + oZ + blockZ;
maxZ = oZ + blockZ;
}
else{
maxZ = dZ * dT + oZ + blockZ;
minZ = oZ + blockZ;
}
if (!collidesBlock(access, minX, minY, minZ, maxX, maxY, maxZ, blockX, blockY, blockZ, id, bounds, blockFlags[id])){
// TODO: Might check for fence too, here.
return true;
}

// TODO: Actual ray-collision checking?
// TODO: Heuristic workaround for certain situations [might be better outside of this, probably a simplified version ofr the normal case]?

// Check for workarounds.
// TODO: check f_itchy once exists.
if (BlockProperties.isPassableWorkaround(access, blockX, blockY, blockZ, oX, oY, oZ, id, dX, dY, dZ, dT)){
return true;
}
// Does collide (most likely).
// TODO: This is not entirely accurate.
// TODO: Moving such that the full move rect overlaps, but no real collision (diagonal moves).
// TODO: "Wrong" moves through edges of blocks (not sure, needs reproducing).
// (Could allow start-end if passable + check first collision time or some estimate.)
return false;
}

}
Expand Up @@ -49,61 +49,14 @@ public void cleanup(){

@Override
protected boolean step(final int blockX, final int blockY, final int blockZ, final double oX, final double oY, final double oZ, final double dT) {
final int id = blockCache.getTypeId(blockX, blockY, blockZ);
if (BlockProperties.isPassable(id)) return true;
double[] bounds = blockCache.getBounds(blockX, blockY, blockZ);
if (bounds == null) return true;

// TODO: Other problem (forgot)...

// // Check if is already inside.
// // TODO: This might be superfluous since below method used.
// if (oX >= bounds[0] && oX < bounds[3] && oY >= bounds[1] && oY < bounds[4] && oZ >= bounds[2] && oZ < bounds[5]){
// if (!BlockProperties.isPassableWorkaround(blockCache, blockX, blockY, blockZ, oX, oY, oZ, id, 0, 0, 0, 0)){
// collides = true;
// return true;
// }
// }
// Check extrapolation [all three intervals must be hit].
if (dX < 0){
if (oX < bounds[0]) return true;
else if (oX + dX * dT >= bounds[3]) return true;
}
else{
if (oX >= bounds[3]) return true;
else if (oX + dX * dT < bounds[0]) return true;
}
if (dY < 0){
if (oY < bounds[1]) return true;
else if (oY + dY * dT >= bounds[4]) return true;
}
else{
if (oY >= bounds[4]) return true;
else if (oY + dY * dT < bounds[1]) return true;
}
if (dZ < 0){
if (oZ < bounds[2]) return true;
else if (oZ + dZ * dT >= bounds[5]) return true;
// Just delegate.
if (BlockProperties.isPassableRay(blockCache, blockX, blockY, blockZ, oX, oY, oZ, dX, dY, dZ, dT)){
return true;
}
else{
if (oZ >= bounds[5]) return true;
else if (oZ + dZ * dT < bounds[2]) return true;
}

// TODO: Heuristic workaround for certain situations [might be better outside of this, probably a simplified version ofr the normal case]?

// Check for workarounds.
// TODO: check f_itchy once exists.
if (BlockProperties.isPassableWorkaround(blockCache, blockX, blockY, blockZ, oX, oY, oZ, id, dX, dY, dZ, dT)){
return true;
collides = true;
return false;
}
// Does collide (most likely).
// TODO: This is not entirely accurate.
// TODO: Moving such that the full move rect overlaps, but no real collision (diagonal moves).
// TODO: "Wrong" moves through edges of blocks (not sure, needs reproducing).
// (Could allow start-end if passable + check first collision time or some estimate.)
collides = true;
return false;
}

}

0 comments on commit b5e8ee7

Please sign in to comment.