4 つの頂点からなる 2 つの三角形からなるタイルで構成されるゲーム用のグリッド テレインがあるとします。4 つの頂点の間のポイントの Y (上) 位置をどのように見つけますか?
私はこれを試しました:
float diffZ1 = lerp(heights[0], heights[2], zOffset);
float diffZ2 = lerp(heights[1], heights[3], zOffset);
float yPosition = lerp(diffZ1, diffZ2, xOffset);
z/yOffset は、タイルの最初の頂点からの z/y オフセット (パーセント / 100) です。
これは、上記が平面で機能する可能性のある三角形から作成された地形に関係していると思います。よくわかりませんが、何が問題なのか知っている人はいますか?
これは、ここで何が起こっているかをよりよく説明するかもしれません:
上記のコードで、"heights[]" は周囲の頂点 v0-3 の Y 座標の配列です。三角形 1 は頂点 0、2、1 で構成されています。三角形 2 は頂点 1、2、3 で構成されています。
x、y座標がv0-3の間にあるときに、p1の座標Yを見つけたいと思います。
そこで、この関数を使用して、ポイントがどの三角形の間にあるかを判断しようとしました:
bool PointInTriangle(float3 pt, float3 pa, float3 pb, float3 pc)
{
// Compute vectors
float2 v0 = pc.xz - pa.xz;
float2 v1 = pb.xz - pa.xz;
float2 v2 = pt.xz - pa.xz;
// Compute dot products
float dot00 = dot(v0, v0);
float dot01 = dot(v0, v1);
float dot02 = dot(v0, v2);
float dot11 = dot(v1, v1);
float dot12 = dot(v1, v2);
// Compute barycentric coordinates
float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
// Check if point is in triangle
return (u >= 0.0f) && (v >= 0.0f) && (u + v <= 1.0f);
}
これは私が期待した結果を与えていません
次に、各三角形内の点 p1 の y 座標を見つけようとしています。
// Position of point p1
float3 pos = input[0].PosI;
// Calculate point and normal for triangles
float3 p1 = tile[0];
float3 n1 = (tile[2] - p1) * (tile[1] - p1); // <-- Error, cross needed
// = cross(tile[2] - p1, tile[1] - p1);
float3 p2 = tile[3];
float3 n2 = (tile[2] - p2) * (tile[1] - p2); // <-- Error
// = cross(tile[2] - p2, tile[1] - p2);
float newY = 0.0f;
// Determine triangle & get y coordinate inside correct triangle
if(PointInTriangle(pos, tile[0], tile[1], tile[2]))
{
newY = p1.y - ((pos.x - p1.x) * n1.x + (pos.z - p1.z) * n1.z) / n1.y;
}
else if(PointInTriangle(input[0].PosI, tile[3], tile[2], tile[1]))
{
newY = p2.y - ((pos.x - p2.x) * n2.x + (pos.z - p2.z) * n2.z) / n2.y;
}
以下を使用して、正しい三角形を見つけます。
if((1.0f - xOffset) <= zOffset)
inTri1 = true;
上記のコードを正しいクロス関数を使用するように修正すると、問題が解決したようです。