osgEarth的Rex引擎原理分析(一零二)如何判断瓦片的添加删除

本文分析了osgEarth的Rex引擎中瓦片何时删除的问题,指出由于缺少监听机制,直接监听意义不大。同时详细阐述了瓦片添加的监听步骤,包括创建、高程修改时的通知,以及更新队列的作用,确保跨阶段和线程的安全。文章还列出了后续一系列关于Rex引擎的问题,涉及瓦片管理、更新机制、引擎结构等多个方面。
摘要由CSDN通过智能技术生成

目标:(一零零)中的问题180

1、瓦片何时删除的事件是无法监听(rex没有提供相应的机制),貌似意义也不大

2、瓦片的添加监听步骤如下:

2.1瓦片在创建、有高程修改时会发出通知

osgEarthDrivers/engine_rex/TileNode.cpp
void
TileNode::create(const TileKey& key, TileNode* parent, EngineContext* context)
{
    context->getEngine()->getTerrain()->notifyTileAdded(getKey(), this);
}


void
TileNode::merge(const TerrainTileModel* model, const RenderBindings& bindings)
{
    if (newElevationData)
    {
        _context->getEngine()->getTerrain()->notifyTileAdded(getKey(), this);
    }
}

2.2如果存在监听回调类,地形服务接口会在更新队列里添加一个通知操作。

osgEarth/Terrain.cpp
void
Terrain::notifyTileAdded( const TileKey& key, osg::Node* node )
{
    if (_callbacksSize > 0)
    {
        _updateQueue->add(new OnTileAddedOperation(key, node, this));
    }
}

2.3在更新遍历地形服务接口时,会通知到每一个回调类。

osgEarth/Terrain.cpp
void
Terrain::update()
{
    _updateQueue->runOperations();
}
osg/OpenThread.cpp
void OperationQueue::runOperations(Object* callingObject)
{
    if (_currentOperationIterator==_operations.end()) _currentOperationIterator = _operations.begin();

    for(;
        _currentOperationIterator != _operations.end();
        )
    {
        (*operation)(callingObject);
    }
}
osgEarth/Terrain.cpp
void Terrain::OnTileAddedOperation::operator()(osg::Object*)
{
    terrain->fireTileAdded( _key, node.get() );
}

void
Terrain::fireTileAdded( const TileKey& key, osg::Node* node )
{
    for( CallbackList::iterator i = _callbacks.begin(); i != _callbacks.end(); )
    {       
        i->get()->onTileAdded( key, node, context );
    }
}

2.4定义回调类,注册回调类,静等回调通知

#ifndef TILEADDCALLBACK_H
#define TILEADDCALLBACK_H

#include <osgEarth/Terrain>
class TileAddCallback:public osgEarth::TerrainCallback
{
public:
    TileAddCallback();

    // TerrainCallback interface
public:
    void onTileAdded(const osgEarth::TileKey &key, osg::Node *graph, osgEarth::TerrainCallbackContext &context);
};

#endif // TILEADDCALLBACK_H
//监听瓦片添加
TileAddCallback* tileAddCB=new TileAddCallback;
Rexter->getTerrain()->addTerrainCallback(tileAddCB);

 

为什么要多出一个2.2的更新队列,而不是直接进行更新。这是因为瓦片添加通知出现的时机要么是在create,要么是在merge时,前者属于裁剪阶段,后者位于DatabasPager线程阶段,而瓦片添加的响应一般是在更新阶段,因此需要有一个更新队列做以缓冲,避免跨阶段或跨线程。

 

 

 

待继续分析列表:

9、earth文件中都有哪些options((九)中问题)

10、如何根据earth文件options创建不同的地理信息引擎节点((九)中问题)

11、rex地理信息引擎的四梁八柱((九)中问题)

12、osgEarth::TerrainEngineNode中setMap方法作用((十二)中问题)

13、RexTerrainEngineNode中_mapFrame的作用((十二)中问题)

14、地形变形(Terrain morphing)((十二)中问题)

15、地球瓦片过期门限的含义((十二)中问题)

16、高分辨率优先的含义(

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值