Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[DOTS] Adding / removing / disabling colliders to compound DynamicBody

Discussion in 'Physics Previews' started by Antypodish, Aug 14, 2019.

  1. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    Revised question in next post #1


    Original question

    I have followed Compound Demo, to create compound dynamic bodies.
    EntityComponentSystemSamples/UnityPhysicsSamples/Assets/Tests/Compound/CompoundDemo.cs

    I was playing about a bit with script, by adding cubic (5x5x5) cubes generation, which works fine.

    Code (CSharp):
    1. for ( int z = 0; z < i_count; z ++ )
    2.             {
    3.                 for ( int y = 0; y < i_count; y ++ )
    4.                 {
    5.                     for ( int x = 0; x < i_count; x ++ )
    6.                     {
    7.                         int i_index = z * i_count * i_count + y * i_count + x ;
    8.                    
    9.                         children [i_index] = new CompoundCollider.ColliderBlobInstance
    10.                         {
    11.                             CompoundFromChild = new RigidTransform(quaternion.identity, new float3( x, y, z )),
    12.                             Collider = Unity.Physics.BoxCollider.Create(float3.zero, quaternion.identity, new float3(1), 0.05f)
    13.                         } ;
    14.                     }
    15.                 }

    Then followed Create method, using as reference point, to generate new compound body.
    Code (CSharp):
    1. BlobAssetReference<Unity.Physics.Collider> collider = CompoundCollider.Create(children);
    2.             children.Dispose();
    3.        
    4.             CreateDynamicBody ( new float3(0, 1, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f ) ;
    From that point, how should I approach now, by amending this compound body, to be able adding, removing, or/and disabling certain amount of colliders?

    If I look inside CreateDynamicBody, there is
    Code (CSharp):
    1. protected Entity CreateDynamicBody(float3 position, quaternion orientation, BlobAssetReference<Collider> collider,
    2.         float3 linearVelocity, float3 angularVelocity, float mass)
    3.     {
    4.         return CreateBody ( position, orientation, collider, linearVelocity, angularVelocity, mass, true ) ;
    5.     }
    Which further leads to
    Code (CSharp):
    1. private Entity CreateBody(float3 position, quaternion orientation, BlobAssetReference<Collider> collider,
    2.         float3 linearVelocity, float3 angularVelocity, float mass, bool isDynamic)
    3.     {
    4.         EntityManager entityManager = EntityManager;
    5.  
    6.         Entity entity = entityManager.CreateEntity(new ComponentType[] { });
    7.  
    8.         entityManager.AddComponentData(entity, new LocalToWorld { });
    9.         entityManager.AddComponentData(entity, new Translation { Value = position });
    10.         entityManager.AddComponentData(entity, new Rotation { Value = orientation });
    11.  
    12.         var colliderComponent = new PhysicsCollider { Value = collider };
    13.         entityManager.AddComponentData(entity, colliderComponent);
    14.  
    15.         Mesh mesh = new Mesh();
    16. #pragma warning disable 618
    17.         List<Unity.Physics.Authoring.DisplayBodyColliders.DrawComponent.DisplayResult> meshes;
    18.         unsafe { meshes = Unity.Physics.Authoring.DisplayBodyColliders.DrawComponent.BuildDebugDisplayMesh(colliderComponent.ColliderPtr); }
    19. #pragma warning restore 618
    20.         CombineInstance[] instances = new CombineInstance[meshes.Count];
    21.         int numVertices = 0;
    22.         for (int i = 0; i < meshes.Count; i++)
    23.         {
    24.             instances[i] = new CombineInstance
    25.             {
    26.                 mesh = meshes[i].Mesh,
    27.                 transform = Matrix4x4.TRS(meshes[i].Position, meshes[i].Orientation, meshes[i].Scale)
    28.             };
    29.             numVertices += meshes[i].Mesh.vertexCount;
    30.         }
    31.         mesh.indexFormat = numVertices > UInt16.MaxValue ? UnityEngine.Rendering.IndexFormat.UInt32 : UnityEngine.Rendering.IndexFormat.UInt16;
    32.         mesh.CombineMeshes(instances);
    33.  
    34.         entityManager.AddSharedComponentData(entity, new RenderMesh
    35.         {
    36.             mesh = mesh,
    37.             material = isDynamic ? dynamicMaterial : staticMaterial
    38.         });
    39.  
    40.         if (isDynamic)
    41.         {
    42.             entityManager.AddComponentData(entity, PhysicsMass.CreateDynamic(colliderComponent.MassProperties, mass));
    43.  
    44.             float3 angularVelocityLocal = math.mul(math.inverse(colliderComponent.MassProperties.MassDistribution.Transform.rot), angularVelocity);
    45.             entityManager.AddComponentData(entity, new PhysicsVelocity()
    46.             {
    47.                 Linear = linearVelocity,
    48.                 Angular = angularVelocityLocal
    49.             });
    50.             entityManager.AddComponentData(entity, new PhysicsDamping()
    51.             {
    52.                 Linear = 0.01f,
    53.                 Angular = 0.05f
    54.             });
    55.         }
    56.  
    57.         return entity;
    58.     }

    I am able follow up to the
    Code (CSharp):
    1. var colliderComponent = new PhysicsCollider { Value = collider };
    2.         entityManager.AddComponentData(entity, colliderComponent);
    But from that point I am bit lost. I see pointer to the array of blocks to add inside colliderComponent. However, I ain't got clue, how to bite the problem, to modify script, so I can add extra / remove / disable some colliders to/from that compound.

    I suppose, I could regenerate whole compound. But surely there is better approach.

    Any thoughts?
     
    Last edited: Aug 14, 2019
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    With revision into problem, I looked a bit further into
    EntityComponentSystemSamples/UnityPhysicsSamples/Assets/Common/Scripts/BasePhysicsDemo.cs
    I understand that CombineMeshes allows to combine meshes into larger mesh.
    I.e.
    Code (CSharp):
    1. mesh.CombineMeshes (instances);
    It is used for example in example of compound colliders.
    I did some basics tests
    Unity 2019.2 DOTS Physics Test: 343k Compounds Cubes

    My revised question would be, what is the opposite function to CombineMeshes, if I want to remove certain meshes / colliders from the compound? In other words, what would be opposite function of CompoundDemo
    EntityComponentSystemSamples/UnityPhysicsSamples/Assets/Tests/Compound/CompoundDemo.cs
    to disconnect / disjoint colliders?

    My immediate thought would be, to look at mesh.subMeshCount (BasePhysicsDemo) from physics and then get relevant meshes somehow, based on vertices.

    But I don't feel this is sufficient to resolve my compound colliders problem. Any thoughts?
     
    Hysparions and Thygrrr like this.
  3. sheikhg1900

    sheikhg1900

    Joined:
    Sep 13, 2021
    Posts:
    8
    I used the following systems to enable and disable colliders. Please let me if this approach has considerable flaws w.r.t performance.

    Code (CSharp):
    1. public struct PhysicsColliderHolder : IComponentData {
    2.     public PhysicsCollider physicsCollider;
    3. }
    4.  
    5. [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    6. [UpdateAfter(typeof(EndFramePhysicsSystem))]
    7. public class DisablePlayerTypeCollisionSystem : SystemBase {
    8.     EntityCommandBufferSystem _entityCommandBufferSystem;
    9.     protected override void OnCreate() {
    10.         _entityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    11.     }
    12.     protected override void OnUpdate() {
    13.         var commandBuffer = _entityCommandBufferSystem.CreateCommandBuffer().AsParallelWriter();
    14.         float deltaTime = Time.DeltaTime;
    15.         Entities.
    16.             ForEach((Entity entity, int entityInQueryIndex, in PhysicsCollider physicsCollider, in PlayerTypeData _, in ColliderTag __, in DisableRendering ____) => {
    17.                 commandBuffer.RemoveComponent<PhysicsCollider>(entityInQueryIndex, entity);
    18.                 commandBuffer.AddComponent<PhysicsColliderHolder>(entityInQueryIndex, entity, new PhysicsColliderHolder { physicsCollider = physicsCollider });
    19.             }).ScheduleParallel();
    20.         _entityCommandBufferSystem.AddJobHandleForProducer(Dependency);
    21.     }
    22. }
    23.  
    24.  
    25.  
    26.  
    27. [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    28. [UpdateAfter(typeof(EndFramePhysicsSystem))]
    29. public class EnablePlayerTypeCollisionSystem : SystemBase {
    30.     EntityCommandBufferSystem _entityCommandBufferSystem;
    31.     protected override void OnCreate() {
    32.         _entityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    33.     }
    34.     protected override void OnUpdate() {
    35.         var commandBuffer = _entityCommandBufferSystem.CreateCommandBuffer().AsParallelWriter();
    36.         float deltaTime = Time.DeltaTime;
    37.         Entities.
    38.             WithNone<DisableRendering, PhysicsCollider>().
    39.             ForEach((Entity entity, int entityInQueryIndex, in PhysicsColliderHolder physicsColliderHolder, in PlayerTypeData _, in ColliderTag __) => {
    40.                 commandBuffer.AddComponent<PhysicsCollider>(entityInQueryIndex, entity, physicsColliderHolder.physicsCollider);
    41.             }).ScheduleParallel();
    42.         _entityCommandBufferSystem.AddJobHandleForProducer(Dependency);
    43.     }
    44. }