示例#1
0
            public MatrixBounds Prepare(CellMatrix matrix, bool block)
            {
                MatrixBounds combinedCoverage;

                //The bounds used last check
                _oldBounds.Mirror(_actualBounds);

                if (!block)
                {
                    //Only unblock is required, so the affected area is the most recent coverage
                    combinedCoverage = _cellCoverage;
                    _actualBounds.Reset();
                    _cellCoverage = MatrixBounds.nullBounds;

                    return(combinedCoverage);
                }

                var velocity = _parent.GetVelocity();

                var obstacleSensitivityRange = _parent.useGridObstacleSensitivity ? matrix.obstacleSensitivityRange : _parent.customSensitivity;

                PrepareHull(velocity, obstacleSensitivityRange);

                //Get the axis-aligned bounding box
                var bounds = _actualBounds.CalculateBounds();

                //Get the new coverage, combine it with the old for coverage of both those to unblock and block
                var newCoverage = matrix.GetMatrixBounds(bounds, matrix.cellSize / 2f, true);

                combinedCoverage = MatrixBounds.Combine(_cellCoverage, newCoverage);
                _cellCoverage    = newCoverage;

                return(combinedCoverage);
            }
示例#2
0
        /// <summary>
        /// Touches the sections overlapping with the specified bounds, marking them as changed.
        /// </summary>
        /// <param name="b">The bounds.</param>
        public void TouchSections(MatrixBounds b)
        {
            var rect = new RectangleXZ(
                _cellMatrix.start.x + (b.minColumn * _cellSize),
                _cellMatrix.start.z + (b.minRow * _cellSize),
                b.maxColumn * _cellSize,
                b.minRow * _cellSize);

            for (int i = 0; i < _gridSections.Length; i++)
            {
                if (_gridSections[i].bounds.Overlaps(rect))
                {
                    _gridSections[i].Touch();
                }
            }
        }
示例#3
0
        internal IGrid Initialize(PortalCell partner, Bounds portalBounds)
        {
            var grid = GridManager.instance.GetGrid(portalBounds.center);

            if (grid == null)
            {
                return(null);
            }

            _partner        = partner;
            this.parent     = grid.cellMatrix;
            this.position   = portalBounds.center;
            _neighbourNodes = grid.GetCoveredCells(portalBounds).ToArray();
            _matrixBounds   = grid.cellMatrix.GetMatrixBounds(portalBounds, 0.0f, true);

            return(grid);
        }
示例#4
0
            public MatrixBounds Prepare(CellMatrix matrix, bool block)
            {
                _lastCoverage = _newCoverage;

                if (!block)
                {
                    _newCoverage = MatrixBounds.nullBounds;
                    return(_lastCoverage);
                }

                var velocity = _parent.GetVelocity();

                var sensitivity = (matrix.cellSize / 2f) - (_parent.useGridObstacleSensitivity ? matrix.obstacleSensitivityRange : _parent.customSensitivity);

                var bounds = GrowBoundsByVelocity(_collider.bounds, velocity);

                _newCoverage = matrix.GetMatrixBounds(bounds, sensitivity, true);

                return(MatrixBounds.Combine(_lastCoverage, _newCoverage));
            }
示例#5
0
 /// <summary>
 /// Assigns height settings to a portion of the matrix.
 /// </summary>
 /// <param name="bounds">The portion of the matrix to update.</param>
 /// <returns>An enumerator which once enumerated will do the update.</returns>
 public abstract IEnumerator AssignHeightSettings(MatrixBounds bounds);
示例#6
0
 public ColliderBoundsBase(Transform t, DynamicObstacle parent)
 {
     _transform    = t;
     _parent       = parent;
     _cellCoverage = MatrixBounds.nullBounds;
 }
