Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Implementación De D3dxmatrixlookatlh

Iniciado por Loover, 30 de Marzo de 2004, 01:06:58 PM

« anterior - próximo »

Loover

 Hola!

Estoy implementando una serie de clases para manejo de matrices y vectores. Y lo estoy haciendo a la manera de D3D pues me parece muy sencilla y fácil de usar. No he tenido problemas con multiplicación de matrices, transformación de vectores, matrices de escalado, rotación y traslación, perspectivas con punto de fuga, axonométricas, caballeras, etc.
Pero ahora que ya tengo eso, me gustaría hacer un modelo de cámara. Me basta con algo sencillo: pos. de cámara, pos. a mirar y vector up... y formar una matriz de vista con esos 3 vectores.
Así que me preguntaba... ¿cómo se implementa la función D3DXMatrixLookAt de D3d? Que hace justo lo que quiero: devolver una matriz de vista a partir de esos 3 vectores.

Gracias por adelantado.

Un saludo!

PD: Apuesto 10 a 1 a que me responde Berserker el primero con la solución.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

BeRSeRKeR

 Aquí está el código para la versión left-handed:

#define EPSILON             1e-5f

D3DXMATRIX * D3DXMatrixLookAtLH(
   D3DXMATRIX * pOut,
   const D3DXVECTOR3 * pEye,
   const D3DXVECTOR3 * pAt,
   const D3DXVECTOR3 * pUp)
{
   D3DXVECTOR3   uAxis, vAxis, nAxis;

   nAxis = (*pAt) - (*pEye);
   if (D3DXVec3Normalize(&nAxis, &nAxis) == NULL) return NULL;

   vAxis = (*pUp) - nAxis * D3DXVec3Dot(pUp, &nAxis);

   if (D3DXVec3Length(&vAxis) < EPSILON)
   {
       vAxis.x =      - nAxis.y * nAxis.x;
       vAxis.y = 1.0f - nAxis.y * nAxis.y;
       vAxis.z =      - nAxis.y * nAxis.z;

       if (D3DXVec3Length(&vAxis) < EPSILON)
       {
           vAxis.x =      - nAxis.z * nAxis.x;
           vAxis.y =      - nAxis.z * nAxis.y;
           vAxis.z = 1.0f - nAxis.z * nAxis.z;

           if (D3DXVec3Length(&vAxis) < EPSILON) return NULL;
       }
   }

   D3DXVec3Normalize(&vAxis, &vAxis);
   D3DXVec3Cross(&uAxis, &vAxis, &nAxis);

   pOut->_11 = uAxis.x; pOut->_12 = vAxis.x; pOut->_13 = nAxis.x; pOut->_14 = 0.0f;
   pOut->_21 = uAxis.y; pOut->_22 = vAxis.y; pOut->_23 = nAxis.y; pOut->_24 = 0.0f;
   pOut->_31 = uAxis.z; pOut->_32 = vAxis.z; pOut->_33 = nAxis.z; pOut->_34 = 0.0f;

   pOut->_41 = -D3DXVec3Dot(pEye, &uAxis);
   pOut->_42 = -D3DXVec3Dot(pEye, &vAxis);
   pOut->_43 = -D3DXVec3Dot(pEye, &nAxis);
   pOut->_44 = 1.0f;

   return pOut;
}


Para la right-handed lo único que tendrías que cambiar si no me equivoco es la línea

nAxis = (*pAt) - (*pEye);

por

nAxis = -((*pAt) - (*pEye));

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

Loover

 Jajajaja, gracias!  (ole)

Aunque ahora me faltan D3DXVec3Length, D3DXVec3Normalize, D3DXVec3Dot, D3DXVec3Cross.
Snif.

Bueno, voy a ver si las saco, sino vuelvo por aquí.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Zaelsius

 Loover me vas a permitir un semi-offtopic sobre D3DXVec3Dot(producto vectorial en castellano)..

Es muy fácil de implementar en C...

d=x1*x2+y1*y2+z1*z2

...pero Hace poco estuve viendo un tutorial de Intel sobre MMX, y habia una bonita rutina para calcular el producto escalar:

Código:


Explicación:


