OSGEarth学习笔记(2)视角与基本渲染

发布于 2024-09-19  3426 次阅读


摄像机控制

osgEarth入门13切换相机拍摄点 - 知乎 (zhihu.com)

看了下viewpoint的源码,还算清晰

记得一定先设置场景数据

// 设置场景数据
    viewer.setSceneData(mapNode);

    Viewpoint vp("demo",
        0,  // 焦点经度 ,单位角度。
        0,  // 焦点维度 ,单位角度。
        0,   // 海拔高度 单位米。
        0,   // Heading 相机指向焦点角度,单位角度。
        -90,   // pitch 相机相对焦点俯仰角度,单位角度。
        1E7 // 距离焦点距离,这里表示距离地表经纬度点的距离,单位米。
    );
    earthManipulator->setViewpoint(vp
        , 0  // 相机移动时间,单位秒。
    );
    vp.setFocalPoint(GeoPoint(SpatialReference::get("wgs84"),118.87, 37.64, 0.0, ALTMODE_ABSOLUTE));
    vp.setRange(Distance(1E5, Units::METERS));
    earthManipulator->setViewpoint(vp
        , 5  // 相机移动时间,单位秒。
    );

    // 运行viewer
    //return Metrics::run(viewer);
    return viewer.run();

用callback机制加定时器,我们可以设置多段视角变化。

// 自定义回调类,用于顺序切换多个 Viewpoint
class MultiViewpointCallback : public osg::NodeCallback
{
public:
    MultiViewpointCallback(osgEarth::EarthManipulator* manipulator,
        const std::vector<osgEarth::Viewpoint>& viewpoints,
        const std::vector<int>& times)
        : _manipulator(manipulator), _viewpoints(viewpoints), _times(times), _currentIndex(0), _elapsedTime(0.0), _firstViewpointExecuted(false)
    {
        _lastUpdateTime = osg::Timer::instance()->tick();
    }

    // 每一帧调用此方法
    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) override
    {
        // 获取当前时间
        osg::Timer_t now = osg::Timer::instance()->tick();
        double deltaTime = osg::Timer::instance()->delta_s(_lastUpdateTime, now);
        _elapsedTime += deltaTime;

        // 如果第一个 Viewpoint 未执行,立即执行
        if (!_firstViewpointExecuted && _currentIndex == 0)
        {
            // 使用 _times 中的过渡时间
            _manipulator->setViewpoint(_viewpoints[_currentIndex], _times[_currentIndex]);
            _firstViewpointExecuted = true;  // 标记第一个 Viewpoint 已执行
            _elapsedTime = 0.0;  // 重置计时器
            _currentIndex++;  // 准备执行下一个 Viewpoint
        }
        // 检查是否到达上一个 Viewpoint 的过渡时间并且还有未切换的视点
        else if (_elapsedTime >= _times[_currentIndex - 1] && _currentIndex < _viewpoints.size())
        {
            // 使用 _times 中的过渡时间
            _manipulator->setViewpoint(_viewpoints[_currentIndex], _times[_currentIndex]);
            _elapsedTime = 0.0;  // 重置计时器
            _currentIndex++;
        }

        _lastUpdateTime = now;  // 更新时间
        // 继续场景图的遍历和更新
        traverse(node, nv);
    }

private:
    osgEarth::EarthManipulator* _manipulator;
    std::vector<osgEarth::Viewpoint> _viewpoints;
    std::vector<int> _times;  // 每个 Viewpoint 的过渡时间
    unsigned int _currentIndex;
    double _elapsedTime;
    osg::Timer_t _lastUpdateTime;
    bool _firstViewpointExecuted;  // 用于标记第一个 Viewpoint 是否已经执行
};

int main(){
    ...
    // 设置场景数据
    viewer.setSceneData(mapNode);
    
    //设置初始点
    osgEarth::Viewpoint Viewpoint1("Viewpoint1", 120.0, 30.0, 0.0, 0.0, -90, 2E7);
    earthManipulator->setViewpoint(Viewpoint1, 0.0);
    // 定义多个 Viewpoint
    std::vector<int> times = { 7, 5 };
    std::vector<osgEarth::Viewpoint> viewpoints;
    viewpoints.push_back(osgEarth::Viewpoint("Viewpoint1", 118.87, 37.64, 0.0, 0.0, -90, 9E5));
    viewpoints.push_back(osgEarth::Viewpoint("Viewpoint2", 118.87, 37.64, 0.0, 0.0, -90, 9E4));

    // 创建自定义回调
    osg::ref_ptr<MultiViewpointCallback> callback = new MultiViewpointCallback(earthManipulator, viewpoints, times);

    // 将回调添加到地图节点上
    mapNode->addUpdateCallback(callback);

    // 运行viewer
    return viewer.run();
}

OSGEarth缓存目录 cache

试了一晚上,cache的源代码我是一点没找到捏妈的地址设置在哪。唯一可行的方法是设置环境变量

    _putenv_s("OSGEARTH_CACHE_PATH", "D:/coding/testdata/cache");
    //_putenv_s("OSGEARTH_CACHE_ONLY", "1");//只从缓存读取

届ける言葉を今は育ててる
最后更新于 2024-09-21