Rabu, 28 Desember 2011

sebuah pengantar untuk rangka informasi

Memahami Rangka Animasi
berisi animasi kerangka! Revolusioner kerangka animasi
sistem! Animasi realistis! Lihatlah hampir semua game 3D baru yang
kotak kata-kata ini, atau beberapa bentuk dari mereka, melompat ke kanan keluar pada Anda. Ini
tampaknya bahwa setiap permainan baru menggunakan beberapa bentuk animasi tulang.
Anda mungkin telah melihat animasi kerangka dalam tindakan; permainan seperti
Half-Life, Unreal Tournament seri, Soldier of Fortune II, dan Doom3
semua menggunakan animasi kerangka dalam satu bentuk atau lain. Gambar 5.1 menunjukkan salah satu permainan pertama yang membawa animasi kerangka ke komputer rumah


MEMAHAMI KERANGKA ANIMASI
Animasi rangka adalah penggunaan "tulang" untuk menghidupkan model daripada
mengedit dan memindahkan setiap sudut atau wajah secara manual. Setiap simpul terpasang
ke tulang (atau dalam beberapa kasus beberapa tulang). Sebuah tulang atau root
hanya titik kontrol untuk sekelompok simpul. Ini adalah serupa dalam
konsep untuk root di tubuh kita rootri, seperti lutut kami atau pergelangan tangan. Ketika bergerak tulang, setiap simpul melekat bergerak juga, seperti
ditunjukkan pada Gambar 5.2. Bahkan gerakan tulang itu rootri dapat menyebabkan
perubahan tulang lainnya. Ini membantu naikkan model tepat,
karena gerakan di salah satu bagian dari tubuh mempengaruhi bagian lain dari
tubuh, seperti dalam kehidupan nyata. Akibatnya, programmer dituntut untuk bekerja
dengan tulang untuk menghitung transformasi untuk simpul individu.
Meskipun hal ini dapat bekerja lebih, hasilnya pasti bagus.

KEUNTUNGAN KERANGKA ANIMASI

Animasi kerangka memiliki banyak keuntungan dibandingkan simpul tradisional animasi, yang Anda lihat dalam bab-bab sebelumnya. Yang pertama, dan paling terlihat pemain permainan realisme meningkat. Karakter animasi Skeletally cenderung bergerak jauh lebih realistis, dan sering muncul untuk berinteraksi lebih baik dengan lingkungan sekitar mereka daripada model tradisional. Model Alasan cenderung bergerak lebih realistis jika mereka skeletally animasi sederhana. Dalam animasi keyframe tradisional,permainan akan interpolasi linear antara dua pose. Namun, dalam kasus ini, root tidak benar-benar memutar, yang dapat menjadi masalah karena organisme hidup bergerak dalam cara rotasi.

Tidak cukup sebagai nyata pada pengguna, tetapi sangat penting bagi programmer,
adalah bahwa animasi seperti mengambil lebih sedikit ruang penyimpanan. Bukan menyimpan satu set baru simpul untuk setiap frame, semua yang perlu disimpan adalah rotasi dan terjemahan tulang. Itu bisa mencapai yang besar tabungan, bahkan setelah Anda menambahkan penyimpanan meningkat awal tulang dan titik-tulang Informasi lampiran.
Ini sedikit tambahan ruang penyimpanan dapat digunakan untuk menyimpan lebih rinci Model, menambahkan frame animasi tambahan, atau bahkan hanya dibiarkan untuk bagian lain dari permainan yang Anda ingin meningkatkan. Anda bisa menambahkan lebih detail untuk permainan dunia, meningkatkan A.I. untuk menyediakan permainan yang lebih menarik, atau bahkan menambahkan beberapa tambahan keren atau telur Paskah yang Anda tidak akan tambah sebaliknya, karena kekhawatiran ruang.
Namun keuntungan lain terletak pada seniman yang membuat konten 3D untuk
permainan Anda. Sebuah sistem animasi yang baik akan memotong kerangka waktu para seniman perlu untuk menghidupkan model mereka. Hampir setiap program animasi yang bagus menggunakan animasi sudah kerangka untuk memastikan transisi yang mulus dari model dari para seniman untuk programmer, untuk permainan, dan akhirnya ke pemain. Ini mempercepat penciptaan konten untuk permainan, dan memastikan bahwa tidak ada animasi atau fitur yang hilang ketika model yang diekspor ke format apapun permainan Anda menggunakan.
Keuntungan keempat adalah satu lagi untuk programmer (itu hanya akan yang lebih baik dan lebih baik, bukan?). Karena sifat tulang, itu adalah mungkin untuk memposisikan mereka secara real-waktu jika Anda ingin, memungkinkan diperlukan animasi yang akan dibuat selama runtime. Hal ini memberikan jauh lebih beragam perpustakaan animasi mungkin. Anda bahkan dapat membiarkan mengendalikan permainan cara tubuh bertindak ketika bertabrakan dengan objek, atau slide ke bawah kemiringan. Ini jenis teknologi yang baru saja datang ke dalam bermain, terkenal contoh yang Unreal Tournament 2003 Fisika sistem (http://
www.epicgames.com). Karakter dan model bereaksi secara realistis dengan lingkungan, termasuk meluncur menuruni lereng dan mengalungkan di tepi.
Kerugian satu adalah bahwa animasi skeletal bisa lebih sulit untuk memahami dan menerapkan dari animasi keyframed tradisional.
Bab ini akan membantu Anda meringankan ketakutan apapun yang mungkin Anda miliki tentang kerangka animasi.


