#ifndef   _STEREO_H_
#define   _STEREO_H_

#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif


#include "algebra.h"

/**
 * Calcula a matrix Essencial que relaciona duas cameras 'a' e 'b'.
 *
 * Entrada:
 * [Ra] = matrix 4x4 (homogenea) que contem apenas a rotacao que leva das coordenadas do mundo
 *        para as coordenadas da camera 'a'.  E' a matriz de rotacao que contem as coordenadas
 *        dos eixos x,y e z da camera nas 3 primeiras linhas da sub-matrix 3x3.  A camera 
 *        e' uma camera OpenGL (ve o lado negativo de z).
 * {eye_a} = posicão do centro de projecao (eye) da camera 'a' em coordendas do mundo.
 * [Rb] = idem [Ra] da camera 'b'.
 * {eye_b} = idem {eye_a} para a camera 'b'.
 *
 * Saida (retorno):
 * [E]  = matriz Essencial.
 */
Matrix stereoEssencialMatrix(Matrix Ra, Vector eye_a, Matrix Rb, Vector eye_b) ;

/**
 * Calcula a matrix Fundamental que relaciona duas cameras 'a' e 'b'.
 *
 * Entrada:
 * [Ka] = matrix 4x4 (homogenea) que representa a transformação de coordenadas camera para as 
 *        coordenadas do imagem gerada. No OpenGL ela combina a matriz de projecao com a 
 *        transformacao para a viewport. A coordenada z e' mantida nesta trasformacao embora
 *        ela nao seja utilizada no calculo da linha epipolar.
 * [Ra] = matrix 4x4 (homogenea) que contem apenas a rotacao que leva das coordenadas do mundo
 *        para as coordenadas da camera 'a'.  E' a matriz de rotacao que contem as coordenadas
 *        dos eixos x,y e z da camera nas 3 primeiras linhas da sub-matrix 3x3.  A camera 
 *        e' uma camera OpenGL (ve o lado negativo de z).
 * {eye_a} = posicão do centro de projecao (eye) da camera 'a' em coordendas do mundo.
 * [Kb] = idem [Ka] da camera 'b'.
 * [Rb] = idem [Ra] da camera 'b'.
 * {eye_b} = idem {eye_a} para a camera 'b'.
 *
 * Saida (retorno):
 * [F] =  matriz Fundamental.
 */
Matrix stereoFundamentalMatrix(Matrix Ka, Matrix Ra, Vector eye_a, Matrix Kb, Matrix Rb, Vector eye_b);

/**
 * Calcula a equacao os ceficientes da reta epipolar (ax+by+c=0) correspondente ao ponto (xm,ym).
 *
 * Entrada:
 * (xm,ym) = ponto na imagem (em coordenadas OpenGL, ou seja, origem no canto inferior esquerdo e 
 *          em unidades de pixel).
 * [F] = matrix Fundamental da camera correspondente a (xm,ym). 
 *
 * Saida:
 * (a,b,c) coeficientes da reta na outra camera.
 */
void stereoEpipolarLineEquation(double xm, double ym, Matrix F, double* a, double *b, double *c);

/**
 * Calcula a reta epipolar (que vai de (x0,y0) a (x1,y1) ) correspondente ao ponto (xm,ym).
 *
 * Entrada:
 * (xm,ym) = ponto na imagem (em coordenadas OpenGL, ou seja, origem no canto inferior esquerdo e 
 *          em unidades de pixel).
 * [F] = matrix Fundamental da camera correspondente a (xm,ym). 
 *
 * Saida:
 * (x0,y0) e (x1,y1) pontos extremos da reta na outra camera.
 */
void stereoEpipolarLine(double x, double y, Matrix F, int width, double* x0, double* y0, double* x1, double* y1);


/** 
 * Calcula a posicao 3D de um ponto correspondente aos pontos (xa,ya) e (xb,yb) das cameras 'a' e 'b',respectivamente.
 * ( pontos dados em coordenadas de janela OpenGL (ou seja, origem no canto inferior esquerdo e em unidades de pixel).
 *
 * Entrada:
 * (xa,ya)   = ponto de correspondencia na imagem da camera 'a'
 * fa        = distancia focal da camera 'a' em unidades de pixel (imaginando que os pixels sejam quadrados)
 * [Ra]      = matrix 4x4 (homogenea) que contem apenas a rotacao que leva das coordenadas do mundo
 *             para as coordenadas da camera 'a'.  E' a matriz de rotacao que contem as coordenadas
 *             dos eixos x,y e z da camera nas 3 primeiras linhas da sub-matrix 3x3.  A camera 
 *             e' uma camera OpenGL (ve o lado negativo de z).
 * {eye_a}   = posicão do centro de projecao (eye) da camera 'a' em coordendas do mundo.
 * (cxa,cya) = centro optico (onde o eixo z da camera fura a imagem). Na convencao OpenGL seria em (w/2,h/2).
 * (xb,ba)   = ponto de correspondencia na imagem da camera 'b'
 * fb        = distancia focal da camera 'b' em unidades de pixel (imaginando que os pixels sejam quadrados)
 * [Rb]      = matrix 4x4 (homogenea) que contem apenas a rotacao que leva das coordenadas do mundo
 *             para as coordenadas da camera 'b'.  E' a matriz de rotacao que contem as coordenadas
 *             dos eixos x,y e z da camera nas 3 primeiras linhas da sub-matrix 3x3.  A camera 
 *             e' uma camera OpenGL (ve o lado negativo de z).
 * {eye_b}   = posicão do centro de projecao (eye) da camera 'a' em coordendas do mundo.
 * (cxb,cyb) = centro optico (onde o eixo z da camera fura a imagem). Na convencao OpenGL seria em (w/2,h/2).
 * 
 * Saida (retorno):
 * {P_a}  = vetor do ponto 3D em coordenadas da camera 'a'.
**/
Vector stereoReconstruct(double xa, double ya, double fa, Matrix Ra, Vector eye_a, double cxa, double cya,
                         double xb, double yb, double fb, Matrix Rb, Vector eye_b, double cxb, double cyb, int *erro);

#ifdef __cplusplus
}
#endif

#endif
