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