Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Collision grid, 16x16 tiles
- - create
- + set( x16, y16 )
- + unset( x16, y16 )
- + test( x, y )
- + raycast( x1, y1, x2, y2, notestfirst ) => null / dt, isp_x, isp_y
- + aabbtest( x1, y1, x2, y2 ) => null / true, xnrm, ynrm, push
- */
- global ColGrid = {};
- function ColGrid.create()
- {
- data =
- {
- tiles = map(),
- };
- return class( data, ColGrid );
- }
- function ColGrid._getkey( x16, y16 )
- {
- return ((x16&0xffff)<<16) | (y16&0xffff);
- }
- function ColGrid.set( x16, y16 )
- {
- this.tiles[ this._getkey( x16, y16 ) ] = true;
- }
- function ColGrid.unset( x16, y16 )
- {
- unset( this.tiles, this._getkey( x16, y16 ) );
- }
- function ColGrid.test( x, y )
- {
- x16 = toint( floor( x / 16 ) );
- y16 = toint( floor( y / 16 ) );
- return isset( this.tiles, this._getkey( x16, y16 ) );
- }
- function ColGrid.raycast( x1, y1, x2, y2, notestfirst )
- {
- x1_16 = toint( floor( x1 / 16 ) );
- y1_16 = toint( floor( y1 / 16 ) );
- x2_16 = toint( floor( x2 / 16 ) );
- y2_16 = toint( floor( y2 / 16 ) );
- if( !notestfirst && isset( this.tiles, this._getkey( x1_16, y1_16 ) ) )
- return 0, x1, y1;
- if( x1_16 == x2_16 && y1_16 == y2_16 )
- return null;
- x16 = x1_16;
- y16 = y1_16;
- xdist = x2 - x1;
- ydist = y2 - y1;
- stepX = if( xdist >= 0, 1, -1 );
- stepY = if( ydist >= 0, 1, -1 );
- len = sqrt( xdist * xdist + ydist * ydist );
- if( xdist == 0 )
- {
- tMaxX = 3.8e+10;
- tDeltaX = 0;
- }
- else
- {
- tMaxX = ( floor( x1_16 + ( xdist > 0 ) ) * 16 - x1 ) * len / xdist; // should be +
- tDeltaX = 16 * len / abs( xdist );
- }
- if( ydist == 0 )
- {
- tMaxY = 3.8e+10;
- tDeltaY = 0;
- }
- else
- {
- tMaxY = ( floor( y1_16 + ( ydist > 0 ) ) * 16 - y1 ) * len / ydist; // should be +
- tDeltaY = 16 * len / abs( ydist );
- }
- t = if( tMaxX < tMaxY, tMaxX, tMaxY );
- while( x16 != x2_16 || y16 != y2_16 )
- {
- if( tMaxX < tMaxY )
- {
- t += tMaxX;
- tMaxX += tDeltaX;
- x16 += stepX;
- }
- else
- {
- t = tMaxY;
- tMaxY += tDeltaY;
- y16 += stepY;
- }
- if( isset( this.tiles, this._getkey( x16, y16 ) ) )
- {
- q = t / len;
- q1 = 1 - q;
- return q, x1 * q1 + x2 * q, y1 * q1 + y2 * q;
- }
- }
- return null;
- }
- function _aabb_aabb_resolve( ax1, ay1, ax2, ay2, bx1, by1, bx2, by2 )
- {
- // in an intersection all of these are non-negative
- dx1 = ax2 - bx1;
- dx2 = bx2 - ax1;
- dy1 = ay2 - by1;
- dy2 = by2 - ay1;
- // find smallest of those and resolve assuming BB1 is to be moved
- if( dx1 < dx2 )
- {
- if( dx1 < dy1 )
- {
- if( dx1 < dy2 )
- return -dx1, 0;
- else // dy2
- return 0, dy2;
- }
- else // dy1
- {
- if( dy1 < dy2 )
- return 0, -dy1;
- else // dy2
- return 0, dy2;
- }
- }
- else // dx2
- {
- if( dx2 < dy1 )
- {
- if( dx2 < dy2 )
- return dx2, 0;
- else
- return 0, dy2;
- }
- else // dy1
- {
- if( dy1 < dy2 )
- return 0, -dy1;
- else // dy2
- return 0, dy2;
- }
- }
- }
- function ColGrid.aabbtest( x1, y1, x2, y2 )
- {
- x1_16 = toint( floor( x1 / 16 ) );
- y1_16 = toint( floor( y1 / 16 ) );
- x2_16 = toint( floor( x2 / 16 ) );
- y2_16 = toint( floor( y2 / 16 ) );
- nx = 0;
- ny = 0;
- isc = 0;
- for( y16 = y1_16; y16 <= y2_16; ++y16 )
- {
- for( x16 = x1_16; x16 <= x2_16; ++x16 )
- {
- if( isset( this.tiles, this._getkey( x16, y16 ) ) )
- {
- (cx,cy) = _aabb_aabb_resolve( x1, y1, x2, y2, x16 * 16, y16 * 16, x16 * 16 + 16, y16 * 16 + 16 );
- nx += cx;
- ny += cy;
- isc++;
- }
- }
- }
- if( isc )
- {
- nx /= isc;
- ny /= isc;
- }
- if( nx != 0 || ny != 0 )
- {
- nd = sqrt( nx * nx + ny * ny );
- nx /= nd;
- ny /= nd;
- return true, nx, ny, nd;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement