Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- #define ISWALL( Z, X, Y ) ((Z->data[ (X) + ((Y) * Z->width) ] & cWall ) > 0 )
- #define IPART( X ) ((float)((int)(X)))
- //
- struct sCollideMap
- {
- // map size and scale
- uint32 width, height;
- uint32 tileSize;
- // tile data encoded as above
- uint8 *data;
- };
- //
- struct sCollideRay
- {
- // ray end points
- sint32 x1, y1, x2, y2;
- // intersection location
- sint32 i_x, i_y;
- };
- //
- bool collide_raycast
- (
- sCollideMap *map,
- sCollideRay *ray
- )
- {
- // ---- ---- ---- ---- ---- ---- ---- ---- SETUP
- // initial location
- float ix = ((float)(ray->x1)) / (float)map->tileSize;
- float iy = ((float)(ray->y1)) / (float)map->tileSize;
- // starting positions
- float x_px = ix, x_py = iy;
- float y_px = ix, y_py = iy;
- // direction vector
- float dx = ((float)(ray->x2)) - ((float)(ray->x1));
- float dy = ((float)(ray->y2)) - ((float)(ray->y1));
- // ---- ---- ---- ---- ---- ---- ---- ---- Y AXIS INTERSECTIONS
- if ( dy > 0 )
- {
- float yp = dx / dy;
- //
- y_px += ( IPART( y_py + 1 ) - y_py ) * yp;
- y_py = IPART( y_py + 1 );
- for ( ;; )
- {
- //
- if ( IPART(y_py) >= map->height ) break;
- if ( IPART(y_px) < 0 ) break;
- if ( IPART(y_px) >= map->width ) break;
- //
- if ( ISWALL( map, (int)y_px, (int)y_py ) )
- break;
- //
- y_px += yp;
- y_py = (float)( (int)y_py + 1 );
- }
- }
- else if ( dy < 0 )
- {
- float yp = dx / dy;
- //
- y_px -= (y_py - IPART( y_py ) ) * yp;
- y_py = IPART( y_py );
- for ( ;; )
- {
- //
- if ( IPART(y_py-1) < 0 ) break;
- if ( IPART(y_px ) < 0 ) break;
- if ( IPART(y_px ) >= map->width ) break;
- //
- if ( ISWALL( map, (int)y_px, (int)(y_py-1) ) )
- break;
- //
- y_px -= yp;
- y_py = (float)( (int)y_py - 1 );
- }
- }
- // ---- ---- ---- ---- ---- ---- ---- ---- X AXIS INTERSECTIONS
- if ( dx > 0 )
- {
- float xp = dy / dx;
- //
- x_py += ( IPART( x_px + 1 ) - x_px ) * xp;
- x_px = IPART( x_px+1 );
- for (;; )
- {
- //
- if ( IPART(x_px) >= map->width ) break;
- if ( IPART(x_py) < 0 ) break;
- if ( IPART(x_py) >= map->height ) break;
- //
- if ( ISWALL( map, (int)x_px, (int)(x_py) ) )
- break;
- //
- x_px = (float)( (int)x_px + 1 );
- x_py += xp;
- }
- }
- else if ( dx < 0 )
- {
- float xp = dy / dx;
- //
- x_py -= (x_px - IPART( x_px )) * xp;
- x_px = IPART( x_px );
- for ( ;; )
- {
- //
- if ( IPART(x_px-1) < 0 ) break;
- if ( IPART(x_py ) < 0 ) break;
- if ( IPART(x_py ) >= map->height ) break;
- //
- if ( ISWALL( map, (int)(x_px-1), (int)(x_py) ) )
- break;
- //
- x_px = (float)( (int)x_px - 1 );
- x_py -= xp;
- }
- }
- // ---- ---- ---- ---- ---- ---- ---- ---- INTERSECTION SELECTION
- float dx1 = (x_px-ix) * (x_px-ix);
- float dy1 = (x_py-iy) * (x_py-iy);
- float dx2 = (y_px-ix) * (y_px-ix);
- float dy2 = (y_py-iy) * (y_py-iy);
- //
- if ( (dx1+dy1) < (dx2+dy2) ) msmark( x_px, x_py );
- else msmark( y_px, y_py );
- //
- return false;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement