|
当对一个物体进行先平移再旋转的操作时 ,目标是将物体沿 x轴正向平移 10个单位 ,再将物体自身绕z轴顺时针旋转 30度 ,但是在实际实施变换的过程中后 ,却得不到正确的结果.如图所示 ,图中水平垂直分别为 x, y坐标轴 , z坐标与纸面垂直.上一行是用户原来希望得到的结果 ,而下一行则是实际实施了变换之后得到的结果.
在osgearth中,无论使用以下哪种都会发生这种现象。
//scale->postMult(osg::Matrix::rotate(osg:egreesToRadians(-90.0), 0, 1, 0));
//locator->getLocator()->setOrientation(osg::Vec3d(-90, 0, 0));
看到一篇osg论文,使用在每次变换前先将物体平移至世界坐标系的原点 ,实施变换之后再将物体进行反平移的方法,实验证明是好用的,代码如下:
//获取场景节点 ,将其转换为 MatrixTransform类型
const osg::Matrix m_matrix = scale->getMatrix(); //获得变换物体表面顶点矩阵
const osg::BoundingSphere m_box = scale->getBound(); //获得变换物体的包围盒 ,从而获得物体的中心
osg::Matrix preMat = osg::Matrix::translate(-m_box.center()) ;
osg::Matrix proMat = osg::Matrix::translate(m_box.center()) ;
osg::Matrix matrix1 = m_matrix * preMat; //将物体中心平移至世界坐标的原点
osg::Matrix matrix2 = matrix1 * osg::Matrix::rotate(osg::DegreesToRadians(-90.0), 0, 1, 0);
//进行变换级联 ,采用先缩放后旋转再平移的顺序
osg::Matrix matrix =matrix2 * proMat; //变换后再将物体移回
scale->setMatrix(matrix) ; //将结果矩阵重新设回物体
不知道是否有更好的方法,盼高手指点 |
|