मैं एक 3 डी गेम बना रहा हूं जिसमें मैंने एक विस्मयबोधक चिह्न को ब्याज के ऊपर रखा है।
यह पता लगाने के लिए कि 2 डी स्क्रीन में मुझे अपना मार्कर कहां लगाना चाहिए, मैं मैन्युअल रूप से 3 डी बिंदु का अनुमान लगा रहा हूं जहां मार्कर होना चाहिए।
यह इस तरह दिख रहा है:
बहुत अच्छा लग रहा है। जब मार्कर स्क्रीन के बाहर होता है, मैं बस निर्देशांक क्लिप करता हूं ताकि वे स्क्रीन में फिट हो सकें। यह इस तरह दिख रहा है:
अब तक यह विचार बहुत अच्छा चल रहा है। हालाँकि, जब रुचि के बिंदु कैमरे के पीछे होते हैं, तो परिणामी X, Y निर्देशांक उलटे होते हैं (जैसा कि धनात्मक / ऋणात्मक), और मुझे मार्कर स्क्रीन के विपरीत कोने पर दिखाई देता है, जैसे:
(अनुमानित-तब-क्लैम्प्ड बिंदु मार्कर की नोक है। मार्कर के रोटेशन को बुरा न मानें)
यह समझ में आता है, चूंकि एक्स और वाई में फ्रिअम के पीछे निर्देशांक उल्टे हैं और इसलिए मैं जो कर रहा हूं वह निर्देशांक को उलटने के लिए है जब वे कैमरे के पीछे होते हैं। हालाँकि, मुझे अभी भी नहीं पता है कि जब निर्देशांक उल्टा होना चाहिए तो वास्तव में क्या स्थिति है।
वर्तमान में यह मेरा प्रोजेक्शन कोड जैसा दिखता है (SharpDX के साथ C # में):
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
नकारात्मक है (मैं नकारात्मक W मान का अर्थ नहीं समझता)- या तो
Z
याW
नकारात्मक है (जो वर्तमान में समय के सबसे अधिक काम कर रहा है) Z
औरW
अलग संकेत के हैं, उर्फ:Z / W < 0
(मेरे लिए समझ में आता है। हालांकि काम नहीं करता है)
लेकिन अभी भी एक सुसंगत तरीका नहीं मिला है जिसके साथ मेरे सभी बिंदु सही ढंग से अनुमानित हैं।
कोई विचार?