1

したがって、最初にどのように実装したいかを説明する必要があります。私のアイデアはかなり単純です。各チャンクを作成し、各チャンクにローカルな浮動小数点グリッドを利用して各頂点の位置を決定し、ボクセルを大きな 64 ビット整数グリッドに配置します (各チャンクの位置は、それが持つ整数値、0,0,0 は中央、20,20,20 は x、y、z 軸上で 20 チャンク離れた場所になります) さらに大規模な世界を作成するには、いくつかのチェックを実行して、チャンクは、整数グリッド内の位置から推測されて生成されますが、これはまだわかりません。(実行することほど重要ではありません)

私が問題を抱えていること:

  1. libnoise を使用して 3D パーリン ノイズを生成する方法を考え出しましたが、このドキュメントでは、私が知る限り、この問題には触れておらず、Google に問い合わせてもまともな結果は得られません。
  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 で書かれた特定のデモに非常に似ていることに気付くかもしれません。これは、多くのコードがそれを読んだ後に書かれたものであり、私に少しこすりつけられたからです。

問題は、それが私の問題をカバーしていないように見えることです.ボクセルがどのように機能するかについての理解がいくらか深まりました.

それで、私のこのプロジェクトを解決するためにどのように進むべきかについての指針はありますか?

PS、これはバトルフィールド 3 が DOOM のクローンであるのと同じくらいマインクラフトのクローンです。それをどのように解釈するかはあなたに任せると思います。

ああ、私は調査を行って、次のことを発見しました: 0fps に関する投稿。あなたのほとんどは、ブログ https://sites.google.com/site/letsmakeavoxelengine と、GPU gems 3 を含むいくつかの他のブログに精通していると確信しています。マーチング キューブやその他のいくつかの機能がありますが、どれも私の問題を解決するものではありません。

4

1 に答える 1

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
  • 必要なプロパティまたは不要なプロパティを削除する必要があります
  • 次の関数を記述します。
    • 世界を解析する
    • リージョンの分割に参加
    • 位置の更新 (ダイナミクス)
    • 衝突、過熱、爆発などのイベント...

オブジェクトが次の場合、多くのメモリを節約することもできます。

1.均質

// 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つの個別のマップがあります(各クラスごとにそれぞれ)

また、セルのプロパティが一定の場合は、要素 (セル) のテーブルを作成できます

  • 各ボクセルのセルの代わりに要素のIDだけを覚えておいてください

少しでもお役に立てば幸いです。

于 2014-02-14T07:46:54.507 に答える