Ejemplo n.º 1
0
        /// <summary>
        /// Splits the game object using an array of planes, instantiating the pieces as new
        /// game objects (clones of the original) and destroying the original game object when finished.
        /// </summary>
        /// <param name="planes">
        /// An array of world-space planes with unit-length normals.
        /// </param>
        public void Split(Plane[] planes)
        {
            if (planes != null && planes.Length > 0 && isIntact && hull != null && !hull.IsEmpty)
            {
                UvMapper    uvMapper    = GetComponent <UvMapper>();
                ColorMapper colorMapper = GetComponent <ColorMapper>();

                if (sendPreSplitMessage)
                {
                    SendMessage("PreSplit", planes, SendMessageOptions.DontRequireReceiver);
                }

                Vector3[] points, normals;
                ConvertPlanesToLocalspace(planes, out points, out normals);

                IList <IHull> newHulls;
                CreateNewHulls(uvMapper, colorMapper, points, normals, out newHulls);

                GameObject[] newGameObjects;
                CreateNewGameObjects(newHulls, out newGameObjects);

                if (sendPostSplitMessage)
                {
                    SendMessage("PostSplit", newGameObjects, SendMessageOptions.DontRequireReceiver);
                }

                //Destroy(gameObject);
                gameObject.SetActive(false);
                generation--;
                //isIntact = false;
            }
        }
Ejemplo n.º 2
0
        protected void CreateNewHulls(UvMapper uvMapper, ColorMapper colorMapper, Vector3[] points, Vector3[] normals, out IList <IHull> newHulls)
        {
            newHulls = new List <IHull>();

            // Add the starting hull
            newHulls.Add(hull);

            for (int j = 0; j < points.Length; j++)
            {
                int previousHullCount = newHulls.Count;

                for (int i = 0; i < previousHullCount; i++)
                {
                    IHull previousHull = newHulls[0];

                    // Split the previous hull
                    IHull a, b;

                    previousHull.Split(points[j], normals[j], fillCut, uvMapper, colorMapper, out a, out b);

                    // Update the list
                    newHulls.Remove(previousHull);

                    if (!a.IsEmpty)
                    {
                        newHulls.Add(a);
                    }

                    if (!b.IsEmpty)
                    {
                        newHulls.Add(b);
                    }
                }
            }
        }
Ejemplo n.º 3
0
        protected void FillCutEdges(LegacyHull a, LegacyHull b, IList <Edge> edgesA, IList <Edge> edgesB, Vector3 planeNormal, UvMapper uvMapper)
        {
            // Create outline data
            int outlineEdgeCount = edgesA.Count;

            Vector3[] outlinePoints = new Vector3[outlineEdgeCount];
            int[]     outlineEdges  = new int[outlineEdgeCount * 2];

            int startIndex = 0;

            for (int i = 0; i < outlineEdgeCount; i++)
            {
                int currentIndex = i;
                int nextIndex    = (i + 1) % outlineEdgeCount;

                Edge current = edgesA[currentIndex];
                Edge next    = edgesA[nextIndex];

                // Set point
                outlinePoints[i] = current.point0.position;

                // Set edge
                outlineEdges[i * 2 + 0] = currentIndex;

                if (current.point1 == next.point0)
                {
                    outlineEdges[i * 2 + 1] = nextIndex;
                }
                else
                {
                    outlineEdges[i * 2 + 1] = startIndex;

                    startIndex = nextIndex;
                }
            }

            // Triangulate
            int[] newEdges, newTriangles, newTriangleEdges;

            ITriangulator triangulator = new Triangulator(outlinePoints, outlineEdges, planeNormal);

            triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);

            // Calculate vertex properties
            Vector3 normalA = -planeNormal;
            Vector3 normalB = planeNormal;

            Vector4[] tangentsA, tangentsB;
            Vector2[] uvsA, uvsB;

            uvMapper.Map(outlinePoints, planeNormal, out tangentsA, out tangentsB, out uvsA, out uvsB);

            // Create new vertices
            int[] verticesA = new int[outlineEdgeCount];
            int[] verticesB = new int[outlineEdgeCount];

            for (int i = 0; i < outlineEdgeCount; i++)
            {
                a.AddVertex(outlinePoints[i], normalA, tangentsA[i], uvsA[i], edgesA[i].point0, out verticesA[i]);

                b.AddVertex(outlinePoints[i], normalB, tangentsB[i], uvsB[i], edgesB[i].point0, out verticesB[i]);
            }

            // Create new edges
            for (int i = 0; i < newEdges.Length / 2; i++)
            {
                int point0 = newEdges[i * 2 + 0];
                int point1 = newEdges[i * 2 + 1];

                Edge edgeA = new Edge(edgesA[point0].point0, edgesA[point1].point0);
                Edge edgeB = new Edge(edgesB[point0].point0, edgesB[point1].point0);

                edgesA.Add(edgeA);
                edgesB.Add(edgeB);

                a.edges.Add(edgeA);
                b.edges.Add(edgeB);
            }

            // Create new triangles
            for (int i = 0; i < newTriangles.Length / 3; i++)
            {
                int point0 = newTriangles[i * 3 + 0];
                int point1 = newTriangles[i * 3 + 1];
                int point2 = newTriangles[i * 3 + 2];

                int edge0 = newTriangleEdges[i * 3 + 0];
                int edge1 = newTriangleEdges[i * 3 + 1];
                int edge2 = newTriangleEdges[i * 3 + 2];

                Triangle triangleA = new Triangle(verticesA[point0], verticesA[point2], verticesA[point1], edgesA[point0].point0, edgesA[point2].point0, edgesA[point1].point0, edgesA[edge2], edgesA[edge1], edgesA[edge0]);
                Triangle triangleB = new Triangle(verticesB[point0], verticesB[point1], verticesB[point2], edgesB[point0].point0, edgesB[point1].point0, edgesB[point2].point0, edgesB[edge0], edgesB[edge1], edgesB[edge2]);

                a.triangles.Add(triangleA);
                b.triangles.Add(triangleB);
            }
        }
Ejemplo n.º 4
0
        public void Split(Vector3 localPointOnPlane, Vector3 localPlaneNormal, bool fillCut, UvMapper uvMapper, ColorMapper colorMapper, out IHull resultA, out IHull resultB)
        {
            lock (key)
            {
                if (localPlaneNormal == Vector3.zero)
                {
                    localPlaneNormal = Vector3.up;
                }

                LegacyHull a = new LegacyHull(this);
                LegacyHull b = new LegacyHull(this);

                SetIndices();

                bool[] pointAbovePlane;

                AssignPoints(a, b, localPointOnPlane, localPlaneNormal, out pointAbovePlane);

                int[] oldToNewVertex;

                AssignVertices(a, b, pointAbovePlane, out oldToNewVertex);

                bool[]    edgeIntersectsPlane;
                EdgeHit[] edgeHits;

                AssignEdges(a, b, pointAbovePlane, localPointOnPlane, localPlaneNormal, out edgeIntersectsPlane, out edgeHits);

                IList <Edge> cutEdgesA, cutEdgesB;

                AssignTriangles(a, b, pointAbovePlane, edgeIntersectsPlane, edgeHits, oldToNewVertex, out cutEdgesA, out cutEdgesB);

                if (fillCut)
                {
                    SortCutEdges(cutEdgesA, cutEdgesB);

                    FillCutEdges(a, b, cutEdgesA, cutEdgesB, localPlaneNormal, uvMapper);
                }

                ValidateOutput(a, b, localPlaneNormal);

                Clear();

                // Set output
                resultA = a;
                resultB = b;
            }
        }
Ejemplo n.º 5
0
        protected void FillCutEdges(FastHull a, FastHull b, IList <Vector3> edges, Vector3 planeNormal, UvMapper uvMapper, ColorMapper colorMapper)
        {
            int edgeCount = edges.Count / 2;

            List <Vector3> points  = new List <Vector3>(edgeCount);
            List <int>     outline = new List <int>(edgeCount * 2);

            int start = 0;

            for (int current = 0; current < edgeCount; current++)
            {
                int next = current + 1;

                // Find the next edge
                int   nearest         = start;
                float nearestDistance = (edges[current * 2 + 1] - edges[start * 2 + 0]).sqrMagnitude;

                for (int other = next; other < edgeCount; other++)
                {
                    float distance = (edges[current * 2 + 1] - edges[other * 2 + 0]).sqrMagnitude;

                    if (distance < nearestDistance)
                    {
                        nearest         = other;
                        nearestDistance = distance;
                    }
                }

                // Is the current edge the last edge in this edge loop?
                if (nearest == start && current > start)
                {
                    int pointStart   = points.Count;
                    int pointCounter = pointStart;

                    // Add this edge loop to the triangulation lists
                    for (int edge = start; edge < current; edge++)
                    {
                        points.Add(edges[edge * 2 + 0]);
                        outline.Add(pointCounter++);
                        outline.Add(pointCounter);
                    }

                    points.Add(edges[current * 2 + 0]);
                    outline.Add(pointCounter);
                    outline.Add(pointStart);

                    // Start a new edge loop
                    start = next;
                }
                else if (next < edgeCount)
                {
                    // Move the nearest edge so that it follows the current edge
                    Vector3 n0 = edges[next * 2 + 0];
                    Vector3 n1 = edges[next * 2 + 1];

                    edges[next * 2 + 0] = edges[nearest * 2 + 0];
                    edges[next * 2 + 1] = edges[nearest * 2 + 1];

                    edges[nearest * 2 + 0] = n0;
                    edges[nearest * 2 + 1] = n1;
                }
            }

            if (points.Count > 0)
            {
                // Triangulate the outline
                int[] newEdges, newTriangles, newTriangleEdges;

                ITriangulator triangulator = new Triangulator(points, outline, planeNormal);

                triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);

                // Add the new vertices
                int offsetA = a.vertices.Count;
                int offsetB = b.vertices.Count;

                a.vertices.AddRange(points);
                b.vertices.AddRange(points);

                if (normals != null)
                {
                    Vector3 normalA = -planeNormal;
                    Vector3 normalB = planeNormal;

                    for (int i = 0; i < points.Count; i++)
                    {
                        a.normals.Add(normalA);
                        b.normals.Add(normalB);
                    }
                }

                if (colors != null)
                {
                    Color32[] colorsA, colorsB;

                    colorMapper.Map(points, planeNormal, out colorsA, out colorsB);

                    a.colors.AddRange(colorsA);
                    b.colors.AddRange(colorsB);
                }

                if (tangents != null || uvs != null)
                {
                    Vector4[] tangentsA, tangentsB;
                    Vector2[] uvsA, uvsB;

                    uvMapper.Map(points, planeNormal, out tangentsA, out tangentsB, out uvsA, out uvsB);

                    if (tangents != null)
                    {
                        a.tangents.AddRange(tangentsA);
                        b.tangents.AddRange(tangentsB);
                    }

                    if (uvs != null)
                    {
                        a.uvs.AddRange(uvsA);
                        b.uvs.AddRange(uvsB);
                    }
                }

                // Add the new triangles
                int newTriangleCount = newTriangles.Length / 3;

                for (int i = 0; i < newTriangleCount; i++)
                {
                    a.indices.Add(offsetA + newTriangles[i * 3 + 0]);
                    a.indices.Add(offsetA + newTriangles[i * 3 + 2]);
                    a.indices.Add(offsetA + newTriangles[i * 3 + 1]);

                    b.indices.Add(offsetB + newTriangles[i * 3 + 0]);
                    b.indices.Add(offsetB + newTriangles[i * 3 + 1]);
                    b.indices.Add(offsetB + newTriangles[i * 3 + 2]);
                }
            }
        }
Ejemplo n.º 6
0
        public void Split(Vector3 localPointOnPlane, Vector3 localPlaneNormal, bool fillCut, UvMapper uvMapper, ColorMapper colorMapper, out IHull resultA, out IHull resultB)
        {
            if (localPlaneNormal == Vector3.zero)
            {
                localPlaneNormal = Vector3.up;
            }

            FastHull a = new FastHull(this);
            FastHull b = new FastHull(this);

            bool[] vertexAbovePlane;
            int[]  oldToNewVertexMap;

            AssignVertices(a, b, localPointOnPlane, localPlaneNormal, out vertexAbovePlane, out oldToNewVertexMap);

            IList <Vector3> cutEdges;

            AssignTriangles(a, b, vertexAbovePlane, oldToNewVertexMap, localPointOnPlane, localPlaneNormal, out cutEdges);

            if (fillCut)
            {
                if (colors != null && colorMapper == null)
                {
                    Debug.LogWarning("Fill cut failed: A ColorMapper was not provided even though the mesh has a color channel");
                }
                else if ((tangents != null || uvs != null) && uvMapper == null)
                {
                    Debug.LogWarning("Fill cut failed: A UvMapper was not provided even though the mesh has a tangent/uv channel");
                }
                else
                {
                    FillCutEdges(a, b, cutEdges, localPlaneNormal, uvMapper, colorMapper);
                }
            }

            ValidateOutput(a, b, localPlaneNormal);

            // Set output
            resultA = a;
            resultB = b;
        }
Ejemplo n.º 7
0
 protected void CreateNewHulls(UvMapper uvMapper, ColorMapper colorMapper, Vector3[] points, Vector3[] normals, out IList<IHull> newHulls)
 {
     newHulls = new List<IHull>();
     
     // Add the starting hull
     newHulls.Add(hull);
     
     for (int j = 0; j < points.Length; j++)
     {
         int previousHullCount = newHulls.Count;
         
         for (int i = 0; i < previousHullCount; i++)
         {
             IHull previousHull = newHulls[0];
             
             // Split the previous hull
             IHull a, b;
             
             previousHull.Split(points[j], normals[j], fillCut, uvMapper, colorMapper, out a, out b);
             
             // Update the list
             newHulls.Remove(previousHull);
             
             if (!a.IsEmpty)
             {
                 newHulls.Add(a);
             }
             
             if (!b.IsEmpty)
             {
                 newHulls.Add(b);
             }
         }
     }
 }
Ejemplo n.º 8
0
 protected void FillCutEdges(FastHull a, FastHull b, IList<Vector3> edges, Vector3 planeNormal, UvMapper uvMapper, ColorMapper colorMapper)
 {
     int edgeCount = edges.Count / 2;
     
     List<Vector3> points = new List<Vector3>(edgeCount);
     List<int> outline = new List<int>(edgeCount * 2);
     
     int start = 0;
     
     for (int current = 0; current < edgeCount; current++)
     {
         int next = current + 1;
         
         // Find the next edge
         int nearest = start;
         float nearestDistance = (edges[current * 2 + 1] - edges[start * 2 + 0]).sqrMagnitude;
         
         for (int other = next; other < edgeCount; other++)
         {
             float distance = (edges[current * 2 + 1] - edges[other * 2 + 0]).sqrMagnitude;
             
             if (distance < nearestDistance)
             {
                 nearest = other;
                 nearestDistance = distance;
             }
         }
         
         // Is the current edge the last edge in this edge loop?
         if (nearest == start && current > start)
         {
             int pointStart = points.Count;
             int pointCounter = pointStart;
             
             // Add this edge loop to the triangulation lists
             for (int edge = start; edge < current; edge++)
             {
                 points.Add(edges[edge * 2 + 0]);
                 outline.Add(pointCounter++);
                 outline.Add(pointCounter);
             }
             
             points.Add(edges[current * 2 + 0]);
             outline.Add(pointCounter);
             outline.Add(pointStart);
             
             // Start a new edge loop
             start = next;
         }
         else if (next < edgeCount)
         {
             // Move the nearest edge so that it follows the current edge
             Vector3 n0 = edges[next * 2 + 0];
             Vector3 n1 = edges[next * 2 + 1];
             
             edges[next * 2 + 0] = edges[nearest * 2 + 0];
             edges[next * 2 + 1] = edges[nearest * 2 + 1];
             
             edges[nearest * 2 + 0] = n0;
             edges[nearest * 2 + 1] = n1;
         }
     }
     
     if (points.Count > 0)
     {
         // Triangulate the outline
         int[] newEdges, newTriangles, newTriangleEdges;
         
         ITriangulator triangulator = new Triangulator(points, outline, planeNormal);
         
         triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);
         
         // Add the new vertices
         int offsetA = a.vertices.Count;
         int offsetB = b.vertices.Count;
         
         a.vertices.AddRange(points);
         b.vertices.AddRange(points);
         
         if (normals != null)
         {
             Vector3 normalA = -planeNormal;
             Vector3 normalB = planeNormal;
             
             for (int i = 0; i < points.Count; i++)
             {
                 a.normals.Add(normalA);
                 b.normals.Add(normalB);
             }
         }
         
         if (colors != null)
         {
             Color32[] colorsA, colorsB;
             
             colorMapper.Map(points, planeNormal, out colorsA, out colorsB);
             
             a.colors.AddRange(colorsA);
             b.colors.AddRange(colorsB);
         }
         
         if (tangents != null || uvs != null)
         {
             Vector4[] tangentsA, tangentsB;
             Vector2[] uvsA, uvsB;
             
             uvMapper.Map(points, planeNormal, out tangentsA, out tangentsB, out uvsA, out uvsB);
             
             if (tangents != null)
             {
                 a.tangents.AddRange(tangentsA);
                 b.tangents.AddRange(tangentsB);
             }
             
             if (uvs != null)
             {
                 a.uvs.AddRange(uvsA);
                 b.uvs.AddRange(uvsB);
             }
         }
         
         // Add the new triangles
         int newTriangleCount = newTriangles.Length / 3;
         
         for (int i = 0; i < newTriangleCount; i++)
         {
             a.indices.Add(offsetA + newTriangles[i * 3 + 0]);
             a.indices.Add(offsetA + newTriangles[i * 3 + 2]);
             a.indices.Add(offsetA + newTriangles[i * 3 + 1]);
             
             b.indices.Add(offsetB + newTriangles[i * 3 + 0]);
             b.indices.Add(offsetB + newTriangles[i * 3 + 1]);
             b.indices.Add(offsetB + newTriangles[i * 3 + 2]);
         }
     }
 }
