I have a sensor (a tracker) whose rotation with respect to world coordinates and position with respect to world coordinates is known. I am rendering a 3D model of the world using VTK camera.
I have already registered the model in world coordinates.
Based on the tracker's rotation and position with respect to world coordinates, relative position between tracker and world is known. So if I can reorient the VTK camera to put it in the same relative position and orientation to the rendered 3D model as that of the tracker with respect to world, I will get an aligned 3D model with the world.
My intuition says that this can be done by changing the VTK camera's view up vector, view angle, focal point and position. trackerMat is a vtkMatrix which has the information about the rotation and position of tracker in world coordinates. camera is the vtkCamera and renderer is the vtkRenderer.
record.x, record.y and record.z are real time positions of the tracker in world coordinates. record.a, record.e and record.r are the azimuth, elevation and roll of the tracker. Basically this is what I want to do:
vtkSmartPointer<vtkMatrix4> trackerMat = vtkSmartPointer<vtkMatrix4>::New();
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
camera->SetPosition(record.x, record.y, record.z);
camera->SetFocalPoint(f.x, f.y, f.z);
camera->SetViewUp(viewUp.x, viewUp.y, viewUp.z);
camera->SetViewAngle(viewAngle);
renderer->SetActiveCamera(camera);
renderer->GetRenderWindow()->Render();
I tried setting vtkCamera azimuth, elevation and roll to the same as that of tracker, but it gave bizarre results
This is why I thought I should set focal point, view up vector and view angle to the vtkCamera rather than the angles. vtkCamera position can be set to the same position as that of the tracker easily. Is there someway I can extract the view up vector, focal point and view angle from trackerMat? My renderWindow size is 1280*720
UPDATE: I ran a serious of trials by setting vtkCamera focal point to different positions and see how the viewMatrix changed:
Case 1:
camera->SetPosition(0,0,-5);
camera->SetFocalPoint(0,0,0);
vtkSmartPointer<vtkMatrix4x4> viewMat = vtkSmartPointer<vtkMatrix4x4>::New();
viewMat = camera->GetViewTransformMatrix();
In this case viewMat is:
-1 0 0 0
0 1 0 0
0 0 0 -5
0 0 0 1
Case 2:
camera->SetPosition(0,0,-5);
camera->SetFocalPoint(0,0,3);
vtkSmartPointer<vtkMatrix4x4> viewMat = vtkSmartPointer<vtkMatrix4x4>::New();
viewMat = camera->GetViewTransformMatrix();
In this case viewMat is:
-1 0 0 0
0 1 0 0
0 0 0 -5
0 0 0 1
So when the focal point is changed only in the z-direction, viewMat will remain same. Makes sense.
Case 3:
camera->SetPosition(0,0,-5);
camera->SetFocalPoint(3,3,3);
vtkSmartPointer<vtkMatrix4x4> viewMat = vtkSmartPointer<vtkMatrix4x4>::New();
viewMat = camera->GetViewTransformMatrix();
In this case viewMat is:
-0.936 0 0.351 1.755
-0.116 0.943 -0.310 -1.551
-0.331 -0.331 -0.883 -4.417
0 0 0 1
If I index the viewMat rows by 0 to 3 and columns by 0 to 3, then what I see is that viewMat(0,3), viewMat(1,3) and viewMat(2,3) does not always correspond to the vtkCamera position in world coordinates.
Direction of projection = unit vector pointing in the direction from camera position to focal point. It seems that -viewMat(2,0), -viewMat(2,1) and -viewMat(2,2) always correspond to the direction of projection.
If you orthogonalise your view up vector so that it is always perpendicular to direction of projection by doing this:
camera->OrthogonaliseViewUp();
Then it is seen that -viewMat(1,0), -viewMat(1,1) and -viewMat(1,2) always correspond to the viewUp vector of vtkCamera.
As far as I know, the translation vectors, viewMat(0,3), viewMat(1,3) and viewMat(2,3), should give your world origin in camera coordinates. But it does not seem so in vtk.