Nez.Portable/Physics/SpatialHash.cs
/// <summary>
/// casts a line through the spatial hash and fills the hits array up with any colliders that the line hits
/// </summary>
/// <returns>the number of Colliders returned</returns>
/// <param name="start">Start.</param>
/// <param name="end">End.</param>
/// <param name="hits">Hits.</param>
/// <param name="layerMask">Layer mask.</param>
casts a line through the spatial hash and fills the hits array up with any colliders that the line hits
casts a line through the spatial hash and fills the hits array up with any colliders that the line hits
public int linecast(Vector2 start, Vector2 end, RaycastHit[] hits, int layerMask)
        {
            var ray = new Ray2D(start, end);
            _raycastParser.start(ref ray, hits, layerMask);
            start.X *= _inverseCellSize;
            start.Y *= _inverseCellSize;
            var endCell = cellCoords(end.X, end.Y);
            var intX = Mathf.floorToInt(start.X);
            var intY = Mathf.floorToInt(start.Y);
            var stepX = Math.Sign(ray.direction.X);
            var stepY = Math.Sign(ray.direction.Y);
            if (intX == endCell.X) stepX = 0;
            if (intY == endCell.Y) stepY = 0;
            var boundaryX = intX + (stepX > 0 ? 1 : 0);
            var boundaryY = intY + (stepY > 0 ? 1 : 0);
            var tMaxX = (boundaryX - start.X) / ray.direction.X;
            var tMaxY = (boundaryY - start.Y) / ray.direction.Y;
            if (ray.direction.X == 0f || stepX == 0)
                tMaxX = float.PositiveInfinity;
            if (ray.direction.Y == 0f || stepY == 0)
                tMaxY = float.PositiveInfinity;
            var tDeltaX = stepX / ray.direction.X;
            var tDeltaY = stepY / ray.direction.Y;
            var cell = cellAtPosition(intX, intY);
            if (cell != null && _raycastParser.checkRayIntersection(intX, intY, cell))
            {
                _raycastParser.reset();
                return _raycastParser.hitCounter;
            }
            while (intX != endCell.X || intY != endCell.Y)
            {
                if (tMaxX < tMaxY)
                {
                    intX += stepX;
                    tMaxX += tDeltaX;
                }
                else
                {
                    intY += stepY;
                    tMaxY += tDeltaY;
                }
                cell = cellAtPosition(intX, intY);
                if (cell != null && _raycastParser.checkRayIntersection(intX, intY, cell))
                {
                    _raycastParser.reset();
                    return _raycastParser.hitCounter;
                }
            }
            _raycastParser.reset();
            return _raycastParser.hitCounter;
        }
public int linecast ( Vector2 start , Vector2 end , RaycastHit [ ] hits , int layerMask ) { var ray = new Ray2D ( start , end ) ; _raycastParser . start ( ref ray , hits , layerMask ) ; start . X *= _inverseCellSize ; start . Y *= _inverseCellSize ; var endCell = cellCoords ( end . X , end . Y ) ; var intX = Mathf . floorToInt ( start . X ) ; var intY = Mathf . floorToInt ( start . Y ) ; var stepX = Math . Sign ( ray . direction . X ) ; var stepY = Math . Sign ( ray . direction . Y ) ; if ( intX == endCell . X ) stepX = 0 ; if ( intY == endCell . Y ) stepY = 0 ; var boundaryX = intX + ( stepX > 0 ? 1 : 0 ) ; var boundaryY = intY + ( stepY > 0 ? 1 : 0 ) ; var tMaxX = ( boundaryX - start . X ) / ray . direction . X ; var tMaxY = ( boundaryY - start . Y ) / ray . direction . Y ; if ( ray . direction . X == 0f || stepX == 0 ) tMaxX = float . PositiveInfinity ; if ( ray . direction . Y == 0f || stepY == 0 ) tMaxY = float . PositiveInfinity ; var tDeltaX = stepX / ray . direction . X ; var tDeltaY = stepY / ray . direction . Y ; var cell = cellAtPosition ( intX , intY ) ; if ( cell != null && _raycastParser . checkRayIntersection ( intX , intY , cell ) ) { _raycastParser . reset ( ) ; return _raycastParser . hitCounter ; } while ( intX != endCell . X || intY != endCell . Y ) { if ( tMaxX < tMaxY ) { intX += stepX ; tMaxX += tDeltaX ; } else { intY += stepY ; tMaxY += tDeltaY ; } cell = cellAtPosition ( intX , intY ) ; if ( cell != null && _raycastParser . checkRayIntersection ( intX , intY , cell ) ) { _raycastParser . reset ( ) ; return _raycastParser . hitCounter ; } } _raycastParser . reset ( ) ; return _raycastParser . hitCounter ; }
casts a line through the spatial hash and fills the hits array up with any colliders that the line hits
casts a line through the spatial hash and fills the hits array up with any colliders that the line hits
// get our start/end position in the same space as our grid // TODO: check gridBounds to ensure the ray starts/ends in the grid. watch out for end cells since they report out of bounds due to int comparison // what voxel are we on // which way we go // we make sure that if we're on the same line or row we don't step  // in the unneeded direction // Calculate cell boundaries. when the step is positive, the next cell is after this one meaning we add 1. // If negative, cell is before this one in which case dont add to boundary // determine the value of t at which the ray crosses the first vertical voxel boundary. same for y/horizontal. // The minimum of these two values will indicate how much we can travel along the ray and still remain in the current voxel // may be infinite for near vertical/horizontal rays // how far do we have to walk before crossing a cell from a cell boundary. may be infinite for near vertical/horizontal rays // start walking and returning the intersecting cells. // debugDrawCellDetails( intX, intY, cell != null ? cell.Count : 0 ); // make sure we are reset
the number of Colliders returned
the number of Colliders returned
start
Vector2
None
end
Vector2
None
hits
RaycastHit[]
None
layerMask
int
None