public static Composite CreateBox(Vector2 position, bool pinRandomCorner = true) { Composite comp = new Composite(); Vector2 center = position; float stiffness = 0.25f; float size = 200f; Particle c1 = new Particle(center + new Vector2(-size, size)); Particle c2 = new Particle(center + new Vector2(size, size)); Particle c3 = new Particle(center + new Vector2(size, -size)); Particle c4 = new Particle(center + new Vector2(-size, -size)); Constraint e1 = new DistanceConstraint(c1, c2, stiffness); Constraint e2 = new DistanceConstraint(c2, c3, stiffness); Constraint e3 = new DistanceConstraint(c3, c4, stiffness); Constraint e4 = new DistanceConstraint(c4, c1, stiffness); Constraint e5 = new DistanceConstraint(c1, c3, stiffness); Constraint e6 = new DistanceConstraint(c2, c4, stiffness); List <Particle> p = new[] { c1, c2, c3, c4 }.ToList(); List <Constraint> c = new[] { e1, e2, e3, e4, e5, e6 }.ToList(); if (pinRandomCorner) { Constraint pin = new PinConstraint(p[Random.Range(0, p.Count())]); c.Add(pin); } comp.particles.AddRange(p); comp.constraints.AddRange(c); return(comp); }
IEnumerator VerletCo() { Debug.Break(); yield return(null); while (true) { for (int j = 0; j < verlet.stiffness; ++j) { for (int i = 0; i < composite.constraints.Count; i++) { IConstraint constraint = composite.constraints[i]; if (constraint is DistanceConstraint) { DistanceConstraint dc = constraint as DistanceConstraint; int i1 = composite.particles.IndexOf(dc.p1); int i2 = composite.particles.IndexOf(dc.p2); title.text = "Iteration:" + (j + 1) + "/" + verlet.stiffness + " Relax nodes: " + (i1 + 1) + " and " + (i2 + 1); links[i].GetComponent <Image>().color = Color.red; } else if (constraint is PinConstraint) { PinConstraint pc = constraint as PinConstraint; int index = composite.particles.IndexOf(pc.p); title.text = "Iteration:" + (j + 1) + "/" + verlet.stiffness + " Pin node: " + (index + 1); } else { title.text = ""; } constraint.Relax(); UpdateView(); UpdateLinks(); yield return(null); if (i < links.Count) { links[i].GetComponent <Image>().color = linkPrefab.GetComponent <Image>().color;; } } } for (int i = 0; i < verlet.composites[0].particles.Count; ++i) { title.text = "Move node: " + (i + 1); Particle p = verlet.composites[0].particles[i]; p.Move(verlet.friction, verlet.gravity); arrow.gameObject.SetActive(true); arrow.transform.position = p.pos; arrow.transform.rotation = Quaternion.LookRotation(Vector3.back, p.pos - p.lastPos); UpdateView(); UpdateLinks(); yield return(null); arrow.gameObject.SetActive(false); } } }
private void AddDistance(int p1, int p2) { DistanceConstraint dc = new DistanceConstraint(bodies[p1], bodies[p2], bodies[p1].position, bodies[p2].position); dc.Softness = 2f; dc.BiasFactor = 0.1f; world.AddConstraint(dc); this.constraints.Add(dc); }
public void RemoveConstraint(DistanceConstraint constr) { if (SimulationSettings.LayerNames.Contains(constr.UpdateLayer) == false) { Debug.Log("Tried to Remove update func by layer name " + constr.UpdateLayer + " which des not exist, GameObject: " + constr.name); return; } ConstrUpdates[constr.UpdateLayer].Remove(constr); AllConstraints.Remove(constr); }
public GameObject RebuildCompositeModel(Composite comp) { if (compObDict.ContainsKey(comp)) { Destroy(compObDict[comp]); } foreach (Particle p in comp.particles) { partObDict.Remove(p); } var bodyGameOb = new GameObject("comp"); foreach (Particle p in comp.particles) { var particleGameOb = new GameObject("particle"); particleGameOb.transform.parent = bodyGameOb.transform; var verletPoint = particleGameOb.AddComponent <VerletPoint>(); verletPoint.particle = p; verletPoint.parentComp = comp; partObDict.Add(p, particleGameOb); } foreach (Constraint c in comp.constraints) { DistanceConstraint dc = c as DistanceConstraint; if (dc != null) { var constraintGameOb = new GameObject("constraint"); constraintGameOb.transform.parent = bodyGameOb.transform; var verletConstraint = constraintGameOb.AddComponent <VerletConstraint>(); verletConstraint.p1 = partObDict[dc.a].GetComponent <VerletPoint>(); verletConstraint.p2 = partObDict[dc.b].GetComponent <VerletPoint>(); verletConstraint.parentComp = comp; verletConstraint.constraint = c; var lineRenderer = constraintGameOb.AddComponent <MagLineRenderer>(); lineRenderer.p1 = partObDict[dc.a].transform; lineRenderer.p2 = partObDict[dc.b].transform; compositeConstraintCounts[comp] += 1; } } var vBody = bodyGameOb.AddComponent <VerletBody>(); vBody.body = comp; return(bodyGameOb); }
Composite MakeSpinalComposite(float length, int rimbNum, Vector2 rootPosition, float angle) { if (rimbNum <= 1) { throw new System.ArgumentException("rimbNumは\"2\"以上に設定してください。"); } float boneLength = length / (rimbNum + 1); var composite = new Composite(); List <int> particleIndices = new List <int>(); List <int> gravityIndices = new List <int>(); List <int> springIndices = new List <int>(); Vector2 direction = AngleToVec2(angle); var tp = new Particle(rootPosition); particleIndices.Add(composite.elemNum); composite.AddSimElement(tp, 0); var g = new ConstantForceConstraint(tp, gravity); gravityIndices.Add(composite.elemNum); composite.AddSimElement(g, 5); //var sinWave = new SinWaveForce(tp, Vector2.right, amplitude, timeScale, 0f); //composite.simElements.Add(sinWave); for (int i = 1; i < rimbNum; ++i) { var p = new Particle(rootPosition + direction * boneLength * i, damping); particleIndices.Add(composite.elemNum); composite.AddSimElement(p, 0); // var s = new SpringConstraint(tp, p); var s = new DistanceConstraint(tp, p); springIndices.Add(composite.elemNum); composite.AddSimElement(s, 1); g = new ConstantForceConstraint(p, gravity); gravityIndices.Add(composite.elemNum); composite.AddSimElement(g, 5); tp = p; } composite.AddRenderingGroup(new SimRenderer.SimRenderingGroup(1, springIndices)); composite.AddRenderingGroup(new SimRenderer.SimRenderingGroup(2, gravityIndices)); composite.AddRenderingGroup(new SimRenderer.SimRenderingGroup(0, particleIndices)); return(composite); }
public void BuildComposite() { Debug.Log("Built composite"); body = new Composite(); VerletHandler.Instance.compObDict.Add(body, gameObject); VerletHandler.Instance.compositeConstraintCounts.Add(body, 0); VerletPoint[] childPoints = GetComponentsInChildren <VerletPoint>(); //Create verts List <Particle> particles = new List <Particle>(); foreach (VerletPoint p in childPoints) { var particle = new Particle(new Vector2(p.transform.position.x, p.transform.position.y)); if (p.Anchored) { body.constraints.Add(new PinConstraint(particle)); } p.parentComp = body; VerletHandler.Instance.partObDict.Add(particle, p.gameObject); p.particle = particle; particles.Add(particle); body.particles.Add(particle); } VerletConstraint[] childConstraints = GetComponentsInChildren <VerletConstraint>(); //Link em up foreach (VerletConstraint e in childConstraints) { Constraint c = new DistanceConstraint(e.p1.particle, e.p2.particle, e.stiffness); body.constraints.Add(c); VerletHandler.Instance.compositeConstraintCounts[body] += 1; e.parentComp = body; e.constraint = c; } VerletHandler.Instance.World.composites.Add(body); }
DistanceConstraint GetClosestConstraint(DistanceConstraint except, out float closestDist, float maxDistance = float.MaxValue) { DistanceConstraint closest = null; closestDist = float.MaxValue; foreach (var constr in SystemUpdater.AllConstraints) { if (except == constr) { continue; } float dist = Vector3.Distance(constr.transform.position, HandlePoint.position); if (dist < closestDist && dist < maxDistance) { closestDist = dist; closest = constr; } } return(closest); }
public static void AdjustNodesByConstraints() { VerletNode[] nodes = Object.FindObjectsOfType <VerletNode>(); DistanceConstraint[] constraints = Object.FindObjectsOfType <DistanceConstraint>(); foreach (var node in nodes) { if (node.FixedPosition) { continue; } DistanceConstraint c1 = null; DistanceConstraint c2 = null; foreach (var distConst in constraints) { if (distConst.Node1 == node || distConst.Node2 == node) { c1 = distConst; } } foreach (var distConst in constraints) { if (distConst == c1) { continue; } if (distConst.Node1 == node || distConst.Node2 == node) { c2 = distConst; } } if (c1 != null && c2 != null) { node.transform.position = (c1.transform.position + c2.transform.position) / 2; } } }
protected void InitPbdWorld() { world.AddParticle(new Particle(segments[0], MassPerSegment)); world.AddStaticConstraint(new AttachConstraint(0, this.transform, Vector3.zero)); world.particles[0].useGravity = false; for (int i = 1; i < segments.Length; i++) { world.AddParticle(new Particle(segments[i], MassPerSegment)); var C = new DistanceConstraint(i - 1, i, SegmentLength); C.relation = Constraint.Relation.Equ; world.AddConstraint(new DistanceConstraint(i - 1, i, SegmentLength)); } switch (longRangeConstraintsMode) { case LongRangeConstraintsMode.None: break; case LongRangeConstraintsMode.Linear: for (int i = 2; i < segments.Length; i *= 2) { for (int j = i; j < segments.Length; j += i) { var C = new DistanceConstraint(j - i, j, SegmentLength * i); C.relation = Constraint.Relation.Leq; world.AddConstraint(C); } } break; case LongRangeConstraintsMode.Normal: // N*log(N) for (int i = 2; i < segments.Length; i *= 2) { for (int j = i; j < segments.Length; j++) { var C = new DistanceConstraint(j - i, j, SegmentLength * i); C.relation = Constraint.Relation.Leq; world.AddConstraint(C); } } break; case LongRangeConstraintsMode.Dense: // N*(N-1)/2 for (int i = 0; i < segments.Length; i++) { for (int j = i + 2; j < segments.Length; j++) { var C = new DistanceConstraint(i, j, SegmentLength * (j - i)); C.relation = Constraint.Relation.Leq; world.AddConstraint(C); } } break; } switch (solverType) { case SolverType.GaussSeidel: world.solver = new GaussSeidelSolver(); break; case SolverType.BackAndForth: world.solver = new BackAndForthSolver(); break; } }
public void RemoveConstraint(DistanceConstraint constr) { _Constraints.Remove(constr); ResetRotationOnConnection = true; }
public override void Build() { this.Demo.World.Solver = Jitter.World.SolverType.Sequential; AddGround(); RigidBody boxb = new RigidBody(new BoxShape(7, 1, 2)); boxb.Position = new JVector(3.0f, 12, 0); this.Demo.World.AddBody(boxb); boxb.Tag = BodyTag.DontDrawMe; boxb.IsStatic = true; this.Demo.World.Solver = Jitter.World.SolverType.Sequential; //this.Demo.World.SetDampingFactors(1.0f, 1.0f); SphereShape shape = new SphereShape(0.501f); for (int i = 0; i < 7; i++) { RigidBody body = new RigidBody(shape); body.Position = new JVector(i, 6, 0); DistanceConstraint dc1 = new DistanceConstraint(boxb, body, body.Position + JVector.Up * 6 + JVector.Backward * 5 + JVector.Down * 0.5f, body.Position); dc1.Softness = 1.0f; DistanceConstraint dc2 = new DistanceConstraint(boxb, body, body.Position + JVector.Up * 6 + JVector.Forward * 5 + JVector.Down * 0.5f, body.Position); dc2.Softness = 1.0f; dc1.BiasFactor = dc2.BiasFactor = 0.8f; dc1.IsMaxDistance = dc2.IsMaxDistance = false; this.Demo.World.AddBody(body); this.Demo.World.AddConstraint(dc1); this.Demo.World.AddConstraint(dc2); body.Restitution = 1.0f; body.StaticFriction = 1.0f; // this.Demo.World.SetDampingFactors(1.0f, 1.0f); } //for (int i = 0; i < 5; i++) //{ // RigidBody sBody = new RigidBody(new SphereShape(0.5f)); // sBody.Position = new JVector(0, 0.5f, i); // this.Demo.World.AddBody(sBody); // sBody.Restitution = 1.0f; // sBody.Friction = 0.0f; //} //for (int i = 0; i < 3; i++) //{ // RigidBody sBody = new RigidBody(new SphereShape(0.5f)); // sBody.Position = new JVector(0, 0.5f, 10 + i); // this.Demo.World.AddBody(sBody); // sBody.LinearVelocity = JVector.Forward * 3; // sBody.Restitution = 1.0f; // sBody.Friction = 0.0f; //} //this.Demo.World.SetDampingFactors(1, 1); }
public void AddConstraint(DistanceConstraint constr) { _Constraints.Add(constr); ResetRotationOnConnection = true; }
DistanceConstraint GetClosestConstraint(DistanceConstraint except, out float closestDist, float maxDistance = float.MaxValue) { DistanceConstraint closest = null; closestDist = float.MaxValue; foreach (var constr in SystemUpdater.AllConstraints) { if (except == constr) continue; float dist = Vector3.Distance(constr.transform.position, HandlePoint.position); if (dist < closestDist && dist < maxDistance) { closestDist = dist; closest = constr; } } return closest; }
DistanceConstraint GetClosestConstraint(DistanceConstraint except, float maxDistance = float.MaxValue) { float dummy; return GetClosestConstraint(except, out dummy, maxDistance); }
public void SetUpdateConstraint(DistanceConstraint constr) { if (SimulationSettings.LayerNames.Contains(constr.UpdateLayer) == false) { Debug.Log("Tried to add update func by layer name " + constr.UpdateLayer + " which des not exist, GameObject: " + constr.name); return; } ConstrUpdates[constr.UpdateLayer].Add(constr); AllConstraints.Add(constr); }
private void LoadParticleSystem(string configFile) { _particles = new List<Particle>(); _constraints = new List<Constraint>(); XmlDocument doc = new XmlDocument(); doc.Load(configFile); // load transforms Vector3 translation = GetVectorFromString(doc.SelectSingleNode("/ParticleSystem/Transform").Attributes["Translation"].Value); Vector3 scale = GetVectorFromString(doc.SelectSingleNode("/ParticleSystem/Transform").Attributes["Scale"].Value); // load particles foreach (XmlElement particleElement in doc.SelectNodes("/ParticleSystem/Particles/Particle")) { Vector3 position = GetVectorFromString(particleElement.Attributes["Position"].Value); position *= scale; position += translation; Particle particle = new Particle(position, this.Game); if (particleElement.HasAttribute("Mass")) { string massString = particleElement.Attributes["Mass"].Value; if (massString == "INFINITE_MASS") particle.Mass = Particle.INFINITE_MASS; else particle.Mass = Convert.ToSingle(massString); } _particles.Add(particle); } // load constraints foreach (XmlElement constraintElement in doc.SelectNodes("/ParticleSystem/Constraints/*")) { string constraintType = constraintElement.Name; Constraint constraint = null; switch (constraintType) { case "DistanceConstraint" : Particle particleA = _particles[Convert.ToInt32(constraintElement.Attributes["ParticleA"].Value)]; Particle particleB = _particles[Convert.ToInt32(constraintElement.Attributes["ParticleB"].Value)]; float restLength; if (constraintElement.HasAttribute("RestLength")) restLength = Convert.ToSingle(constraintElement.Attributes["RestLength"].Value); else restLength = Vector3.Distance(particleA.Position, particleB.Position); constraint = new DistanceConstraint(this, particleA, particleB, restLength); if (constraintElement.HasAttribute("Stiffness")) constraint.Stiffness = Convert.ToSingle(constraintElement.Attributes["Stiffness"].Value); break; } if (constraint != null) _constraints.Add(constraint); } }
// Use this for initialization void Start() { var sd = GetComponent <RectTransform>().sizeDelta; for (int i = 0; i < numberOfParticles; ++i) { GameObject circle = Instantiate(circlePrefab); circle.GetComponentInChildren <Text>().text = (i + 1).ToString(); circle.GetComponent <RectTransform>().anchoredPosition = new Vector3(0, sd.y / 2 - i * sd.y / (numberOfParticles - 1), 0); circles.Add(circle); GameObject prevCircle = Instantiate(prevCirclePrefab); prevCircle.GetComponentInChildren <Text>().text = (i + 1).ToString(); prevCircle.GetComponent <RectTransform>().anchoredPosition = circle.GetComponent <RectTransform>().anchoredPosition; prevCircles.Add(prevCircle); if (i > 0) { GameObject link = Instantiate(linkPrefab); link.transform.position = circle.transform.position; links.Add(link); } } foreach (var link in links) { link.transform.SetParent(this.transform, false); } foreach (var prevCircle in prevCircles) { prevCircle.transform.SetParent(this.transform, false); } foreach (var circle in circles) { circle.transform.SetParent(this.transform, false); } composite = new Composite(); for (int i = 0; i < circles.Count; ++i) { Particle p = new Particle(circles[i].transform.position); composite.particles.Add(p); startingPositions.Add(p.pos); } for (int i = 1; i < composite.particles.Count; ++i) { DistanceConstraint dc = new DistanceConstraint(composite.particles[i - 1], composite.particles[i], 1f); composite.constraints.Add(dc); } PinConstraint pc = new PinConstraint(composite.particles[0]); composite.constraints.Add(pc); verlet.composites.Add(composite); startButton.onClick.AddListener(OnStart); }
public override void Build() { this.Demo.World.Solver = Jitter.World.SolverType.Sequential; AddGround(); RigidBody boxb = new RigidBody(new BoxShape(7,1,2)); boxb.Position = new JVector(3.0f,12,0); this.Demo.World.AddBody(boxb); boxb.Tag = BodyTag.DontDrawMe; boxb.IsStatic = true; this.Demo.World.Solver = Jitter.World.SolverType.Sequential; //this.Demo.World.SetDampingFactors(1.0f, 1.0f); SphereShape shape = new SphereShape(0.501f); for (int i = 0; i < 7; i++) { RigidBody body = new RigidBody(shape); body.Position = new JVector(i, 6, 0); DistanceConstraint dc1 = new DistanceConstraint(boxb, body, body.Position + JVector.Up * 6 + JVector.Backward * 5 + JVector.Down * 0.5f, body.Position); dc1.Softness = 1.0f; DistanceConstraint dc2 = new DistanceConstraint(boxb, body, body.Position + JVector.Up * 6 + JVector.Forward * 5 + JVector.Down * 0.5f, body.Position); dc2.Softness = 1.0f; dc1.BiasFactor = dc2.BiasFactor = 0.8f; dc1.IsMaxDistance = dc2.IsMaxDistance = false; this.Demo.World.AddBody(body); this.Demo.World.AddConstraint(dc1); this.Demo.World.AddConstraint(dc2); body.Restitution = 1.0f; body.StaticFriction = 1.0f; // this.Demo.World.SetDampingFactors(1.0f, 1.0f); } //for (int i = 0; i < 5; i++) //{ // RigidBody sBody = new RigidBody(new SphereShape(0.5f)); // sBody.Position = new JVector(0, 0.5f, i); // this.Demo.World.AddBody(sBody); // sBody.Restitution = 1.0f; // sBody.Friction = 0.0f; //} //for (int i = 0; i < 3; i++) //{ // RigidBody sBody = new RigidBody(new SphereShape(0.5f)); // sBody.Position = new JVector(0, 0.5f, 10 + i); // this.Demo.World.AddBody(sBody); // sBody.LinearVelocity = JVector.Forward * 3; // sBody.Restitution = 1.0f; // sBody.Friction = 0.0f; //} //this.Demo.World.SetDampingFactors(1, 1); }
DistanceConstraint GetClosestConstraint(DistanceConstraint except, float maxDistance = float.MaxValue) { float dummy; return(GetClosestConstraint(except, out dummy, maxDistance)); }