Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Cloth collision actors
#1
Hello,

How can I obtain the actors that have collided with my cloth object?

Thanks!
Christopher
Reply
#2
(15-07-2023, 07:30 AM)domopuff Wrote: Hello,

How can I obtain the actors that have collided with my cloth object?

Thanks!
Christopher

Hi!

You can get a list of all particle-particle contacts each frame by subscribing to solver.OnParticleCollision. Then it’s just a matter of retrieving the actor(s) involved in each contact. How to do this is explained in the manual: http://obi.virtualmethodstudio.com/manua...sions.html

Kind regards,
Reply
#3
(15-07-2023, 11:03 AM)josemendez Wrote: Hi!

You can get a list of all particle-particle contacts each frame by subscribing to solver.OnParticleCollision. Then it’s just a matter of retrieving the actor(s) involved in each contact. How to do this is explained in the manual: http://obi.virtualmethodstudio.com/manua...sions.html

Kind regards,

Thanks for the reply! I managed to get the collisions detection working but performance did take a heavy hit. Any way we can try get the center points of a cloth instead?
Reply
#4
(15-07-2023, 02:55 PM)domopuff Wrote: Thanks for the reply! I managed to get the collisions detection working but performance did take a heavy hit.

If you iterate trough all contacts in the main thread using a simple for loop and there's many contacts in your scene, performance will of course be less than good. Try doing this using jobs instead.

(15-07-2023, 02:55 PM)domopuff Wrote: Any way we can try get the center points of a cloth instead?

Sure, iterate trough all particles in the cloth and calculate their center of mass. There's a snippet in the manual that does just this, pasting it here for convenience:
http://obi.virtualmethodstudio.com/manua...icles.html

Code:
using UnityEngine;
using Obi;

[RequireComponent(typeof(ObiActor))]
public class ActorCOM : MonoBehaviour {

    ObiActor actor;

    void Awake(){
        actor = GetComponent<ObiActor>();
    }

    void OnDrawGizmos(){

        if (actor == null || !actor.isLoaded)
            return;

        Gizmos.color = Color.red;
        Vector4 com = Vector4.zero;
        float massAccumulator = 0;

        // Iterate over all particles in an actor:
        for (int i = 0; i < actor.solverIndices.Length; ++i){

            // retrieve the particle index in the solver:
            int solverIndex = actor.solverIndices[i];

            // look up the inverse mass of this particle:
            float invMass = actor.solver.invMasses[solverIndex];

            // accumulate it:
            if (invMass > 0)
            {
                massAccumulator += 1.0f / invMass;
                com += actor.solver.positions[solverIndex] / invMass;
            }

        }

        com /= massAccumulator;
        Gizmos.DrawWireSphere(com,0.1f);
    }
}

Again, doing this in the main thread using a for loop will be slow. Note you can directly use Obi solver arrays in a job, see the "Using Jobs to process particles" section at the end of the page linked above.

kind regards,
Reply
#5
Thanks for your help. Managed to figure it out!
Reply