Figure out what Actor was collided with - niZmo - 09-08-2017
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();
}
}
RE: Figure out what Actor was collided with - josemendez - 15-08-2017
(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!
RE: Figure out what Actor was collided with - tbookout - 06-09-2017
(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!
RE: Figure out what Actor was collided with - josemendez - 06-09-2017
(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.
RE: Figure out what Actor was collided with - tbookout - 06-09-2017
(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.
|