월드 공간에 화면 공간


10

게임 세계에 x 축이 왼쪽에서 오른쪽으로, y 축이 위에서 아래로, z 축이 화면에서 벗어난 2D 게임을 작성 중입니다.

여기에 이미지 설명을 입력하십시오

내 게임 세계는 하향식이지만 게임은 약간 기울어 져 렌더링됩니다.

여기에 이미지 설명을 입력하십시오

월드 공간에서 스크린 공간으로 또는 그 반대로 투영하는 작업을하고 있습니다. 나는 다음과 같이 일하고있다.

var viewport = new Viewport(0, 0, this.ScreenWidth, this.ScreenHeight);
var screenPoint = viewport.Project(worldPoint.NegateY(), this.ProjectionMatrix, this.ViewMatrix, this.WorldMatrix);

NegateY()확장 방법은 XNA 년대 이후는, 같은 소리 정확히 않는 Y 축이 아래로 대신 상단의 상하로 실행됩니다. 위의 스크린 샷은이 모든 기능을 보여줍니다. 기본적으로 3D 공간에 많은 포인트가 있으며 화면 공간에서 렌더링합니다. 카메라 속성을 실시간으로 수정하여 새로운 위치로 애니메이션을 볼 수 있습니다. 분명히 내 실제 게임은 포인트 대신 스프라이트를 사용하고 카메라 위치는 고정되지만, 그에 도달하기 전에 모든 수학을 제자리에 넣으려고합니다.

이제 다른 방법으로 다시 변환하려고합니다. 즉, 위의 화면 공간에서 xy 지점이 주어지면 월드 공간에서 해당 지점을 결정하십시오. 예를 들어 녹색 사다리꼴의 왼쪽 하단을 커서로 가리키면 (0, 480)의 세계 공간 값을 얻고 싶습니다. Z 좌표는 무관하다. 또는 월드 공간으로 다시 매핑 할 때 z 좌표는 항상 0이됩니다. 기본적 으로이 메소드 서명을 구현하고 싶습니다.

public Vector2 ScreenPointToWorld(Vector2 point)

이 작업을 수행하기 위해 여러 가지를 시도했지만 운이 없습니다. 내 최근 생각은 Viewport.Unproject서로 다른 니어 / 파 z 값으로 두 번 호출 하고 결과 Ray를 계산하고 정규화 한 다음 기본적으로 내 세계의 지상 수준을 나타내는 Ray와의 교차점을 계산해야 Plane한다는 것입니다. 그러나 나는 마지막 단계에 갇혀있어서 복잡한 일을하고 있는지 확실하지 않았습니다.

아무도 이것을 달성하는 방법에 대해 올바른 방향으로 나를 가리킬 수 있습니까?

답변:


4

나는 당신의 생각이 꽤 자리 잡았다 고 생각합니다! 먼저 근거리 평면과 원거리 평면을 2D 좌표의 Z 값으로 사용하여 커서의 광선을 계산합니다 (예 : Z 좌표에 0과 1을 사용). 이를 처리하는 도우미 방법은 다음과 같습니다.

public Ray GetScreenRay(Vector2 screenPosition, Viewport viewport, Matrix projectionMatrix, Matrix viewMatrix, Matrix worldMatrix)
{
    Vector3 nearPoint = viewport.Unproject(new Vector3(screenPosition, 0f), projectionMatrix, viewMatrix, worldMatrix);
    Vector3 farPoint = viewport.Unproject(new Vector3(screenPosition, 1f), projectionMatrix, viewMatrix, worldMatrix);
    return new Ray(nearPoint, Vector3.Normalize(farPoint - nearPoint));
}

다음으로 Plane자신의 입장과 일치 하는 인스턴스가 있어야합니다 . 이를 계산하는 가장 쉬운 방법은 평면에서 3 개의 점을 취하는 생성자를 사용하고 지상 객체에서 3 개의 정점을 전달하는 것입니다. 접지면을 계산하는 방법의 예 :

Plane groundPlane = new Plane(ground.Vertices[0], ground.Vertices[1], ground.Vertices[2]);

마지막 으로이 방법을 사용하여 광선과 평면 사이의 교점을 찾으십시오 . 아래 예와 같이 교차 결과를 계산하기 위해 결과 결과 매개 변수를 사용할 수 있습니다.

float? result;
mouseRay.Intersects(ref groundPlane, out result);
if(result != null)
    Vector3 worldPoint = mouseRay.Position + mouseRay.Direction * result.Value;

NegateY방법에 대해서도 무언가를해야 할 수도 있지만 어디에서 잘 모르겠습니다.


이것은 매우 도움이됩니다. 대단히 감사합니다. 내가 놓친 마지막 줄이었습니다. 플로트가 있으면 어떻게해야할지 알 수 없었습니다! 나는 :) 내 게임 크레딧에 이름이해야 할 거 같아요
가구 있구만

@ user13414 사실,이 문서는 그 방법이 약간 부족하며 거리를 사용하여 교차점을 되 찾는 방법에 대한 예를 제공하지 않습니다.
David Gouveia
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.