Minecraftクローンに最適なボックス選択方法
質問
私は最初の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;
}
実際には驚くほど速く、最初に見つけたキューブの後に止まります。
ご覧のとおり、光線はキューブ(実際には宇宙の位置)を見つける前に複数のオクトスを走らなければなりません - 画面の中央に横切りがあります。増分が低いほど、選択がより正確になりますが、遅くなります。
解決
プリミティブとしてボックスを操作することは、メモリ要件と処理能力が過剰になります。キューブはレンダリングに適しています。そこでも、より良い最終画像(行進キューブ)を提供するより高度なアルゴリズムを見つけることができます。 Minecraftのグラフィックスは、この意味で非常に原始的です。ボクセルレンダリングは長い間存在しており、大きな進歩が遂げられています。
基本的に、すべてのボックスが等間隔で同じサイズであるという事実を活用する必要があります。これらはボクセルと呼ばれます。グリッドでのレイキャスティングは、あなたが持っているものと比較して些細なことです - 広い段階のOCTツリーと狭いフェーズAABBテスト。ボクセルとボクセルセットの衝突検出/レイキャスティングについて少し調査することをお勧めします。
他のヒント
メモリに明示的なoctree構造は必要ありません。必要なのはByte [,,]だけです。検索中にゆっくりと箱の8人の子供を生成するだけです(チェスエンジンが子供のゲームの状態を生成するように)。
また、レンダリングするものを決定するために実際のレイキャストに頼る必要はないと主張します。あなたが事前に定義されたグリッドフォーメーションにいることを考えると、あなたは本当に「正確に目に見える」要件に人質にされていません。カメラの位置を追跡し、いくつかの種類のNSWEコンパスを割り当てることができる場合、それを使用して、GPUバッファーがレンダリングのために頂点の配列を検討すべきかどうかを判断することもできます。
ここでこの理論を詳細に説明します https://stackoverflow.com/a/18028366/94167
しかし、Octreeとカメラの位置付け +カメラの距離/境界を使用すると、基本的にユーザーが見ているものを知っています。レンダリング目的で三角形をより大きなものに統合し、テクスチャを使用して大きな背中の可視性を立方体の形(わずかな手)に分割できる場合は、頂点数を大幅に減らします。それから、船体をレンダリングするだけで、カメラの方向が何であり、どこに座っているかを追跡することで、パフォーマンスに最小限の影響を与えるため、表示すべきでない顔を表示することで逃げることができます(特にあなたのシェーダー自体もいくつかの仕事をしている場合)
カメラの中心点を追跡して水平焦点を決定することでさらに実験しています。それから、直面する方向に見られる可能性のあるチャンクの深さを決定する角度を決定できます。