Создание системы вокселей и застряло, оказавшись в нужде в информации о том, как ее реализовать

Итак, я, вероятно, должен объяснить, как я хочу реализовать это в первую очередь.
Моя идея довольно проста, я хочу создать каждый чанк и определить местоположение каждой вершины, используя сетку с плавающей запятой, локальную для каждого чанка, затем я хочу поместить воксели в большую 64-битную целочисленную сетку (расположение каждого чанка определяется интегральное значение, которое у него есть, 0,0,0 будет серединой, а 20,20,20 — двадцатью частями по осям x, y и z), чтобы создать огромный мир, а затем я выполню некоторую проверку, чтобы определить, как куски будут генерироваться исходя из их местоположения в целочисленной сетке, что я пока не выяснил. (менее важно, чем запустить его)

С чем у меня проблемы:

  1. Изучив, как генерировать трехмерный перлин-шум с помощью libnoise, документация не затронула эту тему из того, что я могу сказать, и я не получаю приличных результатов от запроса Google.
  2. Каким-то образом размещение кусков в целочисленной сетке
  3. точно выяснить, как можно определить, насколько твердым является чанк, исходя из местоположения в сетке (я думаю, это будет просто, если проверить, какие есть окружающие чанки и где в сетке вы находитесь, и определить его на основе этих данных)
  4. Разбрасывать различные руды с редкостью, основываясь на местоположении, выведенном из целочисленной сетки, это довольно просто, но сделать это невозможно, пока другие не будут решены.
  5. вычисление интервальных деревьев.

Итак, есть идеи?
Соответствующий пока код (убрал свет, окклюзию, ультрафиолет и нормальный расчетный код, так как он не имеет отношения к вопросу)

#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, марширующие кубы и некоторые другие вещи, ни одна из которых не решает мою проблему.

1

Решение

Я не уверен, что правильно понял ваш вопрос, но:

  • Вы хотите реализовать мир Voxel, основанный не на полной карте, а на регионах
  • Я не вижу никакой карты в вашем коде (но мог пропустить это)

Я бы сделал это так (в псевдокоде):

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 типа классов объектов для объединения этих подходов

  • используйте лучший подходящий класс для каждого объекта
  • и иметь 3 отдельные карты мира (каждая для каждого класса)

Также, если ваши свойства ячеек постоянны, вы можете создать таблицу элементов (ячеек)

  • и запомните только идентификатор элемента вместо ячейки для каждого вокселя

Надеюсь, это поможет хоть немного.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]