Search Unity

ECS for HexSphereSubdivision

Discussion in 'Entity Component System' started by RoughSpaghetti3211, May 14, 2019.

  1. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    Hello,

    Im currently porting my game to ECS since I hit a performance limit that ESC can solve.
    In my old system this was a simply two struct arrays (HexTri[] , HexTri[] ).

    Code (csharp):
    1.  
    2.     /// <summary>
    3.     /// HexTri - A Hextri is an element of the dual of the (mostly) hex tiling
    4.     /// This is basically our triangle mesh that we draw hexes on.
    5.     /// </summary>
    6.      public struct HexTri
    7.     {
    8.        public int vertA;                                                        // HexA, indices into the Hextile array
    9.         public int vertB;                                                       // HexB, indices into the Hextile array
    10.         public int vertC;                                                       // HexC, indices into the Hextile array
    11.         public int centerVertex;                                           // Center, indices into the Hextile array
    12.         public int neighborsAccrossAB;                              // HexA, indices into the HexTri array
    13.         public int neighborsAccrossBC;                              // HexA, indices into the HexTri array
    14.         public int neighborsAccrossCA;                              // HexA, indices into the HexTri array
    15.     }
    16.  
    Code (csharp):
    1.  
    2.     /// <summary>
    3.     /// HexTile - A Hextile is a single hex (or sometimes pentagon)
    4.     /// in the hex tiled planet. It is a single vertex of the mesh
    5.     /// </summary>
    6.     public struct HexVert
    7.     {
    8.         public float positionX;                                                 // World X space of this HexTile
    9.         public float positionY;                                                 // World Y space of this HexTile
    10.         public float positionZ;                                                 // World Z space of this HexTile
    11.         public int connectedTriA;                                               //Index into the HexTri array that share this hex
    12.         public int connectedTriB;                                               //Index into the HexTri array that share this hex
    13.         public int connectedTriC;                                               //Index into the HexTri array that share this hex
    14.         public int connectedTriD;                                               //Index into the HexTri array that share this hex
    15.         public int connectedTriE;                                               //Index into the HexTri array that share this hex
    16.         public int connectedTriF;                                               //Index into the HexTri array that share this hex
    17.         #endregion
    18.  
    19.     }
    20.  
    21.  
    Code (csharp):
    1.  
    2.     /// <summary>
    3.     /// Main class for building the HexSphere system.
    4.     /// </summary>
    5.     public class HexSphereSystemBuild
    6.     {
    7.         #region FIELDS ---------------------------------------------------------
    8.  
    9.         public HexVert[] hexVerticies;                                               // The hexes or verts ( center of hexegon)
    10.         public HexTri[] hexTriangles;                                                // The triangles around a hex ( hexegon )
    11.  
    12.         #endregion
    13. ............
    14.  
    Phase 1
    The fist step is to get my hexSphere subdivision working using ECS. So Im starting small by trying to store my subdivisionLevel 0 positions in entities. Im brand new at ECS but want to do this right.

    Goal :)
    Screen Shot 2019-05-13 at 11.13.55 PM.png

    Here is my component date ported form the old struct HexVert. Ive added a index and subdivision. In my old system the int HexTri.neighborsAccrossAB was an index into HexVert. So maybe this should now be public Entity;

    Code (csharp):
    1.  
    2.     /// <summary>
    3.     /// HexTile - A Hextile is a single hex (or sometimes pentagon)
    4.     /// in the hex tiled planet. It is a single vertex of the mesh
    5.     /// </summary>
    6.  
    7.     public struct VertexComponent : IComponentData
    8.     {
    9.         #region FLIELDS --------------------------------------------------------
    10.  
    11.         public int index;
    12.         public float3 position;
    13.  
    14.         #endregion
    15.  
    16.     }
    17.  
    18.     public struct VertexTrianglesComponent : IComponentData
    19.     {
    20.         #region FLIELDS --------------------------------------------------------
    21.  
    22.         public int connectedTriA;                                               //Index into the HexTri array that share this hex
    23.         public int connectedTriB;                                               //Index into the HexTri array that share this hex
    24.         public int connectedTriC;                                               //Index into the HexTri array that share this hex
    25.         public int connectedTriD;                                               //Index into the HexTri array that share this hex
    26.         public int connectedTriE;                                               //Index into the HexTri array that share this hex
    27.         public int connectedTriF;                                               //Index into the HexTri array that share this hex
    28.  
    29.         #endregion
    30.  
    31.     }
    32.  
    33.     public struct VertexSubdivisionComponent : IComponentData
    34.     {
    35.         #region FLIELDS --------------------------------------------------------
    36.  
    37.         public int divisionLevel;
    38.  
    39.         #endregion
    40.  
    41.     }
    42.  
    43.  
    Here is my attempt at storing data into my tileEntities. Im having two problmes.
    1) How do I index this
    2) How do I get my Icosahedron data into an entity.
    Code (csharp):
    1.  
    2.     public struct IcosahedronComponent : IComponentData
    3.     {
    4.         #region FLIELDS --------------------------------------------------------
    5.  
    6.         public static float[] posVtxX = { 0.723606f, 0.0f, -0.723606f, 0.0f, 0.723606f, 0.0f, -0.723606f, 0.0f, 1.17082f, 1.17082f, -1.17082f ,-1.17082f };
    7.         public static float[] posVtxY = { 0.0f, 1.17082f, 0.0f, -1.17082f, 0.0f, -1.17082f, 0.0f, 1.17082f, -0.723606f, 0.723606f, 0.723606f, -0.723606f };
    8.         public static float[] posVtxZ = { 1.17082f, 0.723606f, 1.17082f, 0.723606f, -1.17082f, -0.723606f, -1.17082f, -0.723606f, 0.0f, 0.0f, 0.0f, 0.0f };
    9.  
    10.         #endregion
    11.  
    12.     }
    13.  
    14.  
    Code (csharp):
    1.  
    2.         protected override void OnCreateManager()
    3.         {
    4.             //
    5.             // Create Archetype
    6.             tileArchetype = EntityManager.CreateArchetype
    7.                 (
    8.                 typeof(VertexComponent),
    9.                 typeof(VertexTrianglesComponent),
    10.                 typeof(VertexSubdivisionComponent)
    11.                 );
    12.  
    13.             //
    14.             // Create Entities
    15.             EntityManager.CreateEntity( typeof(IcosahedronComponent) );
    16.  
    17.             //
    18.             // Build Icosahedron
    19.             BuildIcosahedronEntities(1.0f);
    20.         }
    21.  
    22.         /// <summary>
    23.         /// Create the lvl 0 Icosahedron.
    24.         /// </summary>
    25.         private void BuildIcosahedronEntities(float raduis)
    26.         {
    27.             //
    28.             // Create first 12 entities for Icosahedron.
    29.             /// </summary>
    30.             NativeArray<Entity> entityArray = new NativeArray<Entity>(12, Allocator.Temp);
    31.             EntityManager.CreateEntity(tileArchetype, entityArray );
    32.             _query = GetEntityQuery(typeof(VertexSubdivisionComponent), typeof(VertexComponent));
    33.             Entities.With(_query).ForEach<VertexSubdivisionComponent, VertexComponent, VertexTrianglesComponent, IcosahedronComponent>((ref VertexSubdivisionComponent vtxSubDiv, ref VertexComponent vtx, ref VertexTrianglesComponent vtxTri, ref IcosahedronComponent icosahedronData) => {
    34.                 vtxTri.connectedTriA = -1;
    35.                 vtxTri.connectedTriB = -1;
    36.                 vtxTri.connectedTriC = -1;
    37.                 vtxTri.connectedTriD = -1;
    38.                 vtxTri.connectedTriE = -1;
    39.                 vtxTri.connectedTriF = -1;
    40.                 vtxSubDiv.divisionLevel = 0;
    41.                 vtx.index =  ??; i++ // not sure what to do here !!!!!!!!!!!!!!!!
    42.                 vtx.position = ?? // Lost as hell !!!!!!!!!!!!!!!
    43.             });
    44. }
    45.  
    Any help would be appreciate Im trying to get back to where I left off but using ECS Screen Shot 2018-11-14 at 12.05.40 AM.png

    Screen Shot 2018-11-14 at 12.05.40 AM.png
     
    Last edited: May 14, 2019
  2. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    Is it best to just initialize the entities with the Icosahedron one by one not in a ForEach loop
     
  3. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    Best way to initialize large groups of entities usually is with

    EntityManager.CreateEntity(EntityArchetype archetype, NativeArray<Entity> entities)
     
  4. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    Im having a really tough time here lol. Thank you for the reply

    Can I ask you for a simple example on how do get existing data into the Entity using Entities.With(_query).ForEach
    . So for my example I have an array or struct of data I want store into my entities. (Sorry this is really basic stuff but I really want to grasp the concepts of ECS)

    here is what I would normally do

    Code (csharp):
    1.  
    2.  
    3.     public struct VertexComponent
    4.     {
    5.         public int index;
    6.         public float3 position;
    7.     }
    8.  
    9.     hexVerticies = new VertexComponen[12];
    10.     for (int i = 0; i<12; i++)
    11.     {
    12.         hexVerticies[i].index = i;
    13.         hexVerticies[i].position.x = posVtxX[i].x
    14.         ...
    15.     }
    16.  
    17.  
    How would I do it the awesome ECS way
     
  5. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    Ok did it brute force but there surely must be a better way

    Code (csharp):
    1.  
    2.     /// <summary>
    3.     /// System for creating a hexSphere
    4.     /// </summary>
    5.     public class HexSphereBuildSystem : ComponentSystem
    6.     {
    7.         #region FIELDS ---------------------------------------------------------
    8.  
    9.         public static EntityArchetype tileArchetype;
    10.         EntityQuery _query;
    11.  
    12.         #endregion
    13.  
    14.  
    15.         #region METHODS --------------------------------------------------------
    16.  
    17.         /// <summary>
    18.         /// OnUpdate, Must implement for ComponentSystem
    19.         /// </summary>
    20.         protected override void OnUpdate()
    21.         {
    22.             Debug.Log("In system");
    23.         }
    24.  
    25.         /// <summary>
    26.         /// OnCreateManager
    27.         /// </summary>
    28.         protected override void OnCreateManager()
    29.         {
    30.             //
    31.             // Create Archetype
    32.             tileArchetype = EntityManager.CreateArchetype
    33.                 (
    34.                 typeof(VertexComponent),
    35.                 typeof(VertexTrianglesComponent),
    36.                 typeof(VertexSubdivisionComponent)
    37.                 );
    38.  
    39.             //
    40.             // Build Icosahedron
    41.             BuildIcosahedronEntities(1.0f);
    42.         }
    43.  
    44.         /// <summary>
    45.         /// Create the lvl 0 Icosahedron.
    46.         /// </summary>
    47.         private void BuildIcosahedronEntities(float raduis)
    48.         {
    49.  
    50.             //
    51.             // Hard code an icosahedron verticies (20 sided die)
    52.  
    53.             Entity tileEntity = EntityManager.CreateEntity(tileArchetype);
    54.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 0, position = new float3(0.723606f, 0.0f, 1.17082f) });
    55.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    56.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent {divisionLevel = 0 });
    57.  
    58.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    59.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 1, position = new float3(0.0f, 1.17082f, 0.723606f) });
    60.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    61.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    62.  
    63.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    64.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 2, position = new float3(-0.723606f, 0.0f, 1.17082f) });
    65.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    66.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    67.  
    68.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    69.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 3, position = new float3(0.0f, -1.17082f, 0.723606f) });
    70.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    71.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    72.  
    73.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    74.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 4, position = new float3(0.723606f, 0.0f, -1.17082f) });
    75.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    76.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    77.  
    78.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    79.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 5, position = new float3(0.0f, -1.17082f, -0.723606f) });
    80.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    81.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    82.            
    83.            tileEntity = EntityManager.CreateEntity(tileArchetype);
    84.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 6, position = new float3(-0.723606f, 0.0f, -1.17082f) });
    85.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    86.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    87.  
    88.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    89.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 7, position = new float3(0.0f, 1.17082f, -0.723606f) });
    90.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    91.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    92.  
    93.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    94.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 8, position = new float3(1.17082f, -0.723606f, 0.0f) });
    95.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    96.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    97.  
    98.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    99.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 9, position = new float3(1.17082f, 0.723606f, 0.0f) });
    100.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    101.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    102.  
    103.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    104.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 10, position = new float3(-1.17082f, 0.723606f, 0.0f) });
    105.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    106.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    107.  
    108.             tileEntity = EntityManager.CreateEntity(tileArchetype);
    109.             EntityManager.SetComponentData(tileEntity, new VertexComponent { index = 11, position = new float3(-1.17082f, -0.723606f, 0.0f) });
    110.             EntityManager.SetComponentData(tileEntity, new VertexTrianglesComponent { connectedTriA = -1, connectedTriB = -1, connectedTriC = -1, connectedTriD = -1, connectedTriE = -1, connectedTriF = -1 });
    111.             EntityManager.SetComponentData(tileEntity, new VertexSubdivisionComponent { divisionLevel = 0 });
    112.  
    113.  
    114.             //
    115.             // Hard code an icosahedron triangles (20 sided die)
    116.  
    117.         }
    118.  
    119.         #endregion
    120.  
    121.     }
    122.  
    123.