Pembinaan Ruangan Lingkup Tertutup (Bounding-Volume) dalam Computer Graphics Menggunakan OpenGL dan Visual C++

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.

Published by razorjr

Research and Academician

One thought on “Pembinaan Ruangan Lingkup Tertutup (Bounding-Volume) dalam Computer Graphics Menggunakan OpenGL dan Visual C++

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: