Ejemplo n.º 1
0
 void InitTreeLinks()
 {
     original = this;
     foreach (LinkedShape linkedShape in linkedShapes)
     {
         linkedShape.neighbors = new List <LinkedShape>(linkedShape.neighborsIndex.Count);
         foreach (int neighbor in linkedShape.neighborsIndex)
         {
             linkedShape.neighbors.Add(linkedShapes[neighbor]);
         }
     }
 }
Ejemplo n.º 2
0
    void Break(LinkedShape shape, Vector3 point, Vector3 force, float quantitéDeMouvement, bool addVelocity)
    {
        if (linkedShapes.Count <= 1)
        {
            return;
        }

        if (intactVisual != null)
        {
            intactVisual.enabled = false;
        }

        //double time1 = EditorApplication.timeSinceStartup;
        Vector3 dir = force.normalized;

        float propagation = Mathf.Max(0, 0.025f * force.magnitude / (0.5f + elasticity) / massPerBlock);

        List <List <LinkedShape> > groups = shape.FormGroupsWithNeighbors(propagation, force.normalized, Mathf.Max(linkedShapes.Count / 2, 1), point);


        //Validate neighbors
        int totalInGroups = 0;

        for (int i = 0; i < groups.Count; i++)
        {
            totalInGroups += groups[i].Count;
            foreach (LinkedShape item in groups[i])
            {
                item.ValidateNeighbors(groups[i]);
            }
        }
        int skipLastGroup = linkedShapes.Count > totalInGroups ? 0 : 1;

        //Remove groups from list
        for (int i = 0; i < groups.Count - skipLastGroup; i++)
        {
            List <LinkedShape> group = groups[i];
            foreach (LinkedShape item in group)
            {
                linkedShapes.Remove(item);
            }
        }

        //Parcourt de l'arbre pour séparé les région qui ne sont plus en contact
        List <List <LinkedShape> > newGroups = FindSeperatedRegions();

        for (int i = 0; i < newGroups.Count; i++)
        {
            totalInGroups += newGroups[i].Count;
            foreach (LinkedShape item in newGroups[i])
            {
                item.ValidateNeighbors(newGroups[i]);
            }
        }
        //Remove newGroups from list
        for (int i = 0; i < newGroups.Count; i++)
        {
            foreach (LinkedShape item in newGroups[i])
            {
                linkedShapes.Remove(item);
            }
        }
        //Ajoute les nouveaux groupes à la liste
        groups.AddRange(newGroups);

        //Kinematic settings
        bool resetKinematic = false;

        if (myRb.isKinematic)
        {
            resetKinematic   = true;
            myRb.isKinematic = false;
        }
        Vector3 oldMassCenter = myRb.worldCenterOfMass;


        float velocityChange = quantitéDeMouvement / (totalInGroups * massPerBlock);

        //Nouveaux blocka
        for (int i = 0; i < groups.Count - skipLastGroup; i++)
        {
            List <LinkedShape> group   = groups[i];
            FragmentTree       newTree = Instantiate(newChunkPrefab.gameObject).GetComponent <FragmentTree>();
            newTree.linkedShapes   = group;
            newTree.hardness       = hardness;
            newTree.debugDraw      = debugDraw;
            newTree.relinkTree     = false;
            newTree.newChunkPrefab = newChunkPrefab;
            newTree.elasticity     = elasticity;
            newTree.original       = original;
            newTree.massPerBlock   = massPerBlock;

            Rigidbody rb = newTree.GetComponent <Rigidbody>();
            rb.velocity        = myRb.velocity;
            rb.angularVelocity = myRb.angularVelocity;
            rb.mass            = newTree.linkedShapes.Count * massPerBlock;
            rb.drag            = myRb.drag;
            rb.angularDrag     = myRb.angularDrag;
            rb.ResetCenterOfMass();

            foreach (LinkedShape item in group)
            {
                item.shape.tr.SetParent(newTree.transform, true);
            }

            Vector3 dist      = rb.worldCenterOfMass - point;
            float   alignment = Vector3.Dot(dist.normalized, dir);                  //de 0 à 1
            //float forceRatio = Mathf.Max(1.5f + 0.5f*alignment, 0.1f); // REMOVE
            float distanceFactor = Mathf.Pow(1 / (dist.magnitude + 1), elasticity); // de 0 à 1

            Vector3 addVel = dir * velocityChange * alignment * distanceFactor * 2;
            //print("remains: " + alignment * distanceFactor + "   vel: " + addVel);

            if (addVelocity)
            {
                rb.AddForceAtPosition(addVel, point, ForceMode.VelocityChange);
            }
            //rb.AddExplosionForce(force.magnitude*forceRatio, point, 10, 0);
        }

        //Reset mass settings
        myRb.ResetCenterOfMass();
        myRb.mass = linkedShapes.Count * massPerBlock;

        if (resetKinematic)
        {
            Vector3 newCenterOfMass = myRb.worldCenterOfMass;

            if (oldMassCenter.y < newCenterOfMass.y)
            {
                myRb.isKinematic = false;
            }
            else
            {
                myRb.isKinematic = true;
            }
        }
    }