Advertisement
runewalsh

Rays 2

Apr 17th, 2020
801
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.87 KB | None | 0 0
  1. public RayCollision rayCast(Double2 coords, Rotation angle, int maxRange) {
  2.     // distances to the horizontal/vertical walls
  3.     RayCollision h = new RayCollision(), v = new RayCollision();
  4.  
  5.     // intersections with "horizontal" walls
  6.     if (angle.sina != 0) {
  7.         // up and down are shuffled because of the coordinates system
  8.         boolean downwards = angle.sina > 0;
  9.  
  10.         // coordinates of the first possible collision
  11.         double invSinA = 1 / angle.sina, invTanA = angle.cosa * invSinA;
  12.         double y = downwards ? Math.ceil(coords.y) : Math.floor(coords.y);
  13.         double x = coords.x + (y - coords.y) * invTanA;
  14.         Double2 current = new Double2(x, y);
  15.         int tilesDistance = 0;
  16.  
  17.         // every next collisions are placed evenly (intercept theorem)
  18.         Double2 step = new Double2((downwards ? 1 : -1) * invTanA, downwards ? 1 : -1);
  19.         while (tilesDistance <= maxRange) {
  20.             Int2 tileCoords = current.add(0, downwards ? 0.1 : -0.1).toInt();
  21.             if (!tileField.isEmpty(tileCoords)) {
  22.                 h.tile = tileCoords;
  23.                     h.hitPoint = downwards ? current.x % 1 : 1 - current.x % 1;
  24.                     break;
  25.             }
  26.             current = current.add(step);
  27.             tilesDistance++;
  28.         }
  29.         if (tilesDistance <= maxRange) {
  30.             h.d = Math.abs((current.y - coords.y) * invSinA);
  31.         }
  32.     }
  33.  
  34.     // intersections with "vertical" walls
  35.     if (angle.cosa != 0) {
  36.         boolean right = angle.cosa > 0;
  37.  
  38.         // first collision
  39.         double invCosA = 1 / angle.cosa, tanA = angle.sina * invCosA;
  40.         double x = right ? Math.ceil(coords.x) : Math.floor(coords.x);
  41.         double y = coords.y + (x - coords.x) * tanA;
  42.         Double2 current = new Double2(x, y);
  43.         int tilesDistance = 0;
  44.  
  45.         // next collisions
  46.         Double2 step = new Double2(right ? 1 : -1, (right ? 1 : -1) * tanA);
  47.         while (tilesDistance <= maxRange) {
  48.             Int2 tileCoords = current.add(right ? 0.1 : -0.1, 0).toInt();
  49.             if (!tileField.isEmpty(tileCoords)) {
  50.                 v.tile = tileCoords;
  51.                 v.hitPoint = right ? 1 - current.y % 1 : current.y % 1;
  52.                 break;
  53.             }
  54.             current = current.add(step);
  55.             tilesDistance++;
  56.         }
  57.         if (tilesDistance <= maxRange) {
  58.             v.d = Math.abs((current.x - coords.x) * invCosA);
  59.         }
  60.     }
  61.     if (h.d < v.d) {
  62.         return h;
  63.     } else {
  64.         return v;
  65.     }
  66. }
  67.  
  68. Double2 pos = player.getCoords();
  69. Rotation angle = player.getRotation();
  70. Rotation angleDelta = new Rotation(FOV / stripsCount);
  71. for (int i = 0; i < stripsCount; i++) {
  72.     // multiplying by cosine scales the distances an removes the fish eye effect
  73.     WalkingGameplay.RayCollision rayCollision = gameplay.rayCast(pos, angle, 10);
  74.     angle = angle.combine(angleDelta);
  75. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement