Search Unity

Collisions with polygons in ECS

Discussion in 'Entity Component System' started by HerpeDerpeDerp, Nov 15, 2018.

  1. HerpeDerpeDerp

    HerpeDerpeDerp

    Joined:
    Nov 15, 2018
    Posts:
    3
    So I've been messing around with ECS + jobs a bit and looking through some examples and although I can find many examples of checking for collisions with spheres, cubes and other simple shapes described by a fixed number of values, I haven't found anything for shapes with a variable number of values describing it such as polygons in 2d and polyhedrons in 3d.

    The specific scenario I have in mind is having a number of line pieces and a number of polygons and I want to find all intersections (or the intersection closest to a specific vertex of the line piece) of line pieces with edges of the polygons. A simple pure ECS way of doing this would be to create entities for all edges of the polygons and simply check all line pieces against all edges. However, for my case the polygons can have hundreds or thousands of edges but will never be very large so first checking the line pieces against the bounding boxes of the polygons should eliminate almost all with only a fraction of the computation time.

    To do this in OOP, you would have polygon objects with a reference to an array of vertices. You'd iterate over all line piece-polygon pairs and first do the broad check. If that doesn't exclude an intersection, then you check the line piece against the edges in the referenced array. My question is: How would this translate to ECS? How do I associate a variable number of edges with a polygon and only process line piece-edge pairs for which the line piece-bounding box test failed?

    If anyone can help me out with this I would be really grateful. I seem to be having a hard time writing anything other than object oriented code
     
  2. MegamaDev

    MegamaDev

    Joined:
    Jul 17, 2017
    Posts:
    77
    Not sure how one would go about implementing Bounding Box/polyline intersection tests in ECS, but I do know that ECS has Dynamic Buffers to behave as component-mounted arrays/Lists. The syntax is a bit unintuitive, though, but the docs explain it pretty well.

    Just in case, though, here's my shot at explaining for you.

    To create a dynamic buffer, you first have to create a struct representing a single member of the buffer. The data-type struct, as I'll call it, also defines the default capacity of the array.
    Code (CSharp):
    1. //If not tagged like so, will default to 128 divided by the struct's size in bytes.
    2. [InternalBufferCapacity(8)]
    3. public struct PolygonVertex : IBufferElementData {
    4.      public float3 Position
    5. }
    The system does require this. Were it not so, we would be limited to one float3 buffer per entity--and also wouldn't be able to do this:
    Code (CSharp):
    1. //Inclusion in archetypes--seems like just what you're after.
    2. EntityArchetype foo = new EntityArchetype(typeof(PolygonVertex) );
    Of course, you can also add buffers to existing entities:
    Code (CSharp):
    1. entityManager.AddBuffer<PolygonVertex>(entity);
    And then when you need to do the intersection tests, just inject a BufferArray<PolygonVertex> into your system/job, and use it about as normal (though you do have to access the buffers the way you access individual non-buffer components):
    Code (CSharp):
    1. public class FooSystem : ComponentSystem {
    2.      struct Data {
    3.           public readonly int Length;
    4.           [ReadOnly] public ComponentDataArray<FooComponent> foo;
    5.           [ReadOnly] public BufferArray<PolygonVertex> verts;
    6.      }
    7.      [Inject] Data data;
    8.  
    9.      protected override void OnUpdate () {
    10.           for (int i = 0; i < data.Length; i++) {
    11.                Debug.Log("FooComponent " + i + "'s value is " + data.foo[i].Value);
    12.                Debug.Log("Polygon vertex array on entity " + i + " is " +
    13.                     data.verts[i].Length + " elements long");
    14.                if (data.verts[i].Length > 0)
    15.                     Debug.Log("Polygon vertex 0 on entity " + i +
    16.                          " is at position " + data.verts[i][0]);
    17.                //For the record, I've never actually used this feature--I don't know the exact syntax of counting the elements, or if you access the actual buffer with an indexer [0]!
    18.           }
    19.      }
    20. }
    Please do pardon my unconventional formatting. I'm proud of it, but I do worry that it may be hard to read sometimes~
     
    Last edited: Nov 17, 2018
    HerpeDerpeDerp likes this.
  3. Zooltan

    Zooltan

    Joined:
    Jun 14, 2013
    Posts:
    19
    You should have a look at this https://github.com/PhilSA/ECSPhysics

    There is also a long post about it here on the forums. It's basically an attempt at making rigidbody physics, like the ones we know in normal Unity, but in pure ECS and Jobs. I've stolen some ideas from it already :)
     
  4. HerpeDerpeDerp

    HerpeDerpeDerp

    Joined:
    Nov 15, 2018
    Posts:
    3
    MegameDev, thank you! That seems to be exactly what I was looking for.

    Zooltan, I looked at that before, but as far as I could see it only supports (or has that changed by now?) shapes so far that have a fixed amount of information that describes them. What I am asking about is shapes with a variable amount of information describing them, because then you can't just use normal components for it
     
    MegamaDev likes this.