Search Unity

Create a collider from a mesh in ECS/DOTS?

Discussion in 'Entity Component System' started by VrTechEx, Sep 11, 2020.

  1. VrTechEx

    VrTechEx

    Joined:
    Aug 4, 2013
    Posts:
    40
    Does anyone know how to create a collider from a mesh in ECS/DOTS?
    I want to create a 2Dmap collider from a mesh
    Here what I've got so far but I didn't get it working at the moment


    Code (CSharp):
    1. EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
    2.         EntityArchetype entityArchetype = entityManager.CreateArchetype(
    3.             typeof(Translation),
    4.             typeof(Rotation),
    5.    
    6.             typeof(PhysicsCollider),
    7.             typeof(PhysicsMass),
    8.             typeof(PhysicsVelocity),  
    9.             typeof(PhysicsDamping),
    10.             typeof(PhysicsGravityFactor)
    11.         );
    12.    
    13.         Entity entity = entityManager.CreateEntity(entityArchetype);
    14.    
    Then I got a mesh from my geometry and convert to vertices and triangles to NativeArray

    Code (CSharp):
    1.  
    2.         NativeArray<float3> vertexBuffer = new NativeArray<float3>(mesh.vertices.Length,Allocator.Temp);
    3.         NativeArray<int3> trianglesBuffer = new NativeArray<int3>(mesh.triangles.Length,Allocator.Temp);
    4.         for(int i = 0; i<mesh.vertices.Length;i++)
    5.         {
    6.             vertexBuffer[i] = new float3(mesh.vertices[i].x,mesh.vertices[i].y,mesh.vertices[i].z);
    7.         }
    8.         for(int i = 0; i<mesh.triangles.Length;i++)
    9.         {
    10.             trianglesBuffer[i] = mesh.triangles[i];
    11.         }
    12.         var vertices = new NativeArray<float3>(vertexBuffer, Allocator.Temp);
    13.         var triangles = new NativeArray<int3>(trianglesBuffer, Allocator.Temp);
    14.        
    15.         //Position
    16.         entityManager.SetComponentData(entity,
    17.             new Translation
    18.             {
    19.                 Value = new float3(0,0,0)
    20.             });
    21.  
    22.         BlobAssetReference<Unity.Physics.Collider> colliderReference =                        Unity.Physics.MeshCollider.Create(vertices,triangles,CollisionFilter.Default);
    23.         //Physics
    24.         entityManager.SetComponentData(entity, new PhysicsCollider { Value = colliderReference });
    25.    
    26.         var mass = PhysicsMass.CreateKinematic(MassProperties.UnitSphere);
    27.         entityManager.SetComponentData(entity, mass);
    28.    
    29.         entityManager.SetComponentData(entity, new PhysicsVelocity()
    30.         {
    31.             Linear = float3.zero,
    32.             Angular = float3.zero
    33.         });
    34.         entityManager.SetComponentData(entity, new PhysicsDamping()
    35.         {
    36.             Linear = 1.0f,
    37.             Angular = 0.05f
    38.         });
    39.         entityManager.SetComponentData(entity, new PhysicsGravityFactor()
    40.         {
    41.             Value = 0f
    42.         });
    43.  
    44.  
    Please help :(
     
  2. slushieboy99

    slushieboy99

    Joined:
    Aug 29, 2014
    Posts:
    88
    Anyone find any solution or documentation for this?
     
  3. MilosNovakovic

    MilosNovakovic

    Joined:
    Jul 24, 2015
    Posts:
    1
    Can you try this? @VrTechEx
    Code (CSharp):
    1. vertices = new NativeArray<float3>(mesh.vertices.Length, Allocator.TempJob);
    2. for (int i = 0; i < mesh.vertices.Length; i++)
    3. {
    4.     vertices[i] = mesh.vertices[i];
    5. }
    6.  
    7. triangles = new NativeArray<int3>(mesh.triangles.Length / 3, Allocator.TempJob);
    8. for (int i = 0; i < mesh.triangles.Length / 3; i += 3)
    9. {
    10.     int3 tmp = new int3
    11.     {
    12.         x = mesh.triangles[i],
    13.         y = mesh.triangles[i + 1],
    14.         z = mesh.triangles[i + 2]
    15.     };
    16.     triangles[i / 3] = tmp;
    17. }
     
    Last edited: Apr 4, 2021
  4. varnon

    varnon

    Joined:
    Jan 14, 2017
    Posts:
    52
    Here is my system for slapping a PhysicsCollider on anything with a RenderMesh.

    Code (CSharp):
    1. Entities
    2.             .WithStructuralChanges()
    3.             .WithAll<ApplyMeshCollider>()
    4.             .ForEach((Entity E, in RenderMesh RM) => {
    5.  
    6.                 NativeArray<BlobAssetReference<Unity.Physics.Collider>> BlobCollider = new NativeArray<BlobAssetReference<Unity.Physics.Collider>>(1, Allocator.TempJob);
    7.                 NativeArray<float3> NVerts = new NativeArray<Vector3>(RM.mesh.vertices, Allocator.TempJob).Reinterpret<float3>();
    8.                 NativeArray<int> NTris = new NativeArray<int>(RM.mesh.triangles, Allocator.TempJob);
    9.  
    10.                 CreateMeshColliderJob CMCJ = new CreateMeshColliderJob{ MeshVerts = NVerts, MeshTris = NTris, BlobCollider = BlobCollider };
    11.                 CMCJ.Run();
    12.  
    13.                 EntityManager.AddComponentData(E, new PhysicsCollider { Value = BlobCollider[0] });
    14.                 NVerts.Dispose();
    15.                 NTris.Dispose();
    16.                 BlobCollider.Dispose();
    17.  
    18.                 EntityManager.RemoveComponent<ApplyMeshCollider>(E);
    19.  
    20.             }).Run();

    And here is the job it uses.

    Code (CSharp):
    1.     [BurstCompile]
    2.     public struct CreateMeshColliderJob : IJob {
    3.  
    4.         [ReadOnly] public NativeArray<float3> MeshVerts;
    5.         [ReadOnly] public NativeArray<int> MeshTris;
    6.         public NativeArray<BlobAssetReference<Unity.Physics.Collider>> BlobCollider;
    7.  
    8.         public void Execute() {
    9.  
    10.             NativeArray<float3> CVerts = new NativeArray<float3>(MeshVerts.Length, Allocator.Temp);
    11.             NativeArray<int3> CTris = new NativeArray<int3>(MeshTris.Length / 3, Allocator.Temp);
    12.  
    13.             for (int i = 0; i < MeshVerts.Length; i++) { CVerts[i] = MeshVerts[i]; }
    14.             int ii = 0;
    15.             for (int j = 0; j < MeshTris.Length; j += 3) {
    16.                 CTris[ii++] = new int3(MeshTris[j], MeshTris[j + 1], MeshTris[j + 2]);
    17.             }
    18.  
    19.             CollisionFilter Filter = new CollisionFilter { BelongsTo = 1, CollidesWith = 1 << 1, GroupIndex = 0 };
    20.  
    21.             BlobCollider[0] = Unity.Physics.MeshCollider.Create(CVerts, CTris, Filter);
    22.             CVerts.Dispose();
    23.             CTris.Dispose();
    24.  
    25.         }
    26.     }

    It isn't optimized, but hopefully this will be helpful.
     
    Enduriel, Ozzieme, FilmBird and 5 others like this.