2

I'm trying to flatten a 3 dimensional array of (x,y,z) coordinates to a flatten array.

So here it basically says the solution is;

elements[x][y][z] = Tiles[x + y*WIDTH + Z*WIDTH*DEPTH]

This is all good for me except that the above one prioritise x-coordinate when iterating.

The thing is that while I iterate the array, I mostly linearly access y values. To give an idea all of my iterations are like

        for (int x = -someXVal; x <=  someXVal; x++)
        {
            for (int z = -someZVal; z <= someZVal; z++)
            {
                for (int y = -someYVal; y < someYVal; y++ )
                {

So i want to prioritise y-coordinate in the flatten list so that my linear y-coordinate read/writes will perform better.

I further found some interesting read here, where he basically uses circular flatten array (and yes I also need my array to be circular).

To calculate a pointer to x,y,z coordinate, he uses the following function;

Public Shared Function GetPTR(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As Integer

    Dim bx, bz As Integer

    bx = x Mod BlockBuffWidth
    If bx < 0 Then
      bx += BlockBuffWidth
    End If
    bz = z Mod BlockBuffWidth
    If bz < 0 Then
      bz += BlockBuffWidth
    End If

    Return bx * BMX + bz * BMZ + y

  End Function

I'm really not sure about how he calculates BlockBuffWidth, BMX and BMZ.

The following piece of code is what I came up with;

/// <summary>
/// Flatten offset x step to advance next block in x direction.
/// </summary>
public static readonly int XStep = CacheLenghtInBlocks*Chunk.HeightInBlocks;

/// <summary>
/// Flatten offset z step to advance next block in z direction.
/// </summary>
public static readonly int ZStep = Chunk.HeightInBlocks;

public static int BlockIndexByWorldPosition(int x, byte y, int z)
{
    var wrapX = x%CacheWidthInBlocks;
    if (wrapX < 0)
        wrapX += CacheWidthInBlocks;

    var wrapZ = z%CacheLenghtInBlocks;
    if (wrapZ < 0)
        wrapZ += CacheLenghtInBlocks;

    var flattenIndex = wrapX * XStep + wrapZ * ZStep + y;
    return flattenIndex;
}

and obviously my code doesn't work as expected. Any ideas welcome.

Community
  • 1
  • 1
HuseyinUslu
  • 4,094
  • 5
  • 33
  • 50

1 Answers1

0

So:

elements[x][y][z] = Tiles[x + y*WIDTH + Z*WIDTH*DEPTH]

Is ok for you but you want to group y values next to each other for the same x and z:

elements[x][y][z] = Tiles[y + x*HEIGHT + Z*HEIGHT*DEPTH]

Where HEIGHT = max y + 1

weston
  • 54,145
  • 21
  • 145
  • 203