If we start from AoS layout, AoS structs can be easily initialized as such:
struct Position { float x; float y; };
struct Position positions[] = {
{ .x = 1.f, .y = 2.f },
{ .x = 20.f, .y = 30.f },
{ .x = 150.f, .y = 200.f },
{ .x = 1000.f, .y = 2000.f },
};
The data is always grouped as I want, two values in each AoS struct. In memory it looks like:
| 1.f 2.f | 20.f 30.f | 150.f 200.f | 1000.f 2000.f |
If I swap it to SoA layout, SoA data can be just as easily initialized as such:
float position_x[] = { 1.f, 20.f, 150.f, 1000.f },
float position_y[] = { 2.f, 30.f, 200.f, 2000.f };
This data is always grouped as I want it to be, one value in each SoA array. In memory it looks like:
| 1.f 20.f 150.f 1000.f |
| 2.f 30.f 200.f 2000.f |
When it comes to AoSoA layout, it works if the width is fixed, here [2]:
struct Position { float x[2]; float y[2]; };
struct Position positions[] = {
{ .x = { 1.f, 20.f },
.y = { 2.f, 3.f } },
{ .x = { 150.f, 1000.f },
.y = { 200.f, 2000.f } },
};
The grouping here is 2 pairs [2] of 2 values (x,y) in each AoSoA struct. In memory it looks like:
| 1.f 20.f | 150.f 1000.f |
| 2.f 30.f | 200.f 1000.f |
But if I want to change the width to [4], the previous code leaves the AoSoA structs half 'empty'. A AoSoA width of [4] is meant to be used as 4 pairs [4] of 2 values (x,y), but the previous code will still only give me 2 pairs of 2 values in the lower parts of each AoSoA struct, leaving the upper slots of the subarrays empty (initialized to zero). Like this:
| 1.f 20.f ZERO ZERO | 150.f 1000.f ZERO ZERO |
| 2.f 30.f ZERO ZERO | 200.f 1000.f ZERO ZERO |
If I want my data to stay grouped such that all [4] spaces of the subarrays are filled with my data, I have to rewrite the initializer like this:
struct Position { float x[4]; float y[4]; };
struct Position positions[] = {
{ .x = { 1.f, 20.f, 150.f, 1000.f },
.y = { 2.f, 3.0f, 200.f, 2000.f } },
};
And in memory, it will look like this:
| 1.f 20.f 150.f 1000.f |
| 2.f 30.f 200.f 1000.f |
If I change the width of my AoSoA, zeros start showing up in the data, but I want no zeros. I want the data to stay tightly grouped no matter what the width of the AoSoA is. I'm searching for a way to write my initializer such that the data will stay grouped automatically.
Is there a way that would allow me to have an initializer list for my AoSoA data such that I can change the width of the AoSoA and get the desired behavior?