public AngleConstraint2D makeAngleConstraint(Spring2D s1, Spring2D s2)
        {
            AngleConstraint2D angle = new AngleConstraint2D(this, s1, s2);

            angles.Add(angle);
            return(angle);
        }
        public Spring2D makeSpring(Particle2D a, Particle2D b)
        {
            float    r = Vector2.Distance(a.Position, b.Position);
            Spring2D s = new Spring2D(this, a, b, r);

            springs.Add(s);
            return(s);
        }
Beispiel #3
0
        void applyConstraints()
        {
            //gravity
            if (setting.gravity != Vector2.zero)
            {
                for (int i = 0; i < sim.numberOfParticles(); ++i)
                {
                    p = sim.getParticle(i);
                    if (p.IsFree)
                    {
                        p.Position += setting.gravity;
                    }
                }
            }

            //iterations
            for (int iter = 0; iter < setting.iteration; iter++)
            {
                if (setting.applyString)
                {
                    for (int p = 1; p <= sim.maxSpringConvergenceID; p++)
                    {
                        for (int i = 0; i < sim.numberOfSprings(); i++)
                        {
                            Spring2D sp = sim.getSpring(i);
                            if (sp.convergenceGroupID == p)
                            {
                                sp.apply();
                            }
                        }
                    }
                }

                if (setting.applyAngle)
                {
                    for (int p = 1; p <= sim.maxAngleConvergenceID; p++)
                    {
                        for (int i = 0; i < sim.numberOfAngleConstraints(); i++)
                        {
                            AngleConstraint2D ag = sim.getAngleConstraint(i);
                            if (ag.convergenceGroupID == p)
                            {
                                ag.GetDelta();
                            }
                        }

                        for (int i = 0; i < sim.numberOfAngleConstraints(); i++)
                        {
                            AngleConstraint2D ag = sim.getAngleConstraint(i);
                            if (ag.convergenceGroupID == p)
                            {
                                ag.apply();
                            }
                        }
                    }
                }
            }
        }
 public void removeSpring(Spring2D a)
 {
     for (int i = angles.Count - 1; i >= 0; i--)
     {
         if (angles[i].ContainSpring(a))
         {
             angles.RemoveAt(i);
         }
     }
     springs.Remove(a);
 }
        public void removeParticle(Particle2D p)
        {
            for (int i = springs.Count - 1; i >= 0; i--)
            {
                if (springs[i].ParticleA == p || springs[i].ParticleB == p)
                {
                    Spring2D s = springs[i];
                    removeSpring(s);
                }
            }

            particles.Remove(p);
        }
 //setup by sticks
 //only b rotates around m, if you need a rotate around m, just make another angle constraint
 public AngleConstraint2D(Simulation sim, Spring2D _spring1, Spring2D _spring2)
 {
     this.on  = true;
     this.sim = sim;
     if (_spring1.ParticleA == _spring2.ParticleA)
     {
         SetTopology(_spring1.ParticleB, _spring1.ParticleA, _spring2.ParticleB); return;
     }
     if (_spring1.ParticleA == _spring2.ParticleB)
     {
         SetTopology(_spring1.ParticleB, _spring1.ParticleA, _spring2.ParticleA); return;
     }
     if (_spring1.ParticleB == _spring2.ParticleA)
     {
         SetTopology(_spring1.ParticleA, _spring1.ParticleB, _spring2.ParticleB); return;
     }
     if (_spring1.ParticleB == _spring2.ParticleB)
     {
         SetTopology(_spring1.ParticleA, _spring1.ParticleB, _spring2.ParticleA); return;
     }
 }
        public SimBuffer_Spring(Simulation sim, Vector2[] particleUV, int width, int height)
        {
            this.sim = sim;
            rt       = new RenderTexture[sim.maxSpringConvergenceID];
            int parNum = sim.numberOfParticles();

            ID_SpringParamRT  = Shader.PropertyToID("_SpringParamRT");
            ID_SpringConstant = Shader.PropertyToID("_SpringConstant");
            ID_PositionRT     = Shader.PropertyToID("_PositionRT");

            //rg = the other end point's uv, b = restlength, a = state
            Color[]   tempColor = new Color[width * height];
            Texture2D tempTex   = new Texture2D(width, height, TextureFormat.RGBAFloat, false, false);

            for (int i = 0; i < sim.maxSpringConvergenceID; i++)
            {
                //init rt
                rt[i] = new RenderTexture(width, height, 0, RTFormat.ARGB);
                rt[i].Create();

                //prepare temp color
                for (int k = 0; k < width * height; k++)
                {
                    if (k < parNum)
                    {
                        Vector2 uv = particleUV[k];
                        tempColor[k] = new Color(uv.x, uv.y, 1f, (sim.getParticle(k).IsFree) ? 1f : 0f);
                    }
                    else
                    {
                        tempColor[k] = new Color(0f, 0f, 1f, 0f);
                    }
                }

                //get info
                for (int j = 0; j < sim.numberOfSprings(); j++)
                {
                    Spring2D sp = sim.getSpring(j);
                    if (sp.convergenceGroupID == i + 1)
                    {
                        int a = sim.getParticleIndex(sp.ParticleA);
                        int b = sim.getParticleIndex(sp.ParticleB);
                        tempColor[a].r = particleUV[b].x;
                        tempColor[a].g = particleUV[b].y;
                        tempColor[a].b = sp.restLength2;
                        tempColor[a].a = (sp.ParticleA.IsFree) ? 1f : 0f;
                        tempColor[b].r = particleUV[a].x;
                        tempColor[b].g = particleUV[a].y;
                        tempColor[b].b = sp.restLength2;
                        tempColor[b].a = (sp.ParticleB.IsFree) ? 1f : 0f;
                    }
                }

                //blit
                tempTex.SetPixels(tempColor);
                tempTex.Apply();
                Graphics.Blit(tempTex, rt[i]);
            }

            Extension.ObjDestroy(tempTex);

            //mpb
            mpb = new MaterialPropertyBlock[sim.maxSpringConvergenceID];
            for (int i = 0; i < sim.maxSpringConvergenceID; i++)
            {
                mpb[i] = new MaterialPropertyBlock();
                mpb[i].SetTexture(ID_SpringParamRT, rt[i]);
                mpb[i].SetFloat(ID_SpringConstant, sim.Settings.springConstant);
            }

            //tempRT
            tempRT = new RenderTexture[sim.maxSpringConvergenceID - 1];
        }
        /// <summary>
        /// Calculates the convergence ID of the springs and angles that are connected to particle specified by particleIndex
        /// </summary>
        /// <param name="particleIndex">Particle index.</param>
        private void CalcConvergenceID(int particleIndex)
        {
            Particle2D pp = this.getParticle(particleIndex);

            //Spring
            List <Spring2D> sp        = new List <Spring2D> (10);   //the conencted spring for particle index
            int             springNum = this.numberOfSprings();

            //get the connected spring
            for (int i = 0; i < springNum; i++)
            {
                Spring2D   s = this.getSpring(i);
                Particle2D a = s.ParticleA;
                Particle2D b = s.ParticleB;
                if (a == pp || b == pp)
                {
                    sp.Add(s);
                }
            }
            //calc the convergence id for the springs which connects to this particle
            List <int> IDinUse = new List <int> (10);

            for (int i = 0; i < sp.Count; i++)
            {
                if (sp[i].convergenceGroupID != 0)
                {
                    IDinUse.Add(sp[i].convergenceGroupID);
                }
            }
            for (int i = 0; i < sp.Count; i++)
            {
                if (sp[i].convergenceGroupID == 0)
                {
                    int id = 1;
                    while (IDinUse.Contains(id))
                    {
                        id++;
                    }
                    sp[i].convergenceGroupID = id;
                    IDinUse.Add(id);
                    if (id > this.maxSpringConvergenceID)
                    {
                        this.maxSpringConvergenceID = id;
                    }
                }
            }

            //angle
            List <AngleConstraint2D> ag = new List <AngleConstraint2D> (10);
            int angleNum = this.numberOfAngleConstraints();

            //get the connected angles
            for (int i = 0; i < angleNum; i++)
            {
                AngleConstraint2D angle = this.getAngleConstraint(i);
                Particle2D        b     = angle.ParticleB;
                Particle2D        m     = angle.ParticleM;
                if (b == pp || m == pp)
                {
                    ag.Add(angle);
                }
            }
            //recalc the convergence id for the angles that are connected to this particle
            IDinUse.Clear();
            for (int i = 0; i < ag.Count; i++)
            {
                if (ag[i].convergenceGroupID != 0)
                {
                    IDinUse.Add(ag[i].convergenceGroupID);
                }
            }
            for (int i = 0; i < ag.Count; i++)
            {
                if (ag[i].convergenceGroupID == 0)
                {
                    int id = 1;
                    while (IDinUse.Contains(id))
                    {
                        id++;
                    }
                    ag[i].convergenceGroupID = id;
                    IDinUse.Add(id);
                    if (id > this.maxAngleConvergenceID)
                    {
                        this.maxAngleConvergenceID = id;
                    }
                }
            }
        }
 public bool ContainSpring(Spring2D spring)
 {
     return(ContainParticle(spring.ParticleA) && ContainParticle(spring.ParticleB));
 }