Commit 38ebfa0b authored by Laurent Belcour's avatar Laurent Belcour

[Add] Adding the 3D parametrization for STARK and NEUMANN.

[Update] The brdf slice plugin to handle the 3D params.
parent 77935530
......@@ -47,6 +47,8 @@ std::map<params::input, const param_info> create_map()
_map.insert(std::make_pair<params::input, const param_info>(params::ISOTROPIC_TL_TV_PROJ_DPHI, param_info("ISOTROPIC_TL_TV_PROJ_DPHI", 3, "Isoptropic projected phi parametrization.")));
_map.insert(std::make_pair<params::input, const param_info>(params::SCHLICK_TL_TK_PROJ_DPHI, param_info("SCHLICK_TL_TK_PROJ_DPHI", 3, "Isoptropic projected phi parametrization centered around the back vector.")));
_map.insert(std::make_pair<params::input, const param_info>(params::RETRO_TL_TVL_PROJ_DPHI, param_info("RETRO_TL_TVL_PROJ_DPHI", 3, "Isoptropic retro projected phi parametrization.")));
_map.insert(std::make_pair<params::input, const param_info>(params::STARK_3D, param_info("STARK_3D", 3, "Stark parametrization H, B.")));
_map.insert(std::make_pair<params::input, const param_info>(params::NEUMANN_3D, param_info("NEUMANN_3D", 3, "Neumann parametrization H, B.")));
/* 4D Params */
_map.insert(std::make_pair<params::input, const param_info>(params::RUSIN_TH_PH_TD_PD, param_info("RUSIN_TH_PH_TD_PD", 4, "Complete Half angle parametrization")));
......@@ -277,6 +279,43 @@ void params::to_cartesian(const double* invec, params::input intype,
outvec[5] = cos(invec[0]);
}
break;
// TODO: Add the phi into the reparametrization.
//
case STARK_3D:
{
const double Hx = invec[0];
const double Hy = 0;
const double Hz = sqrt(1.0 - Hx*Hx - invec[1]*invec[1]);
// Ensuring that <H,B> = 0
const double cosPhi = cos(invec[2]);
const double sinPhi = sin(invec[2]);
const double cosThe = 1.0;
const double sinThe = sqrt(1.0 - cosThe*cosThe);
const double Bx = invec[1]*sinThe*cosPhi;
const double By = invec[1]*sinThe*sinPhi;
const double Bz = invec[1]*cosThe;
outvec[0] = Hx-Bx;
outvec[1] = Hy-By;
outvec[2] = Hz-Bz;
outvec[3] = Hx+Bx;
outvec[4] = Hy+By;
outvec[5] = Hz+Bz;
}
break;
case NEUMANN_3D:
{
const double cosPhi = cos(invec[2]);
const double sinPhi = sin(invec[2]);
outvec[0] = invec[0] + cosPhi*invec[1];
outvec[1] = sinPhi*invec[1];
outvec[2] = sqrt(1.0 - outvec[0]*outvec[0] - outvec[1]*outvec[1]);
outvec[3] = invec[0] + cosPhi*invec[1];
outvec[4] = - sinPhi*invec[1];
outvec[5] = sqrt(1.0 - outvec[3]*outvec[3] - outvec[4]*outvec[4]);
}
break;
// 4D Parametrization
case params::RUSIN_TH_PH_TD_PD:
......@@ -514,6 +553,31 @@ void params::from_cartesian(const double* invec, params::input outtype,
outvec[0] = acos(invec[5]);
outvec[1] = theta_k * cos(dphi);
outvec[2] = theta_k * sin(dphi);
}
break;
case STARK_3D:
{
double Hx = 0.5*(invec[0]+invec[3]);
double Hy = 0.5*(invec[1]+invec[4]);
outvec[0] = sqrt(Hx*Hx + Hy*Hy);
double Bx = 0.5*(invec[3]-invec[0]);
double By = 0.5*(invec[4]-invec[1]);
double Bz = 0.5*(invec[5]-invec[2]);
outvec[1] = sqrt(Bx*Bx + By*By + Bz*Bz);
outvec[2] = atan2(Hy, Hx) - atan2(By, Bx);
}
break;
case NEUMANN_3D:
{
double Hx = 0.5*(invec[0]+invec[3]);
double Hy = 0.5*(invec[1]+invec[4]);
outvec[0] = sqrt(Hx*Hx + Hy*Hy);
double Bx = 0.5*(invec[3]-invec[0]);
double By = 0.5*(invec[4]-invec[1]);
outvec[1] = sqrt(Bx*Bx + By*By);
outvec[2] = atan2(Hy, Hx) - atan2(By, Bx);
}
break;
......
......@@ -105,8 +105,19 @@ class params
and \f$ \tilde{B} = \frac{1}{2}(L-V) \f$. \f$ \tilde{H}_p \f$
is the projected coordinates of \f$ \tilde{H} \f$ on the
tanget plane. */
NEUMANN_2D, /*!< Neumann and Neumann parametrization.*/
NEUMANN_2D, /*!< Neumann and Neumann [1996] parametrization. This parametrization
is defined by the couple \f$ \vec{x} = ||\tilde{H}_p||,
||\tilde{B}_p|| \f$, where \f$ \tilde{H} = \frac{1}{2}(L+V) \f$
and \f$ \tilde{B} = \frac{1}{2}(L-V) \f$. \f$ \tilde{H}_p \f$
is the projected coordinates of \f$ \tilde{H} \f$ on the
tanget plane.*/
STARK_3D, /*!< Modified Stark et al. 2D parametrization. This parametrization
is defined by the tuple \f$ \vec{x} = ||\tilde{H}_p||,
||\tilde{B}||, \phi_B-\phi_H \f$. */
NEUMANN_3D, /*!< Neumann and Neumann [1996] 3D parametrization. This parametrization
is defined by the tuple \f$ \vec{x} = ||\tilde{H}_p||,
||\tilde{B}_p||, \phi_B-\phi_H \f$.*/
CARTESIAN, /*!< View and Light vectors represented in cartesian coordinates.
We always pack the view vector first: \f$[V.x, V.y,
V.z, L.x, L.y, L.z] \f$*/
......
......@@ -38,6 +38,7 @@ class BrdfSlice : public data {
public:
int width, height, slice;
double _phi;
double* _data;
BrdfSlice(const arguments& args) : data()
......@@ -46,6 +47,7 @@ class BrdfSlice : public data {
width = 512; height = 512;
slice = 1;
_data = new double[3*width*height*slice];
_phi = 0.5*M_PI;
// Set the input and output parametrization
_in_param = params::STARK_2D;
......@@ -57,9 +59,20 @@ class BrdfSlice : public data {
// parameters provided.
if(args.is_defined("param")) {
params::input param = params::parse_input(args["param"]);
// The param is a 2D param
if(params::dimension(param) == 2) {
std::cout << "<<INFO>> Specified param \"" << args["param"] << "\"" << std::endl;
this->setParametrization(param);
// The oaram is a 3D param
} else if(params::dimension(param) == 3) {
std::cout << "<<INFO>> Specified param \"" << args["param"] << "\"" << std::endl;
this->setParametrization(param);
this->_phi = (M_PI / 180.0) * args.get_float("phi", 90);
_nX = 3;
} else {
std::cout << "<<ERROR>> Invalid specified param \"" << args["param"] << "\"" << std::endl;
std::cout << "<<ERROR>> Must have 2D input dimension" << std::endl;
......@@ -95,18 +108,20 @@ class BrdfSlice : public data {
// Acces to data
vec get(int id) const
{
vec res(5) ;
vec res(_nX+_nY) ;
const int i = id % width;
const int k = id / (width*height);
const int j = (id - k*width*height) / width;
res[0] = (i+0.5) / double(width);
res[1] = (j+0.5) / double(height);
//res[2] = M_PI*(k+0.5) / double(slice);
if(_nX == 3) {
res[2] = _phi;
}
res[2] = _data[3*id + 0];
res[3] = _data[3*id + 1];
res[4] = _data[3*id + 2];
res[_nX+0] = _data[3*id + 0];
res[_nX+1] = _data[3*id + 1];
res[_nX+2] = _data[3*id + 2];
return res ;
}
......@@ -118,7 +133,7 @@ class BrdfSlice : public data {
//! \todo Test this function
void set(const vec& x)
{
assert(x.size() == 5);
assert(x.size() == _nX+_nY);
assert(x[0] <= 1.0/*0.5*M_PI*/ && x[0] >= 0.0);
assert(x[1] <= 1.0/*0.5*M_PI*/ && x[1] >= 0.0);
......@@ -128,9 +143,9 @@ class BrdfSlice : public data {
//const int k = floor(x[2] * slice / (M_PI));
const int id = i + j*width + k*width*height;
_data[3*id + 0] = x[2];
_data[3*id + 1] = x[3];
_data[3*id + 2] = x[4];
_data[3*id + 0] = x[_nX+0];
_data[3*id + 1] = x[_nX+1];
_data[3*id + 2] = x[_nX+2];
}
void set(int id, const vec& x)
{
......@@ -180,10 +195,12 @@ class BrdfSlice : public data {
// Get min and max input space values
vec min() const
{
vec res(2);
vec res(_nX);
res[0] = 0.0 ;
res[1] = 0.0 ;
//res[2] = 0.0 ;
if(_nX == 3) {
res[2] = 0.0 ;
}
return res ;
}
vec max() const
......@@ -191,13 +208,15 @@ class BrdfSlice : public data {
vec res(2);
res[0] = M_PI / 2 ;
res[1] = M_PI / 2 ;
//res[2] = M_PI;
if(_nX == 3) {
res[2] = 0.0 ;
}
return res ;
}
int dimX() const
{
return 2 ;
return _nX ;
}
int dimY() const
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment