Advertisement
SnowyCoder

Line Raycast with Blocks

Mar 15th, 2017
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.85 KB | None | 0 0
  1. import java.util.function.BiConsumer;
  2.  
  3. import static java.lang.Math.floor;
  4.  
  5. public class RaycastUtil {
  6.  
  7.     public enum Face {
  8.         UP, DOWN, FRONT, BACK, RIGHT, LEFT;
  9.  
  10.         @Override
  11.         public String toString() {
  12.             return name();
  13.         }
  14.     }
  15.  
  16.     public static double fceil(double n) {
  17.         return Math.floor(n) + 1.0;
  18.     }
  19.  
  20.  
  21.  
  22.     //http://www.cse.yorku.ca/~amana/research/grid.pdf
  23.     public static void line3D(double startX, double startY, double startZ, double endX, double endY, double endZ, BiConsumer<Vector3d, Face> callback) {
  24.         //Block's cordinates
  25.         int rx = (int) floor(startX);
  26.         int rex = (int) floor(endX);
  27.         int ry = (int) floor(startY);
  28.         int rey = (int) floor(endY);
  29.         int rz = (int) floor(startZ);
  30.         int rez = (int) floor(endZ);
  31.  
  32.  
  33.         if(rx == rex && ry == rey && rz == rez) {
  34.             callback.accept(new Vector3d(rx, ry, rz), null);
  35.             return;
  36.         }
  37.  
  38.         double dx = endX - startX;
  39.         double dy = endY - startY;
  40.         double dz = endZ - startZ;
  41.  
  42.         int stepX = (int) Math.signum(dx);
  43.         int stepY = (int) Math.signum(dy);
  44.         int stepZ = (int) Math.signum(dz);
  45.  
  46.         double tMaxX = dx == 0 ? Double.POSITIVE_INFINITY : (fceil(startX) - startX) / dx * stepX;
  47.         double tMaxY = dy == 0 ? Double.POSITIVE_INFINITY : (fceil(startY) - startY) / dy * stepY;
  48.         double tMaxZ = dz == 0 ? Double.POSITIVE_INFINITY : (fceil(startZ) - startZ) / dz * stepZ;
  49.  
  50.         double tDeltaX = tMaxX * dx * stepX;
  51.         double tDeltaY = tMaxY * dy * stepY;
  52.         double tDeltaZ = tMaxZ * dz * stepZ;
  53.  
  54.         final Face faceX = stepX > 0 ? Face.LEFT : Face.RIGHT;
  55.         final Face faceY = stepY > 0 ? Face.DOWN : Face.UP;
  56.         final Face faceZ = stepZ > 0 ? Face.FRONT : Face.BACK;
  57.  
  58.         callback.accept(new Vector3d(rx, ry, rz), null);
  59.  
  60.         do {
  61.             Face face;
  62.             if(tMaxX < tMaxY) {
  63.                 if(tMaxX < tMaxZ) {
  64.                     tMaxX += tDeltaX;
  65.                     startX += stepX;
  66.                     rx += stepX;
  67.                     face = faceX;
  68.                 } else {
  69.                     tMaxZ += tDeltaZ;
  70.                     startZ += stepZ;
  71.                     rz += stepZ;
  72.                     face = faceZ;
  73.                 }
  74.             } else {
  75.                 if(tMaxY < tMaxZ) {
  76.                     tMaxY += tDeltaY;
  77.                     startY += stepY;
  78.                     ry += stepY;
  79.                     face = faceY;
  80.                 } else {
  81.                     tMaxZ += tDeltaZ;
  82.                     startZ += stepZ;
  83.                     rz += stepZ;
  84.                     face = faceZ;
  85.                 }
  86.             }
  87.  
  88.             callback.accept(new Vector3d(rx, ry, rz), face);
  89.         } while(!(rx == rex && ry == rey && rz == rez));
  90.     }
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement