#ifndef _TSAI_H_
#define _TSAI_H_

/* Método TSAI - Calibração de Cameras - versão coplanar */

/************************************************************************************************/
/* Calibra a camera dados np pares de pontos.                                                   */
/*  Entrada:                                                                                    */
/*   np - número de pares de pontos - [ (xw,yw) , (xf, yf) ].                                   */
/*   (xw, yw) - ponto do mundo.                                                                 */
/*   (xf, yf) - ponto em coodernadas da tela em pixel (origem no centro da imagem e eixo ox da  */
/*                                                     esquerda para direita e eixo oy de baixo */
/*                                                     para cima).                              */
/*  Saída:                                                                                      */
/*   f - distância focal.                                                                       */
/*   T - translação (origem do mundo em sistema de coordenadas da câmera).                      */
/*   r - rotação.                                                                               */
/************************************************************************************************/
int tsaiCalibration2D(int np, float *xw, float *yw, float *xf, float *yf,
                      float *f, float T[3], float r[9]);

/************************************************************************************************/
/* Calibra a camera dados np pares de pontos, exceto distância focal.                           */
/*  Entrada:                                                                                    */
/*   np - número de pares de pontos - [ (xw,yw) , (xf, yf) ].                                   */
/*   (xw, yw) - ponto do mundo.                                                                 */
/*   (xf, yf) - ponto em coodernadas da tela em pixel (origem no centro da imagem e eixo ox da  */
/*                                                     esquerda para direita e eixo oy de baixo */
/*                                                     para cima).                              */
/*   f - distância focal.                                                                       */
/*  Saída:                                                                                      */
/*   T - translação (origem do mundo em sistema de coordenadas da câmera).                      */
/*   r - rotação.                                                                               */
/************************************************************************************************/
int tsaiCalibration2D_Tr(int np, float *xw, float *yw, float *xf, float *yf, float f,
                         float T[3], float r[9]);

/************************************************************************************************/
/* Projeta o ponto (xw, yw, zw) na tela.                                                        */
/*  Entrada:                                                                                    */
/*   (xw, yw, zw) - ponto a ser projetado.                                                      */
/*   f - distância focal.                                                                       */
/*   T - translação (origem do mundo em sistema de coordenadas da câmera).                      */
/*   r - rotação.                                                                               */
/*  Saída:                                                                                      */
/*   (xf, yf) - ponto projetado.                                                                */
/************************************************************************************************/
void tsaiProject(float xw, float yw, float zw, float *xf, float *yf,
                 float f, float T[3], float r[9]);

/************************************************************************************************/
/* Inverte a projeção do ponto da tela.                                                         */
/*  Entrada:                                                                                    */
/*   (xf, yf) - ponto projetado da tela.                                                        */
/*   f - distância focal.                                                                       */
/*   T - translação (origem do mundo em sistema de coordenadas da câmera).                      */
/*   r - rotação.                                                                               */
/*   zw - coordenada z do ponto do mundo.                                                       */
/*  Saída:                                                                                      */
/*   (xw, yw, zw) - ponto do mundo. Note que zw deve ser dado de entrada.                       */
/************************************************************************************************/
void tsaiUnproject(float xf, float yf, float *xw, float *yw, float zw,
                   float f, float T[3], float r[9]);

/************************************************************************************************/
/* Encontra a posição da câmera no sistema de coordenadas do mundo                              */
/*  Entrada:                                                                                    */
/*   T - translação (origem do mundo em sistema de coordenadas da câmera).                      */
/*   r - rotação.                                                                               */
/*  Saída:                                                                                      */
/*   (x, y, z) - coordenadas da posição da câmera.                                              */
/************************************************************************************************/
void tsaiCameraPosition(float *x, float *y, float *z,
                        float T[3], float r[9]);

/************************************************************************************************/
/* Retorna a matriz Model View a ser utilizado no OpenGL.                                       */
/*  Entrada:                                                                                    */
/*   T - translação (origem do mundo em sistema de coordenadas da câmera).                      */
/*   r - rotação.                                                                               */
/*  Saída:                                                                                      */
/*   mv - matriz Model View.                                                                    */
/************************************************************************************************/
void tsaiOGLModelViewMatrix(float T[3], float r[9], float mv[16]);

/************************************************************************************************/
/* Retorna a matriz de projeção a ser utilizado no OpenGL.                                      */
/*  Entrada:                                                                                    */
/*   f - distância focal.                                                                       */
/*   nearplane - plano near do frustum de visão.                                                */
/*   farplane - plano far do frustum de visão.                                                  */
/*   width - largura do frustum de visão.                                                       */
/*   height - altura do frustum de visão.                                                       */
/*  Saída:                                                                                      */
/*   pr - matriz de projeção.                                                                   */
/************************************************************************************************/
void tsaiOGLProjectionMatrix(float f, float nearplane, float farplane, int width, int height, float pr[16]);

#endif