Exemplo n.º 1
0
    //external segments must ALWAYS be in order
    private List <CSGsegment> getExternalSegments(CSGshape other)
    {
        var retr = new List <CSGsegment>();

        foreach (var i in this.segments)
        {
            if (!other.isPointInside(i.start))
            {
                retr.Add(i);
            }
        }
        return(retr);
    }
Exemplo n.º 2
0
    //collision hull.hull or whatever is null if nothing is left
    public static List <CollisionHull> not(CSGshape shape, CSGshape other, bool isNot, out bool usedFlag, List <CSGshape> holes = null)
    {
        //start with a point on me thats not in the other shape
        //List<CSGshape> retr = new List<CSGshape>();
        List <CollisionHull> hulls            = new List <CollisionHull>();
        List <CSGsegment>    externalSegments = shape.getExternalSegments(other);

        usedFlag = !isNot;
        if (other.segments.TrueForAll(i => !shape.doesIntersect(i)) && !isNot)
        {
            var foo = new CollisionHull();
            foo.externalHull = shape;
            foo.holes        = holes;

            /*var bar = new CollisionHull();
             * bar.externalHull = other;*/
            hulls.Add(foo);
            //hulls.Add(bar);
            usedFlag = false;
            return(hulls);
        }
        else if (externalSegments.Count == 0)        //other completely surrounds this
        {
            if (isNot)
            {
                return(hulls);
            }
            else
            {
                hulls.Add(new CollisionHull());
                hulls[0].externalHull = other;
                return(hulls);
            }
        }
        else if (externalSegments.Count == shape.segments.Count && other.segments.TrueForAll(a => shape.isPointInside(a.start)))        //this completely surrounds other
        {
            if (isNot)
            {
                var foo = new List <CSGshape>();
                foo.Add(other);
                if (holes != null)
                {
                    foo.AddRange(holes);
                }
                foo = andAll(foo);
                var hull = new CollisionHull();
                hull.externalHull = shape;
                hull.holes.Add(other);
                hulls.Add(hull);
            }
            else
            {
                hulls.Add(new CollisionHull());
                hulls[0].externalHull = shape;
            }
            return(hulls);
            //throw new NotImplementedException();

            /*float closestDist = float.PositiveInfinity;
             * CSGsegment closestItem = null;
             * CSGsegment closestInnerItem = null;
             * if (!other.isClockwise())
             * {
             * other.antiRotate();
             * }
             * foreach (var i in shape.segments)
             * {
             * foreach (var j in other.segments)
             * {
             * var dist = (i.end - j.start).magnitude;
             * if (dist < closestDist)
             * {
             * closestItem = i;
             * closestInnerItem = j;
             * closestDist = dist;
             * }
             * }
             * }
             * var enter = new CSGsegment(closestItem.end, closestInnerItem.start);
             * var exit = new CSGsegment(closestInnerItem.start, closestItem.end);
             * var oldnext = closestItem.endSegment;
             * var oldinnernext = closestInnerItem.startSegment;
             * oldnext.startSegment = exit;
             * closestItem.endSegment = enter;
             * enter.endSegment = closestInnerItem;
             * exit.endSegment = oldnext;
             * oldinnernext.endSegment = exit;
             * enter.startSegment = closestItem;
             * closestInnerItem.startSegment = enter;
             * exit.startSegment = oldinnernext;
             *
             * CSGsegment curr = enter;
             * List<Vector2> newPoints = new List<Vector2>();
             * do
             * {
             * newPoints.Add(curr.getPoint(true));
             * curr = curr.next(true);
             * } while (curr!=enter);
             * retr.Add(new CSGshape(newPoints));
             * return retr;*/
        }
        else
        {
            while (externalSegments.Count > 0)
            {
                List <Vector2> newPoints       = new List <Vector2>();
                bool           isMovingForward = true;
                var            first           = externalSegments[0];//better to remove at start or end? look this up
                var            curr            = first;
                var            isStart         = true;
                externalSegments.RemoveAt(0);
                int counter = 0;
                while (true)
                {
                    if (counter > 100)                    //remove this?
                    {
                        throw new Exception("Linerider exceeded 100 steps");
                        //break;
                    }
                    counter++;
                    var partialPath = curr.ridePathUntilIntersection(other, externalSegments, isMovingForward, first, isStart);
                    foreach (var i in partialPath.first)
                    {
                        newPoints.Add(i.getPoint(isMovingForward));
                    }
                    if (partialPath.second == null)
                    {
                        break;
                    }
                    var intersectionPoint = partialPath.first[partialPath.first.Count - 1].intersectionPoint(partialPath.second);
                    isMovingForward = shape.getDirection(partialPath.second, isNot, intersectionPoint);                    //toggle this to add instead of subtract
                    isStart         = false;
                    //now we must enter this shape, so test the two points
                    var exitPoint     = partialPath.second.getPoint(!isMovingForward);                //!isMovingForward so we get end instead of start
                    var entrancePoint = intersectionPoint + smallDelta * (exitPoint - intersectionPoint).normalized;
                    if (isMovingForward)
                    {
                        curr = new CSGsegment(entrancePoint, exitPoint);
                    }
                    else
                    {
                        curr = new CSGsegment(exitPoint, entrancePoint);
                    }
                    curr.startSegment = partialPath.second.startSegment;
                    curr.endSegment   = partialPath.second.endSegment;
                    ////////////////////////now inside this
                    partialPath = curr.ridePathUntilIntersection(shape, externalSegments, isMovingForward, null);                    //null because it can't end inside
                    foreach (var i in partialPath.first)
                    {
                        newPoints.Add(i.getPoint(isMovingForward));
                    }
                    intersectionPoint = partialPath.first[partialPath.first.Count - 1].intersectionPoint(partialPath.second);
                    isMovingForward   = other.getDirection(partialPath.second, false, intersectionPoint);
                    //now we gotta leave this shape
                    exitPoint     = partialPath.second.getPoint(!isMovingForward);                //!isMovingForward so we get end instead of start
                    entrancePoint = intersectionPoint + smallDelta * (exitPoint - intersectionPoint).normalized;
                    if (isMovingForward)
                    {
                        curr = new CSGsegment(entrancePoint, exitPoint);
                    }
                    else
                    {
                        curr = new CSGsegment(exitPoint, entrancePoint);
                    }
                    curr.startSegment = partialPath.second.startSegment;
                    curr.endSegment   = partialPath.second.endSegment;
                }
                var foo      = new CollisionHull();
                var newShape = new CSGshape(newPoints);
                foo.externalHull = newShape;
                hulls.Add(foo);
            }
            return(hulls);
        }
    }