Forum Discussion
lufinkey
3 years agoProtege
Modify current grabbing pose of a HandGrabInteractor dynamically
I'm looking for a simple way to change the current grabbing pose of a HandGrabInteractor as it's being held (for example in response to a button press or change in the object etc). I have a dirty way...
- 3 years ago
After spending WAY too much time trying to figure this out, I was able to get it working with the following code:
public bool ApplyNewPoseToGrabbingInteractor(HandGrabInteractor interactor, HandGrabInteractable interactableWithNewGrabPose) { // ensure we have a selected interactable and a valid snap address if (interactor.SelectedInteractable == null) { return false; } var snapAddress = (SnapAddress<HandGrabInteractable>)MPUtils.GetMemberValue(interactor, "_currentSnap"); if (SnapAddress<HandGrabInteractable>.IsNullOrInvalid(snapAddress)) { return false; } var oldSnapPoint = snapAddress.SnapPoint; // get grab properties var hand = interactor.Hand; var trackedPinchPose = (Pose)MPUtils.GetMemberValue(interactor, "_trackedPinchPose"); var trackedGripPose = (Pose)MPUtils.GetMemberValue(interactor, "_trackedGripPose"); // get previous snap address properties var snappingInteractable = snapAddress.Interactable; var handPose = (HandPose)MPUtils.GetMemberValue(interactor, "_cachedBestHandPose"); var snapPoint = (Pose)MPUtils.GetMemberValue(interactor, "_cachedBestSnapPoint"); var usePinchPoint = snapAddress.SnappedToPinch; // update grab point values var grabPoint = usePinchPoint ? trackedPinchPose : trackedGripPose; bool poseFound = interactableWithNewGrabPose.CalculateBestPose(grabPoint, hand.Scale, hand.Handedness, ref handPose, ref snapPoint, out bool usesHandPose, out float poseScore); MPUtils.SetMemberValue(interactor, "_cachedBestHandPose", handPose); MPUtils.SetMemberValue(interactor, "_cachedBestSnapPoint", snapPoint); // apply pose if able if (poseFound) { var snapHandPose = usesHandPose ? handPose : null; snapAddress.Set(snappingInteractable, snapHandPose, snapPoint, usePinchPoint); if (interactor.SnapData != null) { MPUtils.SetMemberValue(interactor, "SnapData", snapAddress); } // adjust pointable element position/rotation to compensate for pose difference var pointableElementTransform = (snappingInteractable.PointableElement as Component)?.transform; var snapPointRotOffset = snapPoint.rotation * Quaternion.Inverse(oldSnapPoint.rotation); if (pointableElementTransform != null) { var oldRotation = pointableElementTransform.rotation; var newRotation = oldRotation * Quaternion.Inverse(snapPointRotOffset); pointableElementTransform.position -= -(pointableElementTransform.rotation * oldSnapPoint.position) + (newRotation * snapPoint.position); pointableElementTransform.rotation = newRotation; } } return poseFound; }
The MPUtils.SetMemberValue and MPUtils.GetMemberValue methods are just helper methods to access private member variables via reflection.
Hopefully this saves someone else the time I spent trying to get this working! And if the oculus team reads this, it would be really awesome if you could add this as a feature! I'm sure this is probably the worst way to accomplish this
Edit: this was done on oculus interaction sdk v40, for reference
lufinkey
3 years agoProtege
After spending WAY too much time trying to figure this out, I was able to get it working with the following code:
public bool ApplyNewPoseToGrabbingInteractor(HandGrabInteractor interactor, HandGrabInteractable interactableWithNewGrabPose) {
// ensure we have a selected interactable and a valid snap address
if (interactor.SelectedInteractable == null) {
return false;
}
var snapAddress = (SnapAddress<HandGrabInteractable>)MPUtils.GetMemberValue(interactor, "_currentSnap");
if (SnapAddress<HandGrabInteractable>.IsNullOrInvalid(snapAddress)) {
return false;
}
var oldSnapPoint = snapAddress.SnapPoint;
// get grab properties
var hand = interactor.Hand;
var trackedPinchPose = (Pose)MPUtils.GetMemberValue(interactor, "_trackedPinchPose");
var trackedGripPose = (Pose)MPUtils.GetMemberValue(interactor, "_trackedGripPose");
// get previous snap address properties
var snappingInteractable = snapAddress.Interactable;
var handPose = (HandPose)MPUtils.GetMemberValue(interactor, "_cachedBestHandPose");
var snapPoint = (Pose)MPUtils.GetMemberValue(interactor, "_cachedBestSnapPoint");
var usePinchPoint = snapAddress.SnappedToPinch;
// update grab point values
var grabPoint = usePinchPoint ? trackedPinchPose : trackedGripPose;
bool poseFound = interactableWithNewGrabPose.CalculateBestPose(grabPoint, hand.Scale, hand.Handedness,
ref handPose, ref snapPoint, out bool usesHandPose, out float poseScore);
MPUtils.SetMemberValue(interactor, "_cachedBestHandPose", handPose);
MPUtils.SetMemberValue(interactor, "_cachedBestSnapPoint", snapPoint);
// apply pose if able
if (poseFound) {
var snapHandPose = usesHandPose ? handPose : null;
snapAddress.Set(snappingInteractable, snapHandPose, snapPoint, usePinchPoint);
if (interactor.SnapData != null) {
MPUtils.SetMemberValue(interactor, "SnapData", snapAddress);
}
// adjust pointable element position/rotation to compensate for pose difference
var pointableElementTransform = (snappingInteractable.PointableElement as Component)?.transform;
var snapPointRotOffset = snapPoint.rotation * Quaternion.Inverse(oldSnapPoint.rotation);
if (pointableElementTransform != null) {
var oldRotation = pointableElementTransform.rotation;
var newRotation = oldRotation * Quaternion.Inverse(snapPointRotOffset);
pointableElementTransform.position -= -(pointableElementTransform.rotation * oldSnapPoint.position) + (newRotation * snapPoint.position);
pointableElementTransform.rotation = newRotation;
}
}
return poseFound;
}
The MPUtils.SetMemberValue and MPUtils.GetMemberValue methods are just helper methods to access private member variables via reflection.
Hopefully this saves someone else the time I spent trying to get this working! And if the oculus team reads this, it would be really awesome if you could add this as a feature! I'm sure this is probably the worst way to accomplish this
Edit: this was done on oculus interaction sdk v40, for reference
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 2 years ago
- 1 year ago
- 4 years ago
- 1 year ago