Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Grab Rope - VR
#51
If you're using Obi 6.X, you can't just access the solverIndices array directly using contact.bodyA.

contact.bodyA is a simplex index, not a particle index. You need to get the particle index out of that simplex. See the manual for examples on how it's done:
http://obi.virtualmethodstudio.com/tutor...sions.html

For instance:

Code:
// retrieve the offset and size of the simplex in the solver.simplices array:
int simplexStart = solver.simplexCounts.GetSimplexStartAndSize(contact.bodyA, out int simplexSize);

// starting at simplexStart, iterate over all particles in the simplex:
for (int i = 0; i < simplexSize; ++i)
{
    int particleIndex = solver.simplices[simplexStart + i]];

    // do something with each particle, for instance get its position:
    var position = solver.positions[particleIndex];
}
Reply
#52
Regarding the video, the only issue I can see is that the rope jumps to a different position when you grab it, probably related to the indices mismatch above.

Also keep in mind that grabbing one particle will constrain the position of the rope at that point, but it will still be free to rotate around it. Ropes do not model torsion or orientation (unlike rods). You'll have to grab at least two particles if you wish to constrain its orientation. Then, there will be only one DOF left, along the rope's main axis.
Reply
#53
(24-02-2021, 11:06 AM)josemendez Wrote:
Code:
int simplexStart = solver.simplexCounts.GetSimplexStartAndSize(contact.bodyA, out int simplexSize);// starting at simplexStart, iterate over all particles in the simplex:

 'ObiSolver' does not contain a definition for 'simplexCounts' ?  I use obi rope 6
Reply
#54
(24-02-2021, 11:58 AM)tpaslou Wrote:  'ObiSolver' does not contain a definition for 'simplexCounts' ?  I use obi rope 6

Update to latest version  (6.0.1), which also fixed multiple bugs in the initial 6.X release. In 6.0 you have to manually keep track of simplex counts, which is quite inconvenient.
Reply
#55
(24-02-2021, 12:14 PM)josemendez Wrote: Update to latest version  (6.0.1), which also fixed multiple bugs in the initial 6.X release. In 6.0 you have to manually keep track of simplex counts, which is quite inconvenient.

After a bit of experimenting the code  for the grab resulted to be :

Code:
public void Grab()
    {
        var world = ObiColliderWorld.GetInstance();
        Debug.Log(pinConstraints);

        if (solver != null && collisionEvent != null)
        {
            Debug.Log("Collision");
            foreach (Oni.Contact contact in collisionEvent.contacts)
            {
                if (contact.distance < 0.01f)
                {
                    var contactCollider = world.colliderHandles[contact.bodyB].owner;
                    ObiSolver.ParticleInActor pa = solver.particleToActor[contact.bodyA];

                    Debug.Log(pa + " hit " + contactCollider);
                    if (canGrab)
                    {
                        if (contactCollider == obiCollider)
                        {
                            Debug.Log("Hand Collision");
                            var batch = new ObiPinConstraintsBatch();
                            //int solverIndex = rope.solverIndices[contact.bodyA];

                            int simplexStart = solver.simplexCounts.GetSimplexStartAndSize(contact.bodyA, out int simplexSize);
                            int particleIndex=0;
                            // starting at simplexStart, iterate over all particles in the simplex:
                            for (int i = 0; i < simplexSize; ++i)
                            {
                                particleIndex = solver.simplices[simplexStart + i];

                                // do something with each particle, for instance get its position:
                                var position = solver.positions[particleIndex];
                            }

                            Vector3 positionWS = solver.transform.TransformPoint(solver.positions[particleIndex]); // particle position from solver to world space
                            Vector3 positionCS = obiCollider.transform.InverseTransformPoint(positionWS); // particle position from world to collider space*/

                            batch.AddConstraint(rope.solverIndices[particleIndex], obiCollider, positionCS, Quaternion.identity, 0, 0, float.PositiveInfinity);
                            batch.activeConstraintCount = 1;
                            newBatch = batch;
                            pinConstraints.AddBatch(newBatch);

                            canGrab = false;

                            // this will cause the solver to rebuild pin constraints at the beginning of the next frame:
                            rope.SetConstraintsDirty(Oni.ConstraintType.Pin);

                        }
                    }
                }
            }
        }
    }


I grabbed a random index from the simplex. I used the enable-disable & follow constraint code for the Start & End particle attachment so I can pull the rope from whatever part I want and move it. There will be some future improvements.
Reply
#56
Bug 
After a short hiatus I got back into the project this week and I finally updated everything to 6.0.1 and made the necessary changes to my script. However, now I'm getting issues very similar to what tpaslou showed in his video, with the rope particle seeming to snap and pin to a position far from my hand, and respond poorly to being moved or rotated. This jittering and overreaction to rotation was present before 6.0 but the position at least remained close to the player hand. I meant to post this earlier and record a video but I could do that tomorrow if it helps. 

Here is my current code, it's mostly the same as it was, though I may have made some mistake in updating versions:



Code:
{                           
                            var batch = new ObiPinConstraintsBatch();

                            // retrieve the offset and size of the simplex in the solver.simplices array:
                            int simplexStart = solver.simplexCounts.GetSimplexStartAndSize(contact.bodyA, out int simplexSize);
                            int particleToGrab = 0;
                            Vector3 particlePosition = Vector3.zero;
                            // starting at simplexStart, iterate over all particles in the simplex:
                            for (int i = 0; i < simplexSize; ++i)
                            {
                                int particleIndex = solver.simplices[simplexStart + i];
                                var position = solver.positions[particleIndex];
                                if (Vector3.Distance(solver.transform.TransformPoint(position), contactCollider.transform.position)
                                    < Vector3.Distance(particlePosition, contactCollider.transform.position)) // closest particle position
                                {
                                    particleToGrab = particleIndex;
                                    particlePosition = solver.transform.TransformPoint(position);
                                }
                            }

                            if (particleToGrab > 0) //Check particle is valid and prevents grabbing the particle attached to grappling hook
                            {
                                Vector3 positionWS = particlePosition;

                                Vector3 positionCS = obiCollider.transform.InverseTransformPoint(positionWS); // particle position from world to collider space
                                batch.AddConstraint(particleToGrab, obiCollider, positionCS, Quaternion.identity, 0, 0, float.PositiveInfinity);
                                batch.activeConstraintCount = 1;
                                newBatch = batch;
                                pinConstraints.AddBatch(newBatch);

                                canGrab = false;

                                // this will cause the solver to rebuild pin constraints at the beginning of the next frame:
                                rope.SetConstraintsDirty(Oni.ConstraintType.Pin);
                            }

                        }

Hope you can help, does this hold the record for longest Obi forum thread yet?  Gran sonrisa
Reply
#57
Here's the video of what I'm experiencing: https://vimeo.com/519484422 

The jittering looks like a collider problem even though it shouldn't be pinning the particle inside, especially given where the particle seems to pin. Hopefully it's obvious when I'm grabbing the rope, as I'm in the middle of reworking the hand animations, but it should be clear that while the particle follows my hand it is nowhere near the actual position, or even the original position it was in. It gets closer as I rotate my hand, but then it jumps to the other side, still far away.
Reply