osgEarth的Rex引擎原理分析(四十四)如何控制父子TileNode节点的显隐

本文分析了osgEarth的Rex引擎如何控制父子TileNode的显隐。当一个TileNode有子节点且子节点准备就绪时,通常隐藏父节点,反之显示。此控制通过遍历Surface、TerrainCuller和DrawTileCommand来实现。文章还列举了一系列后续分析的主题,涉及osgEarth的多个方面。
摘要由CSDN通过智能技术生成

目标:(三十七)中的105

rex渲染出的地球是靠一块块TileNode瓦片拼接起来的,瓦片之间存在父子关系,一般显示父TileNode就不应显示子TileNode,反之亦然。那么rex是如何做这种显隐控制呢?

1、每一个TileNode瓦片在遍历时,会根据是否有子节点及子节点的准备情况来决定是否遍历其_surface(负责具体的显示内容)。

osgEarthDrivers/engine_rex/TileNode.cpp
bool
TileNode::cull(TerrainCuller* culler)
{

    // determine whether we can and should subdivide to a higher resolution:
    bool childrenInRange = shouldSubDivide(culler, context->getSelectionInfo());

    // whether it is OK to create child TileNodes is necessary.
    bool canCreateChildren = childrenInRange;

    // whether it is OK to load data if necessary.
    bool canLoadData = true;

    // whether to accept the current surface node and not the children.
    bool canAcceptSurface = false;
    
    // Don't create children in progressive mode until content is in place
    if ( _dirty && context->getOptions().progressive() == true )
    {
        canCreateChildren = false;
    }
    
    // If this is an inherit-viewpoint camera, we don't need it to invoke subdivision
    // because we want only the tiles loaded by the true viewpoint.
    const osg::Camera* cam = culler->getCamera();
    if ( cam && cam->getReferenceFrame() == osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT )
    {
        canCreateChildren = false;
        canLoadData       = false;
    }

    if (childrenInRange)
    {
        // We are in range of the child nodes. Either draw them or load them.

        // If the children don't exist, create them and inherit the parent's data.
        if ( !_childrenReady && canCreateChildren )
        {
            _mutex.lock();

            if ( !_childrenReady )
            {
                OE_START_TIMER(createChildren);
                createChildren( context );
                REPORT("TileNode::createChildren", createChildren);
                _childrenReady = true;

                // This means that you cannot start loading data immediately; must wait a frame.
                canLoadData = false;
            }

            _mutex.unlock();
        }

        // If all are ready, traverse them now.
        if ( _childrenReady )
        {
            for(int i=0; i<4; ++i)
            {
                getSubTile(i)->accept(*culler);
            }
        }

        // If we don't traverse the children, traverse this node's payload.
        else
        {
            canAcceptSurface = true;
        }
    }

    // If children are outside camera range, draw the payload and expire the children.
    else
    {
        canAcceptSurface = true;
    }

    // accept this surface if necessary.
    if ( canAcceptSurface )
    {
        _surface->accept( *culler );
        _lastAcceptSurfaceFrame.exchange( culler->getFrameStamp()->getFrameNumber() );
    }
}

2、对于一个TileNode瓦片节点,如果经过1的判断,需要裁剪遍历其_surface的话,会在TerrainCuller下的_terrain(TerrainR

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值