OSG開發筆記(二十七):OSG路徑漫遊之錄製播放固定路徑動畫

歡迎技術交流和幫助,提供IT相關服務,索要源碼請聯繫博主QQ: 21497936,若該文爲原創文章,未經允許不得轉載
原博主博客地址: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效果

       

 

路徑漫遊

       路徑漫遊就是按照固定路徑進行移動的漫遊方式,路徑是預先固定的設計好的,所以是固定路徑漫遊。

       

        記錄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開始;

        

              以上可以說明路徑初始化時,0點就沒對上。

  • 步驟三:檢測保存的關鍵點數據

       起始點是正確的。

  • 步驟四:播放時,直接調用外部的文件,場景還是緊接

       每次啓動,開始播放位置都有存在非時間0點位置的問題

  • 步驟五:場景直接使用動畫路徑漫遊

       每次啓動,開始播放位置都有存在非時間0點位置的問題

       

  • 步驟六:純模型代碼打開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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章