2013-08-29 33 views
1

所以,我应该解释一下我想如何实现它。 我的想法非常简单,我想创建每个块并通过利用每个块本地的浮点网格来确定每个顶点的位置,然后我想将体素放置在一个大的64位整数网格中(每个块的位置推断通过它的整数值,0,0,0将是中间值,20,20,20将在x,y和z轴上离开二十个块)以创建一个更大的世界,我将执行一些检查来确定块将从它们在整数网格中的位置推断出来,这是我还没有弄清楚的。 (比得到它的运行不那么重要)创建体素系统并陷入困境,发现自己需要关于如何实现它的信息

什么我有问题:

  1. 搞清楚如何生成libnoise 3D Perlin杂,文件并没有在这个问题从我可以告诉碰并且我没有得到谷歌要求的体面结果。
  2. 以某种方式将块放置在整数网格中
  3. 搞清楚如何确定从网格中的位置推断块的固定程度(我认为这很简单,因为检查周围的块是什么和在这个网格中,根据这些数据确定它)
  4. 根据从整数网格推断出的位置稀疏地分散各种矿石,这一个相当简单,但是直到其他解决方案才能完成。
  5. 找出间隔树。

那么,有什么想法? 的相关到目前为止的代码(除去轻,闭塞,UV和正常计算的代码,因为它是无关的问题)

#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,这是一个和“战地3”是DOOM克隆的Minecraft克隆一样多,我想我会让你决定如何解释它。

哦,我做我的研究,我发现: 上0fps的职位,我相信大多数人都熟悉的博客 https://sites.google.com/site/letsmakeavoxelengine 和其他几个人,包括GPU的宝石3,踏着多维数据集和几个其他的事情,其中​​没有一个解决我的问题。

+2

是否有一个原因,你需要编写这种可以很容易地被函数替换的丑陋的宏? – thokra

+0

嗯,我写了他们的快速原型,它们将在代码工作时被替换。 – LordHexahedron

+0

是的,但用宏调试代码是一个令人头痛的问题... – Spektre

回答

0

我不知道我得到它的权利从你的问题,但:

  • 您想根据不完整的地图上实现体素的世界,但在地区而不是
  • 我没有看到你的代码中的任何地图(但可能忽略了它)

我会做这样的(伪代码):

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 
  • 你必须添加删除你做什么或不需要
  • 写功能特性:
    • 分析世界各地区
    • 更新位置(动态)
    • 事件,如碰撞
    • 加入分裂,过热,爆炸...

您还可以节省LO的记忆性T,如果你的对象是:

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地图(每每类)

此外,如果你的属性是不变的,那么你可以创建元素的表(细胞)

  • 记得刚元素的ID,而不是细胞为每个体素

希望它有助于至少一点。

+0

哦,我实际上并不记得我原来的意图是什么除了基于体素的世界,每个主轴至少有2×4-1个体素(axii?),最好只限于主机的可用RAM(尽管我能'为我的生活找出解决方法)。 编辑:哦,我想允许在特殊条件下的飞行岛屿,但这将是微不足道的实施,一旦我有我的巨大体素世界) 我应该使用更好的文档... – LordHexahedron

+0

噢,我记得我的意图是什么>。> 不知怎么排列多个体素区域和加入边缘块,以获得一个超级世界,可以跨越理论无限的空间给予足够的内存,现在我不知道该怎么做(我也不知道这是否是解决数据类型大小限制的好方法,我只能在浮点,双精度或整数(任意类型)中存储很多位置) – LordHexahedron