void AllocateAndMergeBufferObjectsVisitor::apply(osg::Drawable& drawable) { osg::Geometry* geom = drawable.asGeometry(); if ( geom ) { // We disable vbo's and then re-enable them to enable sharing of all the arrays. geom->setUseDisplayList( false ); geom->setUseVertexBufferObjects( false ); geom->setUseVertexBufferObjects( true ); } traverse(drawable); }
void BuildTopologyVisitor::apply(osg::Drawable& drawable) { osg::Geometry* geom = drawable.asGeometry(); if (geom) { osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray()); if (verts) { apply(&drawable, verts); } } }
void VertexCacheOptimizer::apply(osg::Drawable& drawable) { if (drawable.getDataVariance() == osg::Object::DYNAMIC) return; osg::Geometry* geom = drawable.asGeometry(); if ( geom ) { if ( geom->getDataVariance() == osg::Object::DYNAMIC ) return; // vertex cache optimizations currently only support surface geometries. // all or nothing in the geode. osg::Geometry::PrimitiveSetList& psets = geom->getPrimitiveSetList(); for( osg::Geometry::PrimitiveSetList::iterator i = psets.begin(); i != psets.end(); ++i ) { switch( (*i)->getMode() ) { case GL_TRIANGLES: case GL_TRIANGLE_FAN: case GL_TRIANGLE_STRIP: case GL_QUADS: case GL_QUAD_STRIP: case GL_POLYGON: break; default: return; } } } //OE_NOTICE << LC << "VC optimizing..." << std::endl; // passed the test; run the optimizer. osgUtil::VertexCacheVisitor vcv; drawable.accept( vcv ); vcv.optimizeVertices(); osgUtil::VertexAccessOrderVisitor vaov; drawable.accept( vaov ); vaov.optimizeOrder(); traverse( drawable ); }
void StatsVisitor::apply(osg::Drawable& drawable) { if (drawable.getStateSet()) { apply(*drawable.getStateSet()); } ++_numInstancedDrawable; drawable.accept(_instancedStats); _drawableSet.insert(&drawable); osg::Geometry* geometry = drawable.asGeometry(); if (geometry) { ++_numInstancedGeometry; _geometrySet.insert(geometry); ++_numInstancedFastGeometry; _fastGeometrySet.insert(geometry); } }
void GeometryClamper::apply(osg::Drawable& drawable) { if ( !_terrainSRS.valid() ) return; osg::Geometry* geom = drawable.asGeometry(); if ( !geom ) return; const osg::Matrixd& local2world = _matrixStack.back(); osg::Matrix world2local; world2local.invert( local2world ); const osg::EllipsoidModel* em = _terrainSRS->getEllipsoid(); osg::Vec3d n_vector(0,0,1), start, end, msl; bool isGeocentric = _terrainSRS->isGeographic(); osgUtil::IntersectionVisitor iv( _lsi.get() ); double r = std::min( em->getRadiusEquator(), em->getRadiusPolar() ); unsigned count = 0; bool geomDirty = false; osg::Vec3Array* verts = static_cast<osg::Vec3Array*>(geom->getVertexArray()); osg::FloatArray* zOffsets = 0L; // if preserve-Z is on, check for our elevations array. Create it if is doesn't // already exist. bool buildZOffsets = false; if ( _preserveZ ) { osg::UserDataContainer* udc = geom->getOrCreateUserDataContainer(); unsigned n = udc->getUserObjectIndex( ZOFFSETS_NAME ); if ( n < udc->getNumUserObjects() ) { zOffsets = dynamic_cast<osg::FloatArray*>(udc->getUserObject(n)); } else { zOffsets = new osg::FloatArray(); zOffsets->setName( ZOFFSETS_NAME ); zOffsets->reserve( verts->size() ); udc->addUserObject( zOffsets ); buildZOffsets = true; } } for( unsigned k=0; k<verts->size(); ++k ) { osg::Vec3d vw = (*verts)[k]; vw = vw * local2world; if ( isGeocentric ) { // normal to the ellipsoid: n_vector = em->computeLocalUpVector(vw.x(),vw.y(),vw.z()); // if we need to build to z-offsets array, calculate the z offset now: if ( buildZOffsets || _scale != 1.0 ) { double lat,lon,hae; em->convertXYZToLatLongHeight(vw.x(), vw.y(), vw.z(), lat, lon, hae); if ( buildZOffsets ) { zOffsets->push_back( (*verts)[k].z() ); } if ( _scale != 1.0 ) { msl = vw - n_vector*hae; } } } else if ( buildZOffsets ) // flat map { zOffsets->push_back( float(vw.z()) ); } _lsi->reset(); _lsi->setStart( vw + n_vector*r*_scale ); _lsi->setEnd( vw - n_vector*r ); _lsi->setIntersectionLimit( _lsi->LIMIT_NEAREST ); _terrainPatch->accept( iv ); if ( _lsi->containsIntersections() ) { osg::Vec3d fw = _lsi->getFirstIntersection().getWorldIntersectPoint(); if ( _scale != 1.0 ) { osg::Vec3d delta = fw - msl; fw += delta*_scale; } if ( _offset != 0.0 ) { fw += n_vector*_offset; } if ( _preserveZ && (zOffsets != 0L) ) { fw += n_vector * (*zOffsets)[k]; } (*verts)[k] = (fw * world2local); geomDirty = true; ++count; } } if ( geomDirty ) { geom->dirtyBound(); if ( geom->getUseVertexBufferObjects() ) { verts->getVertexBufferObject()->setUsage( GL_DYNAMIC_DRAW_ARB ); verts->dirty(); } else { geom->dirtyDisplayList(); } OE_DEBUG << LC << "clamped " << count << " verts." << std::endl; } }