I am trying to configure the osg::Camera
behaviour for an axis indicator for another viewport's camera (in most CAD applications there is a little model representing each of the worldspace axes, in each of the 3D viewports).
I do this by pulling the viewport camera's view matrix:
// fCam is the 'owning' viewport's camera i.e. the followed camera.
Matrixd newMatrix = fCam->getViewMatrix();
I then invert it, to get the camera's transformation matrix and get the camera's inverse view vector:
newMatrix.invert( newMatrix );
Vec3d eye, focus, up;
newMatrix.getLookAt( eye, focus, up );
eye = focus - eye;
eye.normalize();
I use the view vector to position the camera a fixed distance from the origin (where the axes model is), and then invert the matrix again to get the resulting camera view matrix:
newMatrix.setTrans( eye * 4.0f );
newMatrix.invert( newMatrix );
viewCam->setViewMatrix( newMatrix );
This should have the effect of setting the axis indicator camera to follow the 'owning' viewport's camera's orientation, but keeping it a fixed distance from the origin and having the origin always in the dead centre of the viewport.
But it doesn't work. The orientation appears correct, but the position doesn't seem to change resulting in the axis model moving off-screen. I am using OpenSceneGraph for this, and there is no camera manipulator attached to the View
. So I do not understand why the camera does not move as I expect it to - any suggestions?
I 'solved' the issue by using the built in *LookAt(..)
methods for getting and setting:
Vec3d eye, focus, up;
fCam->getViewMatrixAsLookAt( eye, focus, up );
eye = eye - focus;
eye.normalize();
viewCam->setViewMatrixAsLookAt( eye * 4.0, Vec3d(), up );
I can't see what the difference between my 'manual' code and these convenience methods is. I thought OSG may be performing some extra transformation later in the render pipeline, but I couldn't find anything in it's source code.