Correctly apply camera matrix

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Correctly apply camera matrix

andyjk
This post was updated on .
I am trying to save a particular camera view, then reapply it later (ie be
able to reset the the view to a previous position)

I see from here (
http://vtk.1045678.n5.nabble.com/How-to-restore-a-camera-view-td5728916.html
) that I can do this by saving  position, focal_point, View-up and
view_angle,

but I am trying to do this more neatly by saving just the 4x4 transformation
matrix of the camera (and assuming view angle is unchanged).

How can I grab the current camera transformation matrix, and later re-apply
it ?

I have tried :

1) GRAB
vtkSmartPointer<vtkMatrix4x4> mat;
                mat =
iren->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera()->GetModelViewTransformMatrix();

                saveVTKMat4x4(mat, "VTKCamera.vmx");

2) LOAD and APPLY
loadVTKMat4x4(mat, "VTKCamera.vmx");
                mat->Print(std::cout);


                vtkSmartPointer<vtkMatrix4x4> mat_inverse =
vtkSmartPointer<vtkMatrix4x4>::New();
                vtkMatrix4x4::Invert(mat, mat_inverse);
                vtkSmartPointer<vtkTransform> transform =
vtkSmartPointer<vtkTransform>::New();
                transform->SetMatrix(mat);
                transform->Update();


                vtkSmartPointer<vtkMatrix4x4> current_mat;
                current_mat = custom_camera->GetViewTransformMatrix();
               
                vtkSmartPointer<vtkMatrix4x4> current_mat_inverse =
vtkSmartPointer<vtkMatrix4x4>::New();
                vtkMatrix4x4::Invert(current_mat, current_mat_inverse);

                vtkSmartPointer<vtkTransform> transformInv =
vtkSmartPointer<vtkTransform>::New();
                transformInv->SetMatrix(current_mat_inverse);
                transformInv->Update();


                custom_camera->ApplyTransform(transformInv);
                custom_camera->Modified();
                custom_camera->ApplyTransform(transform);


[Where the save/load functions have been verified using vtk::print and are
working fine]

I presume when loading, I have to move the camera back to identity (via an
inverse transform) before applying the new transform because I think
ApplyTransform concatenates.

I find that if I don't move the camera at all between saving and loading, it
works.
If I nudge the camera a tiny bit between loading and saving, the new view is
displaced a bit more when loading, so I think I must be getting some inverse
transforms muddled up?

Is there a neat way to grab the current camera matrix then reapply it later ?






--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: Correctly apply camera matrix

Ken Martin
The best approach in VTK is to save the key variables, camera position, focal point, vup, dop, view angle. This is because the interaction methods directly adjust those parameters, not the computed matrix.

On Mon, Jul 16, 2018 at 4:13 AM, andyjk <[hidden email]> wrote:
I am trying to save a particular camera view, then reapply it later (ie be
able to reset the the view to a previous position)

I see from here (
http://vtk.1045678.n5.nabble.com/How-to-restore-a-camera-view-td5728916.html
) that I can do this by saving  position, focal_point, View-up and
view_angle,

but I am trying to do this more neatly by saving just the 4x4 transformation
matrix of the camera (and assuming view angle is unchanged).

How can I grab the current camera transformation matrix, and later re-apply
it ?

I have tried :

1) GRAB
vtkSmartPointer<vtkMatrix4x4> mat;
                mat =
iren->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera()->GetModelViewTransformMatrix();

                saveVTKMat4x4(mat, "VTKCamera.vmx");

2) LOAD and APPLY
loadVTKMat4x4(mat, "VTKCamera.vmx");
                mat->Print(std::cout);


                vtkSmartPointer<vtkMatrix4x4> mat_inverse =
vtkSmartPointer<vtkMatrix4x4>::New();
                vtkMatrix4x4::Invert(mat, mat_inverse);
                vtkSmartPointer<vtkTransform> transform =
vtkSmartPointer<vtkTransform>::New();
                transform->SetMatrix(mat);
                transform->Update();


                vtkSmartPointer<vtkMatrix4x4> current_mat;
                current_mat = custom_camera->GetViewTransformMatrix();

                vtkSmartPointer<vtkMatrix4x4> current_mat_inverse =
vtkSmartPointer<vtkMatrix4x4>::New();
                vtkMatrix4x4::Invert(current_mat, current_mat_inverse);

                vtkSmartPointer<vtkTransform> transformInv =
vtkSmartPointer<vtkTransform>::New();
                transformInv->SetMatrix(current_mat_inverse);
                transformInv->Update();


                custom_camera->ApplyTransform(transformInv);
                custom_camera->Modified();
                custom_camera->ApplyTransform(transform);


[Where the save/load functions have been verified using vtk::print and are
working fine]

I presume when loading, I have to move the camera back to identity (via an
inverse transform) before applying the new transform because I think
ApplyTransform concatenates.

