/** * Automatically generates tether constraints for the cloth. * Partitions fixed particles into "islands", then generates up to maxTethers constraints for each * particle, linking it to the closest point in each island. */ public override void GenerateTethers(bool[] selected) { tetherConstraintsData = new ObiTetherConstraintsData(); // generate disjoint groups of particles (islands) List <HashSet <int> > islands = GenerateIslands(System.Linq.Enumerable.Range(0, topology.vertices.Count), null); // generate tethers for each one: List <int> particleIndices = new List <int>(); foreach (HashSet <int> island in islands) { GenerateTethersForIsland(island, particleIndices, selected, 4); } // for tethers, it's easy to use the optimal amount of colors analytically. if (particleIndices.Count > 0) { int color = 0; int lastParticle = particleIndices[0]; for (int i = 0; i < particleIndices.Count; i += 2) { if (particleIndices[i] != lastParticle) { lastParticle = particleIndices[i]; color = 0; } // Add a new batch if needed: if (color >= tetherConstraintsData.GetBatchCount()) { tetherConstraintsData.AddBatch(new ObiTetherConstraintsBatch()); } HalfEdgeMesh.Vertex startVertex = topology.vertices[particleIndices[i]]; HalfEdgeMesh.Vertex endVertex = topology.vertices[particleIndices[i + 1]]; tetherConstraintsData.batches[color].AddConstraint(new Vector2Int(particleIndices[i], particleIndices[i + 1]), Vector3.Distance(Vector3.Scale(scale, startVertex.position), Vector3.Scale(scale, endVertex.position)), 1); color++; } } // Set initial amount of active constraints: for (int i = 0; i < tetherConstraintsData.batches.Count; ++i) { tetherConstraintsData.batches[i].activeConstraintCount = tetherConstraintsData.batches[i].constraintCount; } }
public IEnumerable <IObiConstraints> GetConstraints() { if (distanceConstraintsData != null && distanceConstraintsData.GetBatchCount() > 0) { yield return(distanceConstraintsData); } if (bendConstraintsData != null && bendConstraintsData.GetBatchCount() > 0) { yield return(bendConstraintsData); } if (pinConstraintsData != null && pinConstraintsData.GetBatchCount() > 0) { yield return(pinConstraintsData); } if (skinConstraintsData != null && skinConstraintsData.GetBatchCount() > 0) { yield return(skinConstraintsData); } if (tetherConstraintsData != null && tetherConstraintsData.GetBatchCount() > 0) { yield return(tetherConstraintsData); } if (stretchShearConstraintsData != null && stretchShearConstraintsData.GetBatchCount() > 0) { yield return(stretchShearConstraintsData); } if (bendTwistConstraintsData != null && bendTwistConstraintsData.GetBatchCount() > 0) { yield return(bendTwistConstraintsData); } if (shapeMatchingConstraintsData != null && shapeMatchingConstraintsData.GetBatchCount() > 0) { yield return(shapeMatchingConstraintsData); } if (aerodynamicConstraintsData != null && aerodynamicConstraintsData.GetBatchCount() > 0) { yield return(aerodynamicConstraintsData); } if (chainConstraintsData != null && chainConstraintsData.GetBatchCount() > 0) { yield return(chainConstraintsData); } if (volumeConstraintsData != null && volumeConstraintsData.GetBatchCount() > 0) { yield return(volumeConstraintsData); } }