Example #1
0
        /// <summary>
        /// Gets the subdivision that is calculated for the given agent.
        /// </summary>
        /// <param name="agent">The given agent.</param>
        /// <returns>The subdivision that is calculated for the given agent.</returns>
        public SectorSubdivision GetSubdivisionForAgent(Agent agent)
        {
            /// Collect the overlap enabled agents.
            RCSet <Agent> overlapEnabledAgents       = new RCSet <Agent>();
            RCSet <Agent> currentlyOverlappingAgents = this.grid[agent.Area.X, agent.Area.Y].GetAgents(agent.MovingSize);

            foreach (Agent staticAgent in this.staticAgents[agent.MovingSize])
            {
                if (currentlyOverlappingAgents.Contains(staticAgent) ||
                    staticAgent.Client.IsOverlapEnabled(agent.Client) ||
                    agent.Client.IsOverlapEnabled(staticAgent.Client))
                {
                    overlapEnabledAgents.Add(staticAgent);
                }
            }

            /// Try to find an already existing sector subdivision for the agent.
            SectorSubdivision subdivisionForAgent =
                this.subdivisions.FirstOrDefault(subdivision => subdivision.MovingSize == agent.MovingSize &&
                                                 subdivision.OverlapEnabledAgents.SetEquals(overlapEnabledAgents));

            if (subdivisionForAgent == null)
            {
                /// Create a new one if not found.
                subdivisionForAgent = new SectorSubdivision(this, agent.MovingSize, overlapEnabledAgents);
                this.subdivisions.Add(subdivisionForAgent);
            }
            return(subdivisionForAgent);
        }
Example #2
0
        /// <see cref="IGraph&lt;Region&gt;.GetNeighbours"/>
        public IEnumerable <Region> GetNeighbours(Region node)
        {
            if (!this.transitionCells.ContainsKey(node))
            {
                this.transitionCells.Add(node, new Dictionary <Region, RCSet <Cell> >());
                for (int direction = 0; direction < GridDirections.DIRECTION_COUNT; direction++)
                {
                    Sector neighbourSector = node.Subdivision.Sector.GetNeighbour(direction);
                    if (neighbourSector == null)
                    {
                        continue;
                    }

                    SectorSubdivision neighbourSubdivision = neighbourSector.GetSubdivisionForAgent(this.agent);
                    foreach (Region neighbourRegion in neighbourSubdivision.Regions)
                    {
                        RCSet <Cell> transitionCells = node.GetTransitionCells(neighbourRegion, direction);
                        if (transitionCells.Count > 0)
                        {
                            this.transitionCells[node][neighbourRegion] = transitionCells;
                        }
                    }
                }
            }
            return(this.transitionCells[node].Keys);
        }
Example #3
0
        /// <summary>
        /// Constructs a RegionGraph instance with the given target cell for the given agent.
        /// </summary>
        /// <param name="targetCell">The given target cell.</param>
        /// <param name="agent">The given agent.</param>
        //public RegionGraph(Region targetRegion, Agent agent)
        public RegionGraph(Cell targetCell, Agent agent)
        {
            this.agent      = agent;
            this.targetCell = targetCell;
            SectorSubdivision targetSubdivision = this.targetCell.Sector.GetSubdivisionForAgent(this.agent);

            this.targetRegion    = this.targetCell.GetRegion(targetSubdivision);
            this.transitionCells = new Dictionary <Region, Dictionary <Region, RCSet <Cell> > >();
        }
Example #4
0
        /// <summary>
        /// Removes this cell from the region that belongs to the given subdivision.
        /// </summary>
        /// <param name="subdivision">The given subdivision.</param>
        public void RemoveFromRegion(SectorSubdivision subdivision)
        {
            Region regionToRemove = this.regions.FirstOrDefault(region => region.Subdivision == subdivision);

            if (regionToRemove != null)
            {
                this.regions.Remove(regionToRemove);
            }
        }
Example #5
0
 /// <summary>
 /// Constructs a region instance.
 /// </summary>
 /// <param name="subdivision">The sector subdivision that this region belongs to.</param>
 public Region(SectorSubdivision subdivision)
 {
     this.parent      = this;
     this.rank        = 0;
     this.subdivision = subdivision;
     this.edgeCells   = new RCSet <Cell> [GridDirections.DIRECTION_COUNT];
     for (int dir = 0; dir < GridDirections.DIRECTION_COUNT; dir++)
     {
         this.edgeCells[dir] = new RCSet <Cell>();
     }
 }
