Skip to content

BUG: Fix Computation of Interaction Transform Used in PositionProp | ⚠️ Changes removed from master #139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions VirtualReality/MRML/vtkVirtualRealityViewInteractorStyle.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -281,36 +281,50 @@ void vtkVirtualRealityViewInteractorStyle::PositionProp(vtkEventData* ed, double
return;
}

// Get positions and orientations
vtkRenderWindowInteractor3D* rwi = static_cast<vtkRenderWindowInteractor3D*>(this->Interactor);

// Retrieve the last and current event positions in world coordinates
double worldPos[3] = {0.0};
edd->GetWorldPosition(worldPos);
double* lastWorldPos = rwi->GetLastWorldEventPosition(rwi->GetPointerIndex());

// Retrieve the last and current event orientation quaternions
double* worldOrientation = rwi->GetWorldEventOrientation(rwi->GetPointerIndex());
double* lastWorldOrientation = rwi->GetLastWorldEventOrientation(rwi->GetPointerIndex());

// Calculate transform
vtkNew<vtkTransform> interactionTransform;
interactionTransform->PreMultiply();

// Compute the translation vector
double translation[3] = {0.0};
for (int i = 0; i < 3; i++)
{
translation[i] = worldPos[i] - lastWorldPos[i];
}
vtkQuaternion<double> q1;
q1.SetRotationAngleAndAxis(vtkMath::RadiansFromDegrees(
lastWorldOrientation[0]), lastWorldOrientation[1], lastWorldOrientation[2], lastWorldOrientation[3]);
vtkQuaternion<double> q2;
q2.SetRotationAngleAndAxis(vtkMath::RadiansFromDegrees(
worldOrientation[0]), worldOrientation[1], worldOrientation[2], worldOrientation[3]);

// Calculate the relative quaternion rotation between the last and
// current orientations (q2 * q1')
vtkQuaternion<double> q1(lastWorldOrientation);
vtkQuaternion<double> q2(worldOrientation);
q1.Conjugate();
q2 = q2*q1;

// Convert from quaternion to angle-axis representation
double axis[4] = {0.0};
axis[0] = vtkMath::DegreesFromRadians(q2.GetRotationAngleAndAxis(axis+1));

// Apply the calculated relative orientation and translation vector to the
// interaction transform
vtkNew<vtkTransform> interactionTransform;
interactionTransform->PreMultiply();

// Step 1: Translate to the current world position
interactionTransform->Translate(worldPos[0], worldPos[1], worldPos[2]);

// Step 2: Apply relative rotation
interactionTransform->RotateWXYZ(axis[0], axis[1], axis[2], axis[3]);

// Step 3: Translate back to the origin
interactionTransform->Translate(-worldPos[0], -worldPos[1], -worldPos[2]);

// Step 4: Final translation based on the computed translation vector
interactionTransform->Translate(translation[0], translation[1], translation[2]);

// Make sure that the topmost parent transform is the VR interaction transform
Expand Down