Dünya uzayına ekran alanı


10

Oyun dünyamın x ekseni soldan sağa, y ekseni yukarıdan aşağıya ve z ekseni ekrandan çıktığı bir 2D oyun yazıyorum :

resim açıklamasını buraya girin

Oyun dünyam yukarıdan aşağıya iken, oyun hafif bir eğimde işleniyor:

resim açıklamasını buraya girin

Dünya uzayından ekran uzayına ve tam tersine projeksiyon üzerinde çalışıyorum. Önceki çalışma aşağıdaki gibi var:

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

NegateY()Uzatma yöntemi XNA beri, gibi sesler tam olarak ne yapar y ekseni altına yerine üst üste alt çalışır. Yukarıdaki ekran görüntüsü tüm bunların işe yaradığını gösterir. Temel olarak, 3B alanda daha sonra ekran alanında oluşturduğum bir sürü nokta var. Kamera özelliklerini gerçek zamanlı olarak değiştirebilir ve yeni pozisyona hareket ettiğini görebilirim. Açıkçası gerçek oyunum puan yerine sprite kullanacak ve kamera pozisyonu sabitlenecek, ama ben buna başlamadan önce tüm matematiği yerleştirmeye çalışıyorum.

Şimdi, diğer yöne dönmeye çalışıyorum. Yani, yukarıdaki ekran boşluğunda bir x ve y noktası verildiğinde , dünya uzayındaki karşılık gelen noktayı belirleyin. Bu yüzden imleci yeşil trapezoid'in sol alt tarafına doğrultursam, (0, 480) dünya uzay okumasını almak istiyorum. Z koordinat önemsizdir. Ya da daha ziyade, dünya uzayına geri eşlenirken z koordinatı her zaman sıfır olacaktır. Aslında, bu yöntem imzasını uygulamak istiyorum:

public Vector2 ScreenPointToWorld(Vector2 point)

Ben bu işe almak için birkaç şey denedim ama sadece şansım yok. Son düşüncem, Viewport.Unprojectfarklı yakın / uzak z değerleri ile iki kez aramam , ortaya çıkan sonucu hesaplamam Ray, normalleştirmem ve daha sonra temelde dünyamın zemin seviyesini temsil eden Raybir ile kesişimini hesaplamam gerektiğidir Plane. Ancak, son adımda takıldım ve fazla karmaşık olup olmadığımdan emin değildim.

Biri bana bunu nasıl başaracağımı doğru yönde gösterebilir mi?

Yanıtlar:


4

Bence senin fikrin hemen hemen yerinde! Öncelikle 2D koordinatlarınız için hem yakın düzlemi hem de uzak düzlemi Z değerleri olarak kullanarak imleciniz için bir ışın hesaplayın (yani Z koordinatınız için 0 ve 1 kullanın). İşte bununla başa çıkmak için yardımcı bir yöntem:

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));
}

Ardından Plane, yerinizle eşleşen bir örneğiniz olması gerekir. Bunu hesaplamanın en kolay yolu, düzlemde üç nokta alan ve öğeyi zemin nesnesinden herhangi bir üç köşeden geçiren yapıcı kullanmaktır. Yer düzleminin nasıl hesaplanacağına örnek:

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

Ve son olarak bu yöntemi kullanarak ışın ve düzlem arasındaki kesişim noktasını bulun . Aşağıdaki örnekte olduğu gibi kavşak koordinatlarını hesaplamak için out sonuç parametresini kullanabilirsiniz:

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

NegateYYöntem hakkında da bir şeyler yapmanız gerekebilir ama nerede olduğundan emin değilim.


Bu süper yararlı - çok teşekkür ederim. Kaçırdığım son satırdı. Şamandıra ile ne yapacağımı anlayamadım! Oyun kredilerimde isminizin olması gerektiğini düşünüyorum :)
ben--

@ user13414 Gerçekten de, dokümantasyon bu yöntem üzerinde biraz kıttır ve kavşak noktasını geri almak için mesafenin nasıl kullanılacağına dair herhangi bir örnek vermez.
David Gouveia
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.