コードをもっと短くて読みやすくすることができます。例えば、int tNear = INT_MIN
にint tNear = -2147000000
を変更し
if(t1 > t2)
{
// std::swap is built-in
swap(t1, t2);
}
以上
// Define 'order' yourself
order(t1, t2);
と
に
if(t1 > tNear)
{
tNear = t1;
}
を変更する
if(t1 > t2)
{
float temp1 = t1;
t1 = t2;
t2 = temp1;
}
を変更します
// std::max is built in
tNear = max(tNear, t1);
次に、あなたのコードのいずれかのセクションには、次のようになります。
if ((ray.dir.x == 0) && (ray.start.x < Min.x) && (ray.start.x > Max.x))
{
//parallel
return false;
}
else
{
float t1 = (Min.x - ray.start.x)/ray.dir.x;
float t2 = (Max.x - ray.start.x)/ray.dir.x;
order(t1, t2);
tNear = max(tNear, t1);
tFar = max(tFar, t1);
if ((tNear > tFar) || (tFar < 0))
return false;
}
そしてこれは一つの問題を明らかにする。 tNear
とtFar
は、その行がキューブと交差する範囲の値をt
と定義します。テストする各座標(x、y、z)は、間隔をさらに制限します。しかし、コードtFar = max(tFar, t1)
は間隔を広げています。それをtFar = min(tFar, t1)
に変更します。
さらに基本的には軸に沿った立方体に制限されますが、後でより複雑な図形のクイックヒットテストとして役立ちます。とにかく、これが働いたらもっと一般的にしたいかもしれません。
任意の凸多角形を法線が外側を向く無限面の集合として定義できます。すべての平面の「内側」にある場合、ポイントはポリゴンの内側にあります。
プレーンは、スペースを2つの半分に分割します。ノーマルポイントを「外側」とし、残りの半分を「内側」として定義します。その点の平面方程式が正の場合、点は平面の外にあり、値が負の場合は面内、値がゼロの場合は平面上にあります。
これを光線追跡するには、光線/平面の交差点を決定し、最も近いものを選択します。その点が面内にあるかどうかを判断するには(面が無限であることを覚えておいてください)、点が他のすべての面の内側にあるかどうかを確認します。そうでない場合は、次に近い交差点をテストします。
これが機能したら、それを一般的な交差点や形状の違い(例えば、面の1つに半球のくぼみがあるキューブ)に拡張するのは非常に簡単です。
出典
2012-01-18 02:39:29
arx
こんにちはクリス、私はあなたの投稿や助けをお勧めしないが、質問をする前にあなたのコードにいくつかの健全性チェックを行う必要があると思います。たとえば、箱の交差がうまくいかない場合、テストの状況によって正しい答えがどのようになるかが分かりました。すなわち、(1,0,0)に沿って動く(-1,0.5,0.5)のレイと交差するサイズ(1,1,1)の(0,0,0)のコーナーを持つボックスは、(0,0.5) 、0.5)、この種のもの。あなたがここに来るときには、校正の読書サービスとしてだけでなく、助言を得ることができます。 –