Assalammualaikum.
Setelah kita tahu serba sedikit mengenai objek-objek dalam persekitaran 1D,2D dan 3D. Dan kita juga telah mengetahui kaedah untuk loading data .obj.
Maka seterusnya kita akan menggunakan data-data yang ada untuk mewujudkan Bounding-Volume bagi objek yang kompleks.
Tujuaannya adalah untuk memudahkan tugas pengesanan pelanggaran sesama objek.
Sebelum ini. Kita perlu mengetahui beberapa perkara iaitu:-
a) Jumlah Vertex
b) Setiap titik vertex tersebut (X,Y,Z)
c) Kita menyimpan Jumlah Vertex dalam variable integer type. Dan titik vertex saya simpan dalam vector array supaya memudahkan saya
Bagaimana hendak declare vector array?
Oleh sebab saya jenis menggunakan struct untuk declare vector tersebut
#include <vector> using namespace std; typedef struct { float x; float y; float z; }vectorf; typedef struct { int x; int y; int z; }vectori;
Seterusnya, saya memanggil header file yang mengandungi kedua-dua struct ini untuk digunakan dalam function pembinaan AABB ini.
vectorf minPoint,maxPoint; vector<vectori> TPointTest;
Terdapat beza antara kedua dua ini. minPoint dan maxPoint hanya single vector sahaja manakala TPointTest tersebut merupakan vector yang boleh menyimpan lebih dari single vector
Seterusnya ada langkah-langkah yang perlu diikuti untuk mencari titik maksimum dan minimum bagi sesebuah objek
Step Pertama : Calculate Min Max
void cAABB::AABBCalculateMinMax(cAABB *tAB, cObjConf *sourceObj) { //initialize vectorf aabbmin,aabbmax; aabbmin.x = 0; aabbmin.y = 0; aabbmin.z = 0; aabbmax.x = 0; aabbmax.y = 0; aabbmax.z = 0; for(int i=0; i<sourceObj->T_Vertex; i++) { //min x if(aabbmin.x > sourceObj->Vertex[i].x) { aabbmin.x = sourceObj->Vertex[i].x; } //min y if(aabbmin.y > sourceObj->Vertex[i].y) { aabbmin.y = sourceObj->Vertex[i].y; } //min z if(aabbmin.z > sourceObj->Vertex[i].z) { aabbmin.z = sourceObj->Vertex[i].z; } //max x if(aabbmax.x < sourceObj->Vertex[i].x) { aabbmax.x = sourceObj->Vertex[i].x; } //max y if(aabbmax.y < sourceObj->Vertex[i].y) { aabbmax.y = sourceObj->Vertex[i].y; } //max z if(aabbmax.z < sourceObj->Vertex[i].z) { aabbmax.z = sourceObj->Vertex[i].z; } } tAB->minPoint.x = aabbmin.x; tAB->minPoint.y = aabbmin.y; tAB->minPoint.z = aabbmin.z; tAB->maxPoint.x = aabbmax.x; tAB->maxPoint.y = aabbmax.y; tAB->maxPoint.z = aabbmax.z; }
– Saya memperkenalkan dua class iaitu satu untuk cAABB dan satu lagi merupakan class bagi object file iaitu cObjConf.
– sourceObj->T_Vertex merujuk kepada jumlah vertex bagi objek tersebut
– sourceObj->Vertex[i].x, sourceObj->Vertex[i].y, dan sourceObj->Vertex[i].z merupakan titik vertex (x,y,z) yang kita perlu gunakan gegelung for untuk memastikan titik maksimum dan minimum diperoleh. Matlamat kita ada mencari nilai maksimum bagi koordinat x, y dan z.
– tAB->minPoint menyimpan dalam bentuk vector setiap nilai koordinat yang maksimum diperoleh.
Step Kedua : Memetakan nilai maksimum dan nilai minimum
void cAABB::AABBInitVertices(cAABB *tAB) { tAB->VerticesAABB[0][0] = tAB->minPoint.x; tAB->VerticesAABB[0][1] = tAB->minPoint.y; tAB->VerticesAABB[0][2] = tAB->minPoint.z; tAB->VerticesAABB[1][0] = tAB->maxPoint.x; tAB->VerticesAABB[1][1] = tAB->maxPoint.y; tAB->VerticesAABB[1][2] = tAB->maxPoint.z; tAB->VerticesAABB[2][0] = tAB->maxPoint.x; tAB->VerticesAABB[2][1] = tAB->minPoint.y; tAB->VerticesAABB[2][2] = tAB->minPoint.z; tAB->VerticesAABB[3][0] = tAB->minPoint.x; tAB->VerticesAABB[3][1] = tAB->maxPoint.y; tAB->VerticesAABB[3][2] = tAB->maxPoint.z; tAB->VerticesAABB[4][0] = tAB->maxPoint.x; tAB->VerticesAABB[4][1] = tAB->maxPoint.y; tAB->VerticesAABB[4][2] = tAB->minPoint.z; tAB->VerticesAABB[5][0] = tAB->minPoint.x; tAB->VerticesAABB[5][1] = tAB->minPoint.y; tAB->VerticesAABB[5][2] = tAB->maxPoint.z; tAB->VerticesAABB[6][0] = tAB->minPoint.x; tAB->VerticesAABB[6][1] = tAB->maxPoint.y; tAB->VerticesAABB[6][2] = tAB->minPoint.z; tAB->VerticesAABB[7][0] = tAB->maxPoint.x; tAB->VerticesAABB[7][1] = tAB->minPoint.y; tAB->VerticesAABB[7][2] = tAB->maxPoint.z; tAB->FaceV[0][0] = 1; tAB->FaceV[0][1] = 7; tAB->FaceV[0][2] = 2; tAB->FaceV[0][3] = 4; tAB->FaceV[1][0] = 0; tAB->FaceV[1][1] = 5; tAB->FaceV[1][2] = 3; tAB->FaceV[1][3] = 6; tAB->FaceV[2][0] = 1; tAB->FaceV[2][1] = 4; tAB->FaceV[2][2] = 6; tAB->FaceV[2][3] = 3; tAB->FaceV[3][0] = 0; tAB->FaceV[3][1] = 2; tAB->FaceV[3][2] = 7; tAB->FaceV[3][3] = 5; tAB->FaceV[4][0] = 1; tAB->FaceV[4][1] = 3; tAB->FaceV[4][2] = 5; tAB->FaceV[4][3] = 7; tAB->FaceV[5][0] = 0; tAB->FaceV[5][1] = 6; tAB->FaceV[5][2] = 4; tAB->FaceV[5][3] = 2; }
Bagaimana ianya berfungsi?
– tAB->VerticesAABB berfungsi untuk memetakan nilai min dan max yang telah diperoleh seperti dalam rajah di atas
– tAB->FaceV pula merupakan pemetaan terhadap AABB itu sendiri. Di mana kita akan labelkan setiap face(permukaan).
Sebagai contoh
tAB->FaceV[0][0] = 1; tAB->FaceV[0][1] = 7; tAB->FaceV[0][2] = 2; tAB->FaceV[0][3] = 4;
FaceV[0][0] merupakan titik permulaan, ianya akan disambungkan dengan FaceV[0][1] dan FaceV[0][2] dan FaceV[0][3] untuk menjadi satu surface (face)
jadi kita lihat ada 6 line keseluruhannya dan ianya bertujuaan menyimpan data sahaja kerana nanti kita akan gunakan gegelung for untuk cantumkannya. Setakat ini kita akan labelkan terlebih dahulu. jadi bermaksud.
tAB->FaceV[0][0], tAB->FaceV[2][0], dan tAB->FaceV[4][0] merupakan titik yang sama dan dilabelkan dengan nilai yang sama
Lihat rajah di atas untuk keterangan lanjut
Step Ketiga
Proses Rendering
//render aabb box void cAABB::AABBBound(cAABB *targetAABB) { glLoadIdentity(); glPushAttrib(GL_ALL_ATTRIB_BITS ); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(2.0); if (status) { glColor3f (1.0,0.5,1.0); } else { glColor3f (1.0,0.0,0.0); } glBegin(GL_QUADS); for(int i=0; i<6; i++) { glVertex3f(targetAABB->VerticesAABB[targetAABB->FaceV[i][0]][0], targetAABB->VerticesAABB[targetAABB->FaceV[i][0]][1], targetAABB->VerticesAABB[targetAABB->FaceV[i][0]][2]); glVertex3f(targetAABB->VerticesAABB[targetAABB->FaceV[i][1]][0], targetAABB->VerticesAABB[targetAABB->FaceV[i][1]][1], targetAABB->VerticesAABB[targetAABB->FaceV[i][1]][2]); glVertex3f(targetAABB->VerticesAABB[targetAABB->FaceV[i][2]][0], targetAABB->VerticesAABB[targetAABB->FaceV[i][2]][1], targetAABB->VerticesAABB[targetAABB->FaceV[i][2]][2]); glVertex3f(targetAABB->VerticesAABB[targetAABB->FaceV[i][3]][0], targetAABB->VerticesAABB[targetAABB->FaceV[i][3]][1], targetAABB->VerticesAABB[targetAABB->FaceV[i][3]][2]); } glEnd(); glPopAttrib(); }
Jadi kita lihat di situ, targetAABB->VerticesAABB[targetAABB->FaceV merupakan pencantuman hasil pemetaan yang kita lakukan tadi menggunakan function OpenGL iaitu glVertex3f. Gegelung for dibuat sebanyak 6 kali mewakili 6 faces(permukaan)
Step Keempat : Menjana Objek beserta AABB
Maka step terakhir adalah menjana objek beserta AABB tersebut. Proses ini akan dipanggil pada main file (main.cpp)
Disertakan rajah hasil rendering tersebut
**saya akan kemaskini lagi artikel ini agar lebih detail lagi. Disebabkan kesuntukan masa untuk menerangkannya, maka saya cuba upgrade artikel ini senantiasa.
***At least sekarang kita tahu bahawa menerangkan sesuatu yang melibatkan pengaturcaraan object oriented di tambah penggunaan library akan menyebabkan kita kagum bagaimana researcher di luar sana mampu menerangkan dengan lebih tepat dan ringkas lagi.
I will put source code later on. (requires some clean up due to many unrelated files existed in my project)