Guest User

raycast.cpp

a guest
Jun 18th, 2013
276
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. struct sHitInfo
  3. {
  4.     int   tx, ty;   // collision tile coordinates
  5.     float rx, ry;   // intersection point
  6.     int   side;     // face of the tile that was hit
  7.                     // 0[up] 1[right] 2[down] 3[left]
  8. };
  9.  
  10. //
  11. void raycast( float x1, float y1, float x2, float y2, sHitInfo *hit )
  12. {
  13.     // difference vectors
  14.     float dx = x2-x1;
  15.     float dy = y2-y1;
  16.  
  17.     // axis step values
  18.     float x_step = dx / (dy + (dy==0)); // ( avoid / 0 when dy==0 )
  19.     float y_step = dy / (dx + (dx==0)); // ( avoid / 0 when dx==0 )
  20.  
  21.     // set to something un-naturaly large when ((dx or dy) == 0)
  22.     if ( dx == 0 ) y_step = 100000;
  23.     if ( dy == 0 ) x_step = 100000;
  24.  
  25.     // x quantised crossing point
  26.     float x_px  = (float)( (int)x1 + (int)(dx < 0 ) );
  27.     float x_py  = - (x1-x_px) * y_step;
  28.           x_px -= x1;
  29.  
  30.     // y quantised crossing point
  31.     float y_py  = (float)( (int)y1 + (int)(dy < 0 ) );
  32.     float y_px  = - (y1-y_py) * x_step;
  33.           y_py -= y1;
  34.  
  35.     // integer map coords
  36.     int ix = (int)x1;
  37.     int iy = (int)y1;
  38.  
  39.     // span? hmm, gradient riding variables
  40.     float x_sp =-absf( x_px );
  41.     float y_sp =-absf( y_px );
  42.  
  43.     // start stepping
  44.     for ( ;; )
  45.     {
  46.         // make a step along the x axis
  47.         if ( (x_sp+1) < (y_sp+absf(x_step) ) )
  48.         {
  49.             // update integer map cell coords
  50.             ix += signi( dx );
  51.             // update gradient variables
  52.             x_sp += 1;
  53.             // update to find next crossing position
  54.             x_px += signf( dx );
  55.             x_py += absf( y_step ) * signf( dy );
  56.  
  57.             // have we hit a wall
  58.             if ( isBlocked( ix, iy ) )
  59.             {
  60.                 // tile space coordinates of hit tile
  61.                 hit->tx = ix;
  62.                 hit->ty = iy;
  63.                 // ray collision point
  64.                 hit->rx = x1+x_px;
  65.                 hit->ry = y1+x_py;
  66.                 // encode the side that was hit
  67.                 hit->side = 1 + ((dx > 0) << 1);
  68.                 break;
  69.             }
  70.         }
  71.         // make a step along the y axis
  72.         else
  73.         {
  74.             // update integer map cell coords
  75.             iy += signi( dy );
  76.             // update gradient variables
  77.             y_sp += absf( x_step );
  78.             // update to find next crossing position
  79.             y_px += absf( x_step ) * signf( dx );
  80.             y_py += signf( dy );
  81.  
  82.             // have we hit a wall
  83.             if ( isBlocked( ix, iy ) )
  84.             {
  85.                 // tile space coordinates of hit tile
  86.                 hit->tx = ix;
  87.                 hit->ty = iy;
  88.                 // ray collision point
  89.                 hit->rx = x1+y_px;
  90.                 hit->ry = y1+y_py;
  91.                 // encode the side that was hit
  92.                 hit->side = 0 + ((dy < 0) << 1);
  93.                 break;
  94.             }
  95.         }
  96.     }
  97. }
RAW Paste Data