2013-08-29 2 views
1

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

Что я имею проблемы с:

  1. Выяснить, как создавать 3D Перлин шума с 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, это потому, что много кода было написано после прочтения, и это отчасти от меня пошло

Проблема в том, что она, похоже, не охватывает мои проблемы, это дало мне несколько лучшее понимание того, как работают вокселы, вот и все.

Итак, какие-либо указания на то, как я должен решить этот проект?

P.S, это так много клона minecraft, поскольку Battlefield 3 является клоном DOOM, я думаю, что позволю вам решить, как это интерпретировать.

О, и я сделал мое исследование, я нашел: посты на 0к, я уверен, что большинство из вас знакомы с блогом https://sites.google.com/site/letsmakeavoxelengine и несколько других, включая GPU самоцветов 3, марширующих кубов и несколько другие вещи, ни одна из которых не решает мою проблему.

+2

Есть ли причина, по которой вам нужно написать такие отвратительные макросы, которые легко заменить на функцию? – thokra

+0

Ну да, я написал их для быстрого прототипирования, они будут заменены, когда код работает. – LordHexahedron

+0

yep, но отладка кода с помощью макросов - это головная боль ... – Spektre

ответ

0

Я не уверен, что я получаю это прямо из вашего вопроса, но:

  • Вы хотите реализовать 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.sparse заселена

// instead of int xs,ys,zs; 
// instead of cell *map; 
List<cell> map; 
List<int[3]> pos; // position inside object 

3.or вы можете иметь 3 вида классов объектов для объединения этих подходов

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

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

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

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

+0

О, я на самом деле не помню, каково было мое первоначальное намерение (Я обвиняю плохую документацию на моем конце), кроме мира, основанного на вокселе, который был по крайней мере 2⁶⁴-1 вокселей в каждой из кардинальных осей (axii?), Предпочтительно ограничиваясь только отсутствующей оперативной памятью хост-машины (хотя я могу " т для жизни меня выяснить способ решить его). EDIT: О, и я хотел разрешить летающие острова в особых условиях, но это было бы тривиально реализовать, как только у меня будет мой огромный мир вокселей) Я должен использовать лучшую документацию ... – LordHexahedron

+0

О, верно, я помню, каково было мое намерение>.> Как-то выравнивание нескольких областей вокселей и объединение краевых кусков, чтобы получить супермир, который мог бы охватить теоретическое бесконечное пространство, учитывая достаточный барабан, теперь я не знаю, как это сделать this>.> (и я не знаю, будет ли это хорошим способом обойти ограничения по размеру типов данных, я могу хранить только столько мест в float, double или integer (любого типа)) – LordHexahedron