Search Unity

Compound Collision

Discussion in 'Physics for ECS' started by argibaltzi, Jun 12, 2020.

  1. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    Hi
    I have a compound rigidbody and an array of all its colliders
    NativeArray<CompoundCollider.ColliderBlobInstance> blobs;

    After a sphereCast i have an array of hits and i also kept the array of all colliders in the compound rigidbody

    now what i want to do is fairly simple, find out which collider exactly was hit
    I have gotten as far as this
    Code (CSharp):
    1.  ChildCollider childCollider;
    2. if (MyCompoundCollider.Value.GetLeaf(hit.ColliderKey, out childCollider))                      
    3. {
    4.      // WHAT DO I DO HERE?
    5. }
    Any tips?
    Thanks!
     
  2. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    childCollider.Collider gives you exactly the collider you hit. Is that what you need, or you somehow need more info?
     
  3. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    well it has a collider pointer but what do i compare it against?

    unsafe
    {
    childCollider.Collider == blobs.Collider.GetUnsafePtr() ?
    }
    its been awhile since i dealt with pointers in c#
    i am trying to get the INDEX in the collider array eventually because i have some other data i need to access
     
    Last edited: Jun 12, 2020
  4. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Ah, if you need the index in the array you need to go through the array and compare each ColliderBlobInstance.Collider.GetUnsafePtr() to childCollider.Collider pointer, that will give you which one is hit. Although you probably want to mark your colliders as unique (force unique) to be sure it's not reused by multiple children.

    I would advise something a bit more efficient, like storing collider pointers and indices in a map, to get more performant access.

    Edit: your code in the unsafe block is exactly what you need for each array member.
     
  5. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    This simple code does not work, these 2 colliders never match, could it be that they are not "unique" as you say?
    the compound is made out of boxes

    Code (csharp):
    1.  for (int a = 0; a < fallingCompound.blobs.Length; ++a)
    2.  {
    3.       unsafe
    4.        {
    5.         if (childCollider.Collider == fallingCompound.blobs[a].Collider.GetUnsafePtr())
    6.         {
    7.               Debug.Log("collision found");
    8.          }
    9.        }
    10.  }
     
  6. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Actually, scratch that, there is a simpler way. The hit.ColliderKey actually already contains index to the original array - just call PopSubKey() on it. The input argument to this function (numSubKeyBits) is actually stored in CompoundCollider.NumColliderKeyBits, just pass it in and you'll get your index as the out parameter...
     
    cultureulterior and argibaltzi like this.
  7. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Something like hit.ColliderKey.PopSubKey(MyCompoundCollider.Value.NumColliderKeyBits, out uint index) will do the trick.
     
  8. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    it did!! thanks so much!
     
    petarmHavok likes this.
  9. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    @argibaltzi If you donˋt mind - how did you get the array of colliders in the first place? Thanks!
     
  10. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    i am using gameobjects and ecs together, so maybe that makes my life a little easier sometimes and sometimes not...


    There are 2 ways i have access to them actually
    1) i keep the original NativeArray<CompoundCollider.ColliderBlobInstance> blobs in a script
    2) for compound colliders i have an empty gameobject(rigidbody) and all its colliders as children

    Code (CSharp):
    1.  
    2.  
    3. unsafe
    4.             {
    5.                 uint indexKey;
    6.                 var isCompound = (CompoundCollider*)compoundDots.MyCollider.GetUnsafePtr();
    7.                 if (hit.ColliderKey.PopSubKey(isCompound->NumColliderKeyBits, out indexKey))
    8.                 {
    9.                    outGameObject.transform.GetChild((int)indexKey); // this is the collider/gameobject of the compound
    10.                 }
    11.             }
    i also have a scene dictionary to get back gameobjects once i know the entity
    EntityToGameObjectTracker.Instance.EntityToGameobject.TryGetValue(hit.Entity, out outGameObject))

    i use this for key entities/gameobjects that require tracking
     
    florianhanke likes this.