Pero MMX sólo trata con enteros, con lo cual no nos sirve. Si no me equivoco las 3DNow! de AMD suprimen esta limitación y permiten realizar operaciones SIMD con operandos de coma flotante. Mientras lo compruebo, si alguien lo sabe con exactitud que lo diga!!  ;)

Loover

 No es offtopic, me has dado la solución a otra sin tener que buscarla.
Por cierto, antes tenía una web que hablaba sobre como implementar todas estas cosas, y con optimizaciones. ¿Alguien la recuerda?
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

fiero

 Loover, en el fichero d3dx9math.inl del sdk de DX9 tienes las implementaciones de esas funciones. Hay otras que están implementadas en ensamblador, pero en las SDK de DX7, si no recuerdo mal, venian todas implementadas en C.

un saludo
www.videopanoramas.com Videopanoramas 3D player

Zaelsius

 Me ha llamado la atención la macro debug:


D3DXINLINE FLOAT D3DXVec3Dot
   ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
{
#ifdef D3DX_DEBUG
   if(!pV1 || !pV2)
       return 0.0f;
#endif

   return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z;
}


A mí personalmente me gustaria que en modo debug provocase algun error visible, porque hasta que no cambias a release no te das cuenta de si explota.  

Loover

 Anda, no lo sabía, gracias Fiero.
Bueno, ya está, ya tengo todo lo que necesito :D
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

rafaware

 Pagina de apuntes de graficos


No se si sera de mucha ayuda, pero estoy cursando graficos en mi facultad (UAM) y el profesor ha colgado estos apuntes en la red. Los apuntes nos lo he mirado mucho pero parece que todas esas cosas de matrices las explica en el tema 3

Rafa

Loover

 Gracias Rafaware, les echaré un vistazo.

Bueno, ya tengo funcionando el matrixlookat a la perfección. Ahora me gustaría poder construir matrices de proyección indicando el fov (actualmente las matrices de proyección que creo solo paso como parámetro una escala, o si es ortográfica-axonométrica, un par de ángulos).

Vamos, que ¿cómo se implementa: D3DXMatrixPerspectiveFovLH / RH?

No la he visto en d3dx9math.inl

Y de paso Berserker a ver si puedes explicarme en lineas generales como funciona tu implementación de D3DXMatrixLookAtLH. ¿Es tuya o la has pillado de algún sitio? En el segundo caso, ¿qué sitio?
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Loover

IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Loover

 Bueno, tengo tb funcionando ya el D3DXMatrixPerspectiveFovLH, por funcionando me refiero a que pasados los parámetros tanto en mi función como en D3D da como resultado la misma matriz. Ahora bien, cuando intento usar esa matriz para multiplicarla por los vértices y proyectarlos... no sale bien. En pantalla aparece como un punto de fuga y a partir de el lineas irradiando como un sol.

He probado mil cosas pero no sé qué puede ser. Utilizo estos parámetros (he probando a cambiarlos de mil maneras):
mTrans.MatrixProjectionFovLH (&mProjection, PI/4, (float) 1024/768, 1, 8192);

La malla es una lista de triángulos normal y corriente. Y si utilizo una proyección de punto de fuga se ve bien...

¿Alguien tiene alguna idea de qué puedo estar haciendo mal?

PD: Todo esto lo necesito para un pequeño renderer por software de una asignatura.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Loover

 Os pongo un par de capturas:

Sin proyección:



Con proyección tipo MatrixPerspectiveFovLH:  (grrr)  (nooo)



Y una capturilla con la proyección que tengo que si funciona (la de un punto de fuga) y relleno de triángulos simple:
http://galeon.com/loover/p5.png
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Thenend

 Yo hace poco he usado la fórmula que viene en la documentacion de DirectX sobre D3DXMatrixPerspectiveLH y funciona perféctamente.

2*zn/w  0       0              0
0       2*zn/h  0              0
0       0       zf/(zf-zn)     1
0       0       zn*zf/(zn-zf)  0


w
[in] Width of the view volume at the near view-plane.
h
[in] Height of the view volume at the near view-plane.
zn
[in] Z-value of the near view-plane.
zf
[in] Z-value of the far view-plane.

Loover

 Aja, con esa no tengo problemas... no tiene Fov. Me da problemas la otra.
Y el caso es que la matriz la calcula bien, ya digo que es la misma que me devuelve la funcion de D3D.

No sé... que raro.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.