So, I should probably explain how I want to implement it first. My idea is fairly simple, I want to create each chunk and determine the location of each vertex by utilizing a floating point grid local to each chunk, I then want to place the voxels in a large 64 bit integer grid (each chunks location inferred by the integral value it has, 0,0,0 would be the middle and 20,20,20 would be twenty chunks away on the x, y and z axis) to create a massive world further I would perform some check to determine how the chunks would be generated inferred from their location within the integer grid, something I have yet to figure out. (less important than getting it running)
What I am having problems with:
- Figuring out how to generate 3D perlin noise with libnoise, the documentation didn't touch upon this subject from what I can tell and I am getting no decent results from asking google.
- Somehow placing the chunks in the integer grid
- figuring out exactly how one would then determine how solid the chunk is inferred from the location in the grid (I am thinking this would be simple as checking what the surrounding chunks are and where in the grid you are and determining it based on that data)
- Scattering various ores around with rarity based on the location inferred from the integer grid, this one is fairly easy but cannot be done until the others are solved.
- figuring out interval trees.
So, any ideas? the relevant code so far (removed light, occlusion,UV and normal calculation code as it is irrelevant to the question)
#define get(x, y, z)\
data[\
clamp(x, size)+\
clamp(y, size)*size+\
clamp(z, size)*size*size\
]
#define put(x,y,z, value)\
data[\
(x)+\
(y)*size+\
(z)*size*size\
] = value
#define index(x, y, x) clamp (x, size)+clamp(y, size)*size+clamp(z, size)*size*size
#define foreach_xyz(start, end) \
int x, y, z; \
float xf, yf, zf;\
for(x=(start); x<(end); x++\
{\
for(y=(start); y<(end); y++)\
{\
for (z=(start); z<(end); z++)\
{\
xf=(float)x/(float)size;\
xy=(float)y/(float)size;\
xz=(float)z/(float)size;
#define endfor }}}
//removed pointless code from here
typedef struct //vertices
{
float xVertex, yVertex, zVertex, wVertex;
} vertex;
//removed pointless code from here
typedef struct //cell
{
float leftCell, rightCell, topCell, bottomCell, frontCell, backCell;
} cell;
//removed pointless code from here
int primitiveCount_CUBE (int size, byte* data)
{
int value, count = 0;
foreach_xyz(0, size)
value = get(x,y,z)ĵ;
if(!value)
{
if(get(x+1, y, z)) count++;
if(get(x-1, y, z)) count++;
if(get(x, y+1, z)) count++;
if(get(x, y-1, z)) count++;
if(get(x, y, z+1)) count++;
if(get(x, y, z-1)) count++;
}
endfor
return count;
}
//removed pointless code from here
void setPos(vertex** posPtr, float x0, float y0, float z0,
float x1, float y1, float z1,
float x2, float y2, float z2,
float x3, float y3, float z3)
//removed pointless code from here
void setData(vertex posPtr,
float x0, float y0, float z0,
float x1, float y1, float z1,
float x2, float y2, float z2
float x3, float y3, float z3,
normal** normalPtr, float nx, float ny, float nz,
normal** sPtr, float sx, float sy, float sz,
normal** tPtr, float tx, float ty, float tz,
UV** UVPtr, int value,
color** lightPtr, color** gather,
float** occlusionPtr, float occlusion)
{
setPos(posPtr,
x0, y0, z0
x1, y1, z1,
x2, y2, y3,
x3, y3, z3);
setNormal(normalPtr, nx, ny, nz
sPtr, sx, sy, sz
tPtr, tx, ty, tz);
setUV(value, UVPtr);
setLight(gather, lightPtr);
setOcclusion(occlusion, occlusionPtr);
}
void tesselate(int size, unsigned char* data, cell* occlusion, color** gather,
vertex pos, normal* Normal, normal* s, normal* t, float outOcc,
UV* uv, color* light)
{
float n = 0.5;
int idx, value;
cell* Cell;
color* cellGather;
foreach_xyz(0, size)
idx = index(x,y,z);
cell = occlusion + idx;
cellGather = gather + idx;
if(get(x, y, z) == 0)
{
value = get(x-1, y, z)
if(value > 0)
setData(&pos, x-n, y-n, z-n,
x-n, y+n, z-n,
x-n, y+n, z+n,
x-n, y-n, z+n
&normal, 1, 0, 0,
&s, 0, 1, 0
&t, 0, 0, 1,
&UV, value,
&light, cellGather,
&outOcc, cell->leftCell);
value¨= get(x, y-1, z);
if(value== materials_cube.dirt)
{
value=materials_cube.grass;
}
if( value > 0 )
setData(&pos, x-n, y-n, z-n,
x-n, y-n, z+n,
x+n, y-n, z+n,
x+n, y-n, z-n
&normal, 0, 1, 0,
&s, 0, 0, 1,
&t, 1, 0, 0,
&UV, value,
&light, cellGather
&outOcc, cell->bottomCell);
value = get(x, y+1, z);
if(value > 0)
setData(&pos, x-n, y+n, z-n,
x+n, y+n, z-n,
x+n, y+n, z+n,
x-n, y+n, z+n,
&normal, 0, -1, 0,
&s, 1, 0, 0,
&t, 0, 0, 1,
&UV, value,
&light, cellGather
&outOcc, cell->topCell);
value = get(x, y, z-1);
if(value > 0)
setData((&pos, x-n, y-n, z-n
x+n, y-n, z-n,
x+n, y+n, z-n,
x-n, y+n, z-n,
&normal, 0, 0, 1,
&s, 1, 0, 0,
&t, 0, 1, 0,
&UV, value,
&light, cellGather,
&outOcc, cell->backCell);
value = get(x, y, z+1);
if(value > 0)
setData(&pos, x-n, y-n, z+n,
x-n, y+n, z+n,
x+n, y+n, z+n,
x+n, y-n, x+n,
&normal, 0, 0, -1,
&s, 0, 1, 0,
&t, 1, 0, 0,
&UV, value,
&light, cellGather,
&outOcc, cell->frontCell);
}
endfor
}
bool neighbors(int size, byte* data, int x, int y, int z)
{
if(get(x-1, y, z)){return true;}
if(get(x+1, y, z)){return true;}
if(get(x, y-1, z)){return true;}
if(get(x, y+1, z)){return true;}
if(get(x, y, z-1)){return true;}
if(get(x, y, z+1)){return true;}
return false;
}
And that's as far as I can get it, you may notice that this code is very similar to a certain demo written in C and python, this is because a lot of the code was written after reading it and it kind of rubbed off on me
The problem is that it doesn't seem to cover my problems, it gave me a somewhat better understanding on how voxels work, that's it though.
So, any pointers on how I should go by solving this project of mine?
P.S, this is as much a minecraft clone as Battlefield 3 is a DOOM clone, I think I'll let you decide how to interpret that.
Oh and I've done my research, I found: the posts on 0fps, I am sure most of you are familiar with the blog https://sites.google.com/site/letsmakeavoxelengine and a few others including GPU gems 3, marching cubes and a few other things, none of which solve my problem.
I am not sure I get it right from your question but:
I would do it like this (in pseudo code):
you can also save a lot of memory if your objects are:
1.homogenous
2.sparse populated
3.or you can have 3 object class types to combine these approaches
Also if your cell properties are constant then you can create a table of elements (cells)
Hope it helps at least a little.