Example #1
0
        void Start()
        {
            switch (option)
            {
            case FEM_SCENE.BEAM:
                drawWireframe = true;
                drawTexture   = false;
                mouseStrength = 200;
                Scene         = CreateCantileverBeam.Create(new Vector2f(-0.5f, 0.5f), 1.0f, 6, true);
                break;

            case FEM_SCENE.RANDOM_CONVEX:
                drawWireframe = true;
                drawTexture   = false;
                mouseStrength = 200;
                Scene         = CreateRandomConvex.Create(new Vector2f(0.0f, 0.5f), 1.0f, 10);
                break;

            case FEM_SCENE.TORUS:
                drawWireframe = true;
                drawTexture   = false;
                mouseStrength = 200;
                Scene         = CreateTorus.Create(new Vector2f(0.0f, 0.5f), 0.2f, 0.5f, 12);
                break;

            case FEM_SCENE.ARMADILLO:
                drawTexture   = true;
                texture       = armadillo;
                mouseStrength = 2000;
                Scene         = CreateFromImage.Create(texture);
                break;

            case FEM_SCENE.BUNNY:
                drawTexture   = true;
                texture       = bunny;
                mouseStrength = 2000;
                Scene         = CreateFromImage.Create(texture);
                break;

            case FEM_SCENE.DONUT:
                drawTexture   = true;
                texture       = donut;
                mouseStrength = 2000;
                Scene         = CreateFromImage.Create(texture);
                break;
            }

            Scene.Planes.Add(new Vector3f(0.0f, 1.0f, 1.8f));
            Scene.Planes.Add(new Vector3f(1.0f, 0.0f, 2.8f));
            Scene.Planes.Add(new Vector3f(-1.0f, 0.0f, 2.8f));

            if (textureMaterial != null)
            {
                textureMaterial.SetTexture("_MainTex", texture);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        public static FEMScene Create(Vector2f origin, float scale, int numPoints, bool weld)
        {
            FEMScene Scene = new FEMScene();

            Scene.Substeps   = 40;
            Scene.Drag       = 1.0f;
            Scene.LameLambda = 4000.0f;
            Scene.LameMu     = 4000.0f;
            Scene.Damping    = 200.0f;
            Scene.Friction   = 0.5f;
            Scene.Toughness  = 8000.0f;

            float u = scale / (numPoints - 1.0f);

            for (int i = 0; i < numPoints; ++i)
            {
                Scene.Particles.Add(new FEMParticle(origin + new Vector2f(i * u, 0.0f), 1.0f));
                Scene.Particles.Add(new FEMParticle(origin + new Vector2f(i * u, u), 1.0f));

                if (i != 0)
                {
                    // add quad
                    int start = (i - 1) * 2;

                    Scene.Triangles.Add(new Triangle(start + 0, start + 2, start + 1));
                    Scene.Triangles.Add(new Triangle(start + 1, start + 2, start + 3));
                }
            }

            if (weld)
            {
                Scene.Particles[0].invMass = 0.0f;
                Scene.Particles[1].invMass = 0.0f;
            }

            // assign index to particles
            for (int i = 0; i < Scene.Particles.Count; ++i)
            {
                Scene.Particles[i].index = i;
            }

            Scene.CreateElements();

            return(Scene);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }