Obi Official Forum

Full Version: Spatial Query on multiple Actors
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

i have recently started to work with the Obi Package (Rope/Cloth) and am running in some trouble. It is probably a pretty simple fix/problem but i simply am unable to figure it out myself. I used the code example for spatial query which is working really perfectly as long as only one actor is in the solver. As soon as multiple actors from the same type are in the solver the position data is calculated wrong. It stays correct with the last actor in the solver though, which i find curious. 

Code:
using UnityEngine;
using Obi;

public class DistanceToPoint : MonoBehaviour
{
    public ObiSolver solver;
    public float radius = 1;

    void Update()
    {
        int filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything, 0);

        var query = new QueryShape(QueryShape.QueryType.Sphere, Vector3.zero, Vector3.zero, 0, radius, filter);
        var xform = new AffineTransform(transform.position, transform.rotation, transform.localScale);

        QueryResult[] results = solver.SpatialQuery(query, xform);

        // Iterate over results and draw their distance to the point.
        // We're assuming the solver only contains 0-simplices (particles).
        for (int i = 0; i < results.Length; ++i)
        {
            if (results[i].distance < radius)
            {
                Vector3 pos = solver.transform.TransformPoint(solver.positions[results[i].simplexIndex]);
                Debug.DrawLine(transform.position, pos, Color.yellow);
            }
        }
    }
}

Here is a GIF of the problem

Any suggestions why this might be? Does this concern the info in the example code (We're assuming the solver only contains 0-simplices (particles))?

A follow up question would be. I plan on using multiple solvers with multiple actors in my scene and would keep the performance overhead low. What would be the best query method to check which actor/particles are near. Is the spatial query method suited for this purpose?

Any help would be highly appreciated Sonrisa

Best regards, Will
Hi there Will! Sonrisa

Code:
solver.positions[results[i].simplexIndex]

This will only work if you only have one actor per solver and it is not using surface collisions. To get a particle index from a simplex index in the general case, see "Retrieving the particle involved in a contact":

http://obi.virtualmethodstudio.com/manua...icles.html

In your case, assuming you don't use surface collisions the code would be:

Code:
// no surface collisions, so we assume only one particle per simplex:
int particleIndex = solver.simplices[results[i].simplexIndex];
var position = solver.positions[particleIndex];

If you do use surface collisions, the simplices used by queries and collisions will be groups of 2 particles each, so assuming there's only one particle per simplex no longer works. The general code to get all particles in a simplex (whether there's 1, 2 or 3 particles in the simplex) is:

Code:
// retrieve the offset and size of the simplex in the solver.simplices array:
int simplexStart = solver.simplexCounts.GetSimplexStartAndSize(contact.bodyA, out int simplexSize);

// starting at simplexStart, iterate over all particles in the simplex:
for (int i = 0; i < simplexSize; ++i)
{
    int particleIndex = solver.simplices[simplexStart + i];

    // do something with each particle, for instance get its position:
    var position = solver.positions[particleIndex];
}

Since the code to do this for collisions and queries is exactly the same, I will add this info to the queries manual page too as I realized it can be misleading otherwise.

Let me know if I can be of further help!
Thank you so much for your swift reply. I managed to get it working with your help.  Gran sonrisa

I wish you relaxing holidays because i might take you up on that offer with further help in the new year  Gran sonrisa

cheers Will