/// <summary>
        /// Initializes a new instance of the <see cref="CrossGridVectorField"/> class.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="path">The path.</param>
        /// <param name="options">The options.</param>
        public CrossGridVectorField(TransientGroup <IUnitFacade> group, Path path, VectorFieldOptions options)
        {
            Ensure.ArgumentNotNull(group, "group");
            this.group = group;

            _currentPath = path;

            var modelUnit = group.modelUnit;

            _unitProperties = modelUnit;
            var pathOptions = modelUnit.pathFinderOptions;

            // cache options locally
            _allowCornerCutting = pathOptions.allowCornerCutting;
            _allowDiagonals     = !pathOptions.preventDiagonalMoves;
            _announceAllNodes   = modelUnit.pathNavigationOptions.announceAllNodes;

            _obstacleStrengthFactor     = options.obstacleStrengthFactor;
            _builtInContainment         = options.builtInContainment;
            _updateInterval             = options.updateInterval;
            _paddingIncrease            = options.paddingIncrease;
            _maxExtraPadding            = options.maxExtraPadding;
            _boundsPadding              = options.boundsPadding;
            _boundsRecalculateThreshold = options.boundsRecalculateThreshold;
            _expectedGroupGrowthFactor  = 1f + options.expectedGroupGrowthFactor;

            // pre-allocate lists
            _openSet = new SimpleQueue <Cell>(31);
            _tempWalkableNeighbours      = new DynamicArray <Cell>(8);
            _extraTempWalkableNeighbours = new DynamicArray <Cell>(8);
            _groupBounds = new RectangleXZ(group.centerOfGravity, _boundsPadding, _boundsPadding);

            _grids = new List <IGrid>(4);
        }
Exemplo n.º 2
0
        private GridSection[] CreateSubSections(Vector3 start)
        {
            var subSectionsX = Math.Max(this.subSectionsX, 1);
            var subSectionsZ = Math.Max(this.subSectionsZ, 1);

            var overLap         = this.subSectionsCellOverlap * this.cellSize;
            var subSectionWidth = ((this.sizeX + ((subSectionsX - 1) * this.subSectionsCellOverlap)) * this.cellSize) / (subSectionsX * 1.0f);
            var subSectionDepth = ((this.sizeZ + ((subSectionsZ - 1) * this.subSectionsCellOverlap)) * this.cellSize) / (subSectionsZ * 1.0f);

            var subSectionCount = subSectionsX * subSectionsZ;
            var gridSections    = new GridSection[subSectionCount];

            int idx = 0;

            for (int i = 0; i < subSectionsX; i++)
            {
                for (int j = 0; j < subSectionsZ; j++)
                {
                    var rect = new RectangleXZ(
                        start.x + (subSectionWidth * i) - (overLap * i),
                        start.z + (subSectionDepth * j) - (overLap * j),
                        subSectionWidth,
                        subSectionDepth);

                    gridSections[idx++] = new GridSection(rect);
                }
            }

            return(gridSections);
        }
