Search Unity

Faster GetRigidBodyIndex(myEntity) by storing index on component?

Discussion in 'Physics for ECS' started by PhilSA, Aug 29, 2020.

  1. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    I'm wondering if faster ways of getting rigidbodyIndex from Entity would be possible?

    Looking at the code of GetRigidBodyIndex(), I see it does this:
    Code (CSharp):
    1.  
    2.         // Find the index in the Bodies array of a particular Rigid Body from its Entity
    3.         public static int GetRigidBodyIndex(this in PhysicsWorld world, Entity entity)
    4.         {
    5.             int idx = 0;
    6.             for( int i = 0; i < world.Bodies.Length; i++)
    7.             {
    8.                 if (world.Bodies[i].Entity == entity) break;
    9.                 idx++;
    10.             }
    11.             return (idx < world.NumBodies) ? idx : -1;
    12.         }
    I get a feeling that we're not really supposed to use this a lot in its current state because it would be pretty heavy on performance.

    How possible would it be to have an optional "RigidbodyIndexComponent" on Entities that are a PhysicsBody, and RigidbodyIndexComponent would store its latest rigidbodyIndex? The rigidbodyIndex would have to be assigned during the BuildPhysicsWorld jobs on entities that have a RigidbodyIndexComponent, so it's a modification that would have to happen in the UnityPhysics package itself.

    Would there be caveats or downsides to this approach? For example, would it significantly impact BuildPhysics performance?
     
    Last edited: Aug 29, 2020
    flyingmylove and florianhanke like this.
  2. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    260
    Why not store a NativeHashMap that contains the entity as the key and the body index as the value?

    This could be filled by a system after BuildPhysicsWorld is run and accessed in jobs thereafter as read-only. Of course it would be best if this NativeHashMap was part of the PhysicsWorld and the GetRigidBodyIndex function was replaced with looking up the value in this hashmap.

    If you want to store this per entity, you could run a foreach on entities with the RigidBodyIndexComponent, fetch the rigidbody index from the NativeHashMap and store it as the index value.
     
    PhilSA likes this.
  3. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    For some reason I didn't even think about running a IJobParallelFor after BuildPhysics, and in that job, for each body in physicsWorld.Bodies, set RigidbdyIndexComponentFromEntity[myBody.Entity].Value = index

    In my use case I think this would perform better than a hashmap, but they'd both be good solutions and they can both be done without modding the package afterall

    So I think the case is closed, unless the physics team thinks it would be worth it to make that built-in function faster in a future release. It is a relatively rare use case I think, so I would understand not wanting to add that cost to the physics engine by default
     
    Last edited: Aug 30, 2020
    shotoutgames likes this.