目标:(三十七)中的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