Yazýlarýmý Daha Kolay Takip Etmek Ýçin Týklayýn!

XNA’de 3 BOYUT TEMELLERİ ve NESNELERİN HAREKET MANTIĞI

yazan: 12/5/2008 7:19:00 AM

Herkese merhabalar, uzun bir aradan sonra XNA hakkındaki yazılarıma devam ediyorum. Malum vizelerdi, Türkiye’ye dönüş heyecanıydı ödevlerdi … bir sürü bahaneden sonra, tekrar bir seri başlatmayı düşünüyorum. XNA’ de 2 boyut ve XNA’de multiplayer yazı dizilerim oldukça iyi tepkiler aldı. Desteğiniz için hepinize teşekkür ediyorum.

Bu yazımın konusu 3 boyuta girişten ziyade XNA’de 3 boyutun mantığını anlatmak olacak, önce mantığını kavrayalım, sonra zaten bizi kimse tutamaz. Öncelikle bazı konuları maddeler halinde inceleyelim, gerektiği yerde açıklayalım.

. XNA sağ el koordinat sistemini kullanır. Yani sağ elinizin parmak uçları X eksenini gösterirken avucunuz Y eksenini ve baş parmağınız da Z eksenini gösterir.

. XNA’de 2 tip iz düşüm (projeksiyon) vardır. İz düşüm bir nesnenin görüntüsünün mesafesine göre nasıl ölçeklendiğidir gibi bilgisayar oyunlarına özel bir tanım yapalım şimdilik. Bu iki tip sırasıyla;

-          Perspektif: Cisim uzaklaştıkça daha ufak gözükür, görülebilir genişlik artar.

-          Ortogonal: Bu tipte ise uzaklaşsa bile cismin boyutu değişmez, 2 boyut gibi düşünelim.

. Köşeler: Diğer bir deyişle “açısal oluşum noktaları” evrende bir nokta düşünün. Bu noktadan çıkan doğrular aralarında açıları oluşturacaktır. Örneğin hemen bulunduğunuz odanın tavanının köşesine bakın, sırasıyla biri X, biri Y, biri de Z ekseninde 3 doğru çıkıyor değil mi? Ve aralarında 90 derecelik dik açı var. Ve her şekil köşelerin birleştirilmsiyle oluşur, çocukken bulmacalarda noktaları birleştirdiğimizi hatırlayalım. Ve eğer bu noktaların her birinden 3 boyuta doğru çizgilir çıksaydı ne olurdu? Yanıt basit 3 boyutlu modeller. Az önceki örnekten devam edelim odadaki her köşeyi birbirine bağlayın ne oldu? Bir oda yani dikdörgenler prizması, değil mi.

Eh artık 3 boyutun unsurlarını biliyoruz peki bunları nasıl kullanacağız da bir oyun ortaya çıkacak?

XNA’de köşeler:

XNA’de köşeler, yerlerini ve diğer özelliklerini renk vb. içeren yapılar (struct) yardımı ile tanımlanırlar.

VertexPositionColor -> bu yapı ile bir köşe (vertex); yeri (position) ve rengi (color) ile tanımlanır.

VertexPositionTexture -> bu yapı ile bir köşe; yeri ve dokusu (texture) ile tanımlanır, desenin kendi içinde (0,0) desenin sol üst; (1,1) desenin sağ alt köşe limitidir.

VertexPositionColorTexture -> yukarıdaki iki yapının bileşimi gibi düşünelim.

VertexPositionNormalTexture -> bir normal vektörü ve bunun yanında yer ve desen tanımlanır.

XNA’de köşeleri birleştirmek için; GraphicsDevice.DrawPrimitives metodu kullanılır, bu metodun ilkel tipler (Primitive Types) için tanımlanmış enumaration değerlerine göre köşeler bir düzen içinde birleştirilir. Buradaki ilkel tipler programlama dillerindeki int, float vb. ilkel tiplerle karıştırılmamalıdır. Bahsettiğimiz Enum değerleri, 1. Parametre olarak kullanılacaktır; hepsi PrimitiveType. xxxx  şeklinde kullanılabilirler. Bu metodu kullanmadan önce Vertex buffer dediğimiz bir köşe listesini oluşturmamız gerekir. Bunu da Enum değerlerini gösterdikten sonra anlatacağım.

.PointList -> Köşe listesinde (Vertex Buffer) bulunan her vertex birbirinden bağımsız birer nokta şeklinde çizilir.

.LineList -> Köşe listesindeki köşeler sırayla ikişerli olarak gruplandırılır ve her ikilinin arası bir çizgi ile doğrusal olarak birleştirilir.

.LineStrip -> Köşe listesindeki köşeler sıra ile art arda birleştirilir.

.TriangleList -> Köşe listesindeki köşeler üçer üçer gruplandırılır, her üçlü bağımsız bir üçgen oluşturur.

.TriangleStrip -> Her yeni üçgen kendinden önceki üçgenin son iki noktası kullanılarak oluşturulur, dolayısı ile üçgenler bağlıdır, ilk üçgen dışındaki üçgenler için tek nokta gerek ve yeterlidir.

