Exemple #1
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);
                    }
                }
            }
        }
Exemple #2
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;
            }
        }
Exemple #3
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;
            }
        }
Exemple #4
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]);
                }
            }
        }
Exemple #5
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;
        }
Exemple #6
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);
             }
         }
     }
 }
Exemple #7
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]);
         }
     }
 }
Exemple #8
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;
 }
Exemple #9
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;
     }
 }