2014-08-31 12 views
0

4 개의 꼭지점으로 이루어진 두 개의 삼각형으로 이루어진 타일로 구성된 게임의 격자 지형이 있다고 가정 해 봅시다. 네 개의 꼭지점 사이에 점의 Y (위로) 위치를 어떻게 찾을 수 있을까요?4 개의 꼭지점 사이의 점의 Y 위치는 어떻게 찾습니까? HLSL

Terrain

I는 시도이 :

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)의 타일의 최초 정점으로부터 오프셋 너무 잘 울퉁불퉁 한 지형에.

위의 평면이 평면 일 때 삼각형으로 만든 지형과 관련이 있다고 기대합니다. 나는 잘 모르겠지만 아무도 무슨 일이 일어날 지 알지 못합니까?

이 더 나은 여기에 무슨 일이 일어나고 있는지 설명 할 수 코드에서

enter image description here

을 위의 "높이가 []"정점 v0-3 주변의 Y 좌표의 배열입니다. 삼각형 1 정점 0, 2로 이루어지고, 1 삼각형 2 정점 1, 2, I는 X가 Y는 v0-3 간의 꼬임 좌표 때 P1의 Y 좌표 찾고자 3.

이루어진다. 이것은 나에게 결과를 제공하지 않습니다

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); 
} 

내가

내가 다음 y는 좌표 찾기 위해 노력하고 예상 :

그래서 나는 점은이 기능을 통해 사이 인 삼각형을 결정하는 시도 각 삼각형 내부의 점 P1 :

// 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; 
} 

찾기 위해 다음과 같은 일을 사용하여 e 올바른 삼각형 :

if((1.0f - xOffset) <= zOffset) 
    inTri1 = true; 

위의 코드를 수정하여 정확한 교차 함수를 사용하면 문제가 해결 된 것으로 보입니다. 당신의 4 개 정점 비행기에하지 않을 수 있기 때문에

enter image description here

+0

좌표가 첫 번째 또는 두 번째 삼각형 안에있는 경우 중요합니까? – usr2564301

+0

만약 당신이'xOffset'와 같이 사용하는 변수의 관점에서 4 개의 꼭지점을 정의했다면 더욱 명확해질 것입니다 특히 네 개의 꼭지점에서만 두 개의 삼각형을 만드는 방법 두 개의 삼각형 사이에 두 개의 꼭지점을 공유하는 방법 – aecolley

+2

예 , 두 개의 정점이 공유됩니다. 평면 사각형 대신 두 개의 삼각형이있는 것처럼 왜 작동하지 않는지 이해합니다. 아마도 삼각형 당 그것을 점검해야할까요? –

답변

3

별도로 각 삼각형을 고려해야합니다. 먼저 포인트가있는 삼각형을 찾고, 다음 StackOverflow 토론을 사용하여 Z 값을 푸십시오 (축의 다른 이름 지정에 유의하십시오). 나는 개인적으로 DanielKO의 대답처럼 더 나은,하지만 허용 대답도 작동합니다 :

Linear interpolation of three 3D points in 3D space


편집 : 문제 의 두 번째의 경우는 (포인트가에있는 삼각형을 찾는) :를 좌표를 정의 할 때 xz 평면에 타일을 투영하면 완벽한 사각형이되므로 점이있는 삼각형을 찾는 것은 매우 간단한 작업입니다.여기서 x 축 (z 축의 높이가 낮은 값에서 높은 값까지)과 z 축 (z 값이 낮은 값에서 높은 값까지)을 나타 내기 위해 왼쪽에서 오른쪽으로 용어를 사용합니다.

각 타일은 두 가지 방법 중 하나로 분할 할 수 있습니다. 왼쪽 하단 모서리에서 오른쪽 상단 모서리에 대각선을 통해 (A) 또는 오른쪽 하단 모서리에서 왼쪽 상단 구석으로 대각선을 통해 (B). 모든 A와 분할있어 타일 용

  • X는 X '> Z'경우 확인 '을 으로부터의 거리가 지점으로 타일 가장자리를 떠나, Z는'으로부터의 거리 하단 지점까지 타일의 가장자리. x '> z이면 포인트가 오른쪽 아래 삼각형에 있습니다. 그렇지 않으면 왼쪽 위 삼각형에 있습니다. B로 분할 상관 없음 타일에 대한
  • : X 있는지 확인 "> Z ', x는"포인트로 타일의 바로 가장자리로부터의 거리, 및 z'는 아래로부터의 거리입니다 타일의 가장자리를 가리 킵니다. 만약 X "> Z '는 다음 지점은 왼쪽 아래 삼각형에, 그렇지 않으면 오른쪽 삼각형의

(마이너 참고 : 나는 당신의 타일 XZ 평면으로 회전하지 않는 가정 위. 즉, 축과 정렬되어 있는지 확인하십시오. 위의 검사를 수행하기 전에 축을 정렬하기 위해 축을 회전 시키면됩니다.)

+0

그래, 두 답변을 모두 살펴본 후 하나를 구현하려고합니다. –

+0

도움이 필요하면 알려주십시오. – Arda

+0

DanielKO의 답변을 따르려고하지만 포인트가 하나의 삼각형인지 아니면 다른 것인지를 결정하는 데 문제가 있습니다. 어떻게해야합니까? 나는 각 삼각형에 포인트와 법선을 가지고있다. float3 p1 = tile [0]; ' 'float3 n1 = (tile [1] - p1) * (타일 [1] - p1), ' 'float3 p2 = 타일 [3]; ' 'float3 n2 = (tile [2] - p2) * (tile [1] - p2); ' –