|
我想写段程序,导入多个三维模型,然后分别自动获取每个三维模型的图片,并将这些图片在列表控件中显示出来,这就存在两个问题:
问题1:如何自动获取三维模型的图片,我的解决办法是在viewer中分别导入每个三维模型,然后用截屏的代码截取模型的外观并导入至列表控件,请问大家有没有其他更好的方法?
问题2:在截屏的方法中,我想自动截取三维模型范围上的图片,而不是全屏,因此,我求取了模型节点的包围盒,将包围盒的最大最小坐标转换为屏幕坐标,再求屏幕坐标的包围盒,但在这世界坐标转为屏幕坐标的过程中出现了问题,我采用的是论坛上heishuijing2222的方法,传进去(1,1,1),但结果为(-1010,-1280,0),实现代码如下,还请大家帮我看看
int main(int argc, char** argv)
{
osgViewer::Viewer *pViewer=new osgViewer::Viewer();
osg::Group *pRoot=new osg::Group();
osg::Node *pNode=new osg::Node();
osgUtil::Optimizer optimizer;
optimizer.optimize(pRoot);
pViewer->setSceneData(pRoot);
pViewer->realize();
osg::Vec3 sv=WorldToScreen(pViewer,osg::Vec3(1,1,1));
pViewer->run();
}
void Transform_Point(double out[4], const double m[16], const double in[4])
{
#define M(row,col) m[col*4+row]
out[0] =
M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
out[1] =
M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
out[2] =
M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
out[3] =
M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
#undef M
}
osg::Vec3d WorldToScreen(osgViewer::View* view,osg::Vec3 worldpoint)
{
double in[4], out[4];
in[0] = worldpoint._v[0];
in[1] = worldpoint._v[1];
in[2] = worldpoint._v[2];
in[3] = 1.0;
//获得当前的投影矩阵和模型视图矩阵
osg::Matrix projectMatrix= view->getCamera()->getProjectionMatrix();
osg::Matrix viewprojectMatrix = view->getCamera()->getViewMatrix();
//下面计算 模型视图矩阵 * 投影矩阵 * 视口窗口变换矩阵
double modelViewMatrix[16];
memcpy(modelViewMatrix,viewprojectMatrix.ptr(),sizeof(GLdouble) * 16);
Transform_Point(out, modelViewMatrix, in);
double myprojectMatrix[16];
memcpy(myprojectMatrix,projectMatrix.ptr(),sizeof(GLdouble) * 16);
Transform_Point(in, myprojectMatrix, out);
if (in[3] == 0.0)
return osg::Vec3d(0,0,0);
in[0] /= in[3];
in[1] /= in[3];
in[2] /= in[3];
int viewPort[4];
osg::Viewport* myviewPort = view->getCamera()->getViewport();
viewPort[0] = myviewPort->x();
viewPort[1] = myviewPort->y();
viewPort[2] = myviewPort->width();
viewPort[3] = myviewPort->height();
//计算 三维点在屏幕上的二维投影点
osg::Vec3d sceenPoint;
sceenPoint._v[0] = (int)(viewPort[0] + (1 + in[0]) * viewPort[2] / 2 + 0.5);
sceenPoint._v[1] = (int)(viewPort[1] + (1 + in[1]) * viewPort[3] / 2 + 0.5);
sceenPoint._v[2] = 0;
return sceenPoint;
} |
|