Exemplo n.º 1
0
DrawTileCommand*
TerrainCuller::addDrawCommand(UID uid, const TileRenderModel* model, const RenderingPass* pass, TileNode* tileNode)
{
    SurfaceNode* surface = tileNode->getSurfaceNode();

    const RenderBindings&  bindings = _context->getRenderBindings();

    // skip layers that are not visible:
    if (pass && pass->_imageLayer.valid() && !pass->_imageLayer->getVisible())
        return 0L;

    // add a new Draw command to the appropriate layer
    osg::ref_ptr<LayerDrawable> layer = _terrain.layer(uid);
    if (layer.valid())
    {
        layer->_tiles.push_back(DrawTileCommand());
        DrawTileCommand& tile = layer->_tiles.back();

        // install everything we need in the Draw Command:
        tile._colorSamplers = pass ? &pass->_samplers : 0L;
        tile._sharedSamplers = &model->_sharedSamplers;
        tile._matrix = surface->getMatrix();
        tile._modelViewMatrix = *this->getModelViewMatrix();
        tile._keyValue = tileNode->getTileKeyValue();
        tile._geom = surface->getDrawable()->_geom.get();
        tile._morphConstants = tileNode->getMorphConstants();
        tile._key = tileNode->getKey();

#if 1
        osg::Vec3 c = surface->getBound().center() * surface->getInverseMatrix();
        tile._range = getDistanceToViewPoint(c, true);
#else
        osg::Vec3f eyeWorld = getViewPointLocal() * surface->getMatrix();
        tile._range = (eyeWorld - surface->getBound().center()).length();
#endif

        const osg::Image* elevRaster = tileNode->getElevationRaster();
        if (elevRaster)
        {
            float bias = _context->getUseTextureBorder() ? 1.5 : 0.5;

            // Compute an elevation texture sampling scale/bias so we sample elevation data on center
            // instead of on edge (as we do with color, etc.)
            //
            // This starts out as:
            //   scale = (size-1)/size : this shrinks the sample area by one texel since we're sampling on center
            //   bias = 0.5/size : this shifts the sample area over 1/2 texel to the center.
            //
            // But, since we also have a 1-texel border, we need to further reduce the scale by 2 texels to
            // remove the border, and shift an extra texel over as well. Giving us this:
            float size = (float)elevRaster->s();
            tile._elevTexelCoeff.set((size - (2.0*bias)) / size, bias / size);
        }

        return &tile;
    }
    else if (pass)
    {
        // The pass exists but it's layer doesn't - remember this so we can run
        // a visitor to clean up the rendering models.
        ++_orphanedPassesDetected;
    }

    return 0L;
}
Exemplo n.º 2
0
DrawTileCommand*
TerrainCuller::addDrawCommand(UID uid, const TileRenderModel* model, const RenderingPass* pass, TileNode* tileNode)
{
    SurfaceNode* surface = tileNode->getSurfaceNode();

    const RenderBindings& bindings = _context->getRenderBindings();

    // skip layers that are not visible:
    if (pass && 
        pass->visibleLayer() && 
        pass->visibleLayer()->getVisible() == false)
    {
        //OE_DEBUG << LC << "Skipping " << pass->visibleLayer()->getName() << " because it's not visible." << std::endl;
        return 0L;
    }

    // add a new Draw command to the appropriate layer
    osg::ref_ptr<LayerDrawable> drawable = _terrain.layer(uid);
    if (drawable.valid())
    {
        // Layer marked for drawing?
        if (drawable->_draw)
        {
            // Cull based on the layer extent.
            if (drawable->_layer)
            {
                const LayerExtent& le = (*_layerExtents)[drawable->_layer->getUID()];
                if (le._computed && 
                    le._extent.isValid() &&
                    le._extent.intersects(tileNode->getKey().getExtent()) == false)
                {
                    // culled out!
                    //OE_DEBUG << LC << "Skippping " << drawable->_layer->getName() 
                    //    << " key " << tileNode->getKey().str()
                    //    << " because it was culled by extent." << std::endl;
                    return 0L;
                }
            }

            drawable->_tiles.push_back(DrawTileCommand());
            DrawTileCommand* tile = &drawable->_tiles.back();

            // install everything we need in the Draw Command:
            tile->_colorSamplers = pass ? &(pass->samplers()) : 0L;
            tile->_sharedSamplers = &model->_sharedSamplers;
            tile->_modelViewMatrix = this->getModelViewMatrix();
            tile->_keyValue = tileNode->getTileKeyValue();
            tile->_geom = surface->getDrawable()->_geom.get();
            tile->_morphConstants = tileNode->getMorphConstants();
            tile->_key = &tileNode->getKey();
            tile->_order = drawable->_order; // layer order in map tile.

            osg::Vec3 c = surface->getBound().center() * surface->getInverseMatrix();
            tile->_range = getDistanceToViewPoint(c, true);

            const osg::Image* elevRaster = tileNode->getElevationRaster();
            if (elevRaster)
            {
                float bias = _context->getUseTextureBorder() ? 1.5 : 0.5;

                // Compute an elevation texture sampling scale/bias so we sample elevation data on center
                // instead of on edge (as we do with color, etc.)
                //
                // This starts out as:
                //   scale = (size-1)/size : this shrinks the sample area by one texel since we're sampling on center
                //   bias = 0.5/size : this shifts the sample area over 1/2 texel to the center.
                //
                // But, since we also have a 1-texel border, we need to further reduce the scale by 2 texels to
                // remove the border, and shift an extra texel over as well. Giving us this:
                float size = (float)elevRaster->s();
                tile->_elevTexelCoeff.set((size - (2.0*bias)) / size, bias / size);
            }

            return tile;
        }
    }
    else if (pass)
    {
        // The pass exists but it's layer is not in the render data draw list.
        // This means that the layer is no longer in the map. Detect and record
        // this information so we can run a cleanup visitor later on.
        ++_orphanedPassesDetected;
    }
    
    return 0L;
}