Menggunakan format .x untuk mengekspor model dari Blender, saya dapat memuat mesh, armature, dan animasi. Saya tidak punya masalah menghasilkan mesh dan melihat model dalam game. Selain itu, saya memiliki animasi dan armature dimuat dengan benar ke dalam struktur data yang sesuai.
Masalah saya adalah mengaplikasikan animasi ke model dengan benar. Saya memiliki kerangka kerja untuk menerapkan model dan kode untuk memilih animasi dan melangkah melalui bingkai.
Dari apa yang saya mengerti, bagian AnimationKey
dalam AnimationSet
memasok transformasi untuk mengubah pose mengikat ke pose dalam bingkai animasi. Sebagai contoh kecil:
Animation {
{Armature_001_Bone}
AnimationKey {
2; //Position
121; //number of frames
0;3; 0.000000, 0.000000, 0.000000;;,
1;3; 0.000000, 0.000000, 0.005524;;,
2;3; 0.000000, 0.000000, 0.022217;;,
...
}
AnimationKey {
0; //Quaternion Rotation
121;
0;4; -0.707107, 0.707107, 0.000000, 0.000000;;,
1;4; -0.697332, 0.697332, 0.015710, 0.015710;;,
2;4; -0.684805, 0.684805, 0.035442, 0.035442;;,
...
}
AnimationKey {
1; //Scale
121;
0;3; 1.000000, 1.000000, 1.000000;;,
1;3; 1.000000, 1.000000, 1.000000;;,
2;3; 1.000000, 1.000000, 1.000000;;,
...
}
}
Jadi, untuk menerapkan frame 2, saya akan mengambil posisi, rotasi, dan skala dari frame 2, membuat matriks transformasi (sebut saja Transform_A
) dari mereka dan menerapkan matriks yang dikontrol oleh simpul Armature_001_Bone
pada bobotnya. Jadi saya TransformA
memasukkan barang ke shader saya dan mengubah simpul. Sesuatu seperti:
vertexPos = vertexPos * bones[ int(bfs_BoneIndices.x) ] * bfs_BoneWeights.x;
Di mana bfs_BoneIndices
dan bfs_BoneWeights
adalah nilai-nilai khusus untuk simpul saat ini.
Saat memuat dalam simpul jala, saya mengubahnya dengan rootTransform
dan meshTransform
. Ini memastikan mereka berorientasi dan diskalakan dengan benar untuk melihat pose bind.
Masalahnya adalah ketika saya membuat matriks transformasi (menggunakan posisi, rotasi dan skala dari animasi), itu tidak benar mengubah simpul. Ada kemungkinan lebih dari itu daripada hanya menggunakan data animasi. Saya juga mencoba menerapkan hierarki transformasi tulang, masih tidak ada dadu. Pada dasarnya saya berakhir dengan beberapa model bengkok. Juga harus dicatat bahwa saya bekerja di openGL, jadi setiap transpos matriks yang mungkin perlu diterapkan harus dipertimbangkan.
Data apa yang saya butuhkan dan bagaimana cara menggabungkannya untuk menerapkan animasi .x ke model?
Saya telah membuat beberapa tiruan dari apa ini terlihat, jika itu berguna.
Pertama saya hanya ingin menguji terjemahannya, ini adalah bobbing head, seperti apa di Blender:
http://i.stack.imgur.com/NAc4B.gif
Dan seperti apa itu dalam game (tidak masalah warnanya):
http://i.stack.imgur.com/nj2du.gif
Kemudian untuk rotasi saja, animasi adalah kepala berputar 360 derajat di sekitar sumbu vertikal. Seperti inilah tampilannya dalam game:
http://i.stack.imgur.com/gVyUW.gif
Catatan, seharusnya tidak ada kemiringan, hanya rotasi seperti komidi putar.
Memperbarui
Saya memiliki bagian terjemahan dari karya animasi. Tapi rasanya agak berantakan dan saya tidak tahu bagaimana menerapkannya pada rotasi.
Terjemahan bekerja dengan mengambil langkah-langkah ini:
- Ambil posisi dari bingkai animasi dan tukar
y
danz
nilai - Terjemahkan matriks transformasi dengan posisi yang diubah
- Ubah posisi matriks transformasi
- Terapkan matriks transformasi ke simpul
Jadi itulah bagaimana bisa bekerja, tapi bagaimana itu seharusnya bekerja umumnya untuk posisi, skala dan rotasi?
sumber
Jawaban:
Mungkin itu kuncinya, sudahkah Anda mencoba meniadakan beberapa koordinat Z untuk mengkonversi dari koordinat kidal DirectX ke OpenGL yang kanan?
Anda bisa meniadakan semua Zs sebelum menerapkan transformasi Anda, dan meniadakan kembali ketika selesai, melihat apakah hasilnya menjadi lebih baik.
EDIT
Mengganti koordinat Y dan Z adalah cara lain untuk mengubah kidal. Jadi Anda harus menyesuaikan transformasi Anda, periksa makalah ini untuk detailnya .
Fakta bahwa Anda harus memindahkan matriks Anda juga berarti Anda beralih dari baris-utama ke kolom-utama atau sebaliknya. Ini seharusnya tidak terlalu rumit untuk ditangani, Anda mungkin hanya perlu menemukan "tempat" yang tepat untuk melakukannya di saluran pipa Anda. Saya hanya menebak, tetapi melakukannya pada angka empat bisa berarti mengubah mereka menjadi matriks, mengubah posisi, dan kembali angka empat, jika lib Math Anda menawarkan pilihan ini.
sumber
OK, saya meluangkan lebih banyak waktu untuk ini dan membuatnya bekerja untuk banyak tulang, dan jauh lebih sedikit seperti hack (meskipun masih sedikit). Sistem yang saya miliki di tempat semula hampir benar. Namun, masalah utama adalah:
Kode saya untuk mengonversi Quaternion ke matriks salah. Saya sebenarnya masih tidak yakin mengapa ini salah, tapi saya tahu kode berikut berfungsi, sebagai bagian dari kelas Quaternion saya:
Selain itu, hanya saja:
finalMatrix = boneMatrix * skinMatrix * invertedBindMatrix;
Perhatikan bahwa
boneMatrix
harus menggunakan matriks animasi untuk setiap tulang, bukan matriks mengikat. Ini juga harus mendapatkan semua matriks orang tua seperti:Dan itu berhasil. Tinggalkan komentar jika Anda membutuhkan klarifikasi.
sumber