Exemplo n.º 1
0
        /// <summary>
        /// Modification of set subtract for vector space.
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="neg"></param>
        /// <param name="intersec"></param>
        /// <returns></returns>
        public static List <CSGShape> VectorSetSubtract(List <CSGShape> pos, CSGShape neg, List <CSGShape> intersec = null)
        {
            //Look to set subtract algorithm for explinations
            //The primary difference between this algorithm, and the set subtract algorithm, is that this algorithm passes on correct r values to the output

            List <CSGShape>  outputList   = new List <CSGShape>();
            Stack <CSGShape> workingStack = new Stack <CSGShape>(pos);

            while (workingStack.Count > 0)
            {
                CSGShape current = workingStack.Pop();
                int      offendingIndex;
                var      status = CSGPhysics.CalcCollision2D(neg, current, out offendingIndex);
                if (status == CSGPhysics.CollisionType.BEnclosedInA)
                {
                    if (intersec != null)
                    {
                        current.rValue += neg.rValue;
                        intersec.Add(current);
                    }
                }
                else if (status != CSGPhysics.CollisionType.NotColliding)
                {
                    IPoly inside, outside;
                    Divide(current, out inside, out outside, neg.GetPoint(offendingIndex), neg.GetSurfaceNormal(offendingIndex), (x, y) => x.Clone(y));
                    workingStack.Push(new CSGShape(inside, current.rValue));
                    workingStack.Push(new CSGShape(outside, current.rValue));
                }
                else
                {
                    outputList.Add(current);
                }
            }
            return(outputList);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Preforms the set subtract operation with multiple pos and a single neg.
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="neg"></param>
        /// <param name="constructor"></param>
        /// <returns></returns>
        public static List <IPoly> SetSubtract(IEnumerable <IPoly> pos, IPoly neg, Func <IPoly, IEnumerable <Vector3>, IPoly> constructor)
        {
            //set subtract algorithm
            //this version works for only 1 negative poly, and is the basis for multiple polys
            //append all positive polys to a working stack
            //pop polys from the working stack and compare them to the neg poly
            //if they intersect, split them, and push them on the working stack
            //if they are enclosed, remove them from the working list
            //if they aren't instersecting append them to the output stack
            //continue until working stack is empty

            //Initialization
            List <IPoly>  outputList   = new List <IPoly>();
            Stack <IPoly> workingStack = new Stack <IPoly>(pos);

            //working stack loop
            while (workingStack.Count > 0)
            {
                //initialization
                IPoly current = workingStack.Pop();
                int   offendingIndex;

                //detect collision status
                var status = CSGPhysics.CalcCollision2D(neg, current, out offendingIndex);
                //enclosed, just throw away polygon
                if (status == CSGPhysics.CollisionType.BEnclosedInA)
                {
                    continue;
                }
                //if colliding, divide the polygon and push them on the working stack
                else if (status != CSGPhysics.CollisionType.NotColliding)
                {
                    IPoly inside, outside;
                    Divide(current, out inside, out outside, neg.GetPoint(offendingIndex), neg.GetSurfaceNormal(offendingIndex), constructor);
                    workingStack.Push(inside);
                    workingStack.Push(outside);
                }
                //if not colliding, append to output list
                else
                {
                    outputList.Add(current);
                }
            }
            return(outputList);
        }