あるゲームオブジェクトが別のゲームオブジェクトを表示できるかどうかを確認するにはどうすればよいですか?
-
03-07-2019 - |
質問
特定の方向に(たとえば)45度の視野と制限された視野範囲を持つオブジェクトがあります。すべての初期チェック(Quadtreeノード、および距離)を実行しましたが、特定のオブジェクトがそのビューコーン内にあるかどうかを確認する必要があります(この場合、表示できる場合はそのオブジェクトのみを追跡することにします)。
Direction-(FieldOfView / 2)
から Direction +(FieldOfView / 2)
(各段階でレイをキャストすることとは別に、それは恐ろしいです)、この可視性チェックを行う最良の方法は何ですか?
解決
ビュー方向(ベクトルとして理解される)と、あなたから始まりオブジェクトで終わるベクトルとの間の角度を計算します。 FieldOfView / 2に該当する場合、オブジェクトを表示できます。
その角度は:
arccos(scalarProduct(viewDirection, (object - you)) / (norm(viewDirection)*norm(object - you))).
他のヒント
私はビデオゲーム業界で働いてきましたが、フレームごとにarccosのようなトリガー機能を実行するのは理想的とは言えません。代わりに、円錐の角度の余弦を事前計算します。
float cos_angle = cos(PI/4); // 45 degrees, for example
その後、各フレームは、コーンと。とのドット積と比較することにより、ポイントがそのコーン内にあるかどうかをすばやく確認できます。
vector test_point_vector = normalize(test_point_loc - cone_origin);
float dot_product = dot(normalized_cone_vector, text_point_vector);
bool inside_code = dot_product > cos_angle;
トリガー関数はなく、乗算、除算、加算のみがあります。ほとんどのゲームエンジンには、ベクター用に最適化されたnormalize()関数があります。
これは、次の等式が原因で機能します。
A · B = |A| * |B| * cos(Θ)
ベクトルを正規化すると(A-> An)、方程式は単純化されます:
An · Bn = cos(Θ)
視聴者の見出しベクトルと視聴者からターゲットへのベクトルの間の角度を取得します。その角度が(FieldOfView / 2)より小さい場合、ターゲットは視聴者の視野内にあります。
ベクターが2dまたは3dの場合、これは同じように機能します。 (3Dでは、円錐ではなく視錐台がある場合、角度を2つのコンポーネントに分ける必要があります。)2つのベクトル間の角度を見つけるだけです。
単一のポイントよりも大きいターゲットをテストする場合、境界ボックスの角など、ターゲットごとに複数のポイントが必要になります。ビューアーからこれらのポイントのいずれかへのベクトルが視野内で角度を与える場合、ボックスのそのコーナーが表示されます。
3Dを実行していて、表示範囲を錐台として定義できる場合、次のようなフラストラムカリングテクニック。
良い答えはすでにありますが、私はあなたにWolfireブログへのリンクを提供したかっただけです。一例として方程式。 読み進め、よく書かれていて簡単です。