2

(x、y、z) 座標の 3 次元配列を平坦化配列に平坦化しようとしています。

したがって、ここでは基本的に解決策は次のとおりです。

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

上記のものは反復時にx座標を優先することを除いて、これは私にとってはすべて良いことです。

問題は、配列を反復している間、ほとんどの場合 y 値に線形にアクセスすることです。アイデアを与えるために、私のすべての反復は次のようになります

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

したがって、フラット化リストで y 座標を優先して、線形 y 座標の読み取り/書き込みのパフォーマンスが向上するようにします。

ここで、彼は基本的に円形のフラット化配列を使用しています(そして、配列を円形にする必要もあります)

x、y、z 座標へのポインターを計算するために、彼は次の関数を使用します。

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

彼がどのように BlockBuffWidth、BMX、BMZ を計算しているのか、私にはよくわかりません。

次のコードは、私が思いついたものです。

/// <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;
}

明らかに、私のコードは期待どおりに機能しません。どんなアイデアでも大歓迎です。

4

1 に答える 1

0

そう:

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

あなたには問題ありませんが、同じandyの値を隣り合わせにグループ化する必要があります。xz

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

どこHEIGHT = max y + 1

于 2013-01-08T13:14:08.783 に答える