Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
scripting ropes with pin constraints & tethers
#6
(30-12-2017, 07:25 PM)phoberman Wrote: Thanks Jose – that gets me much, much closer.

But it leaves two remaining questions unanswered:

1. The scripted rope still jumps around much more at initialization. Any way to fix that?

2. Assigning both ropes to the same solver (both with SolverA entered in the ObiRopeScriptTest inspector) causes the scripted rope to fail. Multiple "normal" ropes can be assigned to the same solver, but each scripted rope fails if it doesn't have its own dedicated solver.

Thanks once more!

- pH


1.- Since you must wait for the GeneratePhysicRepresentationForMesh() coroutine to finish generating the rope at runtime (which takes more than 1 frame), this allows the rigidbody at the bottom of the procedural rope to fall freely for a few moments. When the rope is finally created, the rigidbody is slightly lower and the rope springs back with slightly more force than its in-editor counterpart. To prevent this, freeze the rigidbody in place (make it kinematic) until the generation coroutine is finished.

2.- At line 54/56 of ObiRopeScriptTest.cs you're doing this:
Code:
constraintsBatch.AddConstraint(rope.particleIndices[rope.particleIndices[0]], upperPinObject.GetComponent<ObiCollider>(), Vector3.zero, 0f);
constraintsBatch.AddConstraint(rope.particleIndices[rope.UsedParticles-1], lowerPinObject.GetComponent<ObiCollider>(), Vector3.zero, 0f);

This doesn't really make sense, but it works for the first rope added to a solver: The first particle in the first rope will be the first particle in the solver, so rope.particleIndices[rope.particleIndices[0]] will evaluate to 0, which is an existing particle. However for the second, third, fourth rope in the solver, this will likely result in an out of bounds access inside the solver, which as pointed out in the docs, leads to undefined behaviour including the possibility of a crash.

The low-level physics library does not perform range checks for performance reasons (it assumes the caller does), so if you pass invalid indices you're in trouble. Also remember that the indices passed to AddConstraint() are actor indices, not solver indices. So if you pass 0, that means first particle in the rope. If you pass rope.UsedParticles-1, that means last particle in the rope.

With all this in mind, you can do this instead and it will work fine:
Code:
constraintsBatch.AddConstraint(0, upperPinObject.GetComponent<ObiCollider>(), Vector3.zero, 0f);
constraintsBatch.AddConstraint(rope.UsedParticles-1, lowerPinObject.GetComponent<ObiCollider>(), Vector3.zero, 0f);

cheers! Sonrisa
Reply


Messages In This Thread
RE: scripting ropes with pin constraints & tethers - by josemendez - 02-01-2018, 12:10 PM