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); }
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)); }