示例#7
0
        private IEnumerator Populate()
        {
            //Create the height map
            _heightLookup = CreateHeightLookup(0);

            if (_generateHeightMap)
            {
                var detailedHeightMap = (GameServices.heightStrategy.heightMapDetail == HeightMapDetailLevel.High);
                var plotRange         = _lowerBoundary + _upperBoundary;
                var down = Vector3.down;

                Vector3 samplePos;
                samplePos.y = _start.y + _upperBoundary;

                RaycastHit hit;
                for (int x = 0; x < _heightMapSizeX; x++)
                {
                    samplePos.x = detailedHeightMap ? (float)Math.Round(_start.x + (x * _granularity), 4) : _start.x + (x * _granularity);

                    for (int z = 0; z < _heightMapSizeZ; z++)
                    {
                        samplePos.z = detailedHeightMap ? (float)Math.Round(_start.z + (z * _granularity), 4) : _start.z + (z * _granularity);

                        if (UnityServices.physics.Raycast(samplePos, down, out hit, plotRange, Layers.terrain))
                        {
                            _heightLookup.Add(x, z, hit.point.y);
                        }
                        else
                        {
                            _heightLookup.Add(x, z, Consts.InfiniteDrop);
                        }

                        yield return(null);
                    }
                }

                _heightLookup.Cleanup();
            }

            //Populate the cell matrix
            var heightSampler    = GetHeightSampler();
            var calculateHeights = (GameServices.heightStrategy.heightMode != HeightSamplingMode.NoHeightSampling);
            var maxHeight        = _origin.y + _upperBoundary;
            var minHeight        = _origin.y - _lowerBoundary;
            var blockThreshold   = Mathf.Max(_obstacleSensitivityRange, 0.01f);

            for (int x = 0; x < this.columns; x++)
            {
                for (int z = 0; z < this.rows; z++)
                {
                    var position = new Vector3(_start.x + (x * _cellSize) + (_cellSize / 2.0f), _origin.y, _start.z + (z * _cellSize) + (_cellSize / 2.0f));
                    if (calculateHeights)
                    {
                        position.y = Mathf.Clamp(heightSampler.SampleHeight(position, this), minHeight, maxHeight);
                    }

                    var blocked = IsBlocked(position, blockThreshold);

                    this.rawMatrix[x, z] = _cellFactory.Create(this, position, x, z, blocked);

                    yield return(null);
                }
            }

            //Set the height block status of each cell
            if (calculateHeights)
            {
                var entireMatrix = new MatrixBounds(0, 0, this.columns - 1, this.rows - 1);

                //Set height map settings for all cells
                var iter = _heightSettingsProvider.AssignHeightSettings(entireMatrix);
                while (iter.MoveNext())
                {
                    yield return(null);
                }
            }
        }
示例#8
0
        internal IEnumerator Update(Bounds extent)
        {
            if (_generateHeightMap)
            {
                //First update the height map
                var min = extent.min;
                var max = extent.max;

                var updateBounds = new MatrixBounds(
                    Mathf.Clamp(Mathf.FloorToInt((min.x - _start.x) / _granularity), 0, _heightMapSizeX - 1),
                    Mathf.Clamp(Mathf.FloorToInt((min.z - _start.z) / _granularity), 0, _heightMapSizeZ - 1),
                    Mathf.Clamp(Mathf.CeilToInt((max.x - _start.x) / _granularity), 0, _heightMapSizeX - 1),
                    Mathf.Clamp(Mathf.CeilToInt((max.z - _start.z) / _granularity), 0, _heightMapSizeZ - 1));

                var heightUpdater = _heightLookup.PrepareForUpdate(updateBounds, out updateBounds);

                var detailedHeightMap = (GameServices.heightStrategy.heightMapDetail == HeightMapDetailLevel.High);
                var plotRange         = _lowerBoundary + _upperBoundary;
                var down = Vector3.down;

                Vector3 samplePos;
                samplePos.y = _start.y + _upperBoundary;

                RaycastHit hit;
                for (int x = updateBounds.minColumn; x <= updateBounds.maxColumn; x++)
                {
                    samplePos.x = detailedHeightMap ? (float)Math.Round(_start.x + (x * _granularity), 4) : _start.x + (x * _granularity);

                    for (int z = updateBounds.minRow; z <= updateBounds.maxRow; z++)
                    {
                        samplePos.z = detailedHeightMap ? (float)Math.Round(_start.z + (z * _granularity), 4) : _start.z + (z * _granularity);

                        if (UnityServices.physics.Raycast(samplePos, down, out hit, plotRange, Layers.terrain))
                        {
                            heightUpdater.Add(x, z, hit.point.y);
                        }
                        else
                        {
                            heightUpdater.Add(x, z, Consts.InfiniteDrop);
                        }

                        yield return(null);
                    }
                }

                _heightLookup.FinishUpdate(heightUpdater);
            }

            //Next update the affected grid cells
            var heightSampler = GetHeightSampler();

            var bounds = GetMatrixBounds(extent.center, extent.extents.x, extent.extents.z, 0.0f, true);

            var blockThreshold = Mathf.Max(_obstacleSensitivityRange, 0.01f);
            var maxHeight      = _origin.y + _upperBoundary;
            var minHeight      = _origin.y - _lowerBoundary;

            for (int x = bounds.minColumn; x <= bounds.maxColumn; x++)
            {
                for (int z = bounds.minRow; z <= bounds.maxRow; z++)
                {
                    var cell = this.rawMatrix[x, z];

                    var cellPos = cell.position;
                    cellPos.y = Mathf.Clamp(heightSampler.SampleHeight(cellPos, this), minHeight, maxHeight);

                    var blocked = IsBlocked(cellPos, blockThreshold);

                    cell.UpdateState(cellPos.y, blocked);

                    yield return(null);
                }
            }

            if (GameServices.heightStrategy.heightMode != HeightSamplingMode.NoHeightSampling)
            {
                var iter = _heightSettingsProvider.AssignHeightSettings(bounds);
                while (iter.MoveNext())
                {
                    yield return(null);
                }
            }
        }
            public IEnumerator AssignHeightSettings(MatrixBounds bounds)
            {
                var  maxColumn      = bounds.maxColumn;
                var  maxRow         = bounds.maxRow;
                bool isPartial      = (maxColumn - bounds.minColumn < _matrix.columns - 1) || (maxRow - bounds.minRow < _matrix.rows - 1);
                var  ledgeThreshold = Mathf.Tan(GameServices.heightStrategy.ledgeThreshold * Mathf.Deg2Rad) * _matrix.granularity;

                var rawMatrix = _matrix.rawMatrix;

                for (int x = bounds.minColumn; x <= maxColumn; x++)
                {
                    for (int z = bounds.minRow; z <= maxRow; z++)
                    {
                        var c = rawMatrix[x, z] as RichCell;
                        if (c.isPermanentlyBlocked)
                        {
                            continue;
                        }

                        //Process neighbours
                        for (int dz = -1; dz <= 1; dz++)
                        {
                            for (int dx = -1; dx <= 1; dx++)
                            {
                                if (dx == 0 && dz == 0)
                                {
                                    continue;
                                }

                                var n = _matrix[x + dx, z + dz] as RichCell;
                                if (n == null || n.isPermanentlyBlocked)
                                {
                                    continue;
                                }

                                //If height data has already been assigned (by neighbour) we don't want to do it again,
                                //unless its a partial in which case we have to since neighbours are not necessarily covered by the update
                                if (!isPartial && c.HasInitializedHeightData(dx, dz))
                                {
                                    continue;
                                }

                                UpdateCellHeightData(c, n, ledgeThreshold, dx, dz);

                                yield return(null);
                            }
                        } /* end neighbour loop */
                    }
                }

                if (!isPartial)
                {
                    yield break;
                }

                //Update corner diagonals, this is only relevant for partial updates
                //Since the cells being updated only update their own relation to neighbours, there will potentially be 4 connections not updated,
                //those are the diagonals between the cells surround each corner of the bounds, e.g. bottom left corner the connection between the cell to the left and the cell below that corner.
                //since updates also update the involved neighbour, we only have to update 4 additional cells, and only on a specific diagonal.
                var bll = _matrix[bounds.minColumn - 1, bounds.minRow] as RichCell;
                var blb = _matrix[bounds.minColumn, bounds.minRow - 1] as RichCell;

                var tll = _matrix[bounds.minColumn - 1, bounds.maxRow] as RichCell;
                var tlt = _matrix[bounds.minColumn, bounds.maxRow + 1] as RichCell;

                var brr = _matrix[bounds.maxColumn + 1, bounds.minRow] as RichCell;
                var brb = _matrix[bounds.maxColumn, bounds.minRow - 1] as RichCell;

                var trr = _matrix[bounds.maxColumn + 1, bounds.maxRow] as RichCell;
                var trt = _matrix[bounds.maxColumn, bounds.maxRow + 1] as RichCell;

                if (bll != null && blb != null)
                {
                    UpdateCellHeightData(bll, blb, ledgeThreshold, 1, -1);
                    yield return(null);
                }

                if (tll != null && tlt != null)
                {
                    UpdateCellHeightData(tll, tlt, ledgeThreshold, 1, 1);
                    yield return(null);
                }

                if (brr != null && brb != null)
                {
                    UpdateCellHeightData(brr, brb, ledgeThreshold, -1, -1);
                    yield return(null);
                }

                if (trr != null && trt != null)
                {
                    UpdateCellHeightData(trr, trt, ledgeThreshold, -1, 1);
                    yield return(null);
                }
            }
        /// <summary>
        /// Assigns height settings to a portion of the _matrix.
        /// </summary>
        /// <param name="matrix">The matrix to update.</param>
        /// <param name="bounds">The portion of the matrix to update.</param>
        /// <returns>
        /// An enumerator which once enumerated will do the update.
        /// </returns>
        public override IEnumerator AssignHeightSettings(CellMatrix matrix, MatrixBounds bounds)
        {
            var inner = new InnerProvider(matrix);

            return(inner.AssignHeightSettings(bounds));
        }
 public override IEnumerator AssignHeightSettings(MatrixBounds bounds)
 {
     yield break;
 }
