Since you're navigating on a sphere, you always need to calculate the bearing based off the local "up" vector of the sphere (ground stabilized) and not the "up" vector of the ownship. The reason why your code works from the birds eye view is because the "up" vectors between the two are the same in this case. When you introduce pitch and roll, the "up" vector of the ownship diverges from the sphere "up" vector which probably explains why your code below no longer works.
Once you calculate the bearing correctly, your compass heading can then be calculated by using the bearing angle to rotate around the z-axis (0,0,1). -Shayne -----Original Message----- From: osg-users-boun...@lists.openscenegraph.org [mailto:osg-users-boun...@lists.openscenegraph.org] On Behalf Of onur akkaya Sent: Thursday, June 28, 2012 1:20 AM To: osg-users@lists.openscenegraph.org Subject: [osg-users] ECEF Oriented Compass Implementation 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 osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.or g _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org