Esempio n. 1
0
        static bool SpawnBuilding(Vector2 center, float direction, Quadtree quadtree, out Allotment allotment, List <Allotment> allotments)
        {
            allotment = new Allotment(default(Vector2),
                                      0,
                                      UnityEngine.Random.Range(Config.allotmentMinHalfDiagonal, Config.allotmentMaxHalfDiagonal),
                                      UnityEngine.Random.Range(Config.allotmentMinAspect, Config.allotmentMaxAspect));
            allotment.UpdateCenterAndDirection(center, direction);
            bool allow = false;

            for (int j = 0; j < Config.allotmentPlacementLoopLimit; j++)
            {
                int     c = 0;
                Vector2 offset;
                var     colliders = quadtree.Retrieve(allotment.GetCollider().GetAABB());
                for (int k = 0; k < colliders.Count && (c == 0 || j < Config.allotmentPlacementLoopLimit - 1); k++)
                {
                    if (allotment.GetCollider().Collide(((ICollidable)colliders[k].reference).GetCollider(), out offset))
                    {
                        c++;
                        allotment.Center = (allotment.Center + offset);
                    }
                }
                for (int k = 0; k < allotments.Count && (c == 0 || j < Config.allotmentPlacementLoopLimit - 1); k++)
                {
                    if (allotment.GetCollider().Collide(allotments[k].GetCollider(), out offset))
                    {
                        c++;
                        allotment.Center = (allotment.Center + offset);
                    }
                }
                if (c == 0)
                {
                    allow = true;
                    break;
                }
            }
            return(allow);
        }
Esempio n. 2
0
        static bool LocalConstraints(Segment segment, List <Segment> segments, Quadtree quadtree, DebugData debugData)
        {
            int         priority = 0;
            Func <bool> action   = null;
            float       t0       = -1;

            var matches = quadtree.Retrieve(segment);

            for (int i = 0, j = 0, k = matches.Count - 1; j <= k; i = j += 1)
            {
                Segment other = (Segment)matches[i].reference;

                if (segment == other)
                {
                    continue;
                }

                // intersection check
                if (priority <= 4)
                {
                    Vector2 intersection;
                    float   t1;
                    if (segment.Intersect(other, out intersection, out t1))
                    {
                        if (t0 == -1 || t1 < t0)
                        {
                            t0       = t1;
                            priority = 4;
                            action   = () =>
                            {
                                float dirDiff          = Mathf.Abs(other.Direction - segment.Direction) % 180.0f;
                                float minDirectionDiff = Mathf.Min(dirDiff, Mathf.Abs(dirDiff - 180.0f));
                                if (minDirectionDiff < Config.minIntersectionDeviation)
                                {
                                    return(false);
                                }
                                IntersectSegments(intersection, other, segment, segments, quadtree);
                                if (debugData != null)
                                {
                                    debugData.intersections.Add(intersection);
                                }
                                return(true);
                            };
                        }
                    }
                }
                // snap to crossing within radius check
                if (priority <= 3)
                {
                    if ((segment.End - other.End).magnitude <= Config.snapDistance)
                    {
                        priority = 3;
                        action   = () =>
                        {
                            List <Segment> links;
                            segment.End     = other.End;
                            segment.Severed = true;
                            foreach (var destination in segment.Destinations)
                            {
                                int index = destination.Sources.IndexOf(other);
                                if (index != -1)
                                {
                                    continue;
                                }
                                destination.Sources.Add(other);
                            }
                            links = other.StartIsBackwards() ? other.Forwards : other.Branches;
                            if (links.Any((Segment link) =>
                            {
                                return(((link.Start == segment.End) &&
                                        (link.End == segment.Start)) ||
                                       ((link.Start == segment.Start) && (link.End == segment.End)));
                            }))
                            {
                                return(false);
                            }
                            links.ForEach((Segment link) =>
                            {
                                link.LinksForEndContaining(other).Add(segment);
                                segment.Forwards.Add(link);
                            });
                            links.Add(segment);
                            segment.Forwards.Add(other);
                            if (debugData != null)
                            {
                                debugData.snaps.Add(other.End);
                            }
                            return(true);
                        };
                    }
                }
                // intersection within radius check
                if (priority <= 2)
                {
                    var     e0          = (segment.End - other.Start);
                    var     e1          = (other.End - other.Start);
                    Vector2 proj        = Vector3.Project(e0, e1);
                    Vector2 pointOnLine = (other.Start + proj);
                    float   distance2   = Vector2.SqrMagnitude(segment.End - pointOnLine);
                    float   lineProj2   = Mathf.Sign(Vector3.Dot(e0, e1)) * Vector2.SqrMagnitude(proj);
                    float   length2     = Vector2.SqrMagnitude(e1);
                    if (distance2 < Config.snapDistance * Config.snapDistance && lineProj2 >= 0 && lineProj2 <= length2)
                    {
                        Vector2 point;
                        point    = pointOnLine;
                        priority = 2;
                        action   = () =>
                        {
                            float dirDiff    = Math.Abs(other.Direction - segment.Direction) % 180.0f;
                            float minDirDiff = Math.Min(dirDiff, Math.Abs(dirDiff - 180.0f));
                            if (minDirDiff < Config.minIntersectionDeviation)
                            {
                                return(false);
                            }
                            IntersectSegments(point, other, segment, segments, quadtree);
                            if (debugData != null)
                            {
                                debugData.intersectionsRadius.Add(point);
                            }
                            return(true);
                        };
                    }
                }
            }

            if (action != null)
            {
                return(action());
            }

            return(true);
        }