Shayne: See this code snippet below. Also, there is lots of useful information at: www.euclideanspace.com. Janusz


Tueller, Shayne R Civ USAF AFMC 519 SMXS/MXDEC pisze:

Is there any method or class in OSG that extracts heading, pitch, and roll angles from a rotation matrix?

I've searched and haven't seen anything. I just want to make sure there isn't anything out there before I embark on writing my own...

Thanks in advance,

-Shayne

------------------------------------------------------------------------

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


---------------

/*

      An example to rotate a model using a sequence of quaternion - Euler - 
quaternion conversions.

      The Euler-to-conversion code is based on the equations on 
www.euclideanspace.com. JG



      P.S: getQuatFromEuler is not neccessary. OSG's Matrix class has a public 
method 'makeRotate(angle,axis)' which

      does the conversion



*/



#include <osgViewer/Viewer>

#include <osgViewer/ViewerEventHandlers>

#include <osg/Geode>

#include <osg/NodeVisitor>

#include <osg/Notify>

#include <osgDB/Registry>

#include <osgDB/ReadFile>

#include <osgGA/TrackballManipulator>

#include <osgUtil/Optimizer>

#include <iostream>

#include <osg/MatrixTransform>









void getEulerFromQuat(osg::Quat q, double& heading, double& attitude, double& 
bank)

{

      double limit = 0.499999;



double sqx = q.x()*q.x(); double sqy = q.y()*q.y();
      double sqz = q.z()*q.z();



      double t = q.x()*q.y() + q.z()*q.w();

      if (t>limit) // gimbal lock ?

      {

            heading = 2 * atan2(q.x(),q.w());

            attitude = osg::PI_2;

            bank = 0;

      }

      else if (t<-limit)

      {

            heading = -2 * atan2(q.x(),q.w());

            attitude = - osg::PI_2;

            bank = 0;

      }

      else

      {



            heading = atan2(2*q.y()*q.w()-2*q.x()*q.z() , 1 - 2*sqy - 2*sqz);

            attitude = asin(2*t);

            bank = atan2(2*q.x()*q.w()-2*q.y()*q.z() , 1 - 2*sqx - 2*sqz);

      }

}



void getQuatFromEuler(double heading, double attitude, double bank, osg::Quat& 
q)

{

double c1 = cos(heading/2); double s1 = sin(heading/2); double c2 = cos(attitude/2); double s2 = sin(attitude/2); double c3 = cos(bank/2);
      double s3 = sin(bank/2);

double c1c2 = c1*c2; double s1s2 = s1*s2;




      double w =c1c2*c3 - s1s2*s3;

      double x =c1c2*s3 + s1s2*c3;

      double y =s1*c2*c3 + c1*s2*s3;

      double z =c1*s2*c3 - s1*c2*s3;



      q[0] = x; q[1] = y;

      q[2] = z; q[3] = w;

}





class RotCallback : public osg::NodeCallback

{

public:

      RotCallback(){};

      ~RotCallback(){};

      virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)

      {

            static double a= 0.0;

            static double b= 0.0;

            static double c= 0.0;



            osg::MatrixTransform* _mt = (osg::MatrixTransform*)node;



            osg::Quat q = _mt->getMatrix().getRotate();

            double heading(0), attitude(0), bank(0);

getEulerFromQuat(q, heading, attitude, bank);


            bank = osg::DegreesToRadians(b++);

            heading = osg::DegreesToRadians(b++);

            attitude = osg::DegreesToRadians(a++);

            getQuatFromEuler(heading, attitude, bank, q);

osg::Matrix m = _mt->getMatrix();
            m.setRotate(q/q.length());

            _mt->setMatrix(m);



traverse(node,nv);
      }



};









int main(int argc, char* argv[])

{

      osgViewer::Viewer viewer;

      osg::Geode* rootnode = 
(osg::Geode*)osgDB::readNodeFile("c:\\temp\\cube.obj");

      if (!rootnode)

      {

            return 1;

      }



      osg::GraphicsContext::Traits* _traits = new osg::GraphicsContext::Traits;

      _traits->x = 100;

      _traits->y = 100;

      _traits->width = 640;

      _traits->height = 480;

      _traits->windowDecoration = true;

      _traits->doubleBuffer = true;

      _traits->sharedContext = 0;





      osg::MatrixTransform* mat = new osg::MatrixTransform;

      
mat->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(90.0),osg::Vec3f(0,0,1)));

      mat->addChild(rootnode);

      mat->setUpdateCallback(new RotCallback());



      osgUtil::Optimizer optimzer;

      optimzer.optimize(rootnode);



      viewer.setSceneData( mat );

      viewer.addEventHandler(new osgViewer::StatsHandler);

      viewer.setCameraManipulator(new osgGA::TrackballManipulator);

      viewer.addEventHandler( new osgViewer::WindowSizeHandler());





      osg::GraphicsContext* 
gc=osg::GraphicsContext::createGraphicsContext(_traits);

      osg::Camera* camera = viewer.getCamera();

      camera->setGraphicsContext(gc);

      camera->setViewport(new 
osg::Viewport(0,0,_traits->width,_traits->height));

      camera->setClearColor(osg::Vec4f(0,0,1,1));





      viewer.run();

}


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

Reply via email to