Пример #1
0
    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);
    }
Пример #2
0
    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);
            }
        }
    }
Пример #3
0
        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);
        }
Пример #4
0
    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);
    }
Пример #5
0
    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);
    }
Пример #6
0
        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);
        }
Пример #7
0
    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);
    }
Пример #8
0
    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);
    }
Пример #9
0
    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;
            }
        }
    }
Пример #10
0
    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;
        }
    }
Пример #11
0
 public void RemoveConstraint(DistanceConstraint constr)
 {
     _Constraints.Remove(constr);
     ResetRotationOnConnection = true;
 }
Пример #12
0
        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);
        }
Пример #13
0
 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);
 }
Пример #14
0
 public void AddConstraint(DistanceConstraint constr)
 {
     _Constraints.Add(constr);
     ResetRotationOnConnection = true;
 }
Пример #15
0
    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;
    }
Пример #16
0
 DistanceConstraint GetClosestConstraint(DistanceConstraint except, float maxDistance = float.MaxValue)
 {
     float dummy;
     return GetClosestConstraint(except, out dummy, maxDistance);
 }
Пример #17
0
 public void AddConstraint(DistanceConstraint constr)
 {
     _Constraints.Add(constr);
     ResetRotationOnConnection = true;
 }
Пример #18
0
 public void RemoveConstraint(DistanceConstraint constr)
 {
     _Constraints.Remove(constr);
     ResetRotationOnConnection = true;
 }
Пример #19
0
    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);
    }
Пример #20
0
		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);
			}
		}
Пример #21
0
    // 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);
    }
Пример #22
0
        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);


        }
Пример #23
0
    DistanceConstraint GetClosestConstraint(DistanceConstraint except, float maxDistance = float.MaxValue)
    {
        float dummy;

        return(GetClosestConstraint(except, out dummy, maxDistance));
    }