https://bitbucket.org/BWerness/voxel-automata-terrain/src/master/ThreeState3dBitbucket.pde [bitbucket.org]
Here is my version in VEX. Something still seems to be failing.
#define L 6 #define K shl(1,L)+1 //array multipliers #define MI 1 #define MJ (K-1) #define MK (K-1)*(K-1) //rules #define CUBERULE "111100110012200211210222110022200200222220000111100110012200211210222110022200200222220000" #define FACERULE "11011101112221022121020000001101110111222102212102000000" #define EDGERULE "11112122112210022020022202001111212211221002202002220200" //three-dimensional array index i@i=@ptnum%(K-1); i@j@ptnum/(K-1))%(K-1); i@k@ptnum/(K-1))/(K-1); @i*=MI; @j*=MJ; @k*=MK; void evalCube(int i, j, k, w){ if((i < 0) || (j < 0) || (k < 0) || (i+w >= K) || (k+w >= K)) return; int idx1 = point(0,"state",i+j+k)==1?1:0 + point(0,"state",i+(w*MI)+j+k)==1?1:0 + point(0,"state",i+j+(w*MJ)+k)==1?1:0 + point(0,"state",i+(w*MI)+j+(w*MJ)+k)==1?1:0 + point(0,"state",i+j+k+(w*MK))==1?1:0 + point(0,"state",i+(w*MI)+j+k+(w*MK))==1?1:0 + point(0,"state",i+j+(w*MJ)+k+(w*MK))==1?1:0 + point(0,"state",i+(w*MI)+j+(w*MJ)+k+(w*MK))==1?1:0; int idx2 = point(0,"state",i+j+k)==2?1:0 + point(0,"state",i+(w*MI)+j+k)==2?1:0 + point(0,"state",i+j+(w*MJ)+k)==2?1:0 + point(0,"state",i+(w*MI)+j+(w*MJ)+k)==2?1:0 + point(0,"state",i+j+k+(w*MK))==2?1:0 + point(0,"state",i+(w*MI)+j+k+(w*MK))==2?1:0 + point(0,"state",i+j+(w*MJ)+k+(w*MK))==2?1:0 + point(0,"state",i+(w*MI)+j+(w*MJ)+k+(w*MK))==2?1:0; setpointattrib(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k+(w*MK/2),int(atoi(CUBERULE[(9*idx1)+idx2]))); } void f1(int i, j, k, w){ if ((i < 0) || (j < 0) || (k-w/2 < 0) || (i+w >= K) || (j+w >= K) || (k+w/2 >= K)) return; int idx1 = point(0,"state",i+j+k)==1?1:0 + point(0,"state",i+(w*MI)+j+k)==1?1:0 + point(0,"state",i+j+(w*MJ)+k)==1?1:0 + point(0,"state",i+(w*MI)+j+(w*MJ)+k)==1?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k-(w*MK/2))==1?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k+(w*MK/2))==1?1:0; int idx2 = point(0,"state",i+j+k)==2?1:0 + point(0,"state",i+(w*MI)+j+k)==2?1:0 + point(0,"state",i+j+(w*MJ)+k)==2?1:0 + point(0,"state",i+(w*MI)+j+(w*MJ)+k)==2?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k-(w*MK/2))==2?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k+(w*MK/2))==2?1:0; setpointattrib(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k,int(atoi(CUBERULE[(9*idx1)+idx2]))); } void f2(int i, j, k, w){ if ((i < 0) || (j-w/2 < 0) || (k < 0) || (i+w >= K) || (j+w/2 >= K) || (k+w >= K)) return; int idx1 = point(0,"state",i+j+k)==1?1:0 + point(0,"state",i+(w*MI)+j+k)==1?1:0 + point(0,"state",i+j+k+(w*MK))==1?1:0 + point(0,"state",i+(w*MI)+j+k+(w*MK))==1?1:0 + point(0,"state",i+(w*MI/2)+j-(w*MJ/2)+k+(w*MK/2))==1?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k+(w*MK/2))==1?1:0; int idx2 = point(0,"state",i+j+k)==2?1:0 + point(0,"state",i+(w*MI)+j+k)==2?1:0 + point(0,"state",i+j+(w*MJ)+k)==2?1:0 + point(0,"state",i+(w*MI)+j+(w*MJ)+k)==2?1:0 + point(0,"state",i+(w*MI/2)+j-(w*MJ/2)+k+(w*MK/2))==2?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k+(w*MK/2))==2?1:0; setpointattrib(0,"state",i+(w*MI/2)+j+k+(w*MK/2),int(atoi(CUBERULE[(9*idx1)+idx2]))); } void f3(int i, j, k, w){ if ((i-w/2 < 0) || (j < 0) || (k < 0) || (i+w/2 >= K) || (j+w >= K) || (k+w >= K)) return; int idx1 = point(0,"state",i+j+k)==1?1:0 + point(0,"state",i+j+k+(w*MJ))==1?1:0 + point(0,"state",i+j+(w*MJ)+k)==1?1:0 + point(0,"state",i+j+(w*MJ)+k+(w*MK))==1?1:0 + point(0,"state",i-(w*MI/2)+j+(w*MJ/2)+k+(w*MK/2))==1?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k+(w*MK/2))==1?1:0; int idx2 = point(0,"state",i+j+k)==2?1:0 + point(0,"state",i+j+k+(w*MJ))==2?1:0 + point(0,"state",i+j+(w*MJ)+k)==2?1:0 + point(0,"state",i+j+(w*MJ)+k+(w*MK))==2?1:0 + point(0,"state",i-(w*MI/2)+j+(w*MJ/2)+k+(w*MK/2))==2?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k+(w*MK/2))==2?1:0; setpointattrib(0,"state",i+j+(w*MJ/2)+k+(w*MK/2),int(atoi(CUBERULE[(9*idx1)+idx2]))); } void f4(int i, j, k, w){ f1(i,j,k+w,w); } void f5(int i, j, k, w){ f1(i,j+w,k,w); } void f6(int i, j, k, w){ f1(i+w,j,k,w); } void evalFaces(int i, j, k, w){ f1(i,j,k,w); f2(i,j,k,w); f3(i,j,k,w); f4(i,j,k,w); f5(i,j,k,w); f6(i,j,k,w); } void e1(int i, j, k, w){ if ((i < 0) || (j-w/2 < 0) || (k-w/2 < 0) || (i+w >= K) || (j+w/2 >= K) || (k+w/2 >= K)) return; int idx1 = point(0,"state",i+j+k)==1?1:0 + point(0,"state",i+(w*MI)+j+k)==1?1:0 + point(0,"state",i+(w*MI/2)+j-(w*MJ/2)+k)==1?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k)==1?1:0 + point(0,"state",i+(w*MI/2)+j+k+(w*MK/2))==1?1:0 + point(0,"state",i+(w*MI/2)+j+k-(w*MK/2))==1?1:0; int idx2 = point(0,"state",i+j+k)==2?1:0 + point(0,"state",i+(w*MI)+j+k)==2?1:0 + point(0,"state",i+(w*MI/2)+j-(w*MJ/2)+k)==2?1:0 + point(0,"state",i+(w*MI/2)+j+(w*MJ/2)+k)==2?1:0 + point(0,"state",i+(w*MI/2)+j+k+(w*MK/2))==2?1:0 + point(0,"state",i+(w*MI/2)+j+k-(w*MK/2))==2?1:0; setpointattrib(0,"state",i+(w*MI/2)+j+k,int(atoi(CUBERULE[(9*idx1)+idx2]))); } void e2(int i, j, k, w){ e1(i,j+w,k,w); } void e3(int i, j, k, w){ e1(i,j,k+w,w); } void e4(int i, j, k, w){ e1(i,j+w,k+w,w); } void e5(int i, j, k, w){ e1(i-w/2,j+w/2,k,w); } void e6(int i, j, k, w){ e1(i+w/2,j+w/2,k,w); } void e7(int i, j, k, w){ e1(i-w/2,j+w/2,k+w,w); } void e8(int i, j, k, w){ e1(i+w/2,j+w/2,k+w,w); } void evalEdges(int i, j, k, w){ e1(i,j,k,w); e2(i,j,k,w); e3(i,j,k,w); e4(i,j,k,w); e5(i,j,k,w); e6(i,j,k,w); e7(i,j,k,w); e8(i,j,k,w); } for(int w=K-1; w>=2; w/=2){ evalCube(@i,@j,@k,w); evalFaces(@i,@j,@k,w); evalEdges(@i,@j,@k,w); }