Exemplo 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]);
         }
     }
 }
Exemplo 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;
                }
            }
        }