Allegro tambi�n contiene algunas funciones de ayuda de 3d para manipular vectores, construir o usar matrices de transformaci�n, y hacer proyecciones de perspectiva de un espacio 3d en la pantalla. Estas funciones no son, y nunca ser�n, una librer�a 3d total (mi objetivo es dar rutinas de soporte gen�ricas, y no c�digo gr�fico muy especializado :-) pero estas funciones pueden serle �tiles para desarrollar su propio c�digo 3d.
Allegro usa el sistema de coordenadas de mano derecha, es decir, si apunta con el dedo gordo de su mano derecha al eje positivo x, y con el �ndice al eje positivo y, su dedo coraz�n apuntar� en la direcci�n positiva del eje z. Esto tambi�n significa que para las rotaciones, si hace que el dedo gordo de su mano derecha siga el eje de rotaci�n, sus dedos se curvar�n en la direcci�n positiva de la rotaci�n.
Hay dos versiones de todas las funciones matem�ticas de 3d: una usando aritm�tica de punto fijo, y la otra usando coma flotante. La sintaxis para ambas es id�ntica, pero las funciones y estructuras de coma flotante tienen el sufijo '_f'. Ejemplo: la funci�n cross_product() de punto fijo tiene el equivalente de coma flotante en cross_product_f(). Si est� programando en C++, Allegro tambi�n sobrecarga estas funciones para que las use con la clase "fija".
La transformaci�n 3d se realiza modelando una matriz. Esta es un array de 4x4 n�meros que pueden ser multiplicados con un punto 3d para producir otro punto 3d. Si ponemos los valores correctos en la matriz, podemos usarla para varias operaciones como translaci�n, rotaci�n y escalado. El truco consiste en que puede multiplicar dos matrices para producir una tercera, y esta tendr� el mismo efecto en los puntos 3d que aplicando las dos matrices originales una despu�s de la otra. Por ejemplo, si tiene una matriz que rota un punto, y otra que lo mueve en una direcci�n, puede combinarlas para producir una matriz que realizara la rotaci�n y translaci�n en un paso. Puede crear transformaciones extremadamente complejas de este modo, teniendo que multiplicar cada punto 3d por una sola matriz.
Allegro hace trampa al implementar la estructura de la matriz. La rotaci�n y el escalado de un punto 3d puede ser realizado con una matriz simple de 3x3, pero para trasladar el punto y proyectarlo en la pantalla, la matriz tiene que ser extendida a 4x4, y el punto extendido a una cuarta dimensi�n, al a�adir una coordenada extra: w=1. Esto es algo malo en t�rminos de eficiencia, pero afortunadamente, es posible realizar una optimizaci�n. Dada la siguiente matriz 4x4:
se puede observar un patr�n de qu� partes hacen qu�. La rejilla 3x3 de arriba a la izquierda implementa la rotaci�n y el escalado. Los tres valores de arriba de la cuarta columna (d, h y l) implementan la translaci�n, y siempre y cuando la matriz sea usada s�lo para transformaciones afines, m, n y o ser�n siempre cero y p siempre ser� 1. Si no sabe que significa 'af�n', lea a Foley & Van Damme: b�sicamente cubre el escalado, la translaci�n y rotaci�n del objeto pero no la proyecci�n. Ya que Allegro usa una funci�n aparte para la proyecci�n, las funciones de matriz s�lo tienen que servir para la transformaci�n af�n, lo que significa que no hay que guardar la fila inferior de la matriz. Allegro asume que esta contiene (0,0,0,1), y por eso optimiza las funciones de manipulaci�n de matrices.( a, b, c, d ) ( e, f, g, h ) ( i, j, k, l ) ( m, n, o, p )
Las matrices se almacenan en estructuras:
extern MATRIX identity_matrix;typedef struct MATRIX - matriz de punto fijo { fixed v[3][3]; - componente 3x3 de escalado y rotaci�n fixed t[3]; - componente x/y/z de translaci�n } MATRIX; typedef struct MATRIX_f - matriz de coma flotante { float v[3][3]; - componente 3x3 de escalado y rotaci�n float t[3]; - componente x/y/z de translaci�n } MATRIX_f
void get_translation_matrix(MATRIX *m, fixed x, fixed y, fixed z);
void get_translation_matrix_f(MATRIX_f *m, float x, float y, float z);
Construye una matriz de translaci�n, guard�ndola en m. Si se aplica a un
punto (px, py, pz), esta matriz producir� el punto (px+x, py+y, pz+z). En
otras palabras: mueve las cosas.
Relacionado con: apply_matrix, get_transformation_matrix, qtranslate_matrix.void get_scaling_matrix(MATRIX *m, fixed x, fixed y, fixed z);
Relacionado con: apply_matrix, get_transformation_matrix, qscale_matrix.void get_x_rotate_matrix(MATRIX *m, fixed r);
Relacionado con: apply_matrix, get_rotation_matrix, get_y_rotate_matrix, get_z_rotate_matrix.void get_y_rotate_matrix(MATRIX *m, fixed r);
Relacionado con: apply_matrix, get_rotation_matrix, get_x_rotate_matrix, get_z_rotate_matrix.void get_z_rotate_matrix(MATRIX *m, fixed r);
Relacionado con: apply_matrix, get_rotation_matrix, get_x_rotate_matrix, get_y_rotate_matrix.void get_rotation_matrix(MATRIX *m, fixed x, fixed y, fixed z);
Relacionado con: apply_matrix, get_transformation_matrix, get_vector_rotation_matrix, get_align_matrix, get_x_rotate_matrix, get_y_rotate_matrix, get_z_rotate_matrix.void get_align_matrix(MATRIX *m, fixed xfront, yfront, zfront, fixed xup, fixed yup, fixed zup);
Relacionado con: apply_matrix, get_camera_matrix.void get_align_matrix_f(MATRIX *m, float xfront, yfront, zfront, float xup, yup, zup);
Relacionado con: get_align_matrix.void get_vector_rotation_matrix(MATRIX *m, fixed x, y, z, fixed a);
Relacionado con: apply_matrix, get_rotation_matrix, get_align_matrix.void get_transformation_matrix(MATRIX *m, fixed scale, fixed xrot, yrot, zrot, x, y, z);
Relacionado con: apply_matrix, get_rotation_matrix, get_scaling_matrix, get_translation_matrix.void get_transformation_matrix_f(MATRIX_f *m, float scale, float xrot, yrot, zrot, x, y, z);
Relacionado con: get_transformation_matrix.void get_camera_matrix(MATRIX *m, fixed x, y, z, xfront, yfront, zfront, fixed xup, yup, zup, fov, aspect);
Relacionado con: apply_matrix, get_align_matrix.void get_camera_matrix_f(MATRIX_f *m, float x, y, z, xfront, yfront,zfront, float xup, yup, zup, fov, aspect);
Relacionado con: get_camera_matrix.void qtranslate_matrix(MATRIX *m, fixed x, fixed y, fixed z);
Relacionado con: get_translation_matrix.void qscale_matrix(MATRIX *m, fixed scale);
Relacionado con: get_scaling_matrix.void matrix_mul(const MATRIX *m1, MATRIX *m2, MATRIX *out);
Relacionado con: apply_matrix.fixed vector_length(fixed x, fixed y, fixed z);
Relacionado con: normalize_vector.void normalize_vector(fixed *x, fixed *y, fixed *z);
Relacionado con: vector_length, dot_product, cross_product.fixed dot_product(fixed x1, y1, z1, x2, y2, z2);
Relacionado con: cross_product, normalize_vector.void cross_product(fixed x1, y1, z1, x2, y2, z2, *xout, *yout, *zout);
Relacionado con: dot_product, polygon_z_normal, normalize_vector.fixed polygon_z_normal(const V3D *v1, V3D *v2, V3D *v3);
Relacionado con: cross_product.void apply_matrix(const MATRIX *m, fixed x, y, z, *xout, *yout, *zout);
Relacionado con: matrix_mul.void set_projection_viewport(int x, int y, int w, int h);
Relacionado con: persp_project.void persp_project(fixed x, y, z, *xout, *yout);
Relacionado con: set_projection_viewport.