Implementando la clase “C谩mara”
El m茅todo Pitch
Como hab铆amos visto anteriormente, la operaci贸n Pitch consiste en hacer girar la c谩mara sobre su eje “derecha”. Por lo tanto los pasos que realizaremos son los siguientes:
1. Crear una matriz de rotaci贸n sobre el eje “derecha” (m_v3Right) con el 谩ngulo (en radianes) especificado por el par谩metro de entrada al m茅todo.
2. Transformaremos los vectores “arriba” (m_v3Up) y “direcci贸n” (m_v3Look) utilizando la matriz de rotaci贸n creada.
El c贸digo:
| void Camera::Pitch(float fAngle)
| {
| Matrix mat;
|
| // Creo una matriz de rotaci贸n sobre el eje m_v3Right
| D3DXMatrixRotationAxis(&mat, &m_v3Right, fAngle);
|
| // Transformo el vector m_v3Up utilizando la matriz de rotaci贸n creada
| D3DXVec3TransformCoord(&m_v3Up,&m_v3Up, &mat);
| // Transformo el vector m_v3Look utilizando la matriz de rotaci贸n creada
| D3DXVec3TransformCoord(&m_v3Look,&m_v3Look, &mat);
| }
El m茅todo Yaw
Como hab铆amos visto anteriormente, la operaci贸n Yaw consiste en hacer girar la c谩mara sobre su eje “arriba”. Por lo tanto los pasos que realizaremos son los siguientes:
1.a. Si la c谩mara es a茅rea: Crear una matriz de rotaci贸n sobre el eje “arriba” (m_v3Up) con el 谩ngulo (en radianes) especificado por el par谩metro de entrada al m茅todo.
1.b. Si la c谩mara es terrestre: Crear una matriz de rotaci贸n sobre el eje Y con el 谩ngulo (en radianes) especificado por el par谩metro de entrada al m茅todo.
2. Transformaremos los vectores “derecha” (m_v3Right) y “direcci贸n” (m_v3Look) utilizando la matriz de rotaci贸n creada.
El c贸digo:
| void Camera::Yaw(float fAngle)
| {
| Matrix mat;
|
| if (m_cameraType == ECT_GROUND)
| {
| m_v3Up.x = 0.0f; m_v3Up.y = 1.0f; m_v3Up.z = 0.0f;
| // Creo una matriz de rotaci贸n que gire fAngle grados sobre el Y
| D3DXMatrixRotationY(&mat, fAngle);
| }
| else if (m_cameraType == ECT_AIR)
| // Creo una matriz de rotaci贸n sobre el eje m_v3Up
| D3DXMatrixRotationAxis(&mat, &m_v3Up, fAngle);
|
| // Transformo el vector m_v3Right utilizando la matriz de rotaci贸n creada
| D3DXVec3TransformCoord(&m_v3Right,&m_v3Right, &mat);
| // Transformo el vector m_v3Look utilizando la matriz de rotaci贸n creada
| D3DXVec3TransformCoord(&m_v3Look,&m_v3Look, &mat);
| }
El m茅todo Walk
En este m茅todo, que consiste en avanzar o retroceder sobre el eje direcci贸n, utilizaremos el mismo (m_v3Look) para movernos una cierta cantidad de unidades expresadas por medio del par谩metro de entrada al m茅todo. Aunque haremos una excepci贸n respecto al eje Y si es que la c谩mara es terrestre.
El c贸digo:
| void Camera::Walk(float fValue)
| {
| // S贸lo avanzo sobre el eje Y cuando la c谩mara es 谩rea
| if (m_cameraType == ECT_AIR)
| // Avanzo una cierta cantidad de unidades sobre el eje Y de m_v3Look
| m_v3Pos.y += m_v3Look.y * fValue;
|
| // Avanzo una cierta cantidad de unidades sobre el eje X de m_v3Look
| m_v3Pos.x += m_v3Look.x * fValue;
| // Avanzo una cierta cantidad de unidades sobre el eje Z de m_v3Look
| m_v3Pos.z += m_v3Look.z * fValue;
| }
El m茅todo Strafe
En este m茅todo, que consiste en avanzar o retroceder sobre el eje derecha, utilizaremos el mismo (m_v3Right) para movernos una cierta cantidad de unidades expresadas por medio del par谩metro de entrada al m茅todo. Aunque haremos una excepci贸n respecto al eje Y si es que la c谩mara es terrestre.
El c贸digo:
| void Camera::Strafe(float fValue)
| {
| // S贸lo me muevo sobre el eje Y cuando la c谩mara es 谩rea
| if (m_cameraType == ECT_AIR)
| // Me muevo una cierta cantidad de unidades sobre el eje Y de m_v3Right
| m_v3Pos.y += m_v3Right.y * fValue;
|
| // Me muevo una cierta cantidad de unidades sobre el eje X de m_v3Right
| m_v3Pos.x += m_v3Right.x * fValue;
| // Me muevo una cierta cantidad de unidades sobre el eje Z de m_v3Right
| m_v3Pos.z += m_v3Right.z * fValue;
| }
El m茅todo Fly
Este m茅todo, en el cual nos movemos sobre el eje "arriba" (m_v3Up) tendr谩 sentido s贸lo cuando la c谩mara sea a茅rea.
El c贸digo:
| void Camera::Fly(float fValue)
| {
| // S贸lo realizo algo en este m茅todo cuando la c谩mara es 谩rea
| if (m_cameraType == ECT_AIR)
| {
| // Me muevo una cierta cantidad de unidades sobre el eje X de m_v3Up
| m_v3Pos.x += m_v3Up.x * fValue;
| // Me muevo una cierta cantidad de unidades sobre el eje Y de m_v3Up
| m_v3Pos.y += m_v3Up.y * fValue;
| // Me muevo una cierta cantidad de unidades sobre el eje Z de m_v3Up
| m_v3Pos.z += m_v3Up.z * fValue;
| }
| }
El m茅todo SetPos
El m茅todo SetPos simplemente fija la posici贸n de la c谩mara en un punto determinado por el par谩metro de entrada al m茅todo. Esta acci贸n no requiere la modificaci贸n de ninguna otra componente.
El c贸digo:
| void Camera::SetPos(Vector3 & v3Pos)
| {
| m_v3Pos = v3Pos;
| }
El m茅todo SetLookAt
Los tres vectores que posee la c谩mara (direcci贸n, derecha y arriba) poseen una relaci贸n entre s铆: son perpendiculares. Esta relaci贸n no debe ser rota por lo tanto la modificaci贸n arbitraria de un vector puede llevar a la modificaci贸n necesaria de los otros dos.
El m茅todo SetLookPos
Ciertamente puede resultar c贸modo modificar la direcci贸n hacia donde mira la c谩mara especificando un punto como objetivo. Pero nosotros almacenamos un vector normalizado hacia donde mirar, por lo tanto deberemos trabajar un poco con el punto recibido por par谩metro. Veamos:
1. Creamos un vector direcci贸n entre el punto posici贸n de la c谩mara y el punto hacia donde debemos mirar.
2. Normalizamos el vector de modo de quedarnos s贸lo con sus componentes de direcci贸n (fijando su magnitud en uno).
3. Invocamos el m茅todo SetLookAt para modificar los componentes que sean necesarios.
El c贸digo:
| void Camera::SetLookPos(Vector3 & v3LookPos)
| {
| Vector3 v3;
|
| v3.x = v3LookPos.x - m_v3Pos.x;
| v3.y = v3LookPos.y - m_v3Pos.y;
| v3.z = v3LookPos.z - m_v3Pos.z;
|
| D3DXVec3Normalize(&v3, &v3);
|
| // Una vez obtenido el vector lookAt, modifico las componentes
| SetLookAt(v3);
| }
Dibujando la c谩mara
Las componentes de la c谩mara transformar谩n la matriz de vista cuando se invoque el m茅todo Draw, en este m茅todo tambi茅n podr铆amos aprovechar para dibujar gu铆as de la c谩mara (como una l铆nea que indique hacia donde mira la c谩mara) y/o un mesh que indique la posici贸n de la misma, todo esto con fines de depuraci贸n.
Para crear una matriz de vista utilizaremos la funci贸n D3DXMatrixLookAtLH, dicha funci贸n solicita b谩sicamente los componentes que ya poseemos en la clase pero existe una expeci贸n:
Poseemos el vector direcci贸n normalizado, es decir hacia donde miramos y la funci贸n de creaci贸n de la matriz de vista nos solicita el punto al cual miramos, por lo tanto dicho punto deberemos construirlo din谩micamente:
punto donde miramos = posici贸n de la c谩mara + vector direcci贸n
Luego creada la matriz de vista modificaremos la que est谩 utilizando DirectX, esto es posible realizarlo por medio del m茅todo SetTransform del dispositivo de Direct3D, en nuestro caso hacemos uso de un m茅todo de la clase Renderer que finalmente har谩 una llamada al m茅todo citado.
El c贸digo:
| void Camera::Draw(float fTimeBetweenFrames)
| {
| Matrix mat;
| Vector3 v3Look = m_v3Pos + m_v3Look;
| D3DXMatrixLookAtLH(&mat, &m_v3Pos, &v3Look, &m_v3Up);
|
| g_renderer.SetMatrixMode(AGL_VIEW);
| g_renderer.SetTransform(mat);
| }
Las dos 煤ltimas l铆neas de la funci贸n Draw son espec铆ficas del motor que utilic茅, all铆 deber谩s utilizar los m茅todos que tu motor/librer铆a/programa posea para modificar la matriz de vista.
~fuzzyLogic





Comentarios (3)



Como siempre, muy bien elaborado.
Muy bueno che, muchas gracias
muy bueno, me aclar贸 todas mis dudas. Estoy haciendo una clase en opengl, as铆 que te la enviar茅 para que la publiques, cuando la termine.