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