Guest User

raycast.cpp

a guest
May 13th, 2013
402
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. #define ISWALL( Z, X, Y ) ((Z->data[ (X) + ((Y) * Z->width) ] & cWall ) > 0 )
  3. #define IPART( X ) ((float)((int)(X)))
  4.  
  5. //
  6. struct sCollideMap
  7. {
  8.     // map size and scale
  9.     uint32  width, height;
  10.     uint32  tileSize;
  11.     // tile data encoded as above
  12.     uint8  *data;
  13. };
  14.  
  15. //
  16. struct sCollideRay
  17. {
  18.     // ray end points
  19.     sint32 x1, y1, x2, y2;
  20.     // intersection location
  21.     sint32 i_x, i_y;
  22. };
  23.  
  24. //
  25. bool collide_raycast
  26. (
  27.     sCollideMap *map,
  28.     sCollideRay *ray
  29. )
  30. {
  31.     // ---- ---- ---- ---- ---- ---- ---- ---- SETUP
  32.     // initial location
  33.     float ix = ((float)(ray->x1)) / (float)map->tileSize;
  34.     float iy = ((float)(ray->y1)) / (float)map->tileSize;
  35.     // starting positions
  36.     float x_px = ix, x_py = iy;
  37.     float y_px = ix, y_py = iy;
  38.     // direction vector
  39.     float dx = ((float)(ray->x2)) - ((float)(ray->x1));
  40.     float dy = ((float)(ray->y2)) - ((float)(ray->y1));
  41.  
  42.     // ---- ---- ---- ---- ---- ---- ---- ---- Y AXIS INTERSECTIONS
  43.     if ( dy > 0 )
  44.     {
  45.         float yp = dx / dy;
  46.         //
  47.         y_px += ( IPART( y_py + 1 ) - y_py ) * yp;
  48.         y_py  =   IPART( y_py + 1 );
  49.         for ( ;; )
  50.         {
  51.             //
  52.             if ( IPART(y_py) >= map->height ) break;
  53.             if ( IPART(y_px) <  0           ) break;
  54.             if ( IPART(y_px) >= map->width  ) break;
  55.             //
  56.             if ( ISWALL( map, (int)y_px, (int)y_py ) )
  57.                 break;
  58.             //
  59.             y_px += yp;
  60.             y_py  = (float)( (int)y_py + 1 );
  61.         }
  62.     }
  63.     else if ( dy < 0 )
  64.     {  
  65.         float yp = dx / dy;
  66.         //
  67.         y_px -= (y_py - IPART( y_py ) ) * yp;
  68.         y_py  =         IPART( y_py );
  69.         for ( ;; )
  70.         {
  71.             //
  72.             if ( IPART(y_py-1) <  0          ) break;
  73.             if ( IPART(y_px  ) <  0          ) break;
  74.             if ( IPART(y_px  ) >= map->width ) break;
  75.             //
  76.             if ( ISWALL( map, (int)y_px, (int)(y_py-1) ) )
  77.                 break;
  78.             //
  79.             y_px -= yp;
  80.             y_py  = (float)( (int)y_py - 1 );
  81.         }
  82.     }
  83.  
  84.     // ---- ---- ---- ---- ---- ---- ---- ---- X AXIS INTERSECTIONS
  85.     if ( dx > 0 )
  86.     {  
  87.         float xp = dy / dx;
  88.         //
  89.         x_py += ( IPART( x_px + 1 ) - x_px ) * xp;
  90.         x_px  =   IPART( x_px+1 );
  91.         for (;; )
  92.         {
  93.             //
  94.             if ( IPART(x_px) >= map->width  ) break;
  95.             if ( IPART(x_py) <  0           ) break;
  96.             if ( IPART(x_py) >= map->height ) break;
  97.             //
  98.             if ( ISWALL( map, (int)x_px, (int)(x_py) ) )
  99.                 break;
  100.             //
  101.             x_px  = (float)( (int)x_px + 1 );
  102.             x_py += xp;
  103.         }
  104.     }
  105.     else if ( dx < 0 )
  106.     {
  107.         float xp = dy / dx;
  108.         //
  109.         x_py -= (x_px - IPART( x_px )) * xp;
  110.         x_px  =         IPART( x_px );
  111.         for ( ;; )
  112.         {
  113.             //
  114.             if ( IPART(x_px-1) <  0           ) break;
  115.             if ( IPART(x_py  ) <  0           ) break;
  116.             if ( IPART(x_py  ) >= map->height ) break;
  117.             //
  118.             if ( ISWALL( map, (int)(x_px-1), (int)(x_py) ) )
  119.                 break;
  120.             //
  121.             x_px  = (float)( (int)x_px - 1 );
  122.             x_py -= xp;
  123.         }
  124.     }
  125.  
  126.     // ---- ---- ---- ---- ---- ---- ---- ---- INTERSECTION SELECTION
  127.     float dx1 = (x_px-ix) * (x_px-ix);
  128.     float dy1 = (x_py-iy) * (x_py-iy);
  129.     float dx2 = (y_px-ix) * (y_px-ix);
  130.     float dy2 = (y_py-iy) * (y_py-iy);
  131.     //
  132.     if ( (dx1+dy1) < (dx2+dy2) )    msmark( x_px, x_py );
  133.     else                msmark( y_px, y_py );
  134.     //
  135.     return false;
  136. }
RAW Paste Data