관심 장소 위에 느낌표를 표시하는 3D 게임을 만들고 있습니다.
2D 화면에서 마커를 어디에 놓아야하는지 확인하기 위해 마커가 있어야 할 3D 포인트를 수동으로 투영하고 있습니다.
다음과 같이 보입니다 :
꽤 좋아 보인다. 마커가 화면 바깥에 있으면 좌표를 화면에 맞추기 위해 단순히 좌표를 자릅니다. 다음과 같이 보입니다 :
지금까지 아이디어는 꽤 잘 진행되고 있습니다. 그러나 관심 지점이 카메라 뒤에있을 때 결과 X, Y 좌표가 양수 / 음수로 반전되어 다음과 같이 화면의 반대편 모서리에 마커가 나타납니다.
(프로젝션 된 클램프 지점은 마커의 끝입니다. 마커의 회전은 신경 쓰지 마십시오)
절두체 뒤의 좌표가 X와 Y로 반전되기 때문에 의미가 있습니다. 따라서 내가하고있는 것은 좌표가 카메라 뒤에서 좌표를 뒤집는 것입니다. 그러나 좌표를 반전 해야하는 조건이 무엇인지 여전히 알지 못합니다.
이것은 현재 프로젝션 코드의 모습입니다 (C #에서 SharpDX 사용).
public override PointF ProjectPosition(float viewportWidth, float viewportHeight, float y)
{
var projectionMatrix = Matrix.PerspectiveFovRH(GetCalibratedFOV(Camera.FOV, viewportWidth, viewportHeight), viewportWidth / viewportHeight, Camera.Near, Camera.Far);
var viewMatrix = Matrix.LookAtRH(new Vector3(Camera.PositionX, Camera.PositionY, Camera.PositionZ), new Vector3(Camera.LookAtX, Camera.LookAtY, Camera.LookAtZ), Vector3.UnitY);
var worldMatrix = Matrix.RotationY(Rotation) * Matrix.Scaling(Scaling) * Matrix.Translation(PositionX, PositionY, PositionZ);
var worldViewProjectionMatrix = worldMatrix * viewMatrix * projectionMatrix;
Vector4 targetVector = new Vector4(0, y, 0, 1);
Vector4 projectedVector = Vector4.Transform(targetVector, worldViewProjectionMatrix);
float screenX = (((projectedVector.X / projectedVector.W) + 1.0f) / 2.0f) * viewportWidth;
float screenY = ((1.0f - (projectedVector.Y / projectedVector.W)) / 2.0f) * viewportHeight;
float screenZ = projectedVector.Z / projectedVector.W;
// Invert X and Y when behind the camera
if (projectedVector.Z < 0 ||
projectedVector.W < 0)
{
screenX = -screenX;
screenY = -screenY;
}
return new PointF(screenX, screenY);
}
보시다시피, 현재 아이디어는 Z 또는 W 좌표가 음수 일 때 좌표를 반전시키는 것입니다. 대부분의 경우 작동하지만 여전히 작동하지 않는 매우 구체적인 카메라 위치가 있습니다. 특히이 점은 하나의 좌표가 작동하고 다른 하나는 작동하지 않음을 나타냅니다 (올바른 위치는 오른쪽 아래 여야 함).
나는 때 반전을 시도했다 :
Z
부정적 (이것이 나에게 가장 의미가있는 것입니다)W
음수 (음수 W 값의 의미를 이해하지 못함)- 하나
Z
또는W
음수 (현재 대부분의 시간을 작동하고 무엇을) Z
그리고W
다른 표시가 있습니다. 일명 :Z / W < 0
(나에게 이해가됩니다.하지만 작동하지 않습니다)
그러나 여전히 내 모든 포인트가 올바르게 투영되는 일관된 방법을 찾지 못했습니다.
어떤 아이디어?