public void Initialize(ILiftManager manager)
        {
            foreach (var floor in manager.Floors)
            {
                var controller = Instantiate(floorPrefab, root);
                controller.Floor = floor;

                var selection = controller.GetComponent <FloorSelection>();
                if (selection == null)
                {
                    continue;
                }

                selection.OnFloorFocusStateChanged += FloorFocusStateChanged;
                if (selection.Floor != manager.CurrentFloor)
                {
                    continue;
                }

                _selected          = selection;
                _selected.Selected = true;
            }

            OnFloorSelected?.Invoke(_selected != null ? _selected.Floor : manager.CurrentFloor);
        }
Exemple #2
0
        public override bool Check(FloorSelection floor, IReadOnlyList <BuildingSideInfo> neighbours, Vector2 edgeStart, Vector2 edgeEnd, float bottom, float top)
        {
            Contract.Requires(floor != null);
            Contract.Requires(neighbours != null);

            return(false);
        }
Exemple #3
0
        public override bool Check(FloorSelection floor, IReadOnlyList <BuildingSideInfo> sides, Vector2 edgeStart, Vector2 edgeEnd, float bottom, float top)
        {
            //Direction of the edge of the building
            var eDir = Vector2.Normalize(edgeEnd - edgeStart);

            foreach (var side in sides)
            {
                var sideLine = new Ray2(side.EdgeStart, side.EdgeEnd - side.EdgeStart);

                //Project out edgeStart/edgeEnd perpendicular and convert to distance along edge
                var iStart = new Ray2(edgeStart, eDir.Perpendicular()).Intersects(sideLine);
                var iEnd   = new Ray2(edgeEnd, eDir.Perpendicular()).Intersects(sideLine);

                //No intersections means we have nothing to do with this neighbour
                if (!iStart.HasValue || !iEnd.HasValue)
                {
                    continue;
                }

                //Extract start and end distances along side
                var st = Math.Min(iStart.Value.DistanceAlongB, iEnd.Value.DistanceAlongB);
                var et = Math.Max(iStart.Value.DistanceAlongB, iEnd.Value.DistanceAlongB);

                //We can select a subsection of the neighbour edge (distances along edge B)
                //Check if all of the neighbours along that subsection have the resource we're looking for
                foreach (var neighbour in side.Neighbours)
                {
                    var ns = Math.Min(neighbour.Start, neighbour.End);
                    var ne = Math.Max(neighbour.Start, neighbour.End);

                    //Skip this subsection if it does not overlap our area of interest
                    if (ns > et || ne < st)
                    {
                        continue;
                    }

                    //Try to find the resource we want
                    bool resource = neighbour.Resources.Any(r => r.Bottom <= bottom && r.Top >= top && r.Type == Type);

                    //If we did not find the resource, then this entire section does not have the resource (obviously) so we have failed
                    if (!resource)
                    {
                        return(false);
                    }
                }
            }

            //We worked through all applicable edges, and did not find the resource lacking along any of them: success!
            return(true);
        }
        private void FloorFocusStateChanged(FloorSelection selection)
        {
            if (selection.Selected && _selected != selection)
            {
                _selected.Selected = false;
                _selected          = selection;
            }

            if (selection.Focused)
            {
                _focused = selection;
            }
            else if (_focused == selection)
            {
                _focused = null;
            }

            OnFloorSelected?.Invoke(_focused != null ? _focused.Floor : _selected.Floor);
        }
Exemple #5
0
 /// <summary>
 /// Check if this constraint is not violated for a given facade
 /// </summary>
 /// <param name="floor">The floor we're checking</param>
 /// <param name="neighbours">Neighbour information around the base footprint of this building</param>
 /// <param name="edgeStart">The 2D start location of the wall we're applying a facade to</param>
 /// <param name="edgeEnd">The 2D end location of the wall we're applying a facade to</param>
 /// <param name="bottom">Altitude of the bottom of the wall we're applying this facade to</param>
 /// <param name="top">Altitude of the top of the wall we're applying this facade to</param>
 /// <returns></returns>
 public abstract bool Check(FloorSelection floor, IReadOnlyList <BuildingSideInfo> neighbours, Vector2 edgeStart, Vector2 edgeEnd, float bottom, float top);
        private static bool Check(float distance, FloorSelection floor, IReadOnlyList <BuildingSideInfo> sides, Vector2 edgeStart, Vector2 edgeEnd)
        {
            Contract.Requires(floor != null);
            Contract.Requires(sides != null);

            //Direction of the edge of the building
            var eDir = Vector2.Normalize(edgeEnd - edgeStart);

            foreach (var side in sides)
            {
                //No point checking sides with no neighbours!
                if (!side.Neighbours.Any())
                {
                    continue;
                }

                var sideLine = new Ray2(side.EdgeStart, side.EdgeEnd - side.EdgeStart);

                //Project out edgeStart/edgeEnd perpendicular and convert to distance along edge
                var iStart = new Ray2(edgeStart, -eDir.Perpendicular()).Intersects(sideLine);
                var iEnd   = new Ray2(edgeEnd, -eDir.Perpendicular()).Intersects(sideLine);

                //No intersections means we can't possibly be obscured by this neighbour
                if (!iStart.HasValue || !iEnd.HasValue)
                {
                    continue;
                }

                //If the intersection is to the wrong side of this line, skip it
                if (iStart.Value.DistanceAlongA < 0 || iEnd.Value.DistanceAlongA < 0)
                {
                    continue;
                }

                //Extract start and end distances along side
                var st = Math.Min(iStart.Value.DistanceAlongB, iEnd.Value.DistanceAlongB);
                var et = Math.Max(iStart.Value.DistanceAlongB, iEnd.Value.DistanceAlongB);

                //We can select a subsection of the neighbour edge (distances along edge B)
                //Check if any of the buildings along that subsection break the clearance constraint
                foreach (var neighbour in side.Neighbours)
                {
                    //Skip this subsection if it is too low to have any impact on this floor
                    if (neighbour.Height <= floor.CompoundHeight)
                    {
                        continue;
                    }

                    var ns = Math.Min(neighbour.Start, neighbour.End);
                    var ne = Math.Max(neighbour.Start, neighbour.End);

                    //Skip this subsection if it does not overlap our area of interest
                    if (ns > et || ne < st)
                    {
                        continue;
                    }

                    //Distance from the start point of this neighbour, to the closest point on the edge of this facade section
                    bool cont;
                    var  startClear = MeasureClearance(out cont, sideLine, sideLine.Position + sideLine.Direction * ns, new LineSegment2(edgeStart, edgeEnd), eDir);
                    if (cont)
                    {
                        continue;
                    }

                    //Distance from the end point of this neighbour, to the closest point on the edge of this facade section
                    var endClear = MeasureClearance(out cont, sideLine, sideLine.Position + sideLine.Direction * ne, new LineSegment2(edgeStart, edgeEnd), eDir);
                    if (cont)
                    {
                        continue;
                    }

                    //Check clearance
                    if (endClear < distance || startClear < distance)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
 public override bool Check(FloorSelection floor, IReadOnlyList <BuildingSideInfo> neighbours, Vector2 edgeStart, Vector2 edgeEnd, float bottom, float top)
 {
     return(Check(Clearance, floor, neighbours, edgeStart, edgeEnd));
 }