Bagian dalam rangka kerja animasi

Lihatlah lengan Anda. Memperpanjang ekstremitas keluar di depan Anda dan lihatlah dalam hal itu. Lengan Anda memiliki beberapa tulang, dua yang utama, dan banyak yang lebih dalam tangan dan jari Anda.
Gerakkan jari-jari Anda di sekitar, hanya jari-jari Anda bergerak ke kanan? Dengan bergerak Anda jari, tidak ada bagian lain dari lengan Anda, atau dalam hal ini, setiap bagian lain dari tubuh Anda bergerak dengan itu. Sekarang tekuk siku Anda. Tidak hanya lengan Anda bergerak, tetapi jari-jari dan tangan Anda bergerak ke atas juga. Jika mereka tidak Anda lengan akan menjadi terputus dari tangan dan jari, dan mereka akan dibiarkan tergantung di sana di udara; pikiran yang tidak cantik.
Bagaimana latihan lengan sedikit berhubungan dengan animasi tulang? Nah,
lengan Anda merupakan bagian dari model 3D, jari-jari Anda, tangan, lebih rendah dan lengan atas semua potongan model ini. Berbagai root dan tulang jalankan
melalui lengan Anda, dengan root di bahu, siku, pergelangan tangan, dan jari.
Ini menunjukkan Anda bahwa ketika Anda memindahkan tulang "jauh sampai" di lengan Anda, segala sesuatu di bawah bergerak juga. Ini adalah salah satu konsep yang paling dasar animasi kerangka.
Keindahan ini adalah bahwa hal itu memungkinkan Anda untuk memindahkan tulang apapun dalam model, dan filter gerakan bawah garis, menerapkannya pada segala sesuatu di bawah asal gerakan. Hal ini memungkinkan Anda untuk memindahkan bahu karakter, misalnya, tanpa perlu khawatir tentang mendapatkan
siku dan tangan di tempat yang tepat. Anda dapat yakin bahwa mereka akan otomatis akan diperbarui juga. Gambar 5.3 menunjukkan beberapa contoh root dan simpul yang menyertainya.Root root adalah root utama dalam model. Setiap root lainnya akhirnya menemukan jalan kembali ke root ini satu. Setiap operasi yang dilakukan pada root akar, apakah mereka akan terjemahan atau rotasi, mempengaruhi setiap verteks dalam model. Anda dapat menganggap root root sebagai root yang mengontrol semua root lainnya. Dengan hanya memodifikasi root root, Anda bisa membuat karakter berjalan tegak, atau Anda bisa memutar begitu dia terbalik dan membiarkan dia berjalan di langit-langit-semua dengan panggilan tunggal.
Hanya ada satu akar bersama di masing-masing model, dan tidak memiliki root orangtua.
Root root umumnya berada di tempat di mana tulang banyak yang datang
bersama, namun di tempat di mana animasi sedikit dibutuhkan. contohini meliputi bagian tengah dan punggung bawah. Tapi tidak ada yang menentukan persis di mana root akar harus terletak di dalam sebuah model, melainkan dapat berbeda untuk setiap model jika Anda inginkan. Gambar 5.4 menunjukkan apa akan terjadi untuk model jika Anda memodifikasi posisi dan orientasi dari root akar.

