Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

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:
    74
    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.
     
    Ozzieme, FilmBird, Goularou and 4 others like this.