Ejemplo n.º 9
0
 public void Split(Vector3 localPointOnPlane, Vector3 localPlaneNormal, bool fillCut, UvMapper uvMapper, ColorMapper colorMapper, out IHull resultA, out IHull resultB)
 {
     if (localPlaneNormal == Vector3.zero)
     {
         localPlaneNormal = Vector3.up;
     }
     
     FastHull a = new FastHull(this);
     FastHull b = new FastHull(this);
     
     bool[] vertexAbovePlane;
     int[] oldToNewVertexMap;
     
     AssignVertices(a, b, localPointOnPlane, localPlaneNormal, out vertexAbovePlane, out oldToNewVertexMap);
     
     IList<Vector3> cutEdges;
     
     AssignTriangles(a, b, vertexAbovePlane, oldToNewVertexMap, localPointOnPlane, localPlaneNormal, out cutEdges);
     
     if (fillCut)
     {
         if (colors != null && colorMapper == null)
         {
             Debug.LogWarning("Fill cut failed: A ColorMapper was not provided even though the mesh has a color channel");
         }
         else if ((tangents != null || uvs != null) && uvMapper == null)
         {
             Debug.LogWarning("Fill cut failed: A UvMapper was not provided even though the mesh has a tangent/uv channel");
         }
         else
         {
             FillCutEdges(a, b, cutEdges, localPlaneNormal, uvMapper, colorMapper);
         }
     }
     
     ValidateOutput(a, b, localPlaneNormal);
     
     // Set output
     resultA = a;
     resultB = b;
 }
