OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画

若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/99712610

目录

前言

Demo效果

路径漫游

动画路径类AnimationPath

关键代码

开始录制

录制过程

录制结束

播放

拓展:存储path文件

拓展:读取path文件

入坑

入坑一:没有进行动画

入坑二:动画路径稍微长一点,如10s以上,关键点也多,那么开始执行动画时,不是从路径0s开始执行,而是从动画中间开始。

工程模板:对应版本号1.24.0


OSG三维开发专栏

OSG开发笔记(一):OSG介绍、编译

OSG开发笔记(二):OSG帮助文档编译

OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序

OSG开发笔记(四):OSG不使用osgQt重写类嵌入Qt应用程序》:

OSG开发笔记(五):OSG场景理解与基础类概述

OSG开发笔记(六):OSG内存管理

OSG开发笔记(七):OSG复现OpenGL入门示例和OSG坐标系

OSG开发笔记(八):OSG模型文件存储与读取

OSG开发笔记(九):OSG模型的基本操作之添加/删除、显示/隐藏、开关节点开/》:

OSG开发笔记(十):OSG模型的变换之平移、旋转和缩放

OSG开发笔记(十一):OSG渲染状态与2D纹理映射

OSG开发笔记(十二):OSG基本几何图形、内置几何类型

OSG开发笔记(十三):OSG三维纹理映射(体渲染)

OSG开发笔记(十四):OSG交互

OSG开发笔记(十五):OSG光照

OSG开发笔记(十六):OSG视口、相机和视点

OSG开发笔记(十七):OSG中的相机移动

OSG开发笔记(十八):OSG鼠标拾取pick、拽托球体以及多光源

OSG开发笔记(十九):OSG文字显示

OSG开发笔记(二十):OSG使用HUD显示文字

OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式

OSG开发笔记(二十二):OSG场景背景

OSG开发笔记(二十三):Qt使用QOpenGLWidget渲染OSG地球仪

OSG开发笔记(二十四):OSG漫游之平移、转向和低抬头

OSG开发笔记(二十五):OSG漫游之CS移动、碰撞检测与跳跃

OSG开发笔记(二十六):OSG漫游之上下楼梯

《OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画

《OSG开发笔记(二十八):OSG模型固定路径动画

  持续补充中…

 

        OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画

 

前言

       在3D的场景中,有时候需要漫游3D场景,随着视口移动来按照预定的路径在遨游,这就是本章需要讲解的路径漫游。

 

Demo效果

       

 

路径漫游

       路径漫游就是按照固定路径进行移动的漫游方式,路径是预先固定的设计好的,所以是固定路径漫游。

       OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画_第1张图片

        记录A,B,C,D四个点,每个点的信息至少包含位置、朝向、时间等关键信息,形成一条动画路径。

 

动画路径类AnimationPath

       在OSG中形成路径的AnimationPath类,使用该类是可以插入关键点,函数如下:

void AnimationPath::insert(double time, const ControlPoint &controlPoint);

       依据路径漫游的原因,可以知道参数的意义:

  • time:记录点的时间(类型double,单位秒);
  • controlPoint:控制点,其构函数包含位置和朝向;

 

关键代码

       使用默认的路径漫游器,设置AnimationPath即可。

开始录制

void AnimationPathCameraMainpulator::startRecord()
{
    // 生成一个动画类
    _pTimer = new osg::Timer;
    _pAnimationPath = new osg::AnimationPath();
    _pAnimationPath->setLoopMode(osg::AnimationPath::LOOP);
    _pTimer->setStartTick();
    _pAnimationPath->insert(0,
                            osg::AnimationPath::ControlPoint(
                                _position,
                                osg::Quat(osg::DegreesToRadians(_originAngleX + _offsetAngleX),
                                          osg::Vec3f(1, 0, 0),
                                          osg::DegreesToRadians(_originAngleY + _offsetAngleY),
                                          osg::Vec3f(0, 1, 0),
                                          osg::DegreesToRadians(_originAngleZ + _offsetAngleZ),
                                          osg::Vec3f(0, 0, 1))));
    _startRecord = true;
}

录制过程

if(_startRecord)
{
    _pAnimationPath->insert(_pTimer->time_s(),
                            osg::AnimationPath::ControlPoint(
                                _position,
                                osg::Quat(osg::DegreesToRadians(_originAngleX + _offsetAngleX),
                                          osg::Vec3f(1, 0, 0),
                                          osg::DegreesToRadians(_originAngleY + _offsetAngleY),
                                          osg::Vec3f(0, 1, 0),
                                          osg::DegreesToRadians(_originAngleZ + _offsetAngleZ),
                                          osg::Vec3f(0, 0, 1))));
    _pOsgWidget->update();
}

录制结束

void AnimationPathCameraMainpulator::stopRecord()
{
    _startRecord = false;
    _pOsgWidget->update();
}

播放

void AnimationPathCameraMainpulator::playRecord()
{
    if(_pOsgViewerWidget)
    {
#if 0
        // 存入文件
        std::ofstream file;
        file.open("path.txt");
        _pAnimationPath->write(file);
        file.flush();
        file.close();
#endif
#if 0
        osgGA::AnimationPathManipulator *p = new osgGA::AnimationPathManipulator("path.txt");
#endif
        osgGA::AnimationPathManipulator *p = new osgGA::AnimationPathManipulator(_pAnimationPath.get());
        _pOsgViewerWidget->setCameraManipulator(p);
    }
    _pOsgWidget->update();
}

拓展:存储path文件

// 存入文件
std::ofstream file;
file.open("path.txt");
_pAnimationPath->write(file);
file.flush();
file.close();

拓展:读取path文件

osgGA::AnimationPathManipulator *p = new osgGA::AnimationPathManipulator("path.txt");
_pOsgViewerWidget->setCameraManipulator(p);

 

入坑

入坑一:没有进行动画

解决方法:

       录入时间以秒为单位,类型为double。

入坑二:动画路径稍微长一点,如10s以上,关键点也多,那么开始执行动画时,不是从路径0s开始执行,而是从动画中间开始。

解决过程:

  • 步骤一:检查存入的零点的时间与坐标是否对上

       能对上。

  • 步骤二:获取回调函数的动画时间播放时间,动画时间从0开始,但是路径的的却不是0这个时刻的点,初始化时也调用reset。所以路径给回调函数后,路径从某个时间点运行,但是前面的路径也没有丢,设置循环时,又会跑完从0开始;

        OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画_第2张图片

              以上可以说明路径初始化时,0点就没对上。

  • 步骤三:检测保存的关键点数据

       起始点是正确的。

  • 步骤四:播放时,直接调用外部的文件,场景还是紧接

       每次启动,开始播放位置都有存在非时间0点位置的问题

  • 步骤五:场景直接使用动画路径漫游

       每次启动,开始播放位置都有存在非时间0点位置的问题

       OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画_第3张图片

  • 步骤六:纯模型代码打开path,无其他代码,依然存在此问题

解决方法:

       暂未解决,期待大佬找到问题原因。

       补充一:OSG群大佬Autumn breeze也出现此问题,单独裸代码demo不会有问题,加载到其他ui框架工程中出现此问题。

       补充二:经笔者笔记《OSG开发笔记(二十八):OSG模型动画》中测试,模型动画不会有此问题。

 

工程模板:对应版本号1.24.0

        对应版本号1.24.0


原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/99712610

你可能感兴趣的:(Qt开发专栏,OSG,OSG三维开发专栏)