2016-08-16 2 views
2

J'ai une question simple. Comment est-ce que je peux décaler un tableau linéaire en 3 dimensions? Cela semble trop de travail mais dans l'axe Y de X & j'ai eu un problème d'index. Le reson pourquoi je veux faire ceci est simple. Je veux créer un terrain volumétrique avec un tampon de bloc, donc je n'ai qu'à recalculer les valeurs sur les bords quand la fenêtre est en mouvement.Array Shifting/Mauvais Index/i = [x + y * taille + z * taille * taille]

J'ai lu un article sur ce système:

Essentiellement, ils fournissent un moyen de faire défiler une des données potentiellement infinies champ par une taille fixe cache multi-résolution.

Donc, mon Pipline pour la partie génération serait:

  1. Lorsque viewport se déplace obtenir axe
  2. décalage de l'axe
  3. Générez un peu de bruit que pour les nouvelles cellules
  4. Trianguler la nouvelle cellules
  5. Mettre à jour toutes les positions de cellule

enter image description here

Voici mes autres images: http://forum.unity3d.com/threads/array-shifting-wrong-index-i-x-y-size-z-size-size.425448/#post-2751774

Personne dans les forums de l'unité pourrait répondre à ma question ...

public int size; 
public float speed; 

private byte[] volume; 
private byte[] shifted; 

public bool widthShift, heightShift, depthShift; 

private int widthOffset = 0; 
private int heightOffset = 0; 
private int depthOffset = 0; 

private float time = 0; 
private int cube; 

void Start() 
{ 
    volume = new byte[size * size * size]; 
    shifted = new byte[size * size * size]; 

    cube = size * size * size; 

    for (int x = 0; x < size; x++) 
     for (int y = 0; y < size; y++) 
      for(int z = 0; z < size; z++) 
       volume[x + y * size + z * size * size] = (x == 0 || y == 0 || z == 0) ? (byte)1 : (byte)0; 
} 

void Update() 
{ 
    time += Time.fixedDeltaTime * speed; 

    if (time > 1) 
    { 
     time = 0; 

     widthOffset = (widthOffset >= size) ? 0 : widthOffset; 
     heightOffset = (heightOffset >= size) ? 0 : heightOffset; 
     depthOffset = (depthOffset >= size) ? 0 : depthOffset; 

     if (widthShift) 
      widthOffset++; 
     else 
      widthOffset = 0; 

     if (heightShift) 
      heightOffset++; 
     else 
      heightOffset = 0; 

     if (depthShift) 
      depthOffset++; 
     else 
      depthOffset = 0; 

     Shift(widthOffset, heightOffset, depthOffset); 
    } 
} 

void Shift(int xOff, int yOff, int zOff) 
{ 
    for (int x = 0; x < size; x++) 
     for (int y = 0; y < size; y++) 
      for(int z = 0; z < size; z++) 
      { 
       int i = ((x + xOff) + (y + yOff) * size + (z + zOff) * size * size); 
       i = (i >= cube) ? (i - cube) : i; 

       shifted[x + y * size + z * size * size] = volume[i]; 
      } 
} 

void OnDrawGizmos() 
{ 
    if(Application.isPlaying) 
     for(int x = 0; x < size; x++) 
      for(int y = 0; y < size; y++) 
       for(int z = 0; z < size; z++) 
       { 
        Gizmos.color = (shifted[x + y * size + z * size * size] == 1) ? new Color32(0, 255, 0, 255) : new Color32(255, 0, 0, 4); 
        Gizmos.DrawWireCube(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f), new Vector3(0.95f, 0.95f, 0.95f)); 
       } 
} 
+0

Je dois dire, pour un nouvel utilisateur, cette question était vraiment nous ll formaté et demandé. Pas quelque chose que je vois trop souvent en passant par les files d'attente d'examen. :) Bienvenue à la pile de débordement! –

Répondre

2

Donnez un essai:

void Shift(int xOff, int yOff, int zOff) 
{ 
    for (int x = 0; x < size; x++) 
     for (int y = 0; y < size; y++) 
      for(int z = 0; z < size; z++) 
      { 
       int nx = (x + xOff) % size; 
       int ny = (y + yOff) % size; 
       int nz = (z + zOff) % size; 
       int i = (nx + ny * size + nz * size * size); 

       shifted[x + y * size + z * size * size] = volume[i]; 
      } 
} 
+0

fonctionne comme un charme! – Michael

+1

@Michael Si c'est le cas, marquez-le comme réponse acceptée – galenus

+0

sacrément cool! – Fattie