I find that if I don't move the camera at all between saving and loading, it
works.
If I nudge the camera a tiny bit between loading and saving, the new view is
displaced a bit more when loading, so I think I must be getting some inverse
transforms muddled up?

Is there a neat way to the current camera matrix then reapply it later ?






--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers



--
Ken Martin PhD
Distinguished Engineer
Kitware Inc.
101 East Weaver Street
Carrboro, North Carolina
27510 USA

This communication, including all attachments, contains confidential and legally privileged information, and it is intended only for the use of the addressee.  Access to this email by anyone else is unauthorized. If you are not the intended recipient, any disclosure, copying, distribution or any action taken in reliance on it is prohibited and may be unlawful. If you received this communication in error please notify us immediately and destroy the original message.  Thank you.

_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: Correctly apply camera matrix

andyjk
Thanks Ken

Looks like this is the sensible way to do it, so I have abandoned the
transformation matrix idea.



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: Correctly apply camera matrix

Bill Lorensen
These two examples save the camera to a file or store it in field data:

https://lorensen.github.io/VTKExamples/site/Cxx/Utilities/SaveSceneToFieldData/
https://lorensen.github.io/VTKExamples/site/Cxx/Utilities/SaveSceneToFile/


On Mon, Jul 16, 2018 at 9:46 AM, andyjk <[hidden email]> wrote:

> Thanks Ken
>
> Looks like this is the sensible way to do it, so I have abandoned the
> transformation matrix idea.
>
>
>
> --
> Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
>
> Search the list archives at: http://markmail.org/search/?q=vtkusers
>
> Follow this link to subscribe/unsubscribe:
> https://public.kitware.com/mailman/listinfo/vtkusers



--
Unpaid intern in BillsParadise at noware dot com
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: Correctly apply camera matrix

andyjk
Hi

I would like to do something similar to the above - ie save the view of the
camera (based on user manipulation) then be able to re-apply the 4x4
extrinsic camera matrix elsewhere.

I know that I can save the View Up, ViewPlaneNormal, Position etc and that
these correctly represent the current camera position.

However, how can I then transform these into an R|T camera matrix, such that
R|T [wx wy wz] brings the world coordinates (wx,wy,wz) into the camera
coordinate frame ?

It certainly seems that vtkCamera->GetModelTransformMatrix() is bugged and
doesn't work, because the upper 3x3 is not orthogonal and so is not a
rotation matrix.

I could set up columns 2 and 3 of the R|T matrix using ViewUp and
ViewPlaneNormal, but if I just calculate the cross-product for filling in
column 1, I presumably risk 'x' facing the wrong way ?
Also, I am fairly sure that T of R|T is not simply vtkCamera->GetPosition()
(as it is the inverse transform?) so I'm not sure how to populate column 4
of R|T.

Am I misunderstanding vtkCamera->GetModelTransformMatrix() ? I was hoping
this is what it is for ?



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://vtk.org/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|

Re: Correctly apply camera matrix

andyjk
Looking deeper - in PerspectiveTransform.cxx we have a function to create the
matrix from a set of view directions.

It looks like vtk does just take the cross-product of Y-Z to get the
X-direction.

However, my confusion is now that the code below stores the rotated X,Y,Z
axes along rows. I thought that it is the *columns* of a rotation matrix
that set its basis ? Can anyone help explain?

void vtkPerspectiveTransform::SetupCamera(const double position[3],
                                          const double focalPoint[3],
                                          const double viewUp[3])
{
  double matrix[4][4];
  vtkMatrix4x4::Identity(*matrix);

  // the view directions correspond to the rows of the rotation matrix,
  // so we'll make the connection explicit
  double *viewSideways =    matrix[0];
  double *orthoViewUp =     matrix[1];
  double *viewPlaneNormal = matrix[2];

  // set the view plane normal from the view vector
  viewPlaneNormal[0] = position[0] - focalPoint[0];
  viewPlaneNormal[1] = position[1] - focalPoint[1];
  viewPlaneNormal[2] = position[2] - focalPoint[2];
  vtkMath::Normalize(viewPlaneNormal);

  // orthogonalize viewUp and compute viewSideways
  vtkMath::Cross(viewUp,viewPlaneNormal,viewSideways);
  vtkMath::Normalize(viewSideways);
  vtkMath::Cross(viewPlaneNormal,viewSideways,orthoViewUp);

  // translate by the vector from the position to the origin
  double delta[4];
  delta[0] = -position[0];
  delta[1] = -position[1];
  delta[2] = -position[2];
  delta[3] = 0.0; // yes, this should be zero, not one

  vtkMatrix4x4::MultiplyPoint(*matrix,delta,delta);

  matrix[0][3] = delta[0];
  matrix[1][3] = delta[1];
  matrix[2][3] = delta[2];

  // apply the transformation
  this->Concatenate(*matrix);
}



--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://vtk.org/mailman/listinfo/vtkusers