Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Solver collision contacts count is always 0
#1
Solver collision contacts count is always 0, even though Obi Rope collides with some boxes that have obi collider and obi rigidbody attached to them. Also documentation about manual rope tearing seems to be outdated. Could you please give some examples how could I perform a rope tearing in script?
Reply
#2
(08-09-2020, 07:59 AM)dosinis Wrote: Solver collision contacts count is always 0, even though Obi Rope collides with some boxes that have obi collider and obi rigidbody attached to them. Also documentation about manual rope tearing seems to be outdated. Could you please give some examples how could I perform a rope tearing in script?

Hi there,

The contact list exposed by the solver is the actual contact list being used for simulation, so the count just can't be zero if collisions are taking place. Can you share the code you're using to count contacts?

Docs on rope tearing are for the latest version, 5.5: http://obi.virtualmethodstudio.com/api.html. Can you specify what parts seem to be outdated?

Rope components have a Tear() method that takes a ObiStructuralElement as input. You can find all structural elements of the rope in the rope.elements array, then it's a matter of passing the appropriate element to the Tear() method and call rope.RebuildConstraintsFromElements(); so that physical constraints match the element description.

You can see a full example in the ObiRope.cs file ApplyTearing() method, which is used to detect which elements are under most stress, sort them by stress, then tear them.

kind regards,
Reply
#3
(08-09-2020, 08:11 AM)josemendez Wrote: Hey, thanks for quick reply!

Code:
  [SerializeField] private ObiSolver solver;
        [SerializeField] private ObiRope rope;
        public void Init(ILevelContext controller)
        {

        }

        private void Awake()
        {
            solver.OnParticleCollision += Solver_OnParticleCollision;
        }

        private void Solver_OnParticleCollision(ObiSolver solver, ObiSolver.ObiCollisionEventArgs args)
        {
            Debug.LogError($"Contacts count: {args.contacts.Count}");

            for (int i = 0; i < args.contacts.Count; ++i)
            {
                if (args.contacts.Data[i].distance < 0)
                {

                }
                else
                {

                }
            }
        }

This is the implementation and log message says it's 0 no matter what Triste
And by docs I meant tutorials, sorry : http://obi.virtualmethodstudio.com/tutor...sions.html
Reply
#4
(08-09-2020, 08:36 AM)dosinis Wrote: This is the implementation and log message says it's 0 no matter what Triste
And by docs I meant tutorials, sorry : http://obi.virtualmethodstudio.com/tutor...sions.html

You've subscribed to the OnParticleCollision event. This is for contacts between particles, as explained in the manual.

To get a list of contacts against colliders, you should subscribe to OnCollision instead.


Quote from http://obi.virtualmethodstudio.com/tutor...sions.html:

Quote:To request the particle-collider contact list from the solver, subscribe to its OnCollision event. To retrieve the particle-particle contact list, subscribe to its OnParticleCollision event.

This page should also be up to date (v5.5). Is there any part of it you're having trouble with?
Reply
#5
(08-09-2020, 08:49 AM)josemendez Wrote: You've subscribed to the OnParticleCollision event. This is for contacts between particles, as explained in the manual.

To get a list of contacts against colliders, you should subscribe to OnCollision instead.


Quote from http://obi.virtualmethodstudio.com/tutor...sions.html:


This page should also be up to date (v5.5). Is there any part of it you're having trouble with?
Right... Missed that somehow. Thank you!
Reply
#6
No worries, you’re welcome! Sonrisa
Reply
#7
(08-09-2020, 08:49 AM)josemendez Wrote: You've subscribed to the OnParticleCollision event. This is for contacts between particles, as explained in the manual.

To get a list of contacts against colliders, you should subscribe to OnCollision instead.


Quote from http://obi.virtualmethodstudio.com/tutor...sions.html:


This page should also be up to date (v5.5). Is there any part of it you're having trouble with?
This page about tearing seems to be outdated, shared wrong one, sorry. http://obi.virtualmethodstudio.com/tutor...aints.html

By the way, is there an effective way to get certain rope ObiStructuralElement straight from collision?
Reply
#8
(08-09-2020, 09:09 AM)dosinis Wrote: This page about tearing seems to be outdated, shared wrong one, sorry. http://obi.virtualmethodstudio.com/tutor...aints.html

By the way, is there an effective way to get certain rope ObiStructuralElement straight from collision?

That page is for a previous version, 4.X to be exact, as evidenced by the URL:

http://obi.virtualmethodstudio.com/tutorials_4/scriptingconstraints.html

The docs for the current version are always at:

http://obi.virtualmethodstudio.com/tutorials/

You can't get the element right away from the collision, as the underlying physics engine is unaware of what an element is, it only works with particles. Each element is an "edge" between two particles (element.particle1 and element.particle2), so you should search for the element that contains the particle you want to tear. These are solver indices (as opposed to actor indices), so you can directly look trough all elements for the particle reported by contact.particle. Once you find an element such that element.particle1 == contact.particle, you can pass that element to rope.Tear() and skip all other elements.

Manual tearing isn't well documented though (on my TODO list), most info you can find is by looking at the API docs, but should be pretty straightforward once you understand the things involved. Let me know if you need help with actual code.
Reply
#9
(08-09-2020, 09:16 AM)josemendez Wrote: That page is for a previous version, 4.X to be exact, as evidenced by the URL:

http://obi.virtualmethodstudio.com/tutorials_4/scriptingconstraints.html

The docs for the current version are always at:

http://obi.virtualmethodstudio.com/tutorials/

You can't get the element right away from the collision, as the underlying physics engine is unaware of what an element is, it only works with particles. Each element is an "edge" between two particles (element.particle1 and element.particle2), so you should search for the element that contains the particle you want to tear. These are solver indices (as opposed to actor indices), so you can directly look trough all elements for the particle reported by contact.particle. Once you find an element such that element.particle1 == contact.particle, you can pass that element to rope.Tear() and skip all other elements.

Manual tearing isn't well documented though (on my TODO list), most info you can find is by looking at the API docs, but should be pretty straightforward once you understand the things involved. Let me know if you need help with actual code.
Hey Sonrisa I've managed to work out Tearing pretty much, though it wasn't piece of cake Gran sonrisa Now I'm completely confused about how path AddControlPoint works and AddConstraints work.. I want to make straight rope which is attached to ragdoll player. But offsets are really painful to work with, I add slight offset to Constraints and it all messes up and when trying to match ControlPoint instead of playing around with offset - it's even more unpredictable. Any help with that? Gran sonrisa My implementation :
Code:
  private IEnumerator CreateRope()
        {
            blueprint.path.Clear();

            Vector3 targetPos = endPoint.position;
            targetPos.y += 1f; // this for some reason shifts rope to x axis, when changing this value to other number then 1 - it shifts rope to y axis

            blueprint.path.AddControlPoint(startPoint.position, Vector3.zero, Vector3.zero, Vector3.down, 0.1f, 0.1f, 1, 1, Color.white, "Hook start");
            blueprint.path.AddControlPoint(targetPos, Vector3.zero, Vector3.zero, Vector3.down, 0.1f, 0.1f, 1, 1, Color.white, "Hook end");

            blueprint.path.FlushEvents();
            yield return blueprint.Generate();

            var pinConstraints = blueprint.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
            var batch = pinConstraints.batches[0];
            batch.AddConstraint(0, startPoint.GetComponent<ObiCollider>(), Vector3.zero, Quaternion.identity);
            batch.AddConstraint(blueprint.activeParticleCount - 1, endPoint.GetComponent<ObiColliderBase>(), Vector3.zero, Quaternion.identity);
            batch.activeConstraintCount = 2;

            rope.ropeBlueprint = blueprint;
            rope.GetComponent<MeshRenderer>().enabled = true;
        }
Reply
#10
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.
Reply