29-04-2025, 11:00 AM
(29-04-2025, 07:12 AM)josemendez Wrote: No, "particleIndex" is as the comment in the code points out. "simplexStart" is the first entry in the simplices array, and "simplexSize" the size of the simplex. So when a simplex collides, you get a start and a size. The indices of the colliding particles are stored in solver.simplices[simplexStart] to solver.simplices[simplexStart+simplexSize].ObiNativeContactList I don't have the definition, it gives a warning.
If none of your ropes use surface-based collisions, all simplices in the solver have size 1 and it's not needed to iterate over all particles in each simplex. You can just do what you were doing before:
Code:int particleIndex = solver.simplices[contact.bodyA];
I just tried the script and it works perfectly for me. I'm attaching the version of the script that I used to perform the test, maybe you can spot any difference with what you're doing?
Code:using UnityEngine;
using Obi;
public class RopeContactNormalized : MonoBehaviour
{
public ObiRope rope;
// Start is called before the first frame update
void Start()
{
rope.solver.OnCollision += OnRopeContactEnter;
}
public void OnRopeContactEnter(ObiSolver solver, ObiNativeContactList contacts)
{
var world = ObiColliderWorld.GetInstance();
float normalizedCoordinate = -1;
foreach (var contact in contacts)
{
if (contact.distance > 0.001f) continue;
int particleIndex = solver.simplices[contact.bodyA];
var col = world.colliderHandles[contact.bodyB].owner;
if (rope != null)
{
var elements = rope.elements;
int elementIndex = -1;
for (int i = 0; i < elements.Count; ++i)
{
var element = elements[i];
if (element.particle1 == particleIndex || element.particle2 == particleIndex)
{
elementIndex = i;
break;
}
}
if (elementIndex != -1)
{
normalizedCoordinate = (float)elementIndex / elements.Count;
Debug.Log("Normalized rope position: " + normalizedCoordinate);
break;
}
else
{
Debug.LogWarning("Element not found for particle " + particleIndex);
}
}
else
{
Debug.LogWarning("Rope reference is missing!");
}
}
if (normalizedCoordinate >= 0)
{
var section = rope.GetComponent<ObiPathSmoother>().GetSectionAt(normalizedCoordinate);
Debug.DrawRay(section.position, section.normal, Color.red);
}
}
}
I'm listening to the events of the script ObiContactEventDispatcher