Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  How can I detect my second actor in a solver?
#1
Pregunta 
Hi, I am working on a project where I need to check if a rope is colliding with another rope, if not I will then destroy that rope after enough frames without collision passes.

It is very similar to how `TangledRopes.unity` sample works. I access the solver and on `Solver.OnParticleCollision()`event I call my collision checker function, here's a snippet of the code and my issue:

 
Code:
private void Solver_OnParticleCollision(ObiSolver solver, ObiNativeContactList contacts)
{
for (int i = 0; i < contacts.count; ++i)
{
    var ropeA = solver.particleToActor[solver.simplices[contacts[i].bodyA]].actor;
    var ropeB = solver.particleToActor[solver.simplices[contacts[i].bodyB]].actor;

    if (ropeA == ropeB) //Always true for some reason
    {
        //Breakpoint
        continue;
    }

    //Do Something
}
}


I never can access to the "Do Something" part of the code. In my debugging I found that EVERY contact is from `Rope_0` and none is from `Rope_1`. The ropes are on top of eachother, even twisted together. They are under the same solver. They are both in group 0 in particles and points in blueprint.

Why may this be?
Reply
#2
Hi,

Your code won’t work if any actor in the solver uses surface collisions. The reason is it assumes every simplex consists of a single particle, which may not be true in the general case. For instance, if all ropes in the solver use surface collisions, all simplices are tuples of 2 particles so your code will likely access indices belonging to the first rope only.

See the manual for example code snippets that show you how to access both actors involved in a contact:
https://obi.virtualmethodstudio.com/manu...sions.html

let me know if you need further help,

Kind regards
Reply
#3
(27-03-2025, 09:11 PM)josemendez Wrote: Hi,

Your code won’t work if any actor in the solver uses surface collisions. The reason is it assumes every simplex consists of a single particle, which may not be true in the general case. For instance, if all ropes in the solver use surface collisions, all simplices are tuples of 2 particles so your code will likely access indices belonging to the first rope only.

See the manual for example code snippets that show you how to access both actors involved in a contact:
https://obi.virtualmethodstudio.com/manu...sions.html

let me know if you need further help,

Kind regards
Hello,

I have a question. If I make my ropes non-surface collision based, I still have this issue, why may this be?
I have my rope.surfacecollisions set to false, yet I still can't access to the second part of my code, which for now is just a simple debug.log function.

Here is how I create my rope in the function:

Code:
public ObiRope CreateRopeProcedurally(Transform parent, ObiCollider[] controlPoints, int index = 0)
        {
            var ropeObject = new GameObject($"Rope_{index}");
            ropeObject.transform.parent = solver.transform;
           
            //Create the rope initially
            var rope = ropeObject.AddComponent<ObiRope>();
            var blueprint = CreateBlueprint(parent, controlPoints, index ,out var length);
            rope.ropeBlueprint = blueprint;
            rope.surfaceCollisions = false;
            rope.collisionMaterial = collisionMaterial;
            var ropeRenderer = ropeObject.AddComponent<ObiRopeExtrudedRenderer>();
            ropeRenderer.material = ropeMaterial;
            ropeRenderer.section = ropeSection;
            var smoother = rope.GetComponent<ObiPathSmoother>();
            smoother.decimation = 0.1f;
            smoother.smoothing = 1;
            ropeRenderer.thicknessScale = (5f/ropeThickness) * 1.5f  ;
            ropeRenderer.uvScale = new Vector2(1, 2*length/3f);
            var ropeReel = ropeObject.AddComponent<ObiRopeReel>();
            ropeReel.outThreshold = 0.08f;
            ropeReel.inThreshold = 0.05f;
            rope.selfCollisions = true;
            ropeReel.outSpeed = 6f;
            ropeReel.inSpeed = 4f;
            ropeReel.maxLength = Mathf.Max(1f, length/3f);
            rope.maxBending = 0.5f;
            rope.bendCompliance = 1f;
            rope.stretchingScale = 3f;
            var cursor = ropeObject.GetComponent<ObiRopeCursor>();
            cursor.cursorMu = 0.05f;
            cursor.sourceMu = 0.1f;
            return rope;
        }

You can see my variables and rope creation process here

I will be honest, I copied some components from sample scenes without truly understanding them, but this should work, right?
I set my Solver into interpolate mode and made surface collision iterations set to 1.
Reply
#4
According to the attached screenshot, these are the only "Collusion points" (Retrieved by using ObiNativeContactList[i].pointB and pointA, iterating the whole contact list.)

As you can see, the collusion is happening between the world obstacles and the ropes, but not in-between ropes. I want to check if there is any ropes touching eachother and if a rope has no other rope touching it. How can I see this information?

Edit:
I also made sure in the blueprint every control point is set to "collide with everything"
Reply
#5
(28-03-2025, 07:03 PM)anthony_dev Wrote: According to the attached screenshot, these are the only "Collusion points" (Retrieved by using ObiNativeContactList[i].pointB and pointA, iterating the whole contact list.)

As you can see, the collusion is happening between the world obstacles and the ropes, but not in-between ropes. I want to check if there is any ropes touching eachother and if a rope has no other rope touching it. How can I see this information?

Hi,

What event are you subscribed to? is it solver.OnCollision or solver.OnParticleCollision? both have the same signature, so maybe you’ve mistakenly subscribed to OnCollision (which returns contacts against colliders, instead of other particles)?

Kind regards
Reply
#6
(28-03-2025, 10:11 PM)josemendez Wrote: Hi,

What event are you subscribed to? is it solver.OnCollision or solver.OnParticleCollision? both have the same signature, so maybe you’ve mistakenly subscribed to OnCollision (which returns contacts against colliders, instead of other particles)?

Kind regards
Hi,

I tried subscribing to both actually, to see which works, neither did. In the picture I subscribed to both at the same time and drew gizmos to see where collisions are, they both returned the same thing.

Thanks for your time
Reply
#7
(29-03-2025, 11:00 AM)anthony_dev Wrote: Hi,

I tried subscribing to both actually, to see which works, neither did. In the picture I subscribed to both at the same time and drew gizmos to see where collisions are, they both returned the same thing.

Thanks for your time

Hi,

I’m unable to reproduce this, each event returns completely different contacts. Would it be possible for you to share the full code you’re using?

Kind regards
Reply