ฉันกำลังสร้างเกม 3 มิติโดยใส่เครื่องหมายอัศเจรีย์เหนือจุดสนใจ
เพื่อที่จะหาว่าในหน้าจอ 2D ที่ฉันควรวางเครื่องหมายของฉันฉันกำลังฉายจุด 3D ด้วยตนเองที่เครื่องหมายควร
ดูเหมือนว่านี้:
ดูดีทีเดียว เมื่อเครื่องหมายอยู่นอกหน้าจอฉันเพียงแค่คลิปพิกัดเพื่อให้พอดีกับหน้าจอ ดูเหมือนว่านี้:
จนถึงตอนนี้ความคิดก็ไปได้สวย อย่างไรก็ตามเมื่อจุดที่น่าสนใจอยู่ด้านหลังกล้องพิกัด X, Y ที่ได้จะกลับด้าน (เหมือนเป็นบวก / ลบ) และฉันก็ได้เครื่องหมายที่ปรากฏบนมุมตรงข้ามของหน้าจอดังนี้:
(จุดที่คาดการณ์ไว้จากนั้นเป็นจุดปลายของเครื่องหมายไม่ต้องคำนึงถึงการหมุนของเครื่องหมาย)
มันสมเหตุสมผลแล้วเนื่องจากพิกัดที่อยู่เบื้องหลัง frustum นั้นกลับด้านใน 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
เป็นสัญญาณที่แตกต่างกัน aka:Z / W < 0
(ทำให้รู้สึกถึงฉันไม่ทำงานแม้ว่า)
แต่ก็ยังไม่พบวิธีที่สอดคล้องกับที่ทุกจุดของฉันถูกฉายอย่างถูกต้อง
ความคิดใด ๆ