स्क्रीन स्पेस टू वर्ल्ड स्पेस


10

मैं एक 2D गेम लिख रहा हूँ जहाँ मेरे खेल की दुनिया में x अक्ष दाएं से बाएं चल रहा है, y अक्ष ऊपर से नीचे चल रहा है, और स्क्रीन से z अक्ष निकल रहा है:

यहाँ छवि विवरण दर्ज करें

जब भी मेरा खेल दुनिया ऊपर-नीचे होता है, खेल को थोड़ा झुकाव पर प्रस्तुत किया जाता है:

यहाँ छवि विवरण दर्ज करें

मैं विश्व अंतरिक्ष से स्क्रीन स्पेस, और इसके विपरीत प्रोजेक्ट करने पर काम कर रहा हूं। मेरे पास पूर्व कार्य निम्नानुसार हैं:

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 अक्ष ऊपर से नीचे के बजाय ऊपर से नीचे चलता है। ऊपर दिया गया स्क्रीनशॉट यह सब काम कर रहा है। मूल रूप से, मेरे पास 3 डी अंतरिक्ष में अंकों का एक गुच्छा है जिसे मैं स्क्रीन स्पेस में प्रस्तुत करता हूं। मैं वास्तविक समय में कैमरा गुणों को संशोधित कर सकता हूं और इसे नए स्थान पर चेतन कर सकता हूं। जाहिर है मेरा वास्तविक खेल अंक के बजाय स्प्राइट का उपयोग करेगा और कैमरे की स्थिति तय हो जाएगी, लेकिन मैं बस कोशिश कर रहा हूं कि इससे पहले कि सभी गणित मिल जाएं।

अब, मैं दूसरे तरीके से वापस बदलने की कोशिश कर रहा हूं। अर्थात्, ऊपर स्क्रीन स्थान में एक x और y बिंदु दिया गया है, जो विश्व अंतरिक्ष में संबंधित बिंदु निर्धारित करता है। इसलिए, यदि मैं कर्सर को इंगित करता हूं, तो, हरे रंग के ट्रेपोज़ॉइड के निचले-बाएं, मैं (0, 480) का विश्व अंतरिक्ष पढ़ना चाहता हूं। Z समन्वय अप्रासंगिक है। या, बल्कि, दुनिया के अंतरिक्ष में वापस मानचित्रण करते समय z समन्वय हमेशा शून्य रहेगा। अनिवार्य रूप से, मैं इस विधि हस्ताक्षर को लागू करना चाहता हूं:

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उदाहरण की आवश्यकता होगी जो आपकी जमीन से मेल खाता हो। इसकी गणना करने का सबसे आसान तरीका है कि उस कंस्ट्रक्टर का उपयोग करना जो विमान पर तीन बिंदुओं को ले जाता है, और इसे जमीन के ऑब्जेक्ट से किसी भी तीन कोने को पार करना है। जमीनी विमान की गणना करने का तरीका:

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विधि के बारे में भी कुछ करना पड़ सकता है लेकिन मुझे यकीन नहीं है कि वह कहाँ है।


यह सुपर सहायक है - बहुत-बहुत धन्यवाद। यह आखिरी पंक्ति थी जो मुझे याद आ रही थी। एक बार मेरे पास यह पता लगाने के लिए कि मैं फ्लोट के साथ क्या कर सकता हूं! मुझे लगता है कि मुझे मेरा गेम क्रेडिट्स में आपका नाम होना चाहिए :)
me--

@ user13414 वास्तव में, प्रलेखन उस पद्धति पर थोड़ा दुर्लभ है और चौराहे के बिंदु को वापस पाने के लिए दूरी का उपयोग करने के तरीके का कोई उदाहरण नहीं देता है।
डेविड गौविया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.