osg在漫游器中旋转模型

目的是希望在漫游器做旋转操作时不按照场景中心,而是模型的中心来旋转。

我的做法是自定义了一个漫游器,继承自osgGA::TrackballManipulator,重写几个函数。

1.getInverseMatrix

父类默认的getInverseMatrix函数如下:

osg::Matrixd OrbitManipulator::getInverseMatrix() const
{
    return osg::Matrixd::translate( -_center ) *
           osg::Matrixd::rotate( _rotation.inverse() ) *
           osg::Matrixd::translate( 0.0, 0.0, -_distance );
}

旋转相关的矩阵为_rotation,因此这个矩阵不能让它再改变了,可自定义成员函数作为旋转矩阵:

osg::Matrix m_rotationMat;

而这个旋转矩阵作用的中心应该是模型中心,可用getBound().center()来获取:

m_modelCenter = m_pSceneData->getBound().center();

修改后的getInverseMatrix函数:

osg::Matrixd MyCameraManipulator::getInverseMatrix() const
{
	osg::Matrix m_viewMat = osg::Matrixd::translate(-_center) *
		osg::Matrixd::rotate(_rotation.inverse()) *
		osg::Matrixd::translate(0.0, 0.0, -_distance);

	osg::Matrix invMat = osg::Matrixd::translate(-m_modelCenter) *
		osg::Matrix::inverse(m_rotationMat) *
		osg::Matrixd::translate(m_modelCenter) *
		m_viewMat;
		
	return invMat;
}

与getInverseMatrix同级的函数getMatrix似乎不对结果产生影响,不过还是可以简单修改一下:

osg::Matrixd MyCameraManipulator::getMatrix() const
{
	return osg::Matrix::inverse(getInverseMatrix());
}

2.rotateTrackball

这个函数中在修改旋转矩阵,也就是将对_rotation的操作改作用到m_rotationMat:

void MyCameraManipulator::rotateTrackball(const float px0, const float py0, const float px1, const float py1, const float scale)
{
	osg::Vec3d axis;
	float angle;

	trackball(axis, angle, px0 + (px1 - px0) * scale, py0 + (py1 - py0) * scale, px0, py0);

	osg::Quat new_rotate;
	new_rotate.makeRotate(angle, axis);

	//_rotation = _rotation * new_rotate;						//这句是父类本来的

	m_rotationMat = m_rotationMat * osg::Matrix::rotate(new_rotate);		//这句是修改的

}

以上应该可以做到旋转时以模型中心为旋转中心的效果了

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值