OSG围绕物体中心旋转等变化

OSG物体围绕自身中心旋转变化

创建场景时,默认旋转中心是view中心。
想要以物体以自身中心为旋转基点的话,思路是把物体先移动到中心,变化后再移动回原来位置。

osg::Matrix view_matrix = _view->getMatrix();
auto trans_temp = view_matrix.getTrans();
// 将场景先移动到view中心
view_matrix *= osg::Matrix::translate(-trans_temp );
// 旋转
view_matrix *= osg::Matrix::rotate(osg::inDegrees(1.0), osg::Vec3d(0,0,1);
// 移动回原来位置
view_matrix *= osg::Matrix::translate(trans_temp );

如果物体导入的物体在局部坐标系中,不处于中心位置,上面的移动就不够了。需要再将物体中心移动到中心点。

但是由于多移动了一个物体center的translate。在旋转时matrix的trans值此时不为零,再在之后操作中matrix.getTrans的值已经不是之前的trans。
所以要多做一步操作,这里的解决方法是,将center也进行matrix的操作,这样物体和物体中心的位置还是相对不变。

// 获取物体中心点
osg::Vec3d center = _model->getBound().center();
*matrix_center *= osg::Matrix::translate(center);

osg::Matrix view_matrix = _view->getMatrix();
auto trans_temp = view_matrix.getTrans();
// 将场景先移动到view中心
view_matrix *= osg::Matrix::translate(-trans_temp );
// 获得新的物体中心
*matrix_center *= view_matrix ;
view_matrix *= osg::Matrix::translate(-matrix_center->getTrans());
// 旋转
view_matrix *= osg::Matrix::rotate(osg::inDegrees(1.0), osg::Vec3d(0,0,1);
// 移动回原来位置
matrix *= osg::Matrix::translate(trans_temp + matrix_center->getTrans());

这样的操作,适用于所有需要以物体为中心的变化操作。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要让子节点绕其中心旋转,您可以使用 `osg::MatrixTransform` 类来对子节点进行变换。下面是一个示例代码片段,展示了如何使用 OSG 让子节点绕其中心旋转: ```cpp #include <osg/MatrixTransform> #include <osgDB/ReadFile> #include <osgViewer/Viewer> int main() { // 加载场景文件 osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("path/to/your/scene.osg"); // 创建 MatrixTransform 节点作为根节点 osg::ref_ptr<osg::MatrixTransform> root = new osg::MatrixTransform; root->addChild(scene); // 创建 MatrixTransform 节点作为子节点 osg::ref_ptr<osg::MatrixTransform> child = new osg::MatrixTransform; // 设置子节点的变换矩阵,将其平移到世界坐标系的某个位置 osg::Matrix translateMatrix; translateMatrix.makeTranslate(osg::Vec3(1.0, 0.0, 0.0)); // 平移 1.0 个单位到 X 轴正方向 child->setMatrix(translateMatrix); // 创建旋转节点,将其作为子节点的子节点 osg::ref_ptr<osg::MatrixTransform> rotate = new osg::MatrixTransform; // 设置旋转节点的中心点 rotate->setReferenceFrame(osg::Transform::ABSOLUTE_RF); rotate->setMatrix(osg::Matrix::translate(-1.0, 0.0, 0.0)); // 将中心点平移到 X 轴负方向 // 添加子节点到旋转节点 rotate->addChild(child); // 将旋转节点添加到根节点 root->addChild(rotate); // 创建查看器并设置根节点 osgViewer::Viewer viewer; viewer.setSceneData(root); // 设置旋转动画 float angle = 0.0; while (!viewer.done()) { angle += 0.01; // 每次迭代增加旋转角度 // 创建旋转矩阵 osg::Matrix rotationMatrix; rotationMatrix.makeRotate(angle, osg::Vec3(0.0, 0.0, 1.0)); // 绕 Z 轴旋转角度 // 设置子节点的变换矩阵,实现旋转 child->setMatrix(rotationMatrix); // 更新视图 viewer.frame(); } return 0; } ``` 在上面的示例中,我们加载了一个场景文件,并创建了一个 `osg::MatrixTransform` 节点作为根节点。然后,我们创建了一个子节点,并使用变换矩阵将其平移到世界坐标系的某个位置。接下来,我们创建了一个旋转节点,并将子节点添加为其子节点。我们还设置了旋转节点的中心点,并将其添加到根节点中。 然后,我们创建了一个 `osgViewer::Viewer` 对象,并将根节点设置为场景数据。在一个循环中,我们更新旋转角度,并根据旋转角度创建旋转矩阵。然后,我们将旋转矩阵设置为子节点的变换矩阵,以实现子节点绕其中心旋转的效果。 请注意,上述代码中的路径 `"path/to/your/scene.osg"` 需要替换为您实际的场景文件路径。此外,您可以根据需要调整旋转角度的增量和动画速度。 希望对您有所帮助!如果您有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值