Beispiel #1
0
        public static bool PlanePolygonIntersection(Polygon polygon, out Vector3 position1, out Vector3 position2, UnityEngine.Plane testPlane)
        {
            position1 = Vector3.zero;
            position2 = Vector3.zero;

            bool position1Set = false;
            bool position2Set = false;

            for (int i = 0; i < polygon.vertices.Length; i++)
            {
                int previousIndex = i - 1;
                if (previousIndex < 0)
                {
                    previousIndex = polygon.vertices.Length - 1;
                }

                Vertex currentVertex  = polygon.vertices[i];
                Vertex previousVertex = polygon.vertices[previousIndex];

                PointPlaneRelation currentRelation  = ComparePointToPlane(currentVertex.Position, testPlane);
                PointPlaneRelation previousRelation = ComparePointToPlane(previousVertex.Position, testPlane);

                if (previousRelation == PointPlaneRelation.InFront && currentRelation == PointPlaneRelation.InFront)
                {
                }
                else if (previousRelation == PointPlaneRelation.Behind && currentRelation == PointPlaneRelation.InFront)
                {
                    float interpolant = Edge.IntersectsPlane(testPlane, previousVertex.Position, currentVertex.Position);
                    position2    = Vector3.Lerp(previousVertex.Position, currentVertex.Position, interpolant);
                    position2Set = true;
                }
                else if (previousRelation == PointPlaneRelation.InFront && currentRelation == PointPlaneRelation.Behind)
                {
                    // Reverse order here so that clipping remains consistent for either CW or CCW testing
                    float interpolant = Edge.IntersectsPlane(testPlane, currentVertex.Position, previousVertex.Position);
                    position1    = Vector3.Lerp(currentVertex.Position, previousVertex.Position, interpolant);
                    position1Set = true;
                }
                else if (previousRelation == PointPlaneRelation.Behind && currentRelation == PointPlaneRelation.Behind)
                {
                }
                else if (currentRelation == PointPlaneRelation.On)
                {
                    if (previousRelation == PointPlaneRelation.InFront)
                    {
                        position1    = currentVertex.Position;
                        position1Set = true;
                    }
                    else if (previousRelation == PointPlaneRelation.Behind)
                    {
                        position2    = currentVertex.Position;
                        position2Set = true;
                    }
                    else
                    {
                        //						throw new System.Exception("Unhandled polygon configuration");
                    }
                }
                else if (currentRelation == PointPlaneRelation.Behind)
                {
                }
                else if (currentRelation == PointPlaneRelation.InFront)
                {
                }
                else
                {
                }
            }

            return(position1Set && position2Set);
        }
Beispiel #2
0
        public static bool SplitPolygon(Polygon polygon, out Polygon frontPolygon, out Polygon backPolygon, out Vertex newVertex1, out Vertex newVertex2, UnityEngine.Plane clipPlane)
        {
            newVertex1 = null;
            newVertex2 = null;

            List <Vertex> frontVertices = new List <Vertex>();
            List <Vertex> backVertices  = new List <Vertex>();

            for (int i = 0; i < polygon.vertices.Length; i++)
            {
                int previousIndex = i - 1;
                if (previousIndex < 0)
                {
                    previousIndex = polygon.vertices.Length - 1;
                }

                Vertex currentVertex  = polygon.vertices[i];
                Vertex previousVertex = polygon.vertices[previousIndex];

                PointPlaneRelation currentRelation  = ComparePointToPlane(currentVertex.Position, clipPlane);
                PointPlaneRelation previousRelation = ComparePointToPlane(previousVertex.Position, clipPlane);

                if (previousRelation == PointPlaneRelation.InFront && currentRelation == PointPlaneRelation.InFront)
                {
                    // Front add current
                    frontVertices.Add(currentVertex);
                }
                else if (previousRelation == PointPlaneRelation.Behind && currentRelation == PointPlaneRelation.InFront)
                {
                    float  interpolant  = Edge.IntersectsPlane(clipPlane, previousVertex.Position, currentVertex.Position);
                    Vertex intersection = Vertex.Lerp(previousVertex, currentVertex, interpolant);

                    // Front add intersection, add current
                    frontVertices.Add(intersection);
                    frontVertices.Add(currentVertex);

                    // Back add intersection
                    backVertices.Add(intersection.DeepCopy());

                    newVertex2 = intersection;
                }
                else if (previousRelation == PointPlaneRelation.InFront && currentRelation == PointPlaneRelation.Behind)
                {
                    // Reverse order here so that clipping remains consistent for either CW or CCW testing
                    float  interpolant  = Edge.IntersectsPlane(clipPlane, currentVertex.Position, previousVertex.Position);
                    Vertex intersection = Vertex.Lerp(currentVertex, previousVertex, interpolant);

                    // Front add intersection
                    frontVertices.Add(intersection);

                    // Back add intersection, current
                    backVertices.Add(intersection.DeepCopy());
                    backVertices.Add(currentVertex);

                    newVertex1 = intersection;
                }
                else if (previousRelation == PointPlaneRelation.Behind && currentRelation == PointPlaneRelation.Behind)
                {
                    // Back add current
                    backVertices.Add(currentVertex);
                }
                else if (currentRelation == PointPlaneRelation.On)
                {
                    // Front add current
                    frontVertices.Add(currentVertex);

                    // Back add current
                    backVertices.Add(currentVertex.DeepCopy());

                    if (previousRelation == PointPlaneRelation.InFront)
                    {
                        newVertex1 = currentVertex;
                    }
                    else if (previousRelation == PointPlaneRelation.Behind)
                    {
                        newVertex2 = currentVertex;
                    }
                    else
                    {
                        //						throw new System.Exception("Unhandled polygon configuration");
                    }
                }
                else if (currentRelation == PointPlaneRelation.Behind)
                {
                    backVertices.Add(currentVertex);
                }
                else if (currentRelation == PointPlaneRelation.InFront)
                {
                    frontVertices.Add(currentVertex);
                }
                else
                {
                    throw new System.Exception("Unhandled polygon configuration");
                }
            }
            //			Debug.Log("done");

            frontPolygon = new Polygon(frontVertices.ToArray(), polygon.Material, polygon.ExcludeFromFinal, polygon.UserExcludeFromFinal, polygon.uniqueIndex);
            backPolygon  = new Polygon(backVertices.ToArray(), polygon.Material, polygon.ExcludeFromFinal, polygon.UserExcludeFromFinal, polygon.uniqueIndex);

            // Because of some floating point issues and some edge cases relating to splitting the tip of a very thin
            // polygon we can't reliable test that the polygon intersects a plane and will produce two valid pieces
            // so after splitting we need to do an additional test to check that each polygon is valid. If it isn't
            // then we mark that polygon as null and return false to indicate the split wasn't entirely successful

            bool splitNecessary = true;

            if (frontPolygon.vertices.Length < 3 || frontPolygon.Plane.normal == Vector3.zero)
            {
                frontPolygon   = null;
                splitNecessary = false;
            }

            if (backPolygon.vertices.Length < 3 || backPolygon.Plane.normal == Vector3.zero)
            {
                backPolygon    = null;
                splitNecessary = false;
            }

            return(splitNecessary);
        }