I'm trying to rotate the camera around the Y
axis of the world, marked in my project by a 3D cross.
What I've accomplished is rotating it around its own axis, which is cool, but it's not what I wanted.
How to achieve that by using quaternions and some maths, not osg::PositionAttitudeTransforms
or any easy-to-use but hard to understand infrastructure.
I would like to be exposed to the maths behind it.
The relevant piece of code is
osg::Matrixd camM;
std::stringstream oss;
osg::Quat x_rot_q(osg::DegreesToRadians(-DEG), osg::Vec3d(1.0, 0.0, 0.0));
osg::Quat y_rot_q(osg::DegreesToRadians(DEG), osg::Vec3d(0.0, 1.0, 0.0));
camM = cameraManipulator->getMatrix();
camM.makeRotate(x_rot_q * y_rot_q);
camM.setTrans(250.0, 300.0, 250.0);
cameraManipulator->setByMatrix(camM);
osg::Quat y_delta_trans(osg::DegreesToRadians(DEG_DELTA), osg::Vec3d(0.0, 1.0, 0.0));
while(!viewer.done()) {
oss.str(std::string());
oss.clear();
camM = cameraManipulator->getMatrix();
camM.makeRotate(camM.getRotate() * y_delta_trans);
camM.setTrans(250.0, 300.0, 250.0);
cameraManipulator->setByMatrix(camM);
oss << getMatrixRepresentation(camM);
hudGeode->setStatus(oss.str());
viewer.frame();
}
which you can find at the bottom of the file Simple.cpp
. The entire project can be found at this revision in a gist.
On a GNU/Linux box, just type make
and it should work out of the box with the proper tools installed.
Rotating the camera around another axis than its own is fairly simple, just perform these steps in order:
Or mathematically as a matrix product:
[ 1 0 0 -Xc ] [ 1 0 0 Xc ]
Transformation Matrix = [ 0 1 0 -Yc ] Rotation Matrix [ 0 1 0 Yc ]
[ 0 0 1 -Zc ] [ 0 0 1 Zc ]
[ 0 0 0 1 ] [ 0 0 0 1 ]
Edit:
Note that this is the general way of rotating an object around an origin not its own.