#include #include #include #include #include #include #include #include #include #include class MoveHorizonWithEyePointTransform : public osg::Transform { public: // Get the transformation matrix which moves from local coords to world coords virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const { osgUtil::CullVisitor* cv = dynamic_cast(nv); if (cv) { osg::Vec3 eyePointLocal = cv->getEyeLocal(); matrix.preMult(osg::Matrix::translate(eyePointLocal)); } return true; } // Get transformation matrix which moves from world coords to local coords virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const { osgUtil::CullVisitor* cv = dynamic_cast(nv); if (cv) { osg::Vec3 eyePointLocal = cv->getEyeLocal(); matrix.postMult(osg::Matrix::translate(-eyePointLocal)); } return true; } }; osg::Transform* createSky(float radius, const std::string filename) { osg::Geode* geode = new osg::Geode; osg::ShapeDrawable* geom = new osg::ShapeDrawable( new osg::Sphere(osg::Vec3(0,0,-radius/4.0),radius) ); // set up the texture state. osg::Texture2D* texture = new osg::Texture2D; texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state. texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); texture->setImage(osgDB::readImageFile(filename.c_str())); osg::StateSet* stateset = new osg::StateSet; stateset->setTextureAttributeAndModes( 0, texture, osg::StateAttribute::ON ); stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); // to prevent being able to push the model back through the sky, we // do two things (i) ensure sky is drawn first, and (ii) skip writing // to the depth buffer stateset->setRenderBinDetails( -1, "RenderBin" ); osg::Depth* depth = new osg::Depth(); depth->setWriteMask( false ); stateset->setAttributeAndModes( depth, osg::StateAttribute::ON ); geom->setStateSet( stateset ); geom->setUseDisplayList( true ); geode->addDrawable(geom); osg::Transform* transform = new MoveHorizonWithEyePointTransform; transform->setCullingActive( false ); transform->addChild( geode ); return transform; }