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

[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,770
    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,770
    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. }