Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Scripting pinconstraints on 2 non-kinematic rigidbodies
#1
Here's my current code to change the pinconstraints during runtime:
Code:
        rope.PinConstraints.RemoveFromSolver (null);

        ObiDistanceConstraintBatch distConstraints = rope.DistanceConstraints.GetFirstBatch ();
        ObiPinConstraintBatch pinConstraints = rope.PinConstraints.GetFirstBatch ();

        pinConstraints.Clear ();

        Oni.SetParticlePositions (
            rope.Solver.OniSolver,
            new Vector4[] { new Vector4 (SubStart.transform.position.x, SubStart.transform.position.y, SubStart.transform.position.z, 1) },
            1,
            distConstraints.springIndices[0]
        );

        pinConstraints.AddConstraint (distConstraints.springIndices[0], SubStart.GetComponent<ObiColliderBase> (), Vector3.zero, 1);

        Oni.SetParticlePositions (
            rope.Solver.OniSolver,
            new Vector4[] { new Vector4 (contactPoint.x, contactPoint.y, contactPoint.z, 1) },
            1,
            distConstraints.springIndices[distConstraints.springIndices.Count - 1]
        );

        pinConstraints.AddConstraint (distConstraints.springIndices[distConstraints.springIndices.Count - 1], Obj.GetComponent<ObiColliderBase> (), Vector3.zero, 1);

        rope.PinConstraints.AddToSolver (null);

It works fine as long as one object I attach them to is kinematic for particles but as soon as I want both objects to be non kinematic in the rigidbody and in the obirigidbody the particles don't follow the object anymore. Not sure what I'm doing wrong right now?

Btw, there was also an error when attaching from the Rigidbody about it's velocities beeing set to NaNs.
I added a float.isNan check in the ObiRigidbody to get rid of it.

Using 3.3.1 with Unity 2017.3


Just found a workaround:
Making one of the objects kinematic for particles when adding the pinconstraints then afterwards make it nonkinematic. Still a bit odd that you need to trick it like this?

EDIT:
Actually that workaround only works sometimes?
Also just found out it doesn't happen in a scene with just two spheres with the same script etc.. so still bug hunting.

EDIT2:
Ok the problem was that I used ObiColliders as pintargets which were slightly inside another ObiCollider with a coll layer which the solver takes into account.
Apparently the solver tries to solve this for a second and then stops.
Reply
#2
(07-03-2018, 05:35 PM)ibbybn Wrote: Here's my current code to change the pinconstraints during runtime:
Code:
rope.PinConstraints.RemoveFromSolver (null);

ObiDistanceConstraintBatch distConstraints = rope.DistanceConstraints.GetFirstBatch ();
ObiPinConstraintBatch pinConstraints = rope.PinConstraints.GetFirstBatch ();

pinConstraints.Clear ();

Oni.SetParticlePositions (
rope.Solver.OniSolver,
new Vector4[] { new Vector4 (SubStart.transform.position.x, SubStart.transform.position.y, SubStart.transform.position.z, 1) },
1,
distConstraints.springIndices[0]
);

pinConstraints.AddConstraint (distConstraints.springIndices[0], SubStart.GetComponent<ObiColliderBase> (), Vector3.zero, 1);

Oni.SetParticlePositions (
rope.Solver.OniSolver,
new Vector4[] { new Vector4 (contactPoint.x, contactPoint.y, contactPoint.z, 1) },
1,
distConstraints.springIndices[distConstraints.springIndices.Count - 1]
);

pinConstraints.AddConstraint (distConstraints.springIndices[distConstraints.springIndices.Count - 1], Obj.GetComponent<ObiColliderBase> (), Vector3.zero, 1);

rope.PinConstraints.AddToSolver (null);

It works fine as long as one object I attach them to is kinematic for particles but as soon as I want both objects to be non kinematic in the rigidbody and in the obirigidbody the particles don't follow the object anymore. Not sure what I'm doing wrong right now?

Btw, there was also an error when attaching from the Rigidbody about it's velocities beeing set to NaNs.
I added a float.isNan check in the ObiRigidbody to get rid of it.

Using 3.3.1 with Unity 2017.3


Just found a workaround:
Making one of the objects kinematic for particles when adding the pinconstraints then afterwards make it nonkinematic. Still a bit odd that you need to trick it like this?

EDIT:
Actually that workaround only works sometimes?
Also just found out it doesn't happen in a scene with just two spheres with the same script etc.. so still bug hunting.

EDIT2:
Ok the problem was that I used ObiColliders as pintargets which were slightly inside another ObiCollider with a coll layer which the solver takes into account.
Apparently the solver tries to solve this for a second and then stops.

You're pinning the particles to the center of the collider (passing  Vector3.zero as the local space pin location). This means the particles will be pushed towards the center of the collider in an attempt to reach the pin location. If the particles are also set to collide with it, then you have a energy feedback loop in which the collision pushes the collider away from the particle, and the pin constraint pushes the particle towards the collider. This can very easily end up blowing up the simulation.

Solution: either disable the collision with that particular collider (seems you already identified the cause and corrected it this way) or set a pin location that's outside the collider.
Reply