Hi,

I have an ECEF terrain and I want to implement a compass node to show the true 
north to the user.

I tried the code below but at some angles it does not work correctly. When the 
camera is vertical (birds eye view) to the terrain, it works perfect but if you 
rotate the camera (elevation or roll) it does not show the correct value.

thanks,

class Compass : public osg::Camera
{
public:
    Compass(void)
    {
    }

    Compass( const Compass& copy, osg::CopyOp copyop = 
osg::CopyOp::SHALLOW_COPY ):
                    osg::Camera(copy, copyop),
                        _plateTransform(copy._plateTransform),
                        _needleTransform(copy._needleTransform),
                        _mainCamera(copy._mainCamera),
                        m_bIsFirst(false)
    {
    }

    Compass::~Compass(void)
    {
    }

    META_Node( osg, Compass );
    void setPlate( osg::MatrixTransform* plate )
    {
        _plateTransform = plate; 
    }

    void setNeedle( osg::MatrixTransform* needle ) 
    {
        _needleTransform = needle; 
    }

    void setMainCamera( osg::Camera* camera ) 
    {
        _mainCamera = camera;
    }

    virtual void traverse( osg::NodeVisitor& nv )
    {
        if ( _mainCamera.valid() && 
nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR )
        {
            osg::Matrix matrix = _mainCamera->getViewMatrix();
            matrix.setTrans( osg::Vec3() );
            osg::Vec3 northVec = osg::Z_AXIS * matrix;  
            northVec.z()= 0.0;

            northVec.normalize();
            osg::Vec3 axis = osg::Y_AXIS ^ northVec;
            float angle = atan2(axis.length(), osg::Y_AXIS*northVec);
            axis.normalize();

            if ( _plateTransform.valid() )
            {
                _plateTransform->setMatrix( osg::Matrix::rotate(angle, axis) );
            }

            _plateTransform->accept( nv );
            _needleTransform->accept( nv );
            osg::Camera::traverse( nv );
        }
    }

    osg::MatrixTransform* createCompassPlate( const std::string& image, float 
radius, float height)
    {
        osg::Vec3 center(-radius, -radius, height);
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        geode->addDrawable(createTexturedQuadGeometry(center, 
osg::Vec3(radius*2.0f,0.0f,0.0f),
            osg::Vec3(0.0f,radius*2.0f,0.0f)) );
        osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;      
        texture->setImage(osgDB::readImageFile(image));

        osg::ref_ptr<osg::MatrixTransform> part =new osg::MatrixTransform();
        part->getOrCreateStateSet()->setTextureAttributeAndModes(0, 
texture.get() );
        
part->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN ); 

        part->addChild(geode.get());

        return part.release();
    }
    osg::MatrixTransform* createCompassNeedle( const std::string& image, float 
radius, float height)
    {
        osg::Vec3 center(-radius/4, -radius, height);
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        geode->addDrawable(createTexturedQuadGeometry(center, 
osg::Vec3(radius/2,0.0f,0.0f),
            osg::Vec3(0.0f,radius*2,0.0f)) );
        osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;      
        texture->setImage(osgDB::readImageFile(image));

        osg::ref_ptr<osg::MatrixTransform> part =new osg::MatrixTransform();
        part->getOrCreateStateSet()->setTextureAttributeAndModes(0, 
texture.get() );
        
part->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN ); 

        part->addChild(geode.get());

        return part.release();
    }

protected:
    osg::ref_ptr<osg::MatrixTransform> _plateTransform;
    osg::ref_ptr<osg::MatrixTransform> _needleTransform;
    osg::observer_ptr<osg::Camera> _mainCamera;
    bool m_bIsFirst;
};

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=48579#48579





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to