private void AddPointsAndSprings(List <TriangleVertexIndices> indices, List <FPVector> vertices) { for (int i = 0; i < vertices.Count; i++) { MassPoint point = new MassPoint(sphere, this, material); point.Position = vertices[i]; point.Mass = FP.EN1; points.Add(point); } for (int i = 0; i < indices.Count; i++) { TriangleVertexIndices index = indices[i]; Triangle t = new Triangle(this); t.indices = index; triangles.Add(t); t.boundingBox = FPBBox.SmallBox; t.boundingBox.AddPoint(points[t.indices.I0].position); t.boundingBox.AddPoint(points[t.indices.I1].position); t.boundingBox.AddPoint(points[t.indices.I2].position); t.dynamicTreeID = dynamicTree.AddProxy(ref t.boundingBox, t); } HashSet <Edge> edges = GetEdges(indices); int count = 0; foreach (Edge edge in edges) { Spring spring = new Spring(points[edge.Index1], points[edge.Index2]); spring.Softness = FP.EN2; spring.BiasFactor = FP.EN1; spring.SpringType = SpringType.EdgeSpring; springs.Add(spring); count++; } }
/// <summary> /// Creates a 2D-Cloth. Connects Nearest Neighbours (4x, called EdgeSprings) and adds additional /// shear/bend constraints (4xShear+4xBend). /// </summary> /// <param name="sizeX"></param> /// <param name="sizeY"></param> /// <param name="scale"></param> public SoftBody(int sizeX, int sizeY, FP scale) { List <TriangleVertexIndices> indices = new List <TriangleVertexIndices>(); List <FPVector> vertices = new List <FPVector>(); for (int i = 0; i < sizeY; i++) { for (int e = 0; e < sizeX; e++) { vertices.Add(new FPVector(i, 0, e) * scale); } } for (int i = 0; i < sizeX - 1; i++) { for (int e = 0; e < sizeY - 1; e++) { TriangleVertexIndices index = new TriangleVertexIndices(); { index.I0 = (e + 0) * sizeX + i + 0; index.I1 = (e + 0) * sizeX + i + 1; index.I2 = (e + 1) * sizeX + i + 1; indices.Add(index); index.I0 = (e + 0) * sizeX + i + 0; index.I1 = (e + 1) * sizeX + i + 1; index.I2 = (e + 1) * sizeX + i + 0; indices.Add(index); } } } EdgeSprings = springs.AsReadOnly(); VertexBodies = points.AsReadOnly(); Triangles = triangles.AsReadOnly(); AddPointsAndSprings(indices, vertices); for (int i = 0; i < sizeX - 1; i++) { for (int e = 0; e < sizeY - 1; e++) { Spring spring = new Spring(points[(e + 0) * sizeX + i + 1], points[(e + 1) * sizeX + i + 0]); spring.Softness = FP.EN2; spring.BiasFactor = FP.EN1; springs.Add(spring); } } foreach (Spring spring in springs) { FPVector delta = spring.body1.position - spring.body2.position; if (delta.z != FP.Zero && delta.x != FP.Zero) { spring.SpringType = SpringType.ShearSpring; } else { spring.SpringType = SpringType.EdgeSpring; } } for (int i = 0; i < sizeX - 2; i++) { for (int e = 0; e < sizeY - 2; e++) { Spring spring1 = new Spring(points[(e + 0) * sizeX + i + 0], points[(e + 0) * sizeX + i + 2]); spring1.Softness = FP.EN2; spring1.BiasFactor = FP.EN1; Spring spring2 = new Spring(points[(e + 0) * sizeX + i + 0], points[(e + 2) * sizeX + i + 0]); spring2.Softness = FP.EN2; spring2.BiasFactor = FP.EN1; spring1.SpringType = SpringType.BendSpring; spring2.SpringType = SpringType.BendSpring; springs.Add(spring1); springs.Add(spring2); } } }