Loading Meshes from X Files

  S E N G

  • H

  Advanced Meshes

  A N S

  Level 9

GRAFIKA KOMPUTER DAN ANIMASI U

  N S E N

  Using Basic Meshes

  G

  • H

   What is a Mesh?

   Making Preconstructed Meshes

  A N

   The Finished Program

  S

  

Loading Meshes from X Files

  U N

   About Subsets  Loading an X File to a Mesh

   The Finished Program S E N

  Loading Textured Meshes

  G

  • H

   Loading and Displaying Textures

   The Finished Program

  A N

  Animated Meshes

  S

   Basic Concepts

  U N

   Loading the Mesh  Rendering the Mesh

   Cleanup

   The Finished Program S E N

   Tanpa menggunakan tekstur, sangatlah sulit untuk

  G membuat pemodelan yang realistis.

  • H

   Untungnya, meshes memiliki kemampuan untuk

  A

  menambahkan tekstur ke suatu file .x, sehingga Anda

  N

  tidak perlu menambahkannya secara manual untuk

  S U setiap tekstur yang ada. N

   Sayangnya, terdapat beberapa code tambahan yang perlu diterapkan.

   Akan dijelaskan pada pertemuan kali ini. S E N G

  http://directxtutorial.com/Lesson.as

  • px?lessonid=9-6-3

  H A N S U

  2 langkah untuk menampilkan

  N

  tekstur:

  1. Load the textures while loading the mesh

  2. Set the subset’s texture before each subset is drawn S E N

  Pointer to the textures

  G

  • H A N S

  Creates a blank texture for each subset

  U N

  S E N G

  • H A N S U N

  Check whether a texture exist or not. If it exists then set the texture. S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N

   Jangan lupa .x file diletakkan dalam folder project Anda.

  S E N G

  • H A N S U N

   Untuk contoh ini, airplane 2.x beserta file teksturnya, yakni bihull.bmp dan wings.bmp. S E N G

  • H A N S U N
S E N

   Untuk membuat suatu animasi, tidak cukup hanya

  G dengan memanggil fungsi D3DXLoadMeshFromX().

  • H

   Terdapat beberapa hal yang perlu diketahui terlebih

  A

  dahulu, seperti:

  N S

   Mesh skeletons

  U

   Mesh hierarchy

  N

   Frames and mesh containers

   Skinning and vertex weight

   Keyframes S E N

   Model animasi memiliki cara yang lebih baik untuk

  G menangani dirinya sendiri.

  • H

   Daripada mengubah koordinat tiap titik setiap kali

  A

  proses render dilakukan, 3D art programs

  N

menanganinya dengan menggunakan skeletons.

  S U

  

Skeleton merupakan kumpulan obyek-obyek yang

  N

  disebut bones, yang digunakan oleh seorang animator untuk mengubah bentuk dari modelnya. S E N G

  • H A N S U N

  http://directxtutorial.com/Lesson.aspx?lessonid=9-6-4 S E N

   Dalam DirectX, digunakan matriks untuk

  G

  merepresentasikan joints yang menggambarkan apa

  • H yang terjadi dalam code programnya.

  A

   Setiap matriks merepresentasikan satu joint dan

  N dapat memiliki rotasi dan translasi.

  S U

   Matriks setiap joint memiliki informasi rotasi joint

  N dan posisi joint terhadap matriks terakhir lainnya.

  

  3D modeling program membangun matriks-matriks ini untuk Anda.

   Setelah di-load, Anda dapat mengikuti hirarki model,

dengan mengalikan matriks-matriks tersebut. S E N G

  • H A N S U N

  http://directxtutorial.com/Lesson.aspx?lessonid=9-6-4 S E N

   Terdapat 2 komponen dalam animated mesh: joints

  G dan mesh containers.

  • H

   Joint disebut juga sebagai frame.

  A

   Mesh container adalah suatu struct yang menyimpan

  N S

  seluruh data tentang mesh, atau suatu bagian dari

  U mesh. N

   Frame adalah suatu struct yang mengandung suatu matriks, yang mendefinisikan lokasi dan rotasi suatu joint → posisi suatu bagian dari suatu mesh. S E N

   Jika bones merupakan bagian yang menyatukan

  G

  semuanya, maka skin adalah apa yang Anda lihat di

  • permukaan.

  H A

   Skin adalah suatu larik polygons yang membangun

  N suatu model.

  S

  

Skin disimpan dalam mesh container dari suatu

  U animated mesh sebagai titik-titik dan indeks-indeks. N

   Dalam animated mesh, setiap titik disimpan dalam