示例#12
0
 public AxisBounds(Collider collider, DynamicObstacle parent)
 {
     _collider     = collider;
     _parent       = parent;
     _lastCoverage = _newCoverage = MatrixBounds.nullBounds;
 }
示例#13
0
        /// <summary>
        /// Assigns height settings to a portion of the matrix.
        /// </summary>
        /// <param name="bounds">The portion of the matrix to update.</param>
        /// <returns>
        /// An enumerator which once enumerated will do the update.
        /// </returns>
        public override IEnumerator AssignHeightSettings(MatrixBounds bounds)
        {
            if (_maxWalkableSlopeAngle >= 90f)
            {
                yield break;
            }

            var ledgeThreshold    = Mathf.Tan(GameServices.heightStrategy.ledgeThreshold * Mathf.Deg2Rad) * _matrix.granularity;
            var maxHeightDiff     = Mathf.Tan(_maxWalkableSlopeAngle * Mathf.Deg2Rad) * _granularity;
            var maxHeightDiffDiag = maxHeightDiff * Consts.SquareRootTwo;

            var  maxColumn = bounds.maxColumn;
            var  maxRow    = bounds.maxRow;
            bool isPartial = (maxColumn - bounds.minColumn < _matrix.columns - 1) || (maxRow - bounds.minRow < _matrix.rows - 1);

            var rawMatrix = _matrix.rawMatrix;

            for (int x = bounds.minColumn; x <= maxColumn; x++)
            {
                for (int z = bounds.minRow; z <= maxRow; z++)
                {
                    var c = rawMatrix[x, z] as StandardCell;
                    if (c.isPermanentlyBlocked)
                    {
                        continue;
                    }

                    //Process neighbours
                    for (int dz = -1; dz <= 1; dz++)
                    {
                        for (int dx = -1; dx <= 1; dx++)
                        {
                            if (dx == 0 && dz == 0)
                            {
                                continue;
                            }

                            var n = _matrix[x + dx, z + dz] as StandardCell;
                            if (n == null || n.isPermanentlyBlocked)
                            {
                                continue;
                            }

                            var pos = n.GetRelativePositionTo(c);
                            if (!isPartial && (c.heightIntializedFrom & pos) > 0)
                            {
                                continue;
                            }

                            //If doing a partial update we need to remove the blocked flag from the neighbour first since he may not be processed on his own.
                            if (isPartial)
                            {
                                c.heightBlockedFrom &= ~pos;
                                n.heightBlockedFrom &= ~c.GetRelativePositionTo(n);
                            }

                            switch (pos)
                            {
                            //Straight neighbours
                            case NeighbourPosition.Bottom:
                            case NeighbourPosition.Top:
                            case NeighbourPosition.Left:
                            case NeighbourPosition.Right:
                            {
                                UpdateCellHeightData(c, n, pos, maxHeightDiff, ledgeThreshold, true);
                                break;
                            }

                            //diagonals
                            default:
                            {
                                UpdateCellHeightData(c, n, pos, maxHeightDiffDiag, ledgeThreshold, false);
                                break;
                            }
                            }

                            yield return(null);
                        }
                    } /* end neighbour loop */
                }
            }

            if (!isPartial)
            {
                yield break;
            }

            //Update corner diagonals, this is only relevant for partial updates
            //Since the cells being updated only update their own relation to neighbours, there will potentially be 4 connections not updated,
            //those are the diagonals between the cells surround each corner of the bounds, e.g. bottom left corner the connection between the cell to the left and the cell below that corner.
            //since updates also update the involved neighbour, we only have to update 4 additional cells, and only on a specific diagonal.
            var bll = _matrix[bounds.minColumn - 1, bounds.minRow] as StandardCell;
            var blb = _matrix[bounds.minColumn, bounds.minRow - 1] as StandardCell;

            var tll = _matrix[bounds.minColumn - 1, bounds.maxRow] as StandardCell;
            var tlt = _matrix[bounds.minColumn, bounds.maxRow + 1] as StandardCell;

            var brr = _matrix[bounds.maxColumn + 1, bounds.minRow] as StandardCell;
            var brb = _matrix[bounds.maxColumn, bounds.minRow - 1] as StandardCell;

            var trr = _matrix[bounds.maxColumn + 1, bounds.maxRow] as StandardCell;
            var trt = _matrix[bounds.maxColumn, bounds.maxRow + 1] as StandardCell;

            if (bll != null && blb != null)
            {
                bll.heightBlockedFrom &= ~NeighbourPosition.BottomRight;
                blb.heightBlockedFrom &= ~NeighbourPosition.TopLeft;
                UpdateCellHeightData(bll, blb, NeighbourPosition.BottomRight, maxHeightDiffDiag, ledgeThreshold, false);
                yield return(null);
            }

            if (tll != null && tlt != null)
            {
                tll.heightBlockedFrom &= ~NeighbourPosition.TopRight;
                tlt.heightBlockedFrom &= ~NeighbourPosition.BottomLeft;
                UpdateCellHeightData(tll, tlt, NeighbourPosition.TopRight, maxHeightDiffDiag, ledgeThreshold, false);
                yield return(null);
            }

            if (brr != null && brb != null)
            {
                brr.heightBlockedFrom &= ~NeighbourPosition.BottomLeft;
                brb.heightBlockedFrom &= ~NeighbourPosition.TopRight;
                UpdateCellHeightData(brr, brb, NeighbourPosition.BottomLeft, maxHeightDiffDiag, ledgeThreshold, false);
                yield return(null);
            }

            if (trr != null && trt != null)
            {
                trr.heightBlockedFrom &= ~NeighbourPosition.TopLeft;
                trt.heightBlockedFrom &= ~NeighbourPosition.BottomRight;
                UpdateCellHeightData(trr, trt, NeighbourPosition.TopLeft, maxHeightDiffDiag, ledgeThreshold, false);
                yield return(null);
            }
        }