Ejemplo n.º 10
0
 protected void FillCutEdges(LegacyHull a, LegacyHull b, IList<Edge> edgesA, IList<Edge> edgesB, Vector3 planeNormal, UvMapper uvMapper)
 {
     // Create outline data
     int outlineEdgeCount = edgesA.Count;
     
     Vector3[] outlinePoints = new Vector3[outlineEdgeCount];
     int[] outlineEdges = new int[outlineEdgeCount * 2];
     
     int startIndex = 0;
     
     for (int i = 0; i < outlineEdgeCount; i++)
     {
         int currentIndex = i;
         int nextIndex = (i + 1) % outlineEdgeCount;
         
         Edge current = edgesA[currentIndex];
         Edge next = edgesA[nextIndex];
         
         // Set point
         outlinePoints[i] = current.point0.position;
         
         // Set edge
         outlineEdges[i * 2 + 0] = currentIndex;
         
         if (current.point1 == next.point0)
         {
             outlineEdges[i * 2 + 1] = nextIndex;
         }
         else
         {
             outlineEdges[i * 2 + 1] = startIndex;
             
             startIndex = nextIndex;
         }
     }
     
     // Triangulate
     int[] newEdges, newTriangles, newTriangleEdges;
     
     ITriangulator triangulator = new Triangulator(outlinePoints, outlineEdges, planeNormal);
     
     triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);
     
     // Calculate vertex properties
     Vector3 normalA = -planeNormal;
     Vector3 normalB = planeNormal;
     Vector4[] tangentsA, tangentsB;
     Vector2[] uvsA, uvsB;
     
     uvMapper.Map(outlinePoints, planeNormal, out tangentsA, out tangentsB, out uvsA, out uvsB);
     
     // Create new vertices
     int[] verticesA = new int[outlineEdgeCount];
     int[] verticesB = new int[outlineEdgeCount];
     
     for (int i = 0; i < outlineEdgeCount; i++)
     {
         a.AddVertex(outlinePoints[i], normalA, tangentsA[i], uvsA[i], edgesA[i].point0, out verticesA[i]);
         
         b.AddVertex(outlinePoints[i], normalB, tangentsB[i], uvsB[i], edgesB[i].point0, out verticesB[i]);
     }
     
     // Create new edges
     for (int i = 0; i < newEdges.Length / 2; i++)
     {
         int point0 = newEdges[i * 2 + 0];
         int point1 = newEdges[i * 2 + 1];
         
         Edge edgeA = new Edge(edgesA[point0].point0, edgesA[point1].point0);
         Edge edgeB = new Edge(edgesB[point0].point0, edgesB[point1].point0);
         
         edgesA.Add(edgeA);
         edgesB.Add(edgeB);
         
         a.edges.Add(edgeA);
         b.edges.Add(edgeB);
     }
     
     // Create new triangles
     for (int i = 0; i < newTriangles.Length / 3; i++)
     {
         int point0 = newTriangles[i * 3 + 0];
         int point1 = newTriangles[i * 3 + 1];
         int point2 = newTriangles[i * 3 + 2];
         
         int edge0 = newTriangleEdges[i * 3 + 0];
         int edge1 = newTriangleEdges[i * 3 + 1];
         int edge2 = newTriangleEdges[i * 3 + 2];
         
         Triangle triangleA = new Triangle(verticesA[point0], verticesA[point2], verticesA[point1], edgesA[point0].point0, edgesA[point2].point0, edgesA[point1].point0, edgesA[edge2], edgesA[edge1], edgesA[edge0]);
         Triangle triangleB = new Triangle(verticesB[point0], verticesB[point1], verticesB[point2], edgesB[point0].point0, edgesB[point1].point0, edgesB[point2].point0, edgesB[edge0], edgesB[edge1], edgesB[edge2]);
         
         a.triangles.Add(triangleA);
         b.triangles.Add(triangleB);
     }
 }
Ejemplo n.º 11
0
 public void Split(Vector3 localPointOnPlane, Vector3 localPlaneNormal, bool fillCut, UvMapper uvMapper, ColorMapper colorMapper, out IHull resultA, out IHull resultB)
 {
     lock (key)
     {
         if (localPlaneNormal == Vector3.zero)
         {
             localPlaneNormal = Vector3.up;
         }
         
         LegacyHull a = new LegacyHull(this);
         LegacyHull b = new LegacyHull(this);
         
         SetIndices();
         
         bool[] pointAbovePlane;
         
         AssignPoints(a, b, localPointOnPlane, localPlaneNormal, out pointAbovePlane);
         
         int[] oldToNewVertex;
         
         AssignVertices(a, b, pointAbovePlane, out oldToNewVertex);
         
         bool[] edgeIntersectsPlane;
         EdgeHit[] edgeHits;
         
         AssignEdges(a, b, pointAbovePlane, localPointOnPlane, localPlaneNormal, out edgeIntersectsPlane, out edgeHits);
         
         IList<Edge> cutEdgesA, cutEdgesB;
         
         AssignTriangles(a, b, pointAbovePlane, edgeIntersectsPlane, edgeHits, oldToNewVertex, out cutEdgesA, out cutEdgesB);
         
         if (fillCut)
         {
             SortCutEdges(cutEdgesA, cutEdgesB);
             
             FillCutEdges(a, b, cutEdgesA, cutEdgesB, localPlaneNormal, uvMapper);
         }
         
         ValidateOutput(a, b, localPlaneNormal);
         
         Clear();
         
         // Set output
         resultA = a;
         resultB = b;
     }
 }