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); } }
protected virtual IEnumerator CreateBendingConstraints() { bendConstraintsData = new ObiBendConstraintsData(); List <int> particleIndices = new List <int>(); List <int> constraintIndices = new List <int>(); Dictionary <int, int> cons = new Dictionary <int, int>(); for (int i = 0; i < topology.vertices.Count; i++) { HalfEdgeMesh.Vertex vertex = topology.vertices[i]; foreach (HalfEdgeMesh.Vertex n1 in topology.GetNeighbourVerticesEnumerator(vertex)) { float cosBest = 0; HalfEdgeMesh.Vertex vBest = n1; foreach (HalfEdgeMesh.Vertex n2 in topology.GetNeighbourVerticesEnumerator(vertex)) { float cos = Vector3.Dot((n1.position - vertex.position).normalized, (n2.position - vertex.position).normalized); if (cos < cosBest) { cosBest = cos; vBest = n2; } } if (!cons.ContainsKey(vBest.index) || cons[vBest.index] != n1.index) { cons[n1.index] = vBest.index; particleIndices.Add(n1.index); particleIndices.Add(vBest.index); particleIndices.Add(vertex.index); constraintIndices.Add(constraintIndices.Count * 3); } } if (i % 500 == 0) { yield return(new CoroutineJob.ProgressInfo("ObiCloth: adding bend constraints...", i / (float)topology.vertices.Count)); } } constraintIndices.Add(constraintIndices.Count * 3); 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 >= bendConstraintsData.GetBatchCount()) { bendConstraintsData.AddBatch(new ObiBendConstraintsBatch()); } HalfEdgeMesh.Vertex n1 = topology.vertices[particleIndices[cIndex]]; HalfEdgeMesh.Vertex vBest = topology.vertices[particleIndices[cIndex + 1]]; HalfEdgeMesh.Vertex vertex = topology.vertices[particleIndices[cIndex + 2]]; Vector3 n1Pos = Vector3.Scale(scale, n1.position); Vector3 bestPos = Vector3.Scale(scale, vBest.position); Vector3 vertexPos = Vector3.Scale(scale, vertex.position); float restBend = ObiUtils.RestBendingConstraint(n1Pos, bestPos, vertexPos); bendConstraintsData.batches[color].AddConstraint(new Vector3Int(particleIndices[cIndex], particleIndices[cIndex + 1], particleIndices[cIndex + 2]), restBend); } // Set initial amount of active constraints: for (int i = 0; i < bendConstraintsData.batches.Count; ++i) { bendConstraintsData.batches[i].activeConstraintCount = bendConstraintsData.batches[i].constraintCount; } }