Composite MakeClothComposite(float rowSize, int row, float colSize, int col, float particleDamping, float springStiffness, Vector2 gravity, Vector2 rootPosition, Vector2 offset) { float rowCellSize = rowSize / row; float colCellSize = colSize / col; Particle[] rowParticles = new Particle[row]; var composite = new Composite(); List <int> particleIndices = new List <int>(); List <int> springIndices = new List <int>(); for (var y = 0; y < col; ++y) { if (y == 0) { for (var x = 0; x < row; ++x) { var p = new Particle(rootPosition + new Vector2(rowCellSize * x, -colCellSize * y) + offset, particleDamping); particleIndices.Add(composite.elemNum); composite.AddSimElement(p, 0); var pc = new PinConstraint(p); composite.AddSimElement(p, 10); if (x != 0) { var s = new SpringConstraint(rowParticles[x - 1], p, springStiffness); // var s = new DistanceConstraint(rowParticles[x - 1], p); springIndices.Add(composite.elemNum); composite.AddSimElement(s, 1); } rowParticles[x] = p; } } else { for (var x = 0; x < row; ++x) { var p = new Particle(rootPosition + new Vector2(rowCellSize * x, -colCellSize * y) + offset, particleDamping); particleIndices.Add(composite.elemNum); composite.AddSimElement(p, 0); var cfc = new ConstantForceConstraint(p, gravity); composite.AddSimElement(cfc, 5); var s = new SpringConstraint(rowParticles[x], p, springStiffness); // var s = new DistanceConstraint(rowParticles[x], p); springIndices.Add(composite.elemNum); composite.AddSimElement(s, 1); if (x != 0) { s = new SpringConstraint(rowParticles[x - 1], p, springStiffness); // s = new DistanceConstraint(rowParticles[x - 1], p); springIndices.Add(composite.elemNum); composite.AddSimElement(s, 1); } rowParticles[x] = p; } } } composite.AddRenderingGroup(new SimRenderer.SimRenderingGroup(1, springIndices)); composite.AddRenderingGroup(new SimRenderer.SimRenderingGroup(0, particleIndices)); return(composite); }