suatu frame (joint) dan memiliki suatu bobot.

   Bobot (weight) merupakan suatu nilai yang menentukan seberapa besar suatu titik dipengaruhi oleh perubahan joint. S E N

   Keyframe merupakan posisi suatu mesh yang

  G

  mendefinisikan titik awal dan akhir dari suatu

  • H animasi.

  A

   Sekumpulan keyframes disimpan dalam animated

  N mesh.

  S U

   Setelah DirectX menentukan posisi awal dan akhir

  N

  dan berapa lama waktu yang dibutuhkan dari satu posisi ke posisi lainnya, DirectX akan menghitung sekumpulan matriks baru untuk mesh setiap kali mesh di-render.

   Hal ini membuat animasi menjadi mudah.

   Merupakan langkah terbanyak yang perlu dilakukan. 

  • H A N S U N

  DirectX 9 memberikan kita kendali penuh untuk mengatur bagaimana data mesh dan hirarki disimpan dalam memory.

   Memberikan programmer kendali penuh terhadap mesh dengan mengizinkan mereka untuk menulis allocation code sendiri.

  S E N G

  Sangat berguna karena animasi mesh dapat bervariasi tergantung pada lingkungan, seperti karakter model yang memanjat tebing, dan sebagainya.

   Meskipun memberikan banyak fleksibilitas bagi game developers, namun sayangnya hal ini juga membuat banyak hal menjadi lebih rumit, karena API untuk animated mesh belum dikembangkan dengan terlalu baik, dan banyak hal yang harus dikerjakan.

  • H A N S U N

  

3 hal yang harus dilakukan untuk me-load dan

menyiapkan suatu animated mesh:

  1. Load the data from the .x file 2.

  Take each frame and mesh container and store it in memory

  3. Link each mesh container to its connecting frames

  S E N G

   Sayangnya urutan dalam coding tidak sama persis seperti urutan yang diberikan sebelumnya.

  • H A N S U N

   Yang harus dilakukan dalam menulis code-nya: 1.

  Add to the D3DXFRAME and D3DXMESHCONTAINER structs

  2. Write the four mesh allocation and deallocation functions 3.

  Call the allocation functions using D3DXLoadMeshHierarchyFromX()

  4. Allocate memory for the modified frame positions 5.

  S E N G

In each mesh container, store a pointer to each frame associated with it

  S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N

   Kedua structs tersebut membawa semua variabel

  G

  yang dibutuhkan untuk me-load hirarki dari frames

  • H

  dan mesh containers, namun belum memiliki semua

  A

nilai yang dibutuhkan untuk me-render-nya.

N

   Perlu ditambah nilai-nilai tertentu, dengan cara

  S U membuat struct kita sendiri. N

  S E N G

  • H A N S U N
S E N G

  • H A N S U N

  http://directxtutorial.com/Lesson.aspx?lessonid=9-6-4 S E N

   Pada langkah ke-3, kita akan memanggil fungsi

  G D3DXLoadMeshHierarchyFromX().

  • H

   Fungsi ini akan memulai seluruh proses loading, yakni

  A me-load data dan menyiapkannya untuk dialokasikan. N S

   Sayangnya, kita harus melakukan alokasi dan

  U dealokasi-nya sendiri. N

  

D3DXLoadMeshHierarchyFromX() memanggil

sekumpulan fungsi untuk mengatur mana yang harus dialokasikan dan mana yang didealokasikan.

   Yang disediakan hanyalah prototype, yang tersimpan dalam ID3DXAllocateHierarchy interface. S E N

  Common function

  G

  • COM

  H A A macro that defines a COM function that returns an HRESULT

  N S U N

  S E

  Will be called every time

  N

  Pointer of location of the new frame DirectX loads a new

  G

  Create a new joint from the x file Name of the frame

  • pointer and allocate

  H

  memory for it

  A N

  Contain the

  S

  address of

  U

  N

  Initialize the new CUSTOM_FRAME with ZeroMemory() Regular string copying S E N

   Fungsi ini dipanggil saat suatu mesh container di-load

  G dari x file.

  • H

   Mengikuti pola yang sama seperti CreateFrame(),

  A

  dimana kita mengalokasikan memory untuk suatu

  N

  mesh container baru, membersihkannya (zero it), dan

  S U kemudian meng-copy parameter-parameternya. N

   Namun fungsi ini sedikit lebih kompleks karena ada banyak parameter yang harus di-copy. S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N

  A. Create and initialize the custom mesh container struct B.

  Check to make sure it’s a normal mesh

  • H A N S U N

  C. Copy the name

  D. Copy the mesh data

  E. Copy the materials F.

  Copy the number of materials G. Copy the adjacency data H. Copy the skin data (if any) I. Allocate memory for the ppFrameMatrices value J. Create a duplicate of the mesh K. Load each texture L.

  S E N G

Find the maximum number of frames

  S E N

   Fungsi ini dimulai dengan cara yang sama seperti

  G pada CreateFrame().

  • H

   Pertama dibentuk suatu mesh container baru (yang

  A

  disebut pMeshContainer), mengatur parameter

  N

  ppNewMeshContainer ke alamat baru yang sama,

  S U dan kemudian menghapus memory-nya. N

   Ingat pMeshContainer ini karena akan sering digunakan.

   Terdapat 3 jenis mesh, yakni 1.

  • H A N S U N

  Patch Meshes, baik digunakan untuk me-render kurva (namun kurang cepat).

  2. Progressive Meshes, dapat mengatur dirinya sendiri untuk memiliki titik-titik yang lebih sedikit dan me- render lebih cepat.

  3. Normal Meshes, normal dan akan kita gunakan.

  

  S E N G

Mesh data struct

  S E N G

  • Check to make sure it’s a normal

  H

  mesh

  A N S U

  Deallocate all the memory

  N

  this function allocates ‘error fail’ or ‘epic fail’ S E N  Sama seperti saat kita meng-copy nama suatu frame.

  G

  

Bedanya hanyalah mengganti pFrame dengan

  • H pMeshContainer.

  A

   Langkah ini akan meng-copy nama dari parameter

  N S ‘Name’ ke pMeshContainer->Name.

  U N

  S E N G

  • H

  Copy the mesh type Copy the pointer

  A N S U N

  Using the AddRef() function which allows a COM object to continue even after the Release() function has been called S E N G

  Allocate some memory for the array of materials

  • H A N S U N

  Loop through each D3DXMATERIAL and copy it, and make the ambient equal to the diffuse S E N G

  • H A N S U N
S E N

  

Adjacency data adalah informasi tentang segitiga-

  G

  segitiga apa yang saling bertautan satu dengan yang

  • H lainnya.

  A

   Terdiri dari suatu larik DWORDs, dan berukuran 3

  N kali lebih besar (satu DWORD untuk 1 sisi segitiga).

  S U

   Saat mengalokasikan larik, digunakan fungsi

  N

  GetNumFaces() untuk memperoleh jumlah permukaan segitiga, lalu mengalikannya dengan 3. S E N

   Mesh merupakan suatu COM object, dan cara meng-

  G

  copy-nya mudah, cukup copy pointer-nya dan panggil

  • H fungsi AddRef().

  A

   Namun, tidak selalu ada informasi skin.

  N S

   Model-model yang tidak dianimasikan tidak

  U

  menggunakan skin information, sehingga kita copy

  N

  pointer dan panggil AddRef() hanya jika modelnya dianimasikan. S E N G

  • H A N S

   Merupakan suatu larik pointer-pointer yang merujuk

  U pada matriks-matriks frame. N

   Digunakan GetNumBones() untuk memperoleh jumlah frame yang ada, mengalokasikan sebanyak ruang tersebut ke ppFrameMatrices, kemudian me- loop kembali satu per satu dengan GetNumBones() dan mengatur nilainya menjadi NULL. S E N G

  • H A N

  A mesh copy of the original, will be used to change all the vertices around as the animation progressed

  S U

   Pada langkah ini, digunakan fungsi CloneMesh()

N untuk membuat tiruan mesh

  Used when we want to change various things such as the FVF Flags for memory management, use D3DXMESH_MANAGED code for the mesh.

  Pointer to device, d3dev S E N G

  • H A N S U N

   Pada langkah ini, kita me-loop setiap material, lalu me-load tekstur-nya jika ada.

   Perhatikan bahwa kita me-load tekstur ke dalam pMeshContainer->pTextures[i]; dan kita harus mengalokasikan ruang yang dibutuhkan terlebih S E N G

  • H

   MaxFrames merupakan global variabel yang

  A

  

menyimpan jumlah maksimum frame yang akan

  N dikaitkan dengan sembarang mesh container.

  S

   Dibutuhkan untuk langkah ke-4 dalam proses loading

  U mesh berikutnya. N

   Dimulai dengan mengecek ada atau tidaknya informasi skin, lalu digunakan fungsi GetNumBones() untuk memperoleh jumlah frames, kemudian dibandingkan dengan angka sebelumnya (jika ada), dan ambil nilai terbesarnya dengan fungsi max(). S E N

  Pointer to the frame we are now freeing

  G

  • H A

  Two macros which similar to

  N

  S U N

  A macro that checks a pointer to make sure it can be deleted, deletes it, and sets it to NULL The same thing as SAFE_DELETE(), but deletes for an array of pointers S E N

   Pada tahap ini kita melepas dan men-dealokasi-kan

  G

  seluruh hal yang dialokasikan di fungsi

  • H CreateMeshContainer().

  A N S U N

  S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N  Fungsi ini dipanggil dari dalam fungsi init_graphics().

  G

   D3DXLoadMeshHierarchyFromX() adalah fungsi

  • H yang memulai seluruh proses loading.

  A

   Hal pertama yang dilakukannya adalah me-load data

  N S dari x file.

  U

   Kemudian memanggil CreateMeshContainer() dan

  N

  CreateFrame() berulang kali hingga tidak ada lagi frames dan mesh containers tersisa.

   Setelah seluruh data di-copy, fungsi ini akan mempersiapkan hal-hal lainnya di belakang layar. S E N

  How the memory is managed for the mesh

  G

  A pointer to that big

  • The filename of the .x file we wish to load class we just wrote

  H A N

  Usual d3ddev

  S U N

  A pointer to a pointer to an animation controller

A pointer to a pointer to a frame.

  

We’ll put a blank pointer here called TopFrame Advanced, set it to NULL S E N G

  • H A N S U N
S E N

   Pada langkah ini, kita akan mengalokasikan memori

  G untuk suatu array matriks-matriks.

  • H

   Saat DirectX menganimasi mesh containers, DirectX

  A

  menginginkan frames ditangani sebagai suatu array

  N

  matriks-matriks, daripada suatu array dari

  S U D3DXFRAMEs atau CUSTOM_FRAMEs. N

  Highest number of frames any mesh container will need Zeroing-out the memory, so it can be properly used later S E N G

  • H A N S U N
S E N

   Tujuan dari langkah ini adalah menginisialisasi

  G ppFrameMatrices member untuk setiap mesh container.

  • H

  

Pertama perlu ditemukan seluruh mesh container.

  A

  Caranya dengan mencari dalam setiap frame dan cek

  N

  

pMeshContainer dari setiap frame. Setelah looping

  S seluruh frames, kita temukan semua mesh containers. U

  N 

  Ingat setiap mesh container dapat memiliki lebih dari 1 frame. Fungsi GetNumBones() memberitahu kita berapa banyak frame-nya. Untuk setiap mesh container, kita loop setiap frame dan buat ppFrameMatrices[] mengarah pada combined matrix frame. S E N G

  • H A N S U N

   Me-render suatu mesh jauh lebih mudah daripada me-load-nya.

  • H A N S U N

   Terdapat 4 langkah dasar: 1.

  Advance the time in the animation controller, getting new animation data

  2. Update each combined matrix with the new data 3.

  Update each mesh container using the combined matrices

  4. Render each mesh container individually

  S E N G

  S E N

   Akan digunakan fungsi AdvanceTime(), yang

  G

  merupakan anggota dari AnimationController yang

  • dirujuk saat kita memanggil

  H D3DXLoadMeshHierarchyFromX(). A N

   Merupakan suatu obyek COM yang menangani

  S seluruh animasi di belakang layar. U

   Pada dasarnya, kita cukup memberikan parameter

  N

  yang kita ingin agar dilakukan oleh model, dan obyek tersebut akan melalui seluruh CUSTOM_FRAMEs dan meng-update seluruh matriks untuk kita.

   Untuk saat ini, parameter yang diisi cukup jumlah waktu yang berlalu sejak model terakhir di-render. S E N G

  • H A N S U N
S E N

   Baris pertama code mengecek apakah ada animasi atau

  G tidak.

  • H

   Di dalam if(), terdapat sebuah variabel bernama Time

  A

  yang bersifat static. Variabel tersebut diinisialisasi dengan

  N

  fungsi GetTickCount() yang mengembalikan jumlah

  S waktu OS telah berjalan dalam miliseconds. U

  N 

  Selanjutnya digunakan AdvanceTime() yang memiliki 2 parameter, tapi yang akan digunakan hanya parameter pertama yang mengindikasikan jumlah waktu (dalam detik) animasi tersebut mesti berjalan.

   Di baris terakhir dalam if(), kita me-reset variabel Time untuk render berikutnya lagi. S E N

   Fungsi AdvanceTime() terhubung, di belakang layar,

  G dengan puncak dari mesh hierarchy.

  • H

   Artinya fungsi tersebut mampu menelusuri dan

  A

  meng-update setiap frame dari

  N TransformationMatrix.

  S U

  

 Namun, di awal kita gunakan matriks tambahan

  N untuk tiap frame, yakni CombTransformationMatrix.

   Untuk langkah ini, kita panggil fungsi rekursif lainnya, yakni update_frames().

   Fungsi ini akan menelusuri tiap frame, satu per satu, dan meng-update CombTransformationMatrix. S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N

   Setelah meng-update setiap frame matrices, kita harus

  G

  menerapkan data tersebut ke mesh containers yang

  • H sebenarnya.

  A

   Akan digunakan fungsi UpdateSkinnedMesh() untuk

  N tiap mesh container.

  S U

   Sebelum melakukannya, kita harus menerapkan apa

  N

  yang disebut sebagai offset matrices, yang akan me- reposisi mesh containers sehingga animation matrices diterapkan dengan benar.

   Pertama, perhatikan fungsi rekursif update_mesh_containers() berikut. S E N G

  • H A N S U N
S E

  Finalizing the

  N

  matrices

  G

  with

  • offsets

  H A N S U

  Updating

  N

  the mesh Recurse S E N

   Fungsi ini juga rekursif dan berjalan di seluruh

  G frames.

  • H

   Parameter fungsi yang diberikan adalah pointer ke

  A TopFrame. N S

   Di baris pertama isi, kita buat suatu pointer mesh

  U container dan memperoleh pointer-nya dari pFrame. N

   Selanjutnya kita punya if() statement. 

  Kita hanya akan melakukan proses selanjutnya bila terdapat mesh container yang memiliki informasi skin.

  Jika tidak ada salah satunya, maka kita cukup rekursif ke frame berikutnya. S E N Finalizing the Matrices with Offsets G

   Di dalam if(), terdapat for() loop.

  Kita peroleh nilai NumFrames dari GetNumBones(), dan

  H menggunakannya dalam loop. A N

   Di dalam loop digunakan fungsi baru yang disebut

  S

GetBoneOffsetMatrix(), yang diperoleh dari pSkinInfo.

U

   Suatu offset matrix adalah matriks untuk suatu frame yang

  N

  memindahkan titik-titik yang dipengaruhi oleh suatu frame ke pusat dari model secara keseluruhan.

   Agar modelnya dapat tampil dengan benar harus digandakan frame matrices dengan frame offset matrices.

   Di dalam loop kita set FinalMatrices ke frame offset menggunakan GetBoneOffsetMatrix(), lalu dikalikan dengan S E N

Updating the Mesh

  G

  • H A N S U N
S E N

  Updating the Mesh

  G

  • The array of matrices to apply Advanced, set it NULL

  H A N

  A pointer to a mesh where

  S

  the original mesh is stored,

  U

  has to be locked

  N

  A pointer to the mesh where the resulting mesh will be saved, has to be locked Flags that handle various details about the lock, set it NULL

  

A pointer to where the function will store the address of the data S E N

   Satu fungsi lagi yang akan dibahas adalah

  G draw_mesh(), yang juga merupakan fungsi rekursif.

  • H A N S U N
S E N G

  • H A N S U N
S E N

   Seperti bagian lainnya, parameter untuk fungsi ini

  G

  adalah suatu pointer ke suatu frame, dan kita

  • kirimkan TopFrame.

  H A

   Baris pertama membuat pMeshContainer, pointer

  N yang diperoleh dari pFrame->pMeshContainer.

  S

  

Selanjutnya dipastikan ada atau tidaknya mesh

  U container, karena kita ingin menggambarnya. N

   Jika ada, kita loop setiap material. Karena terdapat subset untuk setiap material, kita set material, tekstur, dan baru kemudian menggambar subset-nya.

   Sisa dari code tersebut adalah pemanggilan rekursif seperti bagian lainnya. S E N

   Jangan lupa, kita juga harus membersihkan memory

  G yang telah dialokasikan sebelumnya.

  • H

   Beberapa hal yang perlu dilakukan:

  A 1.

  Release the animation controller

  N S 2.

  Free the memory allocated for the animated mesh

  U 3.

  Free the FinalMatrices array

  N

  S E N G

  • H A N S U

   Digunakan fungsi D3DXFrameDestroy().

  N

  The pointer to the topmost frame, or TopFrame A pointer to that big class we wrote in the first half of S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N
S E N G

  • H A N S U N

  

   Untuk menjalankan code di atas, diperlukan Tiny.x model, dan teksturnya, Tiny_skin.dds.

  S E N G

  • H A N S U N

Kedua files tersebut dapat ditemukan dalam folder Samples di dalam DirectX SDK

  S E N G

  • H A N S U N
S E N

  http://directxtutorial.com/

  G

Other web resources.

  • H A N S U N