/** * 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 IEnumerator Generate() { m_Empty = true; m_ActiveParticleCount = 0; distanceConstraintsData = null; bendConstraintsData = null; skinConstraintsData = null; tetherConstraintsData = null; bendTwistConstraintsData = null; stretchShearConstraintsData = null; shapeMatchingConstraintsData = null; aerodynamicConstraintsData = null; chainConstraintsData = null; volumeConstraintsData = null; points = null; edges = null; triangles = null; IEnumerator g = Initialize(); while (g.MoveNext()) { yield return(g.Current); } RecalculateBounds(); m_Empty = false; m_InitialActiveParticleCount = m_ActiveParticleCount; foreach (IObiConstraints constraints in GetConstraints()) { for (int i = 0; i < constraints.GetBatchCount(); ++i) { constraints.GetBatch(i).initialActiveConstraintCount = constraints.GetBatch(i).activeConstraintCount; } } #if UNITY_EDITOR EditorUtility.SetDirty(this); #endif if (OnBlueprintGenerate != null) { OnBlueprintGenerate(this); } }
public ObiTetherConstraintsBatch(ObiTetherConstraintsData constraints = null, ObiTetherConstraintsBatch source = null) : base(source) { m_Constraints = constraints; }
public ObiTetherConstraintsData(ObiActor actor = null, ObiTetherConstraintsData source = null) : base(actor, source) { }
public ObiTetherConstraintsBatch(ObiTetherConstraintsData constraints = null) : base() { }