.TriangleFan -> İlk köşemiz tüm üçgenlerin tepe noktası olur ve üçgenler birfan şeklinde oluşur. Buna örnek olarak ikiye kesilmiş portakalı verebilirim, orta noktasını ilk noktamız kabul edersek, her dilim bir üçgen oluşturacaktır, tepe noktaları ortak olacaktır.

GraphicsDevice ekranKartı;

Şeklinde tanımlanmış bir aygıtımız olduğunu varsayarak; Bir  Vertex buffer ‘ı(Köşe Listemizi) nasıl oluşturacağız; buna bakalım;

VertexBuffer köşeListesi;

           // Diyerek bir VertexBuffer tanımlamış olalım. 

VertexPositionColor[]  köşeler= new  VertexPorsitionColor[10];             

//10 köşe barındıran bir dizi oluşturduk;

köşeler[0] = new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f),Color.White);

            // gibi bir kodla tüm köşelerimizi atayacağınızı varsayıyorum; 

köşelListesi = new VertexBuffer (ekranKartı, 10* VertexPositionColor.SizeInBytes,

                 BufferUsage.WriteOnly);

// diyerek Vertex Bufferımızı oluşturduk. Buradaki 10 listemizdeki eleman sayısı.

 

Yukarıda fark etmişsinizdir; Köşemizin yerini belirlerken Vector3 diye bir yapı kullandık; peki bu yapı nedir?

Adından da anlaşılacağı üzere Vector3 yapısı 3 boyutlu bir vektör tutar, yani X, Y ve Z koordinatlarından oluşan bir vektörü tutar. Vektör denince kafası karışanlar için, buna noktanın tanımlandığı hacim (dünya, oda … vb 3 boyutlu bir mekan) içerisindeki yerini belirtir diyelim. Yani odanın duvarında duran X ve Y koodinatlarına sahip bir sinek değil de odada uçan, oda hacmi içinde herhangi bir yerde olan sineğin konumu Smile.

Madem Vector3 yapısına (struct) giriş yaptık kısaca metotlarının bazılarından bahsedivereyim;

Vector3.Distance() -> verilen iki nokta arasındaki uzaklığı hesaplar.

Vector3.Add()

Vector3.Subtract() -> bu metotlar, vektörel toplama ve çıkartma yapar. Yani X değerleri  X Değerlerinden, Y değerleri Y değerlerinden … çıkartılır.

Vector3.Multiply()

Vector3.Divide() -> Bu iki metor  iki vektör arası çarpma bölme işlemi veya verilen bir sayı ile bir vektörü çarpıp bölme işini yapar.

Vector3.Clamp() -> Vektörü verilen sınırların içinde tutar, sınırın dışarısında bir değer almasını engeller; yani yukarıdaki örnekteki sinek bu metot yardımı ile odanın dışına çıkamaz.

Vector3.Lerp() -> İki vektör arası doğrusal interpolasyonu hesaplar.

Vector3.SmoothStep() -> Verilen bir değeri ağılık kabul ederek, iki vektör arası interpolasyonu hesaplar.

 

Bunlardan ayrı olarak yine Vector3 yapısına dahil özelliklerden bazıları da;

Vector3.Zero -> Geriye tüm değerleri 0 olarak atanmış bir vektör döndürür. (0,0,0)

Vector3.Up -> Yukarıya bakan bir vektör döndürür (0,1,0)

Vector3.Right -> Sağa bakan bir vektör döndürür (1,0,0)

Vector3.Forward -> Sağ el koordinat sistemine göre ileri giden bir vektör döndürür (0,0,-1)

Vector3.Left , Vector3.Down, Vector3.Backward

Vector3.UnitX -> bir birim X vektörü döndürür (1,0,0)

Vector3.UnitY, Vector3.UnitZ

 

Peki bir nesne (model) köşelerin birleştirilmesinden oluşuyorsa ve her köşe bir vektör olarak temsil ediliyorsa, Oyunun geçeceği dünya nasıl temsil edilmeli?

Yanıt matrisler, eğer içinde bulunduğumuz oda bir 3 boyutlu matrisle temsil ediliyor olsaydı, kağıt üzerinde sineğimizin nerede uçuyor olduğunu işaretleyebilecektik.

XNA’de matrisler, bir nesnenin rotasyonunda (bir eksen etrafında dönme hareketleri), ölçeklendirilmesinde (uzağa giden nesne küçülür) ve translasyonunda (sabit yönlü hareket) kullanılır.

Eğer matris kullanmıyor olsaydık, bir nesnenin tüm hareketleri için vektörün her bir değerine tek tek ulaşıp o değeri değiştirecektik. Ama bu işi iki matrisin arasındaki matematiksel işlemler aracılığı ile yaparsak hem X, Y ve Z değerlerine ayrı ayrı ulaşmak zorunda kalmayacağız hem de her bir işlemi tek tek uygulamak yerine aynı anda hem haraket ettirebilecek hem de nesnenin boyutunu değiştirebileceğiz.

