Fix PassablRayTracing not respecting block flags.

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.
This commit is contained in:
asofold 2013-03-14 08:27:58 +01:00
parent 0e506eb967
commit b5e8ee7935
2 changed files with 76 additions and 53 deletions

View File

@ -2177,5 +2177,75 @@ public class BlockProperties {
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;
}
}

View File

@ -49,61 +49,14 @@ public class PassableRayTracing extends RayTracing{
@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;
}
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)){
// Just delegate.
if (BlockProperties.isPassableRay(blockCache, blockX, blockY, blockZ, oX, oY, oZ, 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.)
collides = true;
return false;
else{
collides = true;
return false;
}
}
}