6

私は最初のOpenGLプロジェクトとしてMinecraftのクローンを作成していて、ボックスの選択部分で立ち往生しています。信頼できるボックスを選択するための最良の方法は何でしょうか?

私はいくつかのAABBアルゴリズムを試してきましたが、それらのどれもが正確に何をするのか(特に超微調整されたもの)を十分に説明しておらず、理解できないものは使いたくありません。

世界は立方体で構成されているので、八分木を使用してレイキャスト計算の負担を取り除きました。基本的に必要なのはこの関数だけです。

float cube_intersect(Vector ray, Vector origin, Vector min, Vector max)
{
    //???
}

光線と原点はで簡単に取得できます

Vector ray, origin, point_far;
double mx, my, mz;

gluUnProject(viewport[2]/2, viewport[3]/2, 1.0, (double*)modelview, (double*)projection, viewport, &mx, &my, &mz);
point_far = Vector(mx, my, mz);
gluUnProject(viewport[2]/2, viewport[3]/2, 0.0, (double*)modelview, (double*)projection, viewport, &mx, &my, &mz);
origin = Vector(mx, my, mz);
ray = point_far-origin;

minとmaxは、立方体の反対側の角です。

八分木であっても、チェックしなければならないキューブの数を考えると、これがこれを行う正しい方法であるかどうかさえわかりません。

私も試しましgluProjectたが、動作しますが、信頼性が非常に低く、選択した立方体の面が表示されません。


編集

だからこれは私がやったことです:光線で空間内の位置を計算します:

float t = 0;
for(int i=0; i<10; i++)
{
    Vector p = ray*t+origin;
    while(visible octree)
    {
        if(p inside octree)
        {
            // then call recursive function until a cube is found
            break;
        }
        octree = octree->next;
    }
    if(found a cube)
    {
        break;
    }
    t += .5;
}

実際には驚くほど高速で、最初に見つかったキューブの後で停止します。

代替テキスト

ご覧のとおり、光線は立方体(実際には空間内の位置)を見つける前に複数の八分木を通過する必要があります。画面の中央に十字線があります。増分ステップが低いほど、選択はより正確になりますが、速度も遅くなります。

4

3 に答える 3

5

ボックスをプリミティブとして使用することは、メモリ要件と処理能力においてやり過ぎです。キューブはレンダリングに適していますが、そこでも、より優れた最終画像(マーチングキューブ)を提供するより高度なアルゴリズムを見つけることができます。ボクセルレンダリングが長い間使用されており、大幅な進歩が見られたため、Minecraftのグラフィックはこの意味で非常に原始的です。

基本的に、すべてのボックスが等間隔で同じサイズであるという事実を利用する必要があります。これらはボクセルと呼ばれます。グリッドでのレイキャスティングは、あなたが持っているものと比較して簡単です-広相のオクトツリーと狭相のAABBテスト。ボクセルとボクセルセットの衝突検出/レイキャスティングについて少し調べてみることをお勧めします。実装が簡単で、実行速度が速いアルゴリズムが両方とも見つかるからです。

于 2011-01-03T00:12:16.237 に答える
0

メモリ内に明示的な八分木構造は必要ありません。必要なのはbyte[,,]だけです。検索中にボックスの子を8つ生成するだけです(チェスエンジンが子のゲーム状態を生成するように)。

于 2011-01-22T02:41:00.417 に答える
0

また、何をレンダリングするかを決定するために実際のレイキャストに依存する必要はないと主張します。事前定義されたグリッド構成にいることを考えると、実際には「正確に見える」要件に人質にされることはありません。カメラの位置を追跡し、ある種のNSWEコンパスを割り当てることができる場合は、それを使用して、GPUバッファーがレンダリング用の頂点の配列を考慮する必要があるかどうかを判断することもできます。

この理論については、https://stackoverflow.com/a/18028366/94167で詳しく説明します。

しかし、Octreeとカメラのポジショニング+カメラの距離/境界を使用すると、正確にレイトレーシングに頼る必要なしに、基本的にユーザーが何を見ているかを知ることができますか?レンダリングの目的で三角形をより大きな三角形に統合し、テクスチャを使用して大きな三角形を立方体の形(手先の早業)に戻すことができる場合は、頂点の数を大幅に減らすことができます。次に、船体をレンダリングするだけで、カメラの方向とxyzの位置を追跡することで、パフォーマンスへの影響を最小限に抑えるため、表示されるべきではない顔をいくつか残すことができます(特にシェーダー自体も一部の作業を行う場合)

カメラの中心点を追跡して水平焦点を決定し、そこから角度を決定して、カメラが向いている方向に見える可能性のあるチャンクの深さを決定することで、さらに実験を進めています。

于 2013-08-03T02:01:51.587 に答える