Billboard trụ thực sự

Một phần của tài liệu Billboard và giả lập mô hình 3D trong thực tại ảo (Trang 43)

Billboard trụ thực sự sẽ làm cho đối tượng quay quanh một trục, giống như trong phiên bản giả billboard trụ, nhưng vector lookAt của đối tượng sẽ được quay về phía của camera. Hình sau thể hiện cách thức biến đổi của kỹ thuật billboard trụ.

2.1 Cách quay đối tƣợng trong kỹ thuật billboard trụ thực sự

Lúc này, khi người dùng di chuyển trên mặt đất, những cái cây sẽ thực sự đối mặt với người dùng. Phương pháp sử dụng ở đây đòi hỏi phải biết được vị trí của đối tượng cũng như vị trí của mục tiêu trong hệ trục toàn cục. Thường thì mục tiêu chính là vị trí của camera mà ta đã biết. Tuy nhiên điều tương tự không đúng đối với đối tượng.

Nếu như vị trí của đối tượng được xác định thông qua các phép biến đổi hình học, như là dịch chuyển, phép quay, khi đó giữ được thông tin về vị trí của đối tượng trong hệ trục toàn cục là một nhiệm vụ khá khó khăn

Giả như biết được vị trí của các đối tượng và mục tiêu trong hệ trục toàn cục, khi đó kỹ thuật billboard sẽ trở thành một thao tác biến đổi hình học đơn giản. Vì một lý do đơn giản là giả sử đối tượng có các vector sau:

right vector = [1,0,0] up vector = [0,1,0] lookAt vector = [0,0,1]

Trong thực tế, điều này có nghĩa là đối tượng được vẽ trong hệ trục cục bộ và nhìn về chiều dương của trục Z.

Việc định hướng cho phép quay của đối tượng quanh up vector được xác định thông qua góc giữa lookAt vector và vector từ đối tượng tới camera.

2.2 Xác định góc quay trong billboard trụ thực sự (a)

Vector từ đối tượng tới camera được định nghĩa như sau: objToCam = CamPos – ObjPos.

Vector objToCamProj là chiếu của objToCam lên mặt phẳng XOZ. Vì vậy thành phần Y của nó được đặt bằng 0.

Nếu objToCamProj là normalized khi đó tích giữa lookAt và objToCam sẽ cho phép tính được cosine của góc quay. Tuy nhiên chỉ biết được cosine thì vẫn

chưa đủ, khi mà cos(a) = cos(-a). Việc tính tích có hướng cho phép ta xác định được một góc duy nhất. Vector tích cùng hướng với up vector nếu góc quay là dương và ngược hướng nếu góc quay là âm.

2.3 Xác định góc quay trong billboard trụ thực sự (b)

Các bước cần thực hiện sau khi tính được objToCamProj là: 1. normalize(objToCamProj)

2. angleCosine = innerProduct(lookAt,objToCamProj) 3. upAux = crossProduct(lookAt,objToCamProj)

4. glRotatef(acos(aux)*180/3.14,upAux[0], upAux[1], upAux[2]);

Tương tự như phần trước, một hàm sẽ được xây dựng để thiết lập billboard. Mã nguồn được cho như sau:

void billboardCylindricalBegin( float camX, float camY, float camZ,

float objPosX, float objPosY, float objPosZ) { float lookAt[3],objToCamProj[3],upAux[3];

float modelview[16],angleCosine; glPushMatrix();

// objToCamProj is the vector in world coordinates from the // local origin to the camera projected in the XZ plane objToCamProj[0] = camX - objPosX ;

objToCamProj[1] = 0;

objToCamProj[2] = camZ - objPosZ ;

// This is the original lookAt vector for the object // in world coordinates

lookAt[0] = 0; lookAt[1] = 0; lookAt[2] = 1;

// normalize both vectors to get the cosine directly afterwards

mathsNormalize(objToCamProj);

// easy fix to determine wether the angle is negative or positive

// for positive angles upAux will be a vector pointing in the // positive y direction, otherwise upAux will point downwards // effectively reversing the rotation.

mathsCrossProduct(upAux,lookAt,objToCamProj); // compute the angle

angleCosine = mathsInnerProduct(lookAt,objToCamProj);

// perform the rotation. The if statement is used for stability

reasons

// if the lookAt and objToCamProj vectors are too close together then

// |angleCosine| could be bigger than 1 due to lack of precision

if ((angleCosine < 0.99990) && (angleCosine > -0.9999)) glRotatef(acos(angleCosine)*180/3.14,upAux[0], upAux[1], upAux[2]);

}

Hàm billboardEnd() có thể được gọi sau khi biểu diễn đối tượng.

billboardCylindricalBegin(cx,cy,cz,ox,oy,oz); drawObject();

billboardEnd();

Một phần của tài liệu Billboard và giả lập mô hình 3D trong thực tại ảo (Trang 43)

Tải bản đầy đủ (PDF)

(65 trang)