Search Unity

Question Using OverlapAabb() within Entities.ForEach

Discussion in 'Physics for ECS' started by Egad_McDad, Aug 24, 2020.

  1. Egad_McDad

    Egad_McDad

    Joined:
    Feb 5, 2020
    Posts:
    39
    As the title says, I am attempting to call OverlapAabb() from within a system's Entities.ForEach. Unfortunately, I have not been able to get this to work and have been getting an out of range exception from the OverlapAabb() call, specifically from this line in AabbLeaf() from Broadphase.cs:
    Code (CSharp):
    1. RigidBody body = m_Bodies[rigidBodyIndex];
    I should mention that I am not converting any GameObjects to entities, rather, I create all entities with
    PhysicsCollider 
    and other required components at runtime. The package version I am using is 0.4.1.

    Even though the error was different, I tried using the suggestions from this post, specifically, adding
    [UpdateBefore(typeof(EndFramePhysicsSystem))]
    and
    [UpdateAfter(typeof(StepPhysicsWorld))]
    to the system in question and
    Dependency = JobHandle.CombineDependencies(Dependency, buildPhysicsWorld.GetOutputDependency());
    prior to scheduling the ForEach, this did not fix the problem however. I also tried to running this system only after a few frames had passed to see if uninitialized components were the culprit but that did not work either.

    This is my block of code from inside ForEach:
    Code (CSharp):
    1.  
    2. var hitList = new Unity.Collections.NativeList<int>(1024, Allocator.Temp);
    3. collisionWorld.OverlapAabb(
    4.     new OverlapAabbInput
    5.     {
    6.         Aabb = new Aabb { Max = myMaxValue, Min = myMinValue },
    7.         Filter = new CollisionFilter
    8.         {
    9.             BelongsTo = ~0u,
    10.             CollidesWith = ~0u,
    11.             GroupIndex = 0,
    12.         }
    13.     },
    14.     ref hitList
    15. );
    16.  
    Any help at all would be greatly appreciated!
     
  2. brunocoimbra

    brunocoimbra

    Joined:
    Sep 2, 2015
    Posts:
    679
    It should be
    Code (CSharp):
    1. Dependency = JobHandle.CombineDependencies(Dependency, stepPhysicsWorld.GetOutputDependency());
    2.  
    3. // do foreach stuff
    4.  
    5. endFramePhysicsSystem.AddInputDependency(Dependency);
     
    Egad_McDad likes this.
  3. Egad_McDad

    Egad_McDad

    Joined:
    Feb 5, 2020
    Posts:
    39
    Thanks for the quick reply!

    After adding these two lines I still get an error, albeit a different one. This new error is a null reference exception pointing to this line from AabbOverlap() in BoundingVolumeHierarchy.cs:

    Code (CSharp):
    1. Node* node = m_Nodes + nodeIndex;
    Removing the UpdateAfter and UpdateBefore that I mentioned in my first post didn't change this. I also tried delaying this systems first run again with no luck.

    Judging by the fact that
    m_Nodes
    is a member of BoundingVolumeHierarchy I'm worried that I'm missing some call to build the BVH in the first place. I didn't see any such requirement in the documentation, but I'll go back to double check...
     
  4. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    If BuildPhysicsWorld system is not running, then you need to build the BVH on your own. But if this system is running, you should be good to go. Where did you get your collisionWorld from?
     
  5. Egad_McDad

    Egad_McDad

    Joined:
    Feb 5, 2020
    Posts:
    39
    I fetch the CollisionWorld each time OnUpdate() is called from a PhysicsWorld member. The PhysicsWorld is instantiated in OnCreate() with World.GetOrCreateSystem<PhysicsWorld>().PhysicsWorld


    I checked in the entities debugger and it says BuildPhysicsWorld is running. I'll continue looking into this problem today
     
  6. Egad_McDad

    Egad_McDad

    Joined:
    Feb 5, 2020
    Posts:
    39
    After checking the physics samples I stumbled across the solution. I changed this
    Code (CSharp):
    1. BuildPhysicsWorld m_PhysicsWorld;
    2.  
    3. protected override void OnCreate()
    4. {
    5.     m_PhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>().PhysicsWorld;
    6. }
    7.  
    8. protected override void OnUpdate()
    9. {
    10.     var colWorld = m_PhysicsWorld.CollisionWorld;
    11.  
    12.     // Entities.ForEach...
    13. }
    to

    Code (CSharp):
    1. BuildPhysicsWorld m_BuildPhysicsWorld;
    2.  
    3. protected override void OnCreate()
    4. {
    5.     m_BuildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
    6. }
    7.  
    8. protected override void OnUpdate()
    9. {
    10.     var colWorld = m_BuildPhysicsWorld.PhysicsWorld.CollisionWorld;
    11.  
    12.     // Entities.ForEach...
    13. }
     
  7. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Yes, you need to get the physics world each frame from the BuildPhysicsWorld. Did that help in the end?
     
  8. Egad_McDad

    Egad_McDad

    Joined:
    Feb 5, 2020
    Posts:
    39
    Yes, it did, thanks again for the help!
     
    brunocoimbra and petarmHavok like this.
  9. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    199
    Im getting an error when I do this

    code:
    Code (CSharp):
    1. protected override void OnUpdate()
    2.     {
    3.         var ecb = buffer.CreateCommandBuffer().AsParallelWriter();
    4.         var step = World.GetOrCreateSystem<StepPhysicsWorld>();
    5.         var bpw = World.GetOrCreateSystem<BuildPhysicsWorld>();
    6.         var endframe = World.GetOrCreateSystem<EndFramePhysicsSystem>();
    7.         var pw = bpw.PhysicsWorld;
    8.         var cw = pw.CollisionWorld;
    9.      
    10.         Dependency = JobHandle.CombineDependencies(Dependency, step.GetOutputDependency());
    11.  
    12.         Entities
    13.             .ForEach((in DynamicBuffer<TriggerBuffer> buffer, in LocalToWorld ltw) =>
    14.             {
    15.                 var aabb = pw.CalculateAabb(new RigidTransform(ltw.Value)); //this caused the error below
    16.  
    17.                 var input = new OverlapAabbInput { Aabb = aabb };
    18.                 var hitList = new NativeList<int>(Allocator.Temp);
    19.                 cw.OverlapAabb(input, ref hitList); //does not like this....?
    20.                 Debug.Log(hitList.Length);
    21.                 hitList.Dispose();
    22.             })
    23.             .Schedule();
    24.  
    25.         endframe.AddInputDependency(Dependency);
    26.     }
    27.  
    error:
    Code (CSharp):
    1. InvalidOperationException: The writeable Unity.Collections.NativeArray`1[Unity.Physics.RigidBody] <>c__DisplayClass_OnUpdate_LambdaJob0.JobData.pw.CollisionWorld.m_Bodies is the same Unity.Collections.NativeArray`1[Unity.Physics.RigidBody] as <>c__DisplayClass_OnUpdate_LambdaJob0.JobData.cw.m_Bodies, two containers may not be the same (aliasing).
    any ideas?
     
    Last edited: Nov 18, 2020
  10. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    199
    nvm. This new code worked:

    Code (CSharp):
    1. protected override void OnUpdate()
    2.     {
    3.         var ecb = buffer.CreateCommandBuffer().AsParallelWriter();
    4.         var pw = bpw.PhysicsWorld;
    5.         var cw = pw.CollisionWorld;
    6.  
    7.         Dependency = JobHandle.CombineDependencies(Dependency, step.GetOutputDependency());
    8.  
    9.         Dependency = Entities
    10.             .ForEach((in DynamicBuffer<TriggerBuffer> buffer, in PhysicsCollider col, in LocalToWorld ltw) =>
    11.             {
    12.                 var aabb = col.Value.Value.CalculateAabb(new RigidTransform(ltw.Value));
    13.                 var input = new OverlapAabbInput
    14.                 {
    15.                     Aabb = aabb,
    16.                     Filter = new CollisionFilter()
    17.                     {
    18.                         BelongsTo = ~0u,
    19.                         CollidesWith = ~0u, // all 1s, so all layers, collide with everything
    20.                         GroupIndex = 0
    21.                     }
    22.                 };
    23.                 var hitList = new NativeList<int>(Allocator.Temp);
    24.                 cw.OverlapAabb(input, ref hitList);
    25.                 Debug.Log(hitList.Length);
    26.             })
    27.             .Schedule(Dependency);
    28.         Dependency.Complete(); // can this be avoided?
    29.         endFrame.AddInputDependency(Dependency);
    30.     }
    still don't like the sync point, if it can be avoided?...but it works.
     
  11. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    MNNoxMortem, Egad_McDad and toomasio like this.