Exemplo n.º 1
0
//clustering:
//  troll the external model for geodes. for each geode, create a geode in the target
//  model. then, for each geometry in that geode, replicate it once for each instance of
//  the model in the feature batch and transform the actual verts to a local offset
//  relative to the tile centroid. Finally, reassemble all the geodes and optimize. 
//  hopefully stateset sharing etc will work out. we may need to strip out LODs too.
bool
SubstituteModelFilter::cluster(const FeatureList&           features,
                               const MarkerSymbol*          symbol, 
                               Session* session,
                               osg::Group*                  attachPoint,
                               FilterContext&               cx )
{    
    MarkerToFeatures markerToFeatures;
    MarkerFactory factory( session);
    for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i)
    {
        Feature* f = i->get();
        osg::ref_ptr< osg::Node > model = factory.getOrCreateNode( f, symbol );
        //Try to find the existing entry
        if (model.valid())
        {
            MarkerToFeatures::iterator itr = markerToFeatures.find( model.get() );
            if (itr == markerToFeatures.end())
            {
                markerToFeatures[ model.get() ].push_back( f );
            }
            else
            {
                itr->second.push_back( f );
            }
        }
    }

    /*
    OE_NOTICE << "Sorted models into " << markerToFeatures.size() << " buckets" << std::endl;
    for (MarkerToFeatures::iterator i = markerToFeatures.begin(); i != markerToFeatures.end(); ++i)
    {
        OE_NOTICE << "    Bucket has " << i->second.size() << " features" << std::endl;
    }
    */

    //For each model, cluster the features that use that model

    for (MarkerToFeatures::iterator i = markerToFeatures.begin(); i != markerToFeatures.end(); ++i)
    {
        osg::Node* clone = dynamic_cast<osg::Node*>( i->first->clone( osg::CopyOp::DEEP_COPY_ALL ) );

        // ..and apply the clustering to the copy.
        ClusterVisitor cv( i->second, _modelMatrix, this, cx );
        clone->accept( cv );

        attachPoint->addChild( clone );
    }

    return true;
}
Exemplo n.º 2
0
//clustering:
//  troll the external model for geodes. for each geode, create a geode in the target
//  model. then, for each geometry in that geode, replicate it once for each instance of
//  the model in the feature batch and transform the actual verts to a local offset
//  relative to the tile centroid. Finally, reassemble all the geodes and optimize. 
//  hopefully stateset sharing etc will work out. we may need to strip out LODs too.
bool
SubstituteModelFilter::cluster(const FeatureList&           features,
                               const MarkerSymbol*          symbol, 
                               Session*                     session,
                               osg::Group*                  attachPoint,
                               FilterContext&               context )
{    
    MarkerToFeatures markerToFeatures;

    // first, sort the features into buckets, each bucket corresponding to a
    // unique marker.
    for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i)
    {
        Feature* f = i->get();

        // resolve the URI for the marker:
        StringExpression uriEx( *symbol->url() );
        URI markerURI( f->eval( uriEx, &context ), uriEx.uriContext() );

        // find and load the corresponding marker model. We're using the session-level
        // object store to cache models. This is thread-safe sine we are always going
        // to CLONE the model before using it.
        osg::ref_ptr<osg::Node> model = context.getSession()->getObject<osg::Node>( markerURI.full() );
        if ( !model.valid() )
        {
            osg::ref_ptr<MarkerResource> mres = new MarkerResource();
            mres->uri() = markerURI;
            model = mres->createNode( context.getSession()->getDBOptions() );
            if ( model.valid() )
            {
                // store it, but only if there isn't already one in there.
                context.getSession()->putObject( markerURI.full(), model.get(), false );
            }
        }

        if ( model.valid() )
        {
            MarkerToFeatures::iterator itr = markerToFeatures.find( model.get() );
            if (itr == markerToFeatures.end())
                markerToFeatures[ model.get() ].push_back( f );
            else
                itr->second.push_back( f );
        }
    }

    //For each model, cluster the features that use that marker
    for (MarkerToFeatures::iterator i = markerToFeatures.begin(); i != markerToFeatures.end(); ++i)
    {
        osg::Node* prototype = i->first;

        // we're using the Session cache since we know we'll be cloning.
        if ( prototype )
        {
            osg::Node* clone = osg::clone( prototype, osg::CopyOp::DEEP_COPY_ALL );

            // ..and apply the clustering to the copy.
            ClusterVisitor cv( i->second, symbol, this, context );
            clone->accept( cv );

            attachPoint->addChild( clone );
        }
    }

    return true;
}