The post shows how to use difference matrix to let two camera have same action. We can get the following relationship between viewUp vector and view plane normal. The view transform matrix can be generated from camera focal point, postion and view up vector.
Matrix of camera’s view transform:
The implementation of view transform is at the interface SetupCamera
.
//------------------------------------------------------------------------------
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);
}
Our code for the expect effect.
void CustomIteractorStyle::KeepSameCameraStatus()
{
vtkCamera *targetCamera = m_RightRender->GetActiveCamera();
vtkCamera *sampleCamera = m_LeftRender->GetActiveCamera();
vtkSmartPointer<vtkTransform> curTrans = vtkSmartPointer<vtkTransform>::New();
vtkSPtrNew( matrix1, vtkMatrix4x4 );
matrix1->DeepCopy( sampleCamera->GetViewTransformObject()->GetMatrix() );
curTrans->SetMatrix( matrix1 );
curTrans->Update();
vtkSmartPointer<vtkTransform> LastTransInv = vtkSmartPointer<vtkTransform>::New();
LastTransInv->DeepCopy( m_LastTrans );
LastTransInv->Inverse();
LastTransInv->Update();
vtkSmartPointer<vtkTransform> diffTrans = vtkSmartPointer<vtkTransform>::New();
diffTrans->Concatenate( LastTransInv );
diffTrans->Concatenate( curTrans );
diffTrans->Update();
diffTrans->Inverse();
targetCamera->ApplyTransform( diffTrans ); //finalTrans ); //
targetCamera->SetParallelScale( sampleCamera->GetParallelScale() );
m_LastTrans->DeepCopy( curTrans );
m_LastTrans->Update();
m_RightRender->ResetCameraClippingRange();
m_LeftRender->GetRenderWindow()->Render();
}
Project:
https://github.com/theArcticOcean/tutorials/tree/main/learnVTK/sameStatusCamera
Effect: