Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Solver collision contacts count is always 0
#11
(09-09-2020, 09:34 AM)josemendez Wrote: Hi!

I think you're mixing up different spaces. Control points are expressed in the rope's local space, just like vertices in a mesh. So if you've rotated the rope transform, adding 1 to targetPos.y might shift the rope in world-space x or z axis.

The pin constraint's "offset" is the position that the particle will be pinned to, expressed in the collider's local space. Passing zero will pin the particle inside the collider, at its center. Note that this can result in constraint fighting, if collisions with that collider are enabled. See the last bit of:
http://obi.virtualmethodstudio.com/tutor...aints.html

If you're unfamiliar with vector spaces, it's 3D math 101. Let me know if you need more info/resources about this.
I managed to solve this problem, seems that it was really important that objects scale should be (1;1;1).
Now I have another issue, could you elaborate what's going on with Solvers collision argument contacts? I.e. If I have multiple ropes inside scene contact[i].particle never matches ropes element particle (on one rope it does match, on another it doesn't). When cutting first rope (with 18 elements) everything is as expected. But once trying to cut second rope I get particle number from contact to be 130-150, and that number makes not a lot of sense to me.
Code:
private void Solver_OnCollision(ObiSolver solver, ObiSolver.ObiCollisionEventArgs args)
        {
            for (int i = 0; i < args.contacts.Count; ++i)
            {
                if (args.contacts.Data[i].distance < 0)
                {
                    ObiColliderBase collider = ObiColliderWorld.GetInstance().colliderHandles[args.contacts[i].other].owner;

                    if (collider)
                    {
                        if (collider.CompareTag("Cutter"))
                        {
                            if (selectedRope)
                            {
                                Debug.LogError($"particle { args.contacts[i].particle}");

                                selectedRope.Tear(selectedRope.elements[args.contacts[i].particle]);
                                selectedRope.RebuildConstraintsFromElements();
                                selectedRope = null;
                            }

                        }
                    }
                }
            }
        }
Reply
#12
Hi there,

Non-uniform scales on deformable objects do not make much sense, mathematically speaking. You can't describe the shape/position/orientation of a non-rigid object using a single transform matrix. It's better to stick to unit scaling when dealing with deformables (not just in Obi).

Regarding collision indices, I believe the manual holds the answer Sonrisa
http://obi.virtualmethodstudio.com/tutor...icles.html

Quote:Actor particle indices run from 0 to the amount of particles in that actor. However, since particle data for an actor might be scattered across the solver arrays (see architecture), you need to map from actor index to solver index. You can map from actor particle indices to solver particle indices using the actor's solverIndices array.

Then it follows with some examples of converting actor particle indices to solver particle indices and vice-versa.

The solver does not know what an "actor" is, all it knows about is a literal list of particles. So when you add the first actor -lets say a rope with 20 particles-, particles 0 to 19 in the solver array are assigned to it. When you add the second actor, again with 20 particles, the solver will assign particles 20 to 39. This is very similar to how a simple memory allocator works. When removing actors, gaps might appear in the solver particle array, then later reassigned to new actors that have their particles spread all over the solver. So, in general you can't assume actor indices == solver indices.

If there's a collision between say, the third particle in the first rope and the fifth particle in the second rope, the solver will report a contact between particle indices 2 and 24.

Because ropes can be torn and resized, they preallocate more particles than initially visible. By default the size of this particle pool is 100 (you can control this in the blueprint inspector). So your second rope will have particle indices starting at 120, because the first rope has 18+1+100 = 119 particles. This is why you can't do:

Code:
selectedRope.elements[args.contacts[i].particle]

You must iterate over elements and find the one such that element.particle1 == args.contacts[i].particle, as I pointed out before.
Reply
#13
(09-09-2020, 12:47 PM)josemendez Wrote: Hi there,

Non-uniform scales on deformable objects do not make much sense, mathematically speaking. You can't describe the shape/position/orientation of a non-rigid object using a single transform matrix. It's better to stick to unit scaling when dealing with deformables (not just in Obi).

Regarding collision indices, I believe the manual holds the answer Sonrisa
http://obi.virtualmethodstudio.com/tutor...icles.html


Then it follows with some examples of converting actor particle indices to solver particle indices and vice-versa.

The solver does not know what an "actor" is, all it knows about is a literal list of particles. So when you add the first actor -lets say a rope with 20 particles-, particles 0 to 19 in the solver array are assigned to it. When you add the second actor, again with 20 particles, the solver will assign particles 20 to 39. This is very similar to how a simple memory allocator works. When removing actors, gaps might appear in the solver particle array, then later reassigned to new actors that have their particles spread all over the solver. So, in general you can't assume actor indices == solver indices.

If there's a collision between say, the third particle in the first rope and the fifth particle in the second rope, the solver will report a contact between particle indices 2 and 24.

Because ropes can be torn and resized, they preallocate more particles than initially visible. By default the size of this particle pool is 100 (you can control this in the blueprint inspector). So your second rope will have particle indices starting at 120, because the first particle has 18+1+100 = 119 particles. This is why you can't do:

Code:
selectedRope.elements[args.contacts[i].particle]

You must iterate over elements and find the one such that element.particle1 == args.contacts[i].particle, as I pointed out before.
Thanks! Sonrisa
Reply