Итак, я, вероятно, должен объяснить, как я хочу реализовать это в первую очередь.
Моя идея довольно проста, я хочу создать каждый чанк и определить местоположение каждой вершины, используя сетку с плавающей запятой, локальную для каждого чанка, затем я хочу поместить воксели в большую 64-битную целочисленную сетку (расположение каждого чанка определяется интегральное значение, которое у него есть, 0,0,0 будет серединой, а 20,20,20 — двадцатью частями по осям x, y и z), чтобы создать огромный мир, а затем я выполню некоторую проверку, чтобы определить, как куски будут генерироваться исходя из их местоположения в целочисленной сетке, что я пока не выяснил. (менее важно, чем запустить его)
С чем у меня проблемы:
Итак, есть идеи?
Соответствующий пока код (убрал свет, окклюзию, ультрафиолет и нормальный расчетный код, так как он не имеет отношения к вопросу)
#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;
}
И это насколько я могу понять, вы можете заметить, что этот код очень похож на определенную демонстрацию, написанную на C и Python, потому что большая часть кода была написана после прочтения, и это как бы оттирает мне
Проблема в том, что это, кажется, не покрывает мои проблемы, это дало мне немного лучшее понимание того, как работают воксели, вот и все.
Итак, какие-либо указания о том, как я должен идти, решая этот мой проект?
П.С., это такой же клон Minecraft, как Battlefield 3 — клон DOOM, думаю, я позволю вам решить, как это интерпретировать.
Ох, и я сделал свое исследование, я нашел:
посты на 0fps, я уверен, что большинство из вас знакомы с блогом
https://sites.google.com/site/letsmakeavoxelengine
и несколько других, в том числе графические процессоры 3, марширующие кубы и некоторые другие вещи, ни одна из которых не решает мою проблему.
Я не уверен, что правильно понял ваш вопрос, но:
Я бы сделал это так (в псевдокоде):
class cell
{
public:
// physical properties
float m,Q; // unit mass ,charge, ...
float c0,c1,c2; // friction indexes (could determine if it is liquid,gas or solid
float p[3],v[3],a[3]; // position,velocity,acceleration 3D
};
class object // or region
{
public:
int x0,y0,z0; // obj origin (center preferably)
int xs,ys,zs; // obj size in cells
cell *map; // *map[xs*ys*za] or ***map[xs][ys][zs] do not forget to write dynamic allocation/free resize ...
};
List<object> world; // list of all objects/regions
Вы также можете сэкономить много памяти, если ваши объекты:
1.homogenous
// instead of cell *map;
cell properties; // single property class for whole object
bool *map; // just a bit map if voxel is empty or occupied by cell
2. разреженный
// instead of int xs,ys,zs;
// instead of cell *map;
List<cell> map;
List<int[3]> pos; // position inside object
3. или вы можете иметь 3 типа классов объектов для объединения этих подходов
Также, если ваши свойства ячеек постоянны, вы можете создать таблицу элементов (ячеек)
Надеюсь, это поможет хоть немного.
Других решений пока нет …