Tym razem będzie trochę o animacjach modeli:) Kolejny etap w tworzeniu mojej gry polega bowiem właśnie na zapoznaniu się z tą funkcjonalnością. Wspaniale jest móc dodawać do sceny kolejne modele i miło jest cieszyć oko urozmaicającym się światem gry. Jak się jednak okazuje, można zrobić więcej… można zasymulować ich poruszanie się!
Mechanizm ten właściwie nie jest w żaden sposób związany usilnie z samą technologią XNA, ale w jakże przejrzysty sposób (kolejny już raz) przełożony właśnie na jej podwórko. Dotyczy po prostu sposobu, w jaki zbudowane mogą być obiekty 3D. Obiekty takie skonstruowane powinny być blokowo tak, aby każdy blok mógł być osobnym modelem, który też może składać z mniejszych bloków itd. Mając dostęp do pewnego bloku, a więc pojedynczej części, możemy na niej robić przeróżne rzeczy (przesuwać, obracać, skalować). W ten sposób powstają ciekawe efekty i nasz interakcyjny świat „ruszających” się modeli.
Cała ta struktura drzewiasta modelu w XNA przechowywana jest w prosty sposób w klasie Microsoft.Xna.Framework.Graphics.Model:

Jak widać mamy tam zarówno propertę ‘Meshes’ jak i ‘Bones’, przechowującą obiekty ModelBone. Każdy taki blok (właściwie powinienem mówić chyba „kość”:) ma swoją macierz transformacji w układzie parenta. Tym samym chcąc przesunąć, obrócić bądź przeskalować taki obiekt robimy to w odniesieniu do jego rodzica. Wszystko jasne i klarowne.
Ja też wykorzystałem to w pewien sposób w implementacji mojej gry. Mianowicie skoro mój helikopter już ma fruwać…to naturalnym faktem jest przecież to, że powinien utrzymywać go w powietrzu obrotowy ruch śmigła. I do zaimplementowanie tego wszystko się sprowadziło. Wystarczyło jedynie przeszukać wśród wszystkich „kości” (w tym modelu jest ich całe 25, a moje śmigło złozone było aż z dwóch części) modelu helikoptera te reprezentujące śmigło i obrócić je wokół osi Y. Konkretnie zrobiłem dwie rzeczy:
//w metodzie LoadContent()
//zapamiętałem "kośći" śmigieł oraz ich transformację
heli.Model = Content.Load<Model>("Models\\Helikopter\\helnwsm1");
this.choopBone = heli.Model.Bones[16]; //smiglo cz.1 (klasa ModelBone)
this.choopBone2 = heli.Model.Bones[18]; //smiglo cz.2 (klasa ModelBone)
this.choopRotation = choopBone.Transform; //(macierz transformacji)
oraz
//w metodzie Update()
Vector3 move = objects.ActiveObject.Position;
//obliczyłem nową macierz obrotu (jak już pisałem we wcześniejszym poście
//musiałem najpierw przesunąć, potem obrócić, i znowu przesunąć)
this.choopBone.Transform =
Matrix.CreateTranslation(-move) *
Matrix.CreateRotationY(rot) *
Matrix.CreateTranslation(move);
//tę samą macierz stosujemy do drugiej części śmigła
this.choopBone2.Transform = this.choopBone.Transform;
No dobra, okłamałem Was. Tak powinno być, ale Prawie tak było… zmarnowałem przez mój głupi model helikoptera chyba ze 3h na to, żeby wywnioskować, że jest on trochę skopany ;/ Konkretnie, to ten kod powyżej obracał mi śmigło wokół jakiegoś dziwnego punktu w odniesieniu do parenta – środek śmigła nie był wycentrowany w tym modelu, do diaska!. Poprawiłem to poprzez stworzenie wektora poprawiającego i dodanie go do przesunięcia, czyli mój kod powyżej usprawniłem tak:
Vector3 correction
= -0
.091f
*
new Vector3
((float)Math
.Sin(MathHelper
.ToRadians(totalRotation
)),
0,
(float) Math
.Cos(MathHelper
.ToRadians(totalRotation
)));
Vector3 move
= objects
.ActiveObject.Position + correction
;
Wymyślenie sposobu na odkrycie tej tajemniczej stałej i obrócenie jej o macierz obrotu o całkowity kąt obrotu helikoptera… pozostawiam już samemu sobie jako tajemnicę:) A autorowi modelu 3D tegoż helikoptera chcę tylko powiedzieć: I tak Cię pokonałem skurczybyku:>!
Jak widać, wszystko tutaj śmiga, dopóki mamy ładne modele – jakże poważna jest zatem rola grafików, projektantów i artystów w procesie tworzenia gry. Mój drugi model, czyli auto, składa się tylko z dwóch bloków i niestety niewiele mogę tutaj w kwestii animacji podziałać. A tak bardzo chciałem móc też obracać kołami podczas poruszania się nim. Cóż, pozostaje mi chyba tylko wymienić go na inny.
Grę ściągnąć i podziwiać można tutaj:
http://www.kamilhawdziejuk.pl/gra/GameXna_11082010.exe
Żeby działało, to dodatkowo trzeba sobie ściągnąć następujący pakiet:
Microsoft XNA Framework Redistributable 3.1
Tematyka animacji modeli jest bardzo rozbudowana. Od strony programistycznej istnieją dwie metody: animowanie klatkami oraz animowanie szkieletem. To tę drugą zastosowałem w przykładzie mojej gry. Osobom zainteresowanym szczególnie natomiast polecam rewelacyjny wręcz przykład zastosowania tego mechanizmu, którego źródła można podejrzeć w jednym z tutoriali Microsoftu na XNA Creators:
http://creators.xna.com/en-US/tutorial/skinnedmodelextensions.
Jeśli uda mi się coś takiego przełożyć w zgrabny sposób do swojego projektu, to będę bardzo zadowolony. I może o tym będzie jeden z kolejnych postów:)