protected override IEnumerator CreateDistanceConstraints() { // prepare an array that maps from half edge index to <batch, constraintId> distanceConstraintMap = new Vector2Int[topology.halfEdges.Count]; for (int i = 0; i < distanceConstraintMap.Length; i++) { distanceConstraintMap[i] = new Vector2Int(-1, -1); } //Create distance constraints, one for each half-edge. distanceConstraintsData = new ObiDistanceConstraintsData(); List <int> edges = topology.GetEdgeList(); IEnumerator dc = CreateInitialDistanceConstraints(edges); while (dc.MoveNext()) { yield return(dc.Current); } dc = CreatePooledDistanceConstraints(edges); while (dc.MoveNext()) { yield return(dc.Current); } }
protected virtual IEnumerator CreateDistanceConstraints() { //Create distance constraints: List <int> edges = topology.GetEdgeList(); distanceConstraintsData = new ObiDistanceConstraintsData(); List <int> particleIndices = new List <int>(); List <int> constraintIndices = new List <int>(); for (int i = 0; i < edges.Count; i++) { HalfEdgeMesh.HalfEdge hedge = topology.halfEdges[edges[i]]; particleIndices.Add(topology.GetHalfEdgeStartVertex(hedge)); particleIndices.Add(hedge.endVertex); constraintIndices.Add(constraintIndices.Count * 2); if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiCloth: generating structural constraints...", i / (float)edges.Count)); } } constraintIndices.Add(constraintIndices.Count * 2); int[] constraintColors = GraphColoring.Colorize(particleIndices.ToArray(), constraintIndices.ToArray()); for (int i = 0; i < constraintColors.Length; ++i) { int color = constraintColors[i]; int cIndex = constraintIndices[i]; // Add a new batch if needed: if (color >= distanceConstraintsData.GetBatchCount()) { distanceConstraintsData.AddBatch(new ObiDistanceConstraintsBatch()); } HalfEdgeMesh.HalfEdge hedge = topology.halfEdges[edges[i]]; HalfEdgeMesh.Vertex startVertex = topology.vertices[topology.GetHalfEdgeStartVertex(hedge)]; HalfEdgeMesh.Vertex endVertex = topology.vertices[hedge.endVertex]; distanceConstraintsData.batches[color].AddConstraint(new Vector2Int(particleIndices[cIndex], particleIndices[cIndex + 1]), Vector3.Distance(Vector3.Scale(scale, startVertex.position), Vector3.Scale(scale, endVertex.position))); } // Set initial amount of active constraints: for (int i = 0; i < distanceConstraintsData.batches.Count; ++i) { distanceConstraintsData.batches[i].activeConstraintCount = distanceConstraintsData.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); } }
protected virtual IEnumerator CreateDistanceConstraints() { distanceConstraintsData = new ObiDistanceConstraintsData(); // Add two batches: for even and odd constraints: distanceConstraintsData.AddBatch(new ObiDistanceConstraintsBatch()); distanceConstraintsData.AddBatch(new ObiDistanceConstraintsBatch()); for (int i = 0; i < totalParticles - 1; i++) { var batch = distanceConstraintsData.batches[i % 2] as ObiDistanceConstraintsBatch; if (i < m_ActiveParticleCount - 1) { Vector2Int indices = new Vector2Int(i, i + 1); restLengths[i] = Vector3.Distance(positions[indices.x], positions[indices.y]); batch.AddConstraint(indices, restLengths[i]); batch.activeConstraintCount++; } else { restLengths[i] = m_InterParticleDistance; batch.AddConstraint(Vector2Int.zero, 0); } if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiRope: generating structural constraints...", i / (float)(totalParticles - 1))); } } // if the path is closed, add the last, loop closing constraint to a new batch to avoid sharing particles. if (path.Closed) { var loopClosingBatch = new ObiDistanceConstraintsBatch(); distanceConstraintsData.AddBatch(loopClosingBatch); Vector2Int indices = new Vector2Int(m_ActiveParticleCount - 1, 0); restLengths[m_ActiveParticleCount - 2] = Vector3.Distance(positions[indices.x], positions[indices.y]); loopClosingBatch.AddConstraint(indices, restLengths[m_ActiveParticleCount - 2]); loopClosingBatch.activeConstraintCount++; } }
public ObiDistanceConstraintsData(ObiActor actor = null, ObiDistanceConstraintsData source = null) : base(actor, source) { }
public ObiDistanceConstraintsBatch(ObiDistanceConstraintsData constraints = null, ObiDistanceConstraintsBatch source = null) : base(source) { m_Constraints = constraints; }