Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  How can i detect if two ropes are twisted
#1
Hi,
I just purchased the asset and wonder how to detect if the two ropes are twisted (create a knot). How can i count how many twists / knots that two ropes create ?
Thanks
Reply
#2
(29-06-2020, 04:12 PM)rand123 Wrote: Hi,
I just purchased the asset and wonder how to detect if the two ropes are twisted (create a knot). How can i count how many twists / knots that two ropes create ?
Thanks

Hi rand,

This is a really specific use case. Obi is a physics engine, it does not have built-in knot detection. It does not have any knowledge of what a knot is or if a certain rope configuration should be considered a knot or not.

You must implement this yourself.
Reply
#3
(29-06-2020, 04:17 PM)josemendez Wrote: Hi rand,

This is a really specific use case. Obi is a physics engine, it does not have built-in knot detection. It does not have any knowledge of what a knot is or if a certain rope configuration should be considered a knot or not.

You must implement this yourself.

Hi thanks for your answer,
Is there any tip on how should I approach to detect a knot . Through collisions ?

Also another question, the knot from the ropes break too easily. How can I increase the constraint to make the knot stays if i pull each ropes in different directions ?
Reply
#4
(30-06-2020, 04:22 AM)rand123 Wrote: Hi thanks for your answer,
Is there any tip on how should I approach to detect a knot . Through collisions ?

Also another question, the knot from the ropes break too easily. How can I increase the constraint to make the knot stays if i pull each ropes in different directions ?

Hi there,

Yes, using particle contact callbacks would be a good start. You should subscribe to the solver's OnParticleCollision event. See:
http://obi.virtualmethodstudio.com/tutor...sions.html

You can increase the amount of substeps (in the ObiFixedUpdater) and/or distance constraint iterations (in the ObiSolver) to increase simulation quality. Take a look at this manual page, it explains how the simulation works in detail and how iterations/substeps affect it:
http://obi.virtualmethodstudio.com/tutor...gence.html
Reply
#5
(30-06-2020, 07:43 AM)josemendez Wrote: Hi there,

Yes, using particle contact callbacks would be a good start. You should subscribe to the solver's OnParticleCollision event. See:
http://obi.virtualmethodstudio.com/tutor...sions.html

You can increase the amount of substeps (in the ObiFixedUpdater) and/or distance constraint iterations (in the ObiSolver) to increase simulation quality. Take a look at this manual page, it explains how the simulation works in detail and how iterations/substeps affect it:
http://obi.virtualmethodstudio.com/tutor...gence.html
Code:
private void OnEnable()
    {
        obiSolver.OnParticleCollision += Solver_OnCollision;     
    }

void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
    {
        Oni.Contact[] contacts = e.contacts.Data;
        for (int i = 0; i < e.contacts.Count; ++i)
        {
            Oni.Contact c = contacts[i];
            // make sure this is an actual contact:
            if (c.distance < 0.01f)
            {
                ObiSolver.ParticleInActor pa = obiSolver.particleToActor[c.particle];
                Debug.Log($"collide with { pa.actor.name}");
            }
        }
    }

Hi i use this function to detect collision between 2 ropes. The debug log returns results when each particle of a single rope collides with itself or with other particles belong to that same rope. The two ropes do not twist themselves yet. Is my code the right way to do it ? What I want to achieve is if Rope A collides with Rope B, I want to detect Rope B only. I dont want to detect if particle of Rope A has collided with itself.

Another question, how do I set two ropes and more ropes twist them selves as a default state when the game starts ? I do not want to create and edit every single rope. Is there any way to create a knot in edit mode and save that state into play mode ?
Reply
#6
(01-07-2020, 07:42 AM)rand123 Wrote: Hi i use this function to detect collision between 2 ropes. The debug log returns results when each particle of a single rope collides with itself or with other particles belong to that same rope. The two ropes do not twist themselves yet. Is my code the right way to do it ? What I want to achieve is if Rope A collides with Rope B, I want to detect Rope B only. I dont want to detect if particle of Rope A has collided with itself.

Then look for contacts where the actor for contact.particle and for contact.other are not the same. Right now you're only checking the first particle in the contact.


(01-07-2020, 07:42 AM)rand123 Wrote: Another question, how do I set two ropes and more ropes twist them selves as a default state when the game starts ? I do not want to create and edit every single rope. Is there any way to create a knot in edit mode and save that state into play mode ?

Easiest way is to edit the paths, that's what they're designed for: to set the initial state/shape of ropes. You could write a script to store all particle positions/velocities at runtime, then set them when the scene starts. See:
http://obi.virtualmethodstudio.com/forum...p?tid=2201
Reply
#7
(01-07-2020, 08:03 AM)josemendez Wrote: Then look for contacts where the actor for contact.particle and for contact.other are not the same. Right now you're only checking the first particle in the contact.
Hi, it is not clear how to check for this.

Code:
ObiSolver.ParticleInActor pa = solver.particleToActor[contact.other];


and

Code:
ObiSolver.ParticleInActor pa = solver.particleToActor[contact.particle];


has no differences when i log out the collision.

Code:
if (pa.actor != thisRope) //thisRope is type ObiActor
                {
                    Debug.Log($"collider with other rope {pa.actor.name} vs {thisRope.name}");
                }


This line prints out even though there is no collision between two ropes yet.
Reply
#8
You're still checking for exactly the same thing as before: if either of the two particles involved in the contact belongs to a certain rope.

You need to check if a contact involves two different ropes. So:

Code:
ObiSolver.ParticleInActor pa1 = solver.particleToActor[contact.particle];
ObiSolver.ParticleInActor pa2 = solver.particleToActor[contact.other];

if (pa1.actor != pa2.actor){
// collision between two different ropes
}
Reply
#9
(01-07-2020, 09:34 AM)josemendez Wrote: You're still checking for exactly the same thing as before: if either of the two particles involved in the contact belongs to a certain rope.

You need to check if a contact involves two different ropes. So:

Code:
ObiSolver.ParticleInActor pa1 = solver.particleToActor[contact.particle];
ObiSolver.ParticleInActor pa2 = solver.particleToActor[contact.other];

if (pa1.actor != pa2.actor){
// collision between two different ropes
}

Hi, thanks a lot for this. It works.

Is there any way I can detect 2 ropes not colliding with each other ? It seems to me the collision callback always returns collision result since the particles can collide with themselves.
I check for the count of ObiCollisionEventArgs. If there is 0 count means there is no collision. But the callback are for all the particles/actors in the scene. Is there any way I can set a specific collision call back of 1 single rope only ? Then check for the count of ObiCollisionEventArgs should solve whether the a rope is colliding or not.
Reply
#10
(03-07-2020, 09:40 AM)rand123 Wrote: Hi, thanks a lot for this. It works.

Is there any way I can detect 2 ropes not colliding with each other ? It seems to me the collision callback always returns collision result since the particles can collide with themselves.
I check for the count of ObiCollisionEventArgs. If there is 0 count means there is no collision. But the callback are for all the particles/actors in the scene. Is there any way I can set a specific collision call back of 1 single rope only ? Then check for the count of ObiCollisionEventArgs should solve whether the a rope is colliding or not.

Each frame the engine makes all contact information available to you directly. This is as efficient as it gets, as you're given direct access to the same information used by the engine to resolve collisions. Filtering it to suit your needs is completely up to you, you can of course keep a counter per actor and count the amount of contacts for each one if you wish.
Reply