リファレンスにあるような計算式でgluProject関数は計算している。
これも自分で実装すると、例えば以下のようになる。
※簡潔にするため、OpenCVの新しいC++インターフェイスを用いている
【例】
... ...
static double modelview[16];
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
static double projection[16];
glGetDoublev(GL_PROJECTION_MATRIX, projection);
static int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
cv::Mat Model(4,4,CV_64FC1,modelview);
cv::Mat Proj(4,4,CV_64FC1,projection);
cv::Mat PM = Model *Proj;
MygluProject(PositionXYZ[0],PositionXYZ[1],PositionXYZ[2],PM,viewport,&winX,&winY,&winZ);
... ...
int MygluProject(double objx, double objy, double objz, cv::Mat &PM, const int viewport[4],double *winx,double *winy,double *winz)
{
double in[4]= {objx,objy,objz,1.0};
cv::Mat v(4,1,CV_64FC1,in);
cv::transpose(PM,PM);//転置
cv::Mat v_dash = PM * v;
if(v_dash.at<double>(3,0) == 0.0)
{
return GL_FALSE;
}
v_dash = v_dash / v_dash.at<double>(3,0);
*winx = viewport[0]+(1+v_dash.at<double>(0,0))*viewport[2]/2;
*winy = viewport[1]+(1+v_dash.at<double>(1,0))*viewport[3]/2;
*winz = (1+v_dash.at<double>(2,0))/2;
return GL_TRUE;
}
【メモ】
OpenGLは行列の配置が異なるのでM×Pを計算して転置した。