Advertisement
jargon

// LabDemo2Js (Beta) :: "calculate Walls.js"

Sep 17th, 2024 (edited)
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // LabDemo2Js (Beta) :: "calculate Walls.js"
  2.  
  3. // Raycasting and rendering logic for walls
  4. function calculateWalls(canvas) {
  5.    
  6.     // [ canvas, context, XDIM, YDIM ] = windowFit(canvas);
  7.    
  8.     // [ XDIM, YDIM ] = [ 320, 240 ];
  9.    
  10.     walls.length = 0; // Reset the array
  11.    
  12.     cosang = Math.cos(player.angle);
  13.     sinang = Math.sin(player.angle);
  14.    
  15.     vxinc = sinang * -2 / XDIM;
  16.     vx = cosang + sinang + vxinc * 0.5;
  17.    
  18.     vyinc = cosang * 2 / XDIM;
  19.     vy = sinang - cosang + vyinc * 0.5;
  20.  
  21.     for (let sx = 0; sx < XDIM; sx++) {
  22.        
  23.         scan.x = Math.floor(player.x);
  24.         xdir = Math.sign(vx);
  25.         incx = Math.abs(vx);
  26.        
  27.         scan.y = Math.floor(player.y);
  28.         ydir = Math.sign(vy);
  29.         incy = Math.abs(vy);
  30.        
  31.         xtemp = player.x - scan.x;
  32.         if (xdir > 0) xtemp = 1 - xtemp;
  33.        
  34.         ytemp = player.y - scan.y;
  35.         if (ydir > 0) ytemp = 1 - ytemp;
  36.        
  37.         d = xtemp * incy - ytemp * incx;
  38.  
  39.         let textureX; // Horizontal texture position
  40.        
  41.         // Raycasting loop to find the closest wall
  42.         while (true) {
  43.            
  44.             if (d < 0) {
  45.                
  46.                 scan.x += xdir;
  47.                
  48.                 if (scan.x < 0 || scan.x >= board.length || scan.y < 0 || scan.y >= board[1].length) break;
  49.                
  50.                 if (board[scan.x] && board[scan.x][scan.y] && board[scan.x][scan.y][0]) {
  51.                    
  52.                     hx = scan.x;
  53.                    
  54.                     if (xdir < 0) hx += 1;
  55.                    
  56.                     hy = player.y + vy * (hx - player.x) / vx;
  57.                    
  58.                     bbx = Math.floor((hy - Math.floor(hy)) * board[1].length);
  59.                    
  60.                     if (xdir < 0) bbx = board.length - bbx;
  61.                    
  62.                     // Capture horizontal texture position
  63.                    
  64.                     textureX = hy - Math.floor(hy); // When moving vertically
  65.                    
  66.                     if(detectBackFace()){
  67.                         textureX = hy - textureX;
  68.                     }
  69.                    
  70.                     break;
  71.                 }
  72.                
  73.                 d += incy;
  74.                
  75.             } else {
  76.                
  77.                 scan.y += ydir;
  78.                
  79.                 if (scan.x < 0 || scan.x >= MagicSpan || scan.y < 0 || scan.y >= MagicSpan) break;
  80.                
  81.                 if (
  82.                     board &&
  83.                     board[Math.floor(scan.x)] &&
  84.                     board[Math.floor(scan.x)][Math.floor(scan.y)] &&
  85.                     board[Math.floor(scan.x)][Math.floor(scan.y)][0]
  86.                 ){
  87.                    
  88.                     hy = scan.y;
  89.                    
  90.                     if (ydir < 0) hy += 1;
  91.                    
  92.                     hx = player.x + vx * (hy - player.y) / vy;
  93.                    
  94.                     bbx = Math.floor((hx - Math.floor(hx)) * board.length);
  95.                    
  96.                     if (ydir > 0) bbx = board[0].length - bbx;
  97.                    
  98.                     // Capture horizontal texture position
  99.                    
  100.                     textureX = hx - Math.floor(hx); // When moving horizontally
  101.                    
  102.                     if(detectBackFace()){
  103.                         textureX = hx - textureX;
  104.                     }
  105.                    
  106.                     break;
  107.                 }
  108.                 d -= incx;
  109.             }
  110.         }
  111.  
  112.         // Calculate the distance to the wall
  113.         dist = cosang * (hx - player.x) + sinang * (hy - player.y);
  114.  
  115.         if (dist > MagicMin / MagicSpan) {
  116.            
  117.             // Calculate vertical screen positions
  118.             sy1 = Math.floor(YDIM / 2 + (-player.z - 0.5) * HVAL / dist);
  119.             sy2 = Math.floor(YDIM / 2 + (-player.z + 0.5) * HVAL / dist);
  120.  
  121.             // Apply clipping to ensure the strip stays within the screen
  122.             let clippedTop = 0;
  123.             let clippedBottom = 0;
  124.  
  125.             if (sy1 < 0) {
  126.                 clippedTop = -sy1;
  127.                 sy1 = 0;
  128.             }
  129.             if (sy2 >= YDIM) {
  130.                 clippedBottom = sy2 - (YDIM - MagicMin);
  131.                 sy2 = YDIM - MagicMin;
  132.             }
  133.  
  134.             const visibleHeight = sy2 - sy1 + MagicMin;
  135.  
  136.             // Calculate the vertical texture position (V-coordinate)
  137.            
  138.             let textureYStart = clippedTop / visibleHeight;
  139.            
  140.             let textureYEnd = (visibleHeight - clippedBottom) / visibleHeight;
  141.  
  142.             // Render the wall slice with the calculated height
  143.             // renderMock(sx, visibleHeight);
  144.            
  145.             if (
  146.                 board &&
  147.                 board[Math.floor(scan.x)] &&
  148.                 board[Math.floor(scan.x)][Math.floor(scan.y)] &&
  149.                 board[Math.floor(scan.x)][Math.floor(scan.y)][0] &&
  150.                 board[Math.floor(scan.x)][Math.floor(scan.y)][0] !== ``
  151.             ){
  152.                 mock = mockData[board[Math.floor(scan.x)][Math.floor(scan.y)][0]];
  153.                
  154.                 if (mock.complete && mock.naturalWidth > 0) {
  155.                    
  156.                     walls.push({
  157.                         graphic: board[Math.floor(scan.x)][Math.floor(scan.y)][0],
  158.                         scanx: scan.x,
  159.                         scany: scan.y,
  160.                         sx: sx,
  161.                         sy1: sy1,
  162.                         sy2: sy2,
  163.                         visibleHeight: visibleHeight,
  164.                         dist: dist,
  165.                         textureX: textureX,
  166.                         textureYStart: textureYStart,
  167.                         textureYEnd: textureYEnd
  168.                     });
  169.                    
  170.                     break;             
  171.                    
  172.                 }else{
  173.                     console.log(`Faulty Mock: ${board[Math.floor(scan.x)][Math.floor(scan.y)][0]}`);
  174.                 }
  175.             }else{
  176.                 console.log(`Faulty Board Position: ${Math.floor(scan.x)},${Math.floor(scan.y)}`);
  177.                 break;
  178.             }
  179.         } else {
  180.            
  181.             // If no wall is found, render the floor/ceiling
  182.            
  183.             sy1 = YDIM / 2;
  184.             sy2 = sy1;
  185.            
  186.             visibleHeight = YDIM;
  187.            
  188.             if (
  189.                 board &&
  190.                 board[Math.floor(scan.x)] &&
  191.                 board[Math.floor(scan.x)][Math.floor(scan.y)] &&
  192.                 board[Math.floor(scan.x)][Math.floor(scan.y)][0] &&
  193.                 board[Math.floor(scan.x)][Math.floor(scan.y)][0] !== ``
  194.             ){
  195.                 mock = mockData[board[Math.floor(scan.x)][Math.floor(scan.y)][0]];
  196.                
  197.                 if (mock.complete && mock.naturalWidth > 0) {
  198.                    
  199.                     walls.push({
  200.                         graphic: board[Math.floor(scan.x)][Math.floor(scan.y)][0],
  201.                         scanx: scan.x,
  202.                         scany: scan.y,
  203.                         sx: sx,
  204.                         sy1: sy1,
  205.                         sy2: sy2,
  206.                         visibleHeight: visibleHeight,
  207.                         dist: dist,
  208.                         textureX: textureX,
  209.                         textureYStart: textureYStart,
  210.                         textureYEnd: textureYEnd
  211.                     });
  212.                    
  213.                     break;
  214.                
  215.                 }else{
  216.                     console.log(`Faulty Mock: ${board[Math.floor(scan.x)][Math.floor(scan.y)][0]}`);
  217.                 }
  218.             }else{
  219.                 console.log(`Faulty Board Position: ${Math.floor(scan.x)},${Math.floor(scan.y)}`);
  220.                 break;
  221.             }
  222.         }
  223.  
  224.         // Update the increment values for the next strip
  225.         vx += vxinc;
  226.         vy += vyinc;
  227.     }
  228. }
  229.  
  230. // Function to determine if a face is the back face
  231. function isBackFace(faceNormal, cameraPosition, facePosition) {
  232.     // Calculate the view direction vector
  233.     let viewDirection = {
  234.         x: facePosition.x - cameraPosition.x,
  235.         y: facePosition.y - cameraPosition.y,
  236.         z: facePosition.z - cameraPosition.z
  237.     };
  238.  
  239.     // Normalize the view direction (optional, for consistency)
  240.     let length = Math.sqrt(viewDirection.x * viewDirection.x + viewDirection.y * viewDirection.y + viewDirection.z * viewDirection.z);
  241.     viewDirection.x /= length;
  242.     viewDirection.y /= length;
  243.     viewDirection.z /= length;
  244.  
  245.     // Calculate the dot product of the face normal and the view direction
  246.     let dotProduct = faceNormal.x * viewDirection.x + faceNormal.y * viewDirection.y + faceNormal.z * viewDirection.z;
  247.  
  248.     // If the dot product is negative, it's the back face
  249.     return dotProduct < 0;
  250. }
  251.  
  252. // Example usage
  253. function detectBackFace ( ) {
  254.    
  255.     let cameraPosition = { x: player.x, y: player.y, z: player.z };
  256.     let facePosition = { x: scan.x, y: scan.y, z: 0 };
  257.  
  258.     // Assume this is the normal for a face pointing outwards
  259.     let faceNormal = { x: 0, y: 0, z: -1 };
  260.  
  261.     if (isBackFace(faceNormal, cameraPosition, facePosition)) {
  262.         // console.log("This is the back face.");
  263.         return true;
  264.     } else {
  265.         // console.log("This is the front face.");
  266.         return false;
  267.     }
  268. }
  269.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement