Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Pinning rope particles on collision
#1
Hi there,

I'm currently working with the ropes and want to have it completly stick on collision. I already have code to detect collision and create the Pin constraint but I'm still having several issues with it.

Setting the stickiness value of the collision material to one just makes the rope go crazy around the mesh so I'm using the pin constraints. When all particles of the ropes collided with the collider I want all of them to stay in place and don't even need any physics calculation for it. But I haven't found on how do achieve that yet. I've also noticed that even though there is a pin constraint the rope doesn't really stick and slips off the collider just falling to the ground or there is some particles that are supposed to stick but still fly around.

What I do right now in the code is that I use the OnCollision callback and add a Pin constraint (like in the documentation). The problem is if I have multiple ropes the performance drops quickly so I try to check if all particles already have a pin constraint and then just skip the whole collision detection.

But from what I see is that I have to iterate over all contact points which grows a lot with the mesh collider and the amount ropes with the particles (each rope has about 8 particles). For me it feels like I iterate over every contact even those that are not part of the rope.

If you need more information please let me know.
Reply
#2
(28-09-2022, 07:47 PM)Spartan190 Wrote: Hi there,

I'm currently working with the ropes and want to have it completly stick on collision. I already have code to detect collision and create the Pin constraint but I'm still having several issues with it.

Pin constraints are only useful the pinning to dynamic rigidbodies, if you're glueing particles to walls or other static objects there's easier/simpler approaches (read on).

(28-09-2022, 07:47 PM)Spartan190 Wrote: Setting the stickiness value of the collision material to one just makes the rope go crazy around the mesh so I'm using the pin constraints.

Stickiness is not a normalized value, but a force. This means that 1 is not "maximum stickiness". Being a force, it is expressed in Newtons and the resulting acceleration towards the surface of the object depends on the mass of your particles. 1 is a rather strong force, might very well cause the simulation to jitter if your timestep is not small enough.

(28-09-2022, 07:47 PM)Spartan190 Wrote: When all particles of the ropes collided with the collider I want all of them to stay in place and don't even need any physics calculation for it. But I haven't found on how do achieve that yet.

As long as the rope is present in the solver, it will be simulated. What you want is to swap the rope with a static mesh once all its particles have been glued to the wall. ObiRopeExtrudedRenderer has a "extrudedMesh" properly that you can access, instantiate it and destroy the rope once all particles in the rope are glued.

(28-09-2022, 07:47 PM)Spartan190 Wrote: What I do right now in the code is that I use the OnCollision callback and add a Pin constraint (like in the documentation).

Pin constraints are only useful for rigidbodies, if you just want to fix a particle in place you can set its inverse mass to zero. Quoting the docs:

Quote:Inverse mass: Inverse mass for each particle. An inverse mass of 0 means the particle's mass is infinite, so its position will be unaffected by dynamics (allowing you to override it manually).

To do this, just write a zero in the solver's invMasses array like this:

Code:
solver.invMasses[rope.solverIndices[index]] = 0;

(28-09-2022, 07:47 PM)Spartan190 Wrote: The problem is if I have multiple ropes the performance drops quickly so I try to check if all particles already have a pin constraint and then just skip the whole collision detection. But from what I see is that I have to iterate over all contact points which grows a lot with the mesh collider and the amount ropes with the particles (each rope has about 8 particles). For me it feels like I iterate over every contact even those that are not part of the rope.

Regardless of how you approach this, you need to iterate over all contact points at least once. There's no other way of knowing if a specific contact happens between a rope and a object. Generally, if you have a list of objects you need to check them all at least once to see if at least one of them meets a certain condition.

Contacts are not "part of a rope", they do not belong to any specific actor. The engine generates contacts for all object pairs, and solves them all simultaneously regardless of which actor-object or actor-actor pair they're affecting. Doing this on a per-actor basis would be extremely inefficient: still need to check all contacts, but instead of having a nicely packed & cache-friendly array that we can iterate in parallel, we now have many small arrays (one per actor).

This is also what Unity does internally when calling OnCollision for a specific object: it just iterates trough all contact pairs reported by the physics engine, and calls OnCollision for each one. If using a regular for loop in the main thread is too slow, I can suggest iterating trough the contacts using jobs.

kind regards,
Reply
#3
Thank you very much for your time and effort in explaining it all to me. It's my first time using Obi Physics and already read some documentation but not all of it.

The informations already help me a lot and I will take them into account. Also will take a look at the Jobs (about time anyway) to check for the collisions.
Reply