Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Figure out what Actor was collided with
#1
I am going to be cutting ropes, with multiple ropes on one solver. I have a knife which tears the rope at the particle index collided with. The only problem is I don't know how to get which rope is being collided with to cut the right one. I've looked through the classes and couldn't find anything. Right now I have a public field to apply the tear to a rope. Here is the code, which is applied to the knife object.

Code:
using UnityEngine;
using Obi;

public class RopeCutter : MonoBehaviour
{
   public ObiSolver solver;
   public ObiRope rope;


   void OnEnable()
   {
       solver.OnCollision += Solver_OnCollision;
   }

   void OnDisable()
   {
       solver.OnCollision -= Solver_OnCollision;
   }

   void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
   {
       if (solver.colliderGroup == null) return;

       foreach (Oni.Contact c in e.contacts)
       {
           // make sure this is an actual contact:
           if (c.distance < 0.01f)
           {
               // get the collider:
               //Collider collider = solver.colliderGroup.colliders[c.other];
               
               // Cut at particle index
               
               CutRopeAtIndex(rope, c.particle);
           }
       }
   }

   void CutRopeAtIndex(ObiRope rope, int index)
   {
       // remove constraints from solver:
       rope.DistanceConstraints.RemoveFromSolver(null);
       rope.BendingConstraints.RemoveFromSolver(null);

       rope.Tear(index); // tear the fifth distance constraint.
                         // you could call Tear() as many times as you wish here.

       // add constraints to solver
       rope.BendingConstraints.AddToSolver(rope);
       rope.DistanceConstraints.AddToSolver(rope);

       // update active bending constraints:
       rope.BendingConstraints.SetActiveConstraints();

       // only for cloth: commit changes to the topology:
       // UpdateDeformableTriangles();

       // upload active particle list to solver:
       rope.Solver.UpdateActiveParticles();
   }
}
Reply
#2
(09-08-2017, 12:40 AM)niZmo Wrote: I am going to be cutting ropes, with multiple ropes on one solver. I have a knife which tears the rope at the particle index collided with. The only problem is I don't know how to get which rope is being collided with to cut the right one. I've looked through the classes and couldn't find anything. Right now I have a public field to apply the tear to a rope. Here is the code, which is applied to the knife object.


Code:
using UnityEngine;
using Obi;

public class RopeCutter : MonoBehaviour
{
   public ObiSolver solver;
   public ObiRope rope;


   void OnEnable()
   {
       solver.OnCollision += Solver_OnCollision;
   }

   void OnDisable()
   {
       solver.OnCollision -= Solver_OnCollision;
   }

   void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
   {
       if (solver.colliderGroup == null) return;

       foreach (Oni.Contact c in e.contacts)
       {
           // make sure this is an actual contact:
           if (c.distance < 0.01f)
           {
               // get the collider:
               //Collider collider = solver.colliderGroup.colliders[c.other];
               
               // Cut at particle index
               
               CutRopeAtIndex(rope, c.particle);
           }
       }
   }

   void CutRopeAtIndex(ObiRope rope, int index)
   {
       // remove constraints from solver:
       rope.DistanceConstraints.RemoveFromSolver(null);
       rope.BendingConstraints.RemoveFromSolver(null);

       rope.Tear(index); // tear the fifth distance constraint.
                         // you could call Tear() as many times as you wish here.

       // add constraints to solver
       rope.BendingConstraints.AddToSolver(rope);
       rope.DistanceConstraints.AddToSolver(rope);

       // update active bending constraints:
       rope.BendingConstraints.SetActiveConstraints();

       // only for cloth: commit changes to the topology:
       // UpdateDeformableTriangles();

       // upload active particle list to solver:
       rope.Solver.UpdateActiveParticles();
   }
}

Hi!

Basically you have to find out which actor contains the contact particle index in its "particleIndices" array. This is quite expensive to do since in involves a IndexOf() operation which runs in linear time on the number of particles for each actor.

In the next update we've added a much easier way to do this, that runs in constant time.

cheers!
Reply
#3
(15-08-2017, 11:34 AM)josemendez Wrote: Hi!

Basically you have to find out which actor contains the contact particle index in its "particleIndices" array. This is quite expensive to do since in involves a IndexOf() operation which runs in linear time on the number of particles for each actor.

In the next update we've added a much easier way to do this, that runs in constant time.

cheers!

Does 3.2 have this new method of determining which actor/particle collision occurred on?

If so, please tell is what it is!
Reply
#4
(06-09-2017, 07:38 PM)tbookout Wrote: Does 3.2 have this new method of determining which actor/particle collision occurred on?

If so, please tell is what it is!

Yes!

Not documented yet, but: given a contact, you can simply do this:

Code:
ObiSolver.ParticleInActor pa = solver.particleToActor[contact.particle];

The ParticleInActor struct contains the actor to which the particle belongs, as well as the index of that particle in the actor's arrays.
Reply
#5
(06-09-2017, 08:01 PM)josemendez Wrote: Yes!

Not documented yet, but: given a contact, you can simply do this:


Code:
ObiSolver.ParticleInActor pa = solver.particleToActor[contact.particle];

The ParticleInActor struct contains the actor to which the particle belongs, as well as the index of that particle in the actor's arrays.

Awesome! 
My hack was a list of which actors I cared about, and particle range they contained..   Will gladly switch to using this method.
Reply