public static FEMScene Create(Vector2f origin, float scale, int numPoints) { FEMScene Scene = new FEMScene(); Scene.Substeps = 40; Scene.Drag = 1.0f; Scene.LameLambda = 10000.0f; Scene.LameMu = 10000.0f; Scene.Damping = 80.0f; Scene.Friction = 0.95f; Scene.Toughness = 20000.0f; List <Vector2f> points = new List <Vector2f>(); //Random.InitState(0); for (int i = 0; i < numPoints; ++i) { float rx = Random.Range(-scale, scale) * 0.5f; float ry = Random.Range(-scale, scale) * 0.5f; points.Add(origin + new Vector2f(rx, ry)); } List <Vector2f> verts; List <int> tris; Mesher.TriangulateDelaunay(points, out verts, out tris); // generate elements for (int i = 0; i < verts.Count; ++i) { Scene.Particles.Add(new FEMParticle(verts[i], 1.0f)); } for (int i = 0; i < tris.Count / 3; ++i) { Scene.Triangles.Add(new Triangle(tris[i * 3], tris[i * 3 + 1], tris[i * 3 + 2])); } // assign index to particles for (int i = 0; i < Scene.Particles.Count; ++i) { Scene.Particles[i].index = i; } Scene.CreateElements(); return(Scene); }
public static FEMScene Create(Vector2f origin, float inner, float outer, int segments) { FEMScene Scene = new FEMScene(); Scene.Substeps = 40; Scene.Drag = 1.0f; Scene.LameLambda = 10000.0f; Scene.LameMu = 10000.0f; Scene.Damping = 80.0f; Scene.Friction = 0.95f; Scene.Toughness = 20000.0f; List <Vector2f> verts = new List <Vector2f>(); List <int> tris = new List <int>(); Mesher.CreateTorus(verts, tris, inner, outer, segments); // generate elements for (int i = 0; i < verts.Count; ++i) { Scene.Particles.Add(new FEMParticle(origin + verts[i], 1.0f)); } for (int i = 0; i < tris.Count / 3; ++i) { Scene.Triangles.Add(new Triangle(tris[i * 3], tris[i * 3 + 1], tris[i * 3 + 2])); } // assign index to particles for (int i = 0; i < Scene.Particles.Count; ++i) { Scene.Particles[i].index = i; } Scene.CreateElements(); return(Scene); }
public static FEMScene Create(Texture2D img) { FEMScene Scene = new FEMScene(); if (img == null) { return(Scene); } Scene.Substeps = 80; Scene.Drag = 0.1f; Scene.LameLambda = 42000.0f; Scene.LameMu = 42000.0f; Scene.Damping = 250.0f; Scene.Friction = 0.8f; Scene.Toughness = 40000.0f; List <Vector2f> points = new List <Vector2f>(); List <Vector2f> bpoints = new List <Vector2f>(); // controls how finely the object is sampled aspect = (float)img.height / img.width; float fw = img.width; float fh = img.height; int inc = Mathf.FloorToInt(img.width * resolution); int margin = Mathf.Max((inc - 1) / 2, 1); // distribute points interior to the object or near it's boundary for (int y = 0; y < img.height; y += inc) { for (int x = 0; x < img.width; x += inc) { // if value non-zero then add a point int n = Neighbours(img, x, y, margin); if (n > 0) { Vector2f uv = new Vector2f(x / fw, y / fh); points.Add(uv); } } } // distribute points on the boundary for (int y = 0; y < img.height; y++) { for (int x = 0; x < img.width; x++) { if (EdgeDetect(img, x, y)) { Vector2f uv = new Vector2f(x / fw, y / fh); bpoints.Add(uv); } } } // triangulate int iterations = 7; List <Vector2f> verts; List <int> tris; Mesher.TriangulateVariational(points, bpoints, iterations, out verts, out tris); //no longer used points = null; bpoints = null; // discard triangles whose centroid is not inside the shape for (int i = 0; i < tris.Count;) { Vector2f p = verts[tris[i + 0]]; Vector2f q = verts[tris[i + 1]]; Vector2f r = verts[tris[i + 2]]; Vector2f c = (p + q + r) / 3.0f; //int x = Mathf.FloorToInt(c.x * fw); //int y = Mathf.FloorToInt(c.y * fh); //Color col = img.GetPixel(x, y); Color col = img.GetPixelBilinear(c.x, c.y); if (col.grayscale == 0.0f) { tris.RemoveRange(i, 3); } else { i += 3; } } // generate particles for (int i = 0; i < verts.Count; ++i) { Vector2f uv = verts[i]; Scene.Particles.Add(new FEMParticle(ToWorldPos(uv), uv, 0.0f)); } // generate elements and assign mass based on connected area for (int t = 0; t < tris.Count; t += 3) { int i = tris[t]; int j = tris[t + 1]; int k = tris[t + 2]; // calculate tri area Vector2f a = Scene.Particles[i].p; Vector2f b = Scene.Particles[j].p; Vector2f c = Scene.Particles[k].p; float area = 0.5f * Vector2f.Cross(b - a, c - a); float mass = density * area / 3.0f; Scene.Particles[i].invMass += mass; Scene.Particles[j].invMass += mass; Scene.Particles[k].invMass += mass; Scene.Triangles.Add(new Triangle(i, j, k)); } // convert mass to invmass for (int i = 0; i < Scene.Particles.Count; ++i) { if (Scene.Particles[i].invMass > 0.0f) { Scene.Particles[i].invMass = 1.0f / Scene.Particles[i].invMass; } } // assign index to particles for (int i = 0; i < Scene.Particles.Count; ++i) { Scene.Particles[i].index = i; } Scene.CreateElements(); return(Scene); }