Induk dan Anak Root
Root dapat memiliki orang tua dan root anak. Induk dari root mempengaruhi
semua yang dilakukannya. Rotasi induk dan terjemahan ini diambil ke account ketika menghitung posisi baru root saat ini. Menggunakan analogi lengan lagi, root siku akan menjadi induk dari tangan bersama. Pindah siku mempengaruhi tangan. Dalam implementasi sederhana animasi kerangka, setiap root hanya memiliki satu root orang tua, jika memiliki sama sekali.

Namun, root root dapat memiliki banyak anak. Sebuah root anak sebaliknya
pada root induk. Segala sesuatu yang Anda lakukan untuk bersama orang tua akan menyaring ke dalam root anak. Cara lain untuk melihat ini adalah bahwa bersama saat ini adalah induk untuk semua root di bawahnya.

Keyframes dalam rangka Animasi

Seperti kunci berbingkai animasi yang menyimpan beberapa salinan simpul, sistem animasi tulang juga memiliki keyframes. ingat bahwa keyframes adalah snapshot dari posisi model. Namun, daripada setiap keyframe berisi salinan rootri dari
simpul, animasi keyframe kerangka atau boneframe mengandung transformasi,
baik rotasi dan translasi, umumnya dalam bentuk X, Y, Z nilai untuk terjemahan, dan tiga nilai yang mengandung rotasi di sekitar X, Y, dan sumbu Z, masing-masing. Sama seperti dengan keyframes dhuwur biasa, ini boneframes harus diinterpolasi untuk memberikan hasil yang halus.
Nilai-nilai posisi atau penerjemahan dapat interpolasi linear antara, sama seperti Anda telah melakukan dengan simpul di pasar tradisional animasi. Rotasi menimbulkan masalah. Cukup disisipkan antara mereka seperti yang Anda lakukan dengan nilai-nilai terjemahan dapat menyebabkan aneh efek. Rotasi tidak akan mulus, tetapi akan mempercepat dan memperlambat tergantung pada lokasi. Jika perbedaan rotasi besar,
Model mungkin muncul untuk "cairan" seperti benjolan dari gelatin. Hal ini karena
bila menggunakan interpolasi linier, semuanya akan diinterpolasi sepanjang garis lurus. Hal ini dapat menyebabkan efek aneh jika dilakukan dengan rotasi karena rotasi dimaksudkan untuk diinterpolasi sepanjang busur bukan garis. Memotong lurus melintasi busur daripada mengikuti hal itu menyebabkan "cairan" efek.

Cara terbaik untuk berkeliling ini adalah dengan menggunakan quaternions. Seperti yang Anda pelajari dalam Bab 2, "Pengantar Quaternions," salah satu yang terbesar keuntungan dari quaternions adalah bahwa mereka dapat diinterpolasi dengan mudah. Tidak hanya bisa mereka dengan mudah diinterpolasi, mereka dapat dengan mudah bola linear diinterpolasi.
Interpolasi linier Bulat interpolates antara dua titik pada permukaan bola. Namun, daripada memotong langsung dari satu sampai interpolasi, lainnya linier bola mengikuti permukaan bola. Anda dapat memvisualisasikan ini dengan mengambil sebuah bola bundar, seperti basket, dan penandaan dua poin di atasnya. Kemudian, dengan menggunakan jari Anda, menemukan jalur terpendek antara dua titik. Karena jari Anda tidak bisa pergi di dalam bola, jalur yang dihasilkan antara dua poin akan busur.
Ini adalah apa SLERP tidak. Menggunakan fungsi SLERP, rotasi dapat diinterpolasi sepanjang busur, menciptakan mulus bagus, mata-efek menyenangkan.

Mengambil posisi

Interpolasi linier Bulat interpolates antara dua titik pada permukaan bola. Namun, daripada memotong langsung dari satu sampai interpolasi, lainnya linier bola mengikuti permukaan bola. Anda dapat memvisualisasikan ini dengan mengambil sebuah bola bundar, seperti basket, dan penandaan dua poin di atasnya. Kemudian, dengan menggunakan jari Anda, menemukan jalur terpendek antara dua titik. Karena jari Anda tidak bisa pergi di dalam bola, jalur yang dihasilkan antara dua poin akan busur.
Ini adalah apa SLERP tidak. Menggunakan fungsi SLERP, rotasi dapat diinterpolasi sepanjang busur, menciptakan mulus bagus, mata-efek menyenangkan.

Bagian ini membahas tentang bagaimana mengubah ini sehingga root bekerja
bersama-sama. Hal pertama yang Anda lakukan adalah membangun sebuah matriks transformasi untuk setiap titik menggunakan data dari arus rotasi dan translasi keyframes. Sebuah matriks transformasi dapat dibangun dengan pertama-tama menghasilkan matriks dan matriks rotasi tiga terjemahan seperti yang ditunjukkan dalam Bab 1.
Mengalikan bersama tiga akan menghasilkan transformasi akhir matriks. Atau Anda dapat menggunakan SetRotation dan SetTranslation fungsi dalam kelas matriks untuk menghindari harus membangun dan berkembang biak matriks rootri. Matriks ini disebut matriks relatif.
Selanjutnya, Anda perlu menghitung apa yang disebut matriks absolut. mutlak
matriks adalah matriks relatif root absolut dikalikan dengan induknya
matriks. Matriks transformasi absolut memberitahu Anda mutlak root.
Ini termasuk transformasi relatif, serta semua transformasi setiap root sebelum dalam hirarki telah dibuat. Hal ini yang memungkinkan root untuk bergerak lainnya sebagai akibat dari bergerak bersama jauh sampai di baris. Pertimbangkan, misalnya, bagaimana siku Anda bergerak ketika Anda bergerak bahu Anda. Hal ini menimbulkan pertanyaan: bagaimana Anda menghitung

Dunia yang dihasilkan matriks posisi segala sesuatu sehingga ketika tulang berikutnya ditarik, transformasi dari root orangtua dipertimbangkan.
Sebagai contoh, pinggul karakter dapat diputar tertentu jumlah. Karena root lutut dan pergelangan kaki adalah anak-anak dari pinggul bersama, mereka juga akan diputar.
Fungsi rekursif menggambar begitu, seperti setiap root ditarik, itu panggilan yang
menggambar fungsi anak-anaknya. Setiap anak panggilan rendering fungsi dari anak-anaknya, dan sebagainya. Hanya ketika bersama terminal mencapai (satu dengan tidak ada anak), adalah matriks tumpukan ulang menggunakan perintah seperti glPopMatrix. Misalnya, ketika menggambar kaki dari karakter, matriks baru dapat mendorong pada stack untuk lutut, sudut, dan kaki root. Tetapi ketika saatnya untuk mulai pada lengan, Anda ingin untuk pop kembali ke posisi semula. Jika tidak, setiap kali Anda pindah kaki, lengan akan bergerak juga.

Menempelkan Mesh

Ketika anda lancar dengan root, sekarang saatnya untuk melampirkan mesh.
Mesh adalah apa yang membentuk bentuk model. Ini adalah sekelompok
simpul dan segitiga yang membantu model memiliki volume dan detail.
Tanpa mesh, model skeletally animasi hanya akan menjadi kerangka. Setiap simpul jaring menyimpan indeks ke dalam array bersama untuk menandakan
yang terpasang pada tulang tertentu. Sekarang, cara root disimpan menentukan metode transformasi dan rendering simpul tersebut.
Jika root yang disimpan dengan indeks masing-masing memiliki induknya, dan Anda memiliki sudah pergi melalui dan menghitung matriks mutlak akhir, melampirkan mesh sederhana. Setiap simpul harus diubah oleh patungan yang
mutlak matriks. Pastikan untuk menyimpan verteks Anda diubah dalam khusus
tempat, jangan menimpa Anda simpul asli. Hal ini dilakukan karena dalam
format yang paling, yang boneframes tidak kumulatif. Setiap frame menyimpan
rotasi dan translasi pada root tertentu dari titik awal. Jika Anda tidak kembali ke simpul asli ketika menghitung verteks baru posisi setiap waktu, model ini akan bekerja tidak konsisten.
Sekarang Anda mungkin berpikir untuk diri sendiri, "baik, saya bisa menghidupkan simpul model, tapi bagaimana dengan segitiga, normals, dan koordinat tekstur "?
Ini adalah di mana animasi kerangka benar-benar mulai bersinar. Setiap Model hanya berisi satu set koordinat tekstur dan informasi segitiga.
Hanya karena posisi simpul perubahan tidak berarti indeks segitiga dan koordinat tekstur harus. Ini berarti Anda tidak perlu khawatir tentang mereka setelah Anda mengaturnya.
Normals adalah cerita lain. Karena orientasi poligon dan simpul perubahan, sehingga akan normals. Jika Anda hanya menggunakan wajah normals, Anda perlu menghitung ulang secara manual setiap frame sebelumnya mengirim mereka ke penyaji. Namun, jika Anda dihitung verteks normals di awal, Anda sedang beruntung. Normals Vertex tidak memiliki harus benar-benar dihitung kembali setelah transformasi. Mereka dapat ditransformasikan oleh matriks sama dengan simpul tersebut. Satu-satunya perbedaan di sini adalah bahwa Anda tidak mengambil dalam terjemahan akun. Menggunakan Transform3 () fungsi dari kelas matriks akan memutar titik yang normal Anda, sementara masih mempertahankan besarnya aslinya. Jika root menyimpan indeks anak dan Anda mendorong arus
matriks transformasi ke stack menggunakan glPushMatrix, render model Anda menjadi sangat mudah. Dalam hal ini, tidak perlu mengubah setiap titik sebelum menampilkan itu. Tidak ada perubahan yang diperlukan untuk rendering apa pun. Segala sesuatu yang Anda membuat sekarang akan berubah benar, bahkan wajah normals. Isu lain yang perlu dipertimbangkan adalah bagaimana simpul yang melekat pada lebih dari satu tulang. Dalam hal ini, setiap tulang

Demo
Demo pada bab ini memungkinkan Anda untuk melihat hubungan antara orang tua
dan anak root, dan melihat apa yang terjadi ketika root individu dimanipulasi, seperti yang ditunjukkan pada Gambar 5.9.
Demo memungkinkan Anda untuk memilih dari salah satu dari empat root dan memodifikasi nya rotasi dan penerjemahan nilai-nilai. Nilai-nilai baru pada gilirannya mempengaruhi root yang jauh di bawah garis (root anak). Dengan memanipulasi yang berbeda root, Anda dapat melihat efek dari tindakan Anda pada semua root lain.
Angka-angka root, dari atas layar ke bawah, sebagai berikut: 1,0, 2, 3. Bersama 1 dan 3 merupakan root terminal. Mereka adalah tepat pada ujung"model" dan bergerak baik dari mereka akan memiliki efek pada root lainnya dalam model.
Bersama 2 adalah induk dari 3 root. Mengubah nilai-nilai ini menyebabkan root
bersama 3 untuk bergerak juga: mencoba dan melihat. Akhirnya, root root 0 adalah akar.
Apa pun yang Anda lakukan untuk bersama ini akan mempengaruhi setiap root lain pada layar.

Demo Kontrol
Di sisi kiri layar, Anda akan melihat kotak dialog berisi berbagai kontrol dan kotak teks, seperti yang ditunjukkan pada Gambar 5.10.

Gambar 5.9 Sebuah demo animasi kecil sederhana kerangka. Anda dapat memutar dan menerjemahkan
individu root, menggunakan panel kontrol di sebelah kiri, dan melihat efeknya pada root lainnya.

Gambar 5.10 Panel kontrol memungkinkan Anda untuk mengontrol posisi dan
rotasi setiap root. Memilih root dari tombol pada bagian atas kotak kontrol, dan kemudian menggunakan panah atas dan bawah pada kotak kontrol memungkinkan Anda untuk menerjemahkan dan memutar root dalam model.
Tombol radio pada bagian paling atas dari kotak dialog kontrol pilih root Anda ingin memodifikasi.
Di bawah tombol radio enam mengedit kotak. Kotak-kotak ini memungkinkan
Anda untuk mengubah orientasi dari root yang dipilih. Set atas kotak mengubah rotasi root di sekitar X, Y, dan sumbu Z, sedangkan set X berubah bawah objek, Y, dan Z penerjemahan.
Di bawah kotak-kotak adalah satu set hanya-baca mengedit kotak. kotak-kotak ini
berisi angka empat rotasi setara dan matriks transformasi yang akan digunakan untuk mengubah setiap simpul terhubung ke root. Bersama Induk kotak kecil berlabel menampilkan orang tua root saat ini.
Demo menyenangkan untuk menulis dan dapat menghibur untuk bermain dengan. Perhatikan dengan seksama untuk melihat bagaimana tindakan Anda mempengaruhi root-root lain di TKP. Pastikan untuk memeriksa bantuan pada layar ketika Anda pertama kali menjalankan program. Membantu akan ditampilkan pada layar ketika Anda pertama kali mulai dan dapat toggled dan mematikan dengan menekan H.

TIP
Meskipun Anda dapat menerjemahkan root dalam animasi rangka, maka
umumnya terbaik untuk tetap dengan rotasi. Jika Anda berpikir tentang itu, pada tubuh Anda rootri, tidak ada perubahan root Anda pernah posisi, bersama lebih tinggi-up hanya berputar. Misalnya, jika anda menggerakkan tangan Anda menjauh dari tubuh Anda, Anda tidak menerjemahkan tangan, Anda memutar siku sebagai gantinya. Para tubuh manusia tidak memiliki pelengkap telescoping,
sehingga hampir 100% dari gerakan dapat dilakukan dalam hal rotasi, bukan terjemahan.
Satu-satunya pengecualian untuk aturan ini bersama akar. Menerjemahkan root root akan memindahkan seluruh model, yang berguna jika Anda ingin mengubah posisi sebenarnya dari model dalam animasi. Anda akan menggunakan ini jika
Anda perlu model Anda untuk mengubah posisi selama animasi, seperti untuk berjalan maju. Namun, secara umum terbaik untuk membiarkan permainan mengurus bergerak model di seluruh dunia. Ini berarti bahwa semua model yang perlu berjalan atau berlari animasi akan berjalan dan berlari "dalam
tempat ". Game ini akan menambahkan dalam maju atau mundur Gerakan kemudian.
Aplikasi Lanjutan rangka Animasi
Itu cukup banyak wraps up pengantar untuk animasi kerangka. Tapi sebelum Anda pergi, melihat beberapa cool stuff yang dapat dilakukan dengan lebih maju teknik, di luar cakupan buku ini.
Gambar 5.11 menunjukkan tembakan dari Epic itu Unreal Tournament 2003. Unreal Turnamen 2003 adalah salah satu permainan pertama yang menerapkan yang baik "Ragdoll" sistem. Dalam sistem Ragdoll, tubuh berubah sesuai dengan mereka lingkungan. Sebagai contoh, ketika seseorang terbunuh dalam permainan sementara berdiri di atas bukit, tubuh mereka tidak tetap berbaring dalam garis lurus seperti yang umum dalam banyak permainan penembak lainnya. Sebaliknya, tubuh slide menuruni bukit dengan cara realistis, terpental dan meluncur saat mengikuti orientasi medan. Metode animasi menambahkan banyak realisme dan believability permainan apapun.



Gambar 5.11 Unreal Tournament 2003 yang Ragdoll sistem dalam tindakan. Perhatikan bagaimana
tirai tubuh rootri sekitar lubang, seperti manusia nyata.

Kesimpulan
Ini menyimpulkan pengenalan Anda untuk animasi kerangka. Mudah-mudahan Anda memiliki pemahaman tentang bagaimana animasi kerangka bekerja dan mengapa banyak permainan yang mulai menggunakannya.
Beberapa bab berikutnya akan menggunakan informasi ini sebagai Anda mulai belajar tentang format yang menggunakan animasi rangka untuk animasi. Anda akan dapat melihat langsung gerakan, kelancaran cairan model dan mulai
menghargai ide di balik animasi kerangka. Bab berikutnya mencakup format 3D Milkshape, juga dikenal sebagai MS3D. Hal ini dibuat oleh seorang editor shareware, juga disebut 3D Milkshape. Dirilis oleh penulisnya sebagai shareware, itu dengan cepat menjadi salah satu terpanas alat untuk pengembang game independen mana-mana. nya rendah harga, kemampuan untuk model output untuk berbagai permainan dan program, dan upgrade melalui plug-in telah dengan cepat berhasil menjadi favorit di antara seniman dan programmer sama. Baca terus untuk mengetahui tentang format ini menarik dan berguna.

Tidak ada komentar:

Posting Komentar