Search Unity

Wake up sleeping objects (Havok)

Discussion in 'Physics for ECS' started by argibaltzi, Sep 6, 2020.

  1. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    Hi

    I have some resting objects on a dynamic terrain. When the terrain is destroyed the objects dont fall because they are in sleep state. i tested with sleeping disabled and they fall.

    What is the best way to handle such cases ? Do i have to find out which objects are sleeping and wake them up manually? how do you wake up a sleeping physics object.

    Thanks!
     
  2. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    You shouldn't have to do anything, it sounds like an issue, bodies should wake up on their own. How are you destroying the terrain object?
     
  3. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    first i update the terrain collider so it no longer collides with anything(i update the collision filter in runtime), then i do some destruction animation(no collisions anymore) and then disable the entity

    so right after after i change the collision filter, i would expect objects above the terrain to fall down
     
  4. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Do you happen to have a small repro project, or can create one and post it here? I can try to recreate the scenario, but I'd like to be sure I have the identical setup for this.
     
  5. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    i dont have a project handy, its on the main big project. i would need to make a new one (need a little time :) )
    i am using custom code for all my ECS work (no conversion classes)

    Code (CSharp):
    1.  public void UpdateCollisionLayerOnEntity(PhysicsCategoryTags newBelongsTo, PhysicsCategoryTags collidesWith)
    2.     {
    3.         CollidesWith = collidesWith;
    4.         BelongsTo = newBelongsTo;
    5.         PhysicsCollider colliderComponent = EntityManagerRef.GetComponentData<PhysicsCollider>(ECSEntity);
    6.         colliderComponent.Value.Value.Filter = MyCollisionFilter;
    7.         EntityManagerRef.SetComponentData<PhysicsCollider>(ECSEntity, colliderComponent);
    8.     }
    9.  
    10.  
    i call this function at some point and then i move the terrain object away(the animation part). Once its in certain distance i disable it

    I wonder if i move it first by some small value and then update the collider filter what would happen
     
    Last edited: Sep 7, 2020
  6. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    How do you move it? Do you set a velocity on it or just teleport it?
     
  7. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    i use physics velocity to push it down

    EDIT
    Here is a more detailed explanation
    1. the terrain is a static collider (no rigid body, just collider)
    2. a bomb hits the terrain
    3. i update the terrain filter to not collide with anything
    4. i created a rigid body for the terrain ( I call PhysicsMass.CreateDynamic)
    5. The object begins to fall down
    6. sleeping objects above it don't update (with sleeping disabled, they fall immediately)


    I did a quick test with no collision filter changes and the problem is still there
     
    Last edited: Sep 7, 2020
  8. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Just another question, do steps 1-4 happen in the same step (frame)?
     
  9. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Also one more thing - what do you mean "no rigid body, just collider"? If there is a collider, consequently there is a rigid body in the PhysicsWorld, since the collision obviously works for you. I'd like to see that code if possible?

    Or are you not using BuildPhysicsWorld at all and adding the dynamic body to the PhysicsWorld on your own?
     
  10. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    I've tried the following code (after the dynamic bodies settle on the static ground) and bodies start falling immediately:

    Code (CSharp):
    1. // Get the physics collider component
    2. var colliderComponent = EntityManager.GetComponentData<PhysicsCollider>(terrainEntity);
    3.  
    4. // Add the PhysicsMass of 1kg to the terrain body
    5. EntityManager.AddComponentData(terrainEntity, PhysicsMass.CreateDynamic(colliderComponent.MassProperties, 1.0f));
    6.  
    7. // Add the PhysicsVelocity of 5m/s downwards to the terrain body
    8. EntityManager.AddComponentData(entity, new PhysicsVelocity
    9. {
    10.     Linear = new float3(0.0f, -5.0f, 0.0f),
    11.     Angular = float3.zero
    12. });
     
  11. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    What i mean with the rigid bodies is that after i create an entity
    i add a collider like this

    Code (CSharp):
    1.  
    2.   PhysicsCollider colliderComponent = new PhysicsCollider() { Value = MyCollider };
    3.             EntityManagerRef.SetComponentData<PhysicsCollider>(ECSEntity, new PhysicsCollider() { Value = MyCollider });
    4.  
    This body now will collide with moving bodies

    and when i want this body(terrain) to move in the simulation i call this code

    Code (CSharp):
    1. PhysicsCollider colliderComponent = EntityManagerRef.GetComponentData<PhysicsCollider>(ECSEntity);
    2.  
    3.             LastKnowMassData = PhysicsMass.CreateDynamic(colliderComponent.MassProperties, Mass);
    4.             LastKnowMassData.InverseInertia[0] = LockRotationX ? 0 : LastKnowMassData.InverseInertia[0];
    5.             LastKnowMassData.InverseInertia[1] = LockRotationY ? 0 : LastKnowMassData.InverseInertia[1];
    6.             LastKnowMassData.InverseInertia[2] = LockRotationZ ? 0 : LastKnowMassData.InverseInertia[2];
    7.             EntityManagerRef.AddComponentData(ECSEntity, LastKnowMassData);
    8.  
    9.             float3 angularVelocityLocal = math.mul(math.inverse(colliderComponent.MassProperties.MassDistribution.Transform.rot), float3.zero);
    10.             EntityManagerRef.AddComponentData(ECSEntity, new PhysicsVelocity()
    11.             {
    12.                 Linear = float3.zero,
    13.                 Angular = angularVelocityLocal
    14.             });
    15.             EntityManagerRef.AddComponentData(ECSEntity, new PhysicsDamping()
    16.             {
    17.                 Linear = LinearDamping,
    18.                 Angular = AngularDamping
    19.             });

    "Just another question, do steps 1-4 happen in the same step (frame)?"
    1. the terrain is a static collider (no rigid body, just collider)
    This happens when the scene is loaded

    2. a bomb hits the terrain
    I set a flag that this has happened to be picked up on this or next frame

    3. i update the terrain filter to not collide with anything
    4. i created a rigid body for the terrain ( I call PhysicsMass.CreateDynamic)
    these are called in the same function
     
  12. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Your code seems fine and should work out of the box. So I'm gonna have to continue with questions:
    1. What collision method are you using for the terrain - triangles or vertex samples?
    2. What version of the Unity/Havok physics package are you using?
     
  13. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    everything is using box colliders
    Havok: Version 0.3.1-preview - July 28, 2020
    Unity Physics: 0.4.1-preview

    Perhaps there is a glitch somewhere in the order as i am using a mixture of monobehaviour and entities,i will investigate further
     
    petarmHavok likes this.
  14. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Oh, I was trying with mesh and terrain collider. When I switched to boxes I got the repro. Will look into it and get back to you, thanks!

    Edit: it only happens for me if I play around with collision filter, without it it doesn't happen. Can you verify that on your end?
     
  15. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    if you have BOX A(static) at base and then BOX B(dynamic) on top of it.
    BOX B will eventually sleep on top of A
    BOX A, change its filter so they are no longer colliding
    BOX B, will not move (this is the bug, its locked in resting place)

    If you dont change the filter then everything is normal
     
  16. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Yeah that's what I observed, if no filter is touched, everything works fine. Thanks, I'll get back to you!
     
    argibaltzi likes this.
  17. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Alright, we know the root cause to this, I'll work on the fix but it's in the Havok plugin code, so I can't really share it here, you wouldn't have the option to apply it. In the meantime, I suggest delaying the collision filter change for 1 frame, that should be enough to get you moving until the fix is out. Does that sound ok?
     
    argibaltzi likes this.
  18. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    i was able to find a workaround while i was doing some optimizations but i am glad we tracked down the bug :)
    thanks pete!!
     
    petarmHavok likes this.