Exemplo n.º 3
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();
                }
            }
        }
        private bool ConstructGroupBounds(bool forceConstruction = false)
        {
            int membersCount = group.count;

            if (membersCount == 0)
            {
                return(false);
            }

            // find minimum and maximum coordinates for the group
            float   minX = float.MaxValue, minZ = float.MaxValue, maxX = float.MinValue, maxZ = float.MinValue;
            Vector3 groupCog = Vector3.zero;

            for (int i = 0; i < membersCount; i++)
            {
                var member = group[i];
                if (member == null)
                {
                    continue;
                }

                var pos = member.position;
                if (pos.x < minX)
                {
                    minX = pos.x;
                }

                if (pos.z < minZ)
                {
                    minZ = pos.z;
                }

                if (pos.x > maxX)
                {
                    maxX = pos.x;
                }

                if (pos.z > maxZ)
                {
                    maxZ = pos.z;
                }

                // sum up all unit positions
                groupCog += pos;
            }

            // divide the summed up unit positions by the unit count, in order to get the "average group position" or center of gravity
            groupCog /= membersCount;
            if (!forceConstruction && ((groupCog - _groupBounds.center).sqrMagnitude < (_boundsRecalculateThreshold * _boundsRecalculateThreshold)))
            {
                // if not forcing the construction, check whether the group has moved from its last group bounds center enough
                return(false);
            }

            // first grid is the one where the group center is
            var grid = GridManager.instance.GetGrid(groupCog);

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

            if (_portalNewGroupThreshold <= 0f)
            {
                // if we have not set our portal new group threshold yet, then do it (based on diagonal cell size)
                _portalNewGroupThreshold = (grid.cellSize * Consts.SquareRootTwo) + 0.1f;
            }

            _grids.Clear();
            AddGrid(grid);

            // push the minimum and maximum values by the bounds padding and the potential extra padding resultant from growing bounds
            var padding = _boundsPadding + _extraPadding;

            minX -= padding;
            minZ -= padding;
            maxX += padding;
            maxZ += padding;

            float yPos = groupCog.y;

            // find minimum and maximum cells, in order to construct the group bounds "cell-aligned" and in order to add all relevant grids
            Vector3 vecMinXZ  = new Vector3(minX, yPos, minZ);
            var     gridMinXZ = GridManager.instance.GetGrid(vecMinXZ);

            // bottom left corner grid
            if (gridMinXZ != null)
            {
                AddGrid(gridMinXZ);

                Cell minXZ = gridMinXZ.GetCell(vecMinXZ, true);
                minX = minXZ.position.x;
                minZ = minXZ.position.z;
            }

            Vector3 vecMaxXZ  = new Vector3(maxX, yPos, maxZ);
            var     gridMaxXZ = GridManager.instance.GetGrid(vecMaxXZ);

            // top right corner grid
            if (gridMaxXZ != null)
            {
                AddGrid(gridMaxXZ);

                Cell maxXZ = gridMaxXZ.GetCell(vecMaxXZ, true);
                maxX = maxXZ.position.x;
                maxZ = maxXZ.position.z;
            }

            // top left corner grid
            var gridMinXMaxZ = GridManager.instance.GetGrid(new Vector3(minX, yPos, maxZ));

            AddGrid(gridMinXMaxZ);

            // bottom right corner grid
            var gridMaxXMinZ = GridManager.instance.GetGrid(new Vector3(maxX, yPos, minZ));

            AddGrid(gridMaxXMinZ);

            // finally, actually instantiate the new group bounds
            _groupBounds = new RectangleXZ(minX, minZ, (maxX - minX), (maxZ - minZ));

            return(true);
        }
Exemplo n.º 5
0
        private bool ConstructGroupBounds(bool forceConstruction = false)
        {
            int membersCount = group.count;

            if (membersCount == 0)
            {
                return(false);
            }

            // find minimum and maximum coordinates for the group
            float   minX = float.MaxValue, minZ = float.MaxValue, maxX = float.MinValue, maxZ = float.MinValue;
            Vector3 groupCog = Vector3.zero;

            for (int i = 0; i < membersCount; i++)
            {
                var member = group[i];
                if (member == null)
                {
                    continue;
                }

                var pos = member.position;
                if (pos.x < minX)
                {
                    minX = pos.x;
                }

                if (pos.z < minZ)
                {
                    minZ = pos.z;
                }

                if (pos.x > maxX)
                {
                    maxX = pos.x;
                }

                if (pos.z > maxZ)
                {
                    maxZ = pos.z;
                }

                // sum up all unit positions
                groupCog += pos;
            }

            // divide the summed up unit positions by the unit count, in order to get the "average group position" or center of gravity
            groupCog /= membersCount;
            if (!forceConstruction && ((groupCog - _groupBounds.center).sqrMagnitude < (_boundsRecalculateThreshold * _boundsRecalculateThreshold)))
            {
                // if not forcing the construction, check whether the group has moved from its last group bounds center enough
                return(false);
            }

            // push the minimum and maximum values by the bounds padding and the potential extra padding resultant from growing bounds
            var padding = _boundsPadding + _extraPadding;

            minX -= padding;
            minZ -= padding;
            maxX += padding;
            maxZ += padding;

            float yPos = groupCog.y;

            // find minimum and maximum cells, in order to construct the group bounds "cell-aligned"
            Vector3 vecMinXZ = new Vector3(minX, yPos, minZ);
            Cell    minXZ    = _grid.GetCell(vecMinXZ, true);

            minX = minXZ.position.x;
            minZ = minXZ.position.z;

            Vector3 vecMaxXZ = new Vector3(maxX, yPos, maxZ);
            Cell    maxXZ    = _grid.GetCell(vecMaxXZ, true);

            maxX = maxXZ.position.x;
            maxZ = maxXZ.position.z;

            // finally, actually instantiate the new group bounds
            _groupBounds = new RectangleXZ(minX, minZ, (maxX - minX), (maxZ - minZ));

            return(true);
        }
Exemplo n.º 6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GridSection"/> class.
 /// </summary>
 /// <param name="rect">The rectangle defining the section.</param>
 public GridSection(RectangleXZ rect)
 {
     this.bounds      = rect;
     this.lastChanged = -1f;
 }