public static MovingObjectPosition raytrace(final World world,final Vec3 start,final Vec3 end,final CollisionDetector callback){
  final int startPosX=MathHelper.floor_double(start.xCoord);
  final int startPosY=MathHelper.floor_double(start.yCoord);
  final int startPosZ=MathHelper.floor_double(start.zCoord);
  final int endPosX=MathHelper.floor_double(end.xCoord);
  final int endPosY=MathHelper.floor_double(end.yCoord);
  final int endPosZ=MathHelper.floor_double(end.zCoord);
  final int stepX=endPosX > startPosX ? 1 : endPosX < startPosX ? -1 : 0;
  final int stepY=endPosY > startPosY ? 1 : endPosY < startPosY ? -1 : 0;
  final int stepZ=endPosZ > startPosZ ? 1 : endPosZ < startPosZ ? -1 : 0;
  final int gxp=startPosX + (endPosX > startPosX ? 1 : 0);
  final int gyp=startPosY + (endPosY > startPosY ? 1 : 0);
  final int gzp=startPosZ + (endPosZ > startPosZ ? 1 : 0);
  final double vx=end.xCoord == start.xCoord ? 1 : end.xCoord - start.xCoord;
  final double vy=end.yCoord == start.yCoord ? 1 : end.yCoord - start.yCoord;
  final double vz=end.zCoord == start.zCoord ? 1 : end.zCoord - start.zCoord;
  final double vxvy=vx * vy;
  final double vxvz=vx * vz;
  final double vyvz=vy * vz;
  final double scaledErrorX=stepX * vyvz;
  final double scaledErrorY=stepY * vxvz;
  final double scaledErrorZ=stepZ * vxvy;
  double errorX=(gxp - start.xCoord) * vyvz;
  double errorY=(gyp - start.yCoord) * vxvz;
  double errorZ=(gzp - start.zCoord) * vxvy;
  int currentPosX=startPosX;
  int currentPosY=startPosY;
  int currentPosZ=startPosZ;
  int emergencyExit=200;
  while (--emergencyExit > 0) {
    final BlockPos position=new BlockPos(currentPosX,currentPosY,currentPosZ);
    final MovingObjectPosition hit=callback.intersect(world,position,start,end);
    if (hit != null && hit.typeOfHit != MovingObjectPosition.MovingObjectType.MISS) {
      return hit;
    }
    if (currentPosX == endPosX && currentPosY == endPosY && currentPosZ == endPosZ) {
      return null;
    }
    final double xr=Math.abs(errorX);
    final double yr=Math.abs(errorY);
    final double zr=Math.abs(errorZ);
    if (stepX != 0 && (stepY == 0 || xr < yr) && (stepZ == 0 || xr < zr)) {
      currentPosX+=stepX;
      errorX+=scaledErrorX;
    }
 else     if (stepY != 0 && (stepZ == 0 || yr < zr)) {
      currentPosY+=stepY;
      errorY+=scaledErrorY;
    }
 else     if (stepZ != 0) {
      currentPosZ+=stepZ;
      errorZ+=scaledErrorZ;
    }
  }
  return null;
}

public static MovingObjectPosition raytrace ( final World world , final Vec3 start , final Vec3 end , final CollisionDetector callback ) { final int startPosX = MathHelper . floor_double ( start . xCoord ) ; final int startPosY = MathHelper . floor_double ( start . yCoord ) ; final int startPosZ = MathHelper . floor_double ( start . zCoord ) ; final int endPosX = MathHelper . floor_double ( end . xCoord ) ; final int endPosY = MathHelper . floor_double ( end . yCoord ) ; final int endPosZ = MathHelper . floor_double ( end . zCoord ) ; final int stepX = endPosX > startPosX ? 1 : endPosX < startPosX ? - 1 : 0 ; final int stepY = endPosY > startPosY ? 1 : endPosY < startPosY ? - 1 : 0 ; final int stepZ = endPosZ > startPosZ ? 1 : endPosZ < startPosZ ? - 1 : 0 ; final int gxp = startPosX + ( endPosX > startPosX ? 1 : 0 ) ; final int gyp = startPosY + ( endPosY > startPosY ? 1 : 0 ) ; final int gzp = startPosZ + ( endPosZ > startPosZ ? 1 : 0 ) ; final double vx = end . xCoord == start . xCoord ? 1 : end . xCoord - start . xCoord ; final double vy = end . yCoord == start . yCoord ? 1 : end . yCoord - start . yCoord ; final double vz = end . zCoord == start . zCoord ? 1 : end . zCoord - start . zCoord ; final double vxvy = vx * vy ; final double vxvz = vx * vz ; final double vyvz = vy * vz ; final double scaledErrorX = stepX * vyvz ; final double scaledErrorY = stepY * vxvz ; final double scaledErrorZ = stepZ * vxvy ; double errorX = ( gxp - start . xCoord ) * vyvz ; double errorY = ( gyp - start . yCoord ) * vxvz ; double errorZ = ( gzp - start . zCoord ) * vxvy ; int currentPosX = startPosX ; int currentPosY = startPosY ; int currentPosZ = startPosZ ; int emergencyExit = 200 ; while ( -- emergencyExit > 0 ) { final BlockPos position = new BlockPos ( currentPosX , currentPosY , currentPosZ ) ; final MovingObjectPosition hit = callback . intersect ( world , position , start , end ) ; if ( hit != null && hit . typeOfHit != MovingObjectPosition . MovingObjectType . MISS ) { return hit ; } if ( currentPosX == endPosX && currentPosY == endPosY && currentPosZ == endPosZ ) { return null ; } final double xr = Math . abs ( errorX ) ; final double yr = Math . abs ( errorY ) ; final double zr = Math . abs ( errorZ ) ; if ( stepX != 0 && ( stepY == 0 || xr < yr ) && ( stepZ == 0 || xr < zr ) ) { currentPosX += stepX ; errorX += scaledErrorX ; } else if ( stepY != 0 && ( stepZ == 0 || yr < zr ) ) { currentPosY += stepY ; errorY += scaledErrorY ; } else if ( stepZ != 0 ) { currentPosZ += stepZ ; errorZ += scaledErrorZ ; } } return null ; }
trace along the specified line , testing for collision with blocks along the way .
