public void ExplosionHandler(int fragments)
    {
        MeshFilter mf = GetComponent <MeshFilter>();

        // se la MeshFilter è null, non far nulla
        if (mf == null)
        {
            //yield return null;
        }
        else
        {
            // recupero la mesh del GameObject originale
            Mesh originalMesh = GetComponent <MeshFilter>().mesh;
            HE = HalfEdgeHelper.GetHalfEdges(originalMesh.vertices, originalMesh.triangles);

            if (fragments >= originalMesh.triangles.Length / 3)
            {
                Explode_max(mf);
            }
            else
            {
                if (fragments <= 0)
                {
                    fragments = 1;
                }
                Explode(mf, fragments);
            }
        }
    }
    void Awake()
    {
        Mesh originalMesh = GetComponent <MeshFilter>().mesh;

        verts     = originalMesh.vertices;
        triangles = originalMesh.triangles;

        var watch = System.Diagnostics.Stopwatch.StartNew();

        HE = HalfEdgeHelper.GetHalfEdges(verts, triangles);
        watch.Stop();
        elapsedHE = watch.ElapsedMilliseconds;

        watch            = System.Diagnostics.Stopwatch.StartNew();
        visitedTriangles = new HashSet <int>();
        trianglesQueue   = new Queue <int>();

        // per ora forzo il triangolo 0 come punto di partenza
        //int collidingTriangle = 0;
        int collidingTriangle = UnityEngine.Random.Range(0, triangles.Length);

        // per ogni FRAMMENTO creo un nuovo gameobject.
        // Versione 1. divido in parti uguali la mia mesh per il numero di frammenti che voglio creare
        int trianglesXFragment = Mathf.FloorToInt((triangles.Length / 3) / fragments);

        // parto dal mio triangolo x. recupero il primo dei 3 edges collegati
        int pos = Array.FindIndex(HE, halfEdge => halfEdge.faceIndex == collidingTriangle);

        if (pos >= 0)
        {
            trianglesQueue.Enqueue(pos);
        }

        List <int> availableTriangles = new List <int>();

        // riempio la mia lista di triangoli disponibili con tutti i triangoli possibili
        for (int i = 0; i < triangles.Length; i += 3)
        {
            availableTriangles.Add(i);
        }

        fragmentsFaces = new Dictionary <int, List <int> >();

        List <int> newFaces;

        // per ogni frammento
        for (int j = 0; j < fragments; j++)
        {
            // azzero il mio contatore triangoli
            int trianglesCount = 0;

            newFaces = new List <int>();

            // se il frammento precedente è finito in un vicolo cieco, prendo il primo triangolo disponibile
            if (trianglesQueue.Count == 0)
            {
                trianglesQueue.Enqueue(availableTriangles[0]);
            } // altrimenti prenderà un qualunque triangolo che stavo già per analizzare

            // finché ho elementi nella coda dei triangoli da visitare
            while (trianglesQueue.Count > 0)
            {
                // esamino il prossimo triangolo
                int t1 = trianglesQueue.Dequeue();

                // incremento di 1 il mio contatore
                trianglesCount++;

                // segno il mio triangolo fra i triangoli visitati, e allo stesso tempo lo tolgo dai triangoli ancora disponibili
                visitedTriangles.Add(t1);
                availableTriangles.Remove(t1);
                newFaces.Add(t1);

                // se ho raggiunto il numero di triangoli previsto dal mio frammento, esco
                if (trianglesCount == trianglesXFragment)
                {
                    if (trianglesQueue.Count > 0)
                    {
                        t1 = trianglesQueue.Dequeue();
                        trianglesQueue.Clear();
                        trianglesQueue.Enqueue(t1);
                    }
                    break;
                }

                // dagli edge esamino i triangoli accanto. Parto sempre da un triangolo diverso per aggiungere casualità alla forma del frammento
                //int offset = UnityEngine.Random.Range(0, 3);
                for (int x = 0; x < 3; x++)
                {
                    int crossingEdge = HE[t1 + x].twinEdge;

                    // recupero l'indice della faccia del triangolo interno all'edge appena recuperato
                    int t2 = HE[crossingEdge].faceIndex;
                    // controllo se il triangolo in questione sia già stato visitato (o sia già in coda)
                    if (!visitedTriangles.Contains(t2) && !trianglesQueue.Contains(t2))
                    {
                        // se non è stato visitato e non è in coda, lo aggiungo al mio elenco
                        trianglesQueue.Enqueue(t2);
                    }
                }
            }

            // arrivato qui, ho creato un certo frammento X. Lo registro nel mio array dei frammenti
            fragmentsFaces.Add(j, newFaces);
        }

        // ripulisco la coda
        trianglesQueue.Clear();

        // arrivato a questo punto, potrebbero essere rimasti dei buchi. devo recuperarli e aggiungerli a uno dei frammenti sopracitati
        while (availableTriangles.Count > 0)
        {
            bool found = false;
            // prendo il primo triangolo disponibile
            trianglesQueue.Enqueue(availableTriangles[0]);

            newFaces = new List <int>();

            // finché ho elementi nella coda dei triangoli da visitare
            while (trianglesQueue.Count > 0)
            {
                // esamino il prossimo triangolo
                int t1 = trianglesQueue.Dequeue();

                // segno il mio triangolo fra i triangoli visitati, e allo stesso tempo lo tolgo dai triangoli ancora disponibili
                visitedTriangles.Add(t1);
                availableTriangles.Remove(t1);
                newFaces.Add(t1);

                // dagli edge esamino i triangoli accanto.
                //int offset = UnityEngine.Random.Range(0, 3);
                for (int x = 0; x < 3; x++)
                {
                    int crossingEdge = HE[t1 + x].twinEdge;

                    // recupero l'indice di partenza del triangolo interno all'edge appena recuperato
                    int t2 = HE[crossingEdge].faceIndex;
                    // controllo se il triangolo in questione sia già stato visitato (o sia già in coda)
                    if (!visitedTriangles.Contains(t2))
                    {
                        // se non è stato visitato, lo aggiungo al mio elenco
                        trianglesQueue.Enqueue(t2);
                    }
                    else // se invece è stato visitato, sarà associabile ad un determinato frammento
                    {
                        for (int y = 0; y < fragmentsFaces.Count; y++)
                        {
                            if (fragmentsFaces[y].Contains(t2))
                            {
                                fragmentsFaces[y].AddRange(newFaces);
                                found = true;
                                trianglesQueue.Clear();
                                break;
                            }
                        }
                        break;
                    }
                }
                if (found)
                {
                    break;
                }
            }
        }
        watch.Stop();
        elapsedBFS = watch.ElapsedMilliseconds;

        if (writeDebugFiles)
        {
            writeDebug();
        }
    }
    // Use this for initialization
    void Start()
    {
        Mesh originalMesh = GetComponent <MeshFilter>().mesh;

        HE = HalfEdgeHelper.GetHalfEdges(originalMesh.vertices, originalMesh.triangles);
    }