Matrislerin kullanılmasının bir diğer sebebi ise çağdaş ekran kartlarının tümünde GPU üzerinde matris algoritmaları olması, böylece CPU üzerine binecek yükten de kurtulmuş oluyoruz.

Bir nesneye Matris işlemleri ile haraket nasıl verilir?

Bir noktamız var koordinatları (20,10,30) olsun. Bunu 30 birim yukarı hareket ettirmek istiyoruz. Bunu nasıl yapacağız?

Sonunda Lineer Cebir dersleri bir işe yarıyor ve matrislerde çarpma yapıyoruz.

         [1, 0, 0, 0]

[20,10,30,1] x|0, 1, 0, 0|  = [20, 40, 30, 1]

                     |0, 0, 1, 0|

                     [ 0,30,0, 1]

Gördüğünüz gibi y değeri 30 arttı.

Eğer bu işlemde, ilk matrisimizde en sondaki 1’i arttırsaydık 60 birim ilerlemiş olacaktık, yani bu ilerleme katsayısıdır.

Eğer, İkinci matristeki köşegende bulunan 1’leri  arttırsaydık, nesnemizin boyu büyüyecekti, yani bu köşegen de nesnemizin ölçeklendirilmesinden sorumlu.

Ve aynı zamanda eğer ikinci matrisimizde sin ve cos değerleri kullanıyor olsaydık, nesnemiz dönme hareketi yapacaktı. Gördüğünüz gibi neredeyse hiç uğraşmadan tek matris işleminde nesnemizi hareket ettirdik.

Yazımı bitirmeden önce son bir şey söylemek istiyorum, matrisler sizi korkutmasın çünkü bu işlemleri XNA sizin için Matrix sınıfı aracılığı ile yapıyor, buradaki amacım size işin işleyiş mantığını göstermekti. Bir sonraki yazımda size Matris sınıfından bazı işlevlerinden bahsedeceğim, Eğer zaman bulursam Efektlere de tanıtma niyetinde bir giriş yapmak istiyorum. Hepinize kolay gelsin.

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Etiketler: , , ,

XNA

Related posts

Comments

3/3/2010 12:37:38 PM

ucvhost

Thanks for the great post,i love to read articles that are informative and beneficial in nature.

ucvhost us

3/30/2010 12:27:31 PM

ucvhost

Your blog is my favorite, congratulates. Often I'll look here, a lot of information and nice site.

ucvhost us

5/22/2010 5:16:33 PM

cheap hosting

Your blog is my favorite, congratulates

cheap hosting

5/27/2010 11:55:21 PM

discount handbags sale

Nice content, I trust this is a nice blog. Wish to see fresh content next time.

discount handbags sale US

6/1/2010 11:53:48 PM

wallets bags

I was very pleased to find this site.I wanted to thank you for this great read!! I definitely enjoying every little bit of it and I have you bookmarked to check out new stuff you post.

wallets bags US

6/25/2010 3:24:16 PM

discount prada

This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.

discount prada US

7/9/2010 11:01:27 AM

regio dating

I love reading and I am always searching for informative information like this Great content.This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.

regio dating nl

Add comment


(Will show your Gravatar icon)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

9/4/2010 12:04:35 PM

 

Yazar Hakkýnda

Erçin YONTAR
Erçin Yontar
1986 yýlýnda Çorlu'da doðdu.Ýlk öðrenimini Ankara'da, ortaöðrenimini Eskiþehir'de gördü.
Çanakkale 18 Mart Üniversitesi Bilgisayar Mühendisliði Bölümü mezunu.
Yazýlým ile çok ilgili; Visual Studiosu daima açýk :) bunun sayesinde Imagine Cup 2008 Türkiye 3.sü ve bir çok proje geliþtiriyor.
Yazýlým dýþýnda : Frp hastasý, rock/metal dinliyor, organizasyon iþlerine merak sardý. Bunlarýn yanýnda o bir; 
MCTS (Microsoft Certified Technology Specialist)



MSP (Microsoft Student Partner)

Bana posta atýn Send mail

Favorilerine Ekle


Add to Technorati Favorites

 

Twitter - Ne Yapýyorum?

    Pages

      Recent comments

      Feragatname

      Burada yazan yazýlar ve içerdikleri fikirler yazarýna aittir. Baþkasýný ilgilendirmez. Yazýlarý kaynaðýný kopyaladýðýnýz yazýnýn içinde týklanabilir link halinde belirtmek þartý ile olduðu gibi kullanabilirsiniz. Bu kurallarý deðiþtirme hakkým saklýdýr. Yarýn bir gün benim yazým benim blogumdan baþka bir yerde olamaz dersem Kopyaladýðýnýz yazýyý da silmek zorundasýnýz. Bu iþe girþen kiþi bu koþullarý ve doðan yasal yükümlülükleri kabul etmiþ sayýlýr. Eyvallah diyen devam etsin.

      © Tüm haklarý saklýdýr.

      Giriþ