문제

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.

다른 팁

Update

I misunderstood the mathematical requirement but found the problem after looking your solution.

newMatrix.getLookAt( eye, focus, up );

getLookAt method takes the inverse of the given matrix itself before returning eye, focus, and up. Since you're providing inverted matrix your original code fails so it should be like this:

Matrixd newMatrix = fCam->getViewMatrix();

Vec3d eye, focus, up;
newMatrix.getLookAt( eye, focus, up );

eye = eye - focus;
eye.normalize();

newMatrix.invert( newMatrix );
newMatrix.setTrans( eye * 4.0f );
newMatrix.invert( newMatrix );

viewCam->setViewMatrix( newMatrix );

I think that the problem comes from:

newMatrix.setTrans( eye * 4.0f );

This method set position with respect to origin (0, 0, 0). You should use something like that:

osg::Vec3 direction = focus - eye;
direction.normalize();

newMatrix.setTrans( eye + direction * 4.0f );
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top