osg实现物体绕自身轴旋转及地球自转且绕太阳公转

目录

1. 太阳、地球模型

2. 思路说明

3. 代码实现


1. 太阳、地球模型

       我们知道,地球在自转的同时绕太阳公转。这就涉及到地球绕自身轴旋转及绕太阳轴公转,如何用osg实现呢?即效果如下(这里我们假定太阳是静止的):

2. 思路说明

       如果一个模型不在场景的中心点,这时候使用 osg::Matrix::rotate旋转的话,这个对象会围绕场景的中心点进行旋转,会转一个大圈,那么怎么做才能让他在任何位置的时候,围绕自己的轴心进行旋转?解决思路如下:

  1. 先保存物体在世界坐标系下的坐标,即物体在世界坐标系下的中心点坐标
  2. 再将物体移动到世界坐标系的原点。
  3. 在世界坐标系的原点旋转好后,再移动回原来的位置,即步骤1中的提到的坐标。
     
const osg::BoundingSphere& loaded_bs = m_spTrans0->getBound();  
osg::Vec3d center = m_spTrans0->getBound().center();  // 先保存物体中心点坐标
float fX = m_spTrans0->getBound().center().x();  
float fY = m_spTrans0->getBound().center().y();  
float fZ = m_spTrans0->getBound().center().z(); 

osg::Matrix curMatrix = m_spTrans0->getMatrix();
curMatrix *= osg::Matrix::translate(-center);     // 再将物体移动到世界坐标系原点
curMatrix *= osg::Matrix::rotate(osg::inDegrees(1.0), osg::Vec3d(0, 0, 1)); // 旋转
curMatrix *= osg::Matrix::translate(cen
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
要让子节点其中心旋转,您可以使用 `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"` 需要替换为您实际的场景文件路径。此外,您可以根据需要调整旋转角度的增量和动画速度。 希望对您有所帮助!如果您有任何进一步的问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值