Example #6
0
 /// <summary>
 /// Gets the region of the given subdivision that this cell belongs to or null if no such region found.
 /// </summary>
 /// <param name="subdivision">The given subdivision.</param>
 public Region GetRegion(SectorSubdivision subdivision)
 {
     return(this.regions.FirstOrDefault(region => region.Subdivision == subdivision));
 }
Example #7
0
        /// <summary>
        /// Calculates the next region on this path.
        /// </summary>
        /// <exception cref="InvalidOperationException">If this path is not in state PathStatusEnum.Partial.</exception>
        public void CalculateNextRegion()
        {
            if (this.Status != PathStatusEnum.Partial)
            {
                throw new InvalidOperationException("The state of this path shall be PathStatusEnum.Partial!");
            }

            /// Calculate the high-level path if not yet calculated.
            if (this.highLevelPath == null)
            {
                SectorSubdivision             sourceSubdivision          = this.sourceCell.Sector.GetSubdivisionForAgent(this.agent);
                Region                        sourceRegion               = this.sourceCell.GetRegion(sourceSubdivision);
                RegionGraph                   regionGraph                = new RegionGraph(this.targetCell, this.agent);
                PathfindingAlgorithm <Region> highLevelPathfinding       = new PathfindingAlgorithm <Region>(sourceRegion, regionGraph);
                PathfindingResult <Region>    highLevelPathfindingResult = highLevelPathfinding.Execute();
                this.highLevelPath = new List <Tuple <Region, RCSet <Cell> > >();
                for (int i = 0; i < highLevelPathfindingResult.Path.Count; i++)
                {
                    Region       currentRegion = highLevelPathfindingResult.Path[i];
                    Region       nextRegion    = i < highLevelPathfindingResult.Path.Count - 1 ? highLevelPathfindingResult.Path[i + 1] : null;
                    RCSet <Cell> targetCells   = nextRegion != null?regionGraph.GetTransitionCells(currentRegion, nextRegion) : new RCSet <Cell>
                    {
                        this.targetCell
                    };
                    this.highLevelPath.Add(Tuple.Create(currentRegion, targetCells));
                }
            }

            /// Check if the region to be calculated is still valid -> if not then this path is broken.
            if (!this.highLevelPath[this.regionIndex].Item1.IsValid)
            {
                this.isBroken = true;
                return;
            }

            IGraph <Cell> graph = null;

            if (this.regionIndex < this.highLevelPath.Count - 1)
            {
                graph = new TransitRegionGraph(
                    this.highLevelPath[this.regionIndex].Item1,
                    this.highLevelPath[this.regionIndex + 1].Item1.Subdivision.Sector.Center,
                    this.highLevelPath[this.regionIndex].Item2);
            }
            else
            {
                graph = new TransitRegionGraph(
                    this.highLevelPath[this.regionIndex].Item1,
                    this.targetCell.Coords,
                    this.highLevelPath[this.regionIndex].Item2);
            }
            Cell fromCell = this.lowLevelPath != null ? this.lowLevelPath[this.lowLevelPath.Count - 1] : this.sourceCell;
            PathfindingAlgorithm <Cell> lowLevelPathfinding       = new PathfindingAlgorithm <Cell>(fromCell, graph);
            PathfindingResult <Cell>    lowLevelPathfindingResult = lowLevelPathfinding.Execute();

            /// Check if a transition cell of the current region could be found -> if not then this path is broken.
            if (this.regionIndex < this.highLevelPath.Count - 1 && !lowLevelPathfindingResult.TargetFound)
            {
                this.isBroken = true;
                return;
            }

            /// Save the next section of the low level path and move to the next region.
            if (this.lowLevelPath == null)
            {
                this.lowLevelPath = lowLevelPathfindingResult.Path;
            }
            else
            {
                this.lowLevelPath.RemoveAt(this.lowLevelPath.Count - 1);
                this.lowLevelPath.AddRange(lowLevelPathfindingResult.Path);
            }
            this.regionIndex++;
        }