protected override void HandlePointerEventRaised(PointerArgs args) { base.HandlePointerEventRaised(args); if (SelectedInteractable == null) { return; } if (args.Identifier != Identifier && (args.PointerEvent == PointerEvent.Select || args.PointerEvent == PointerEvent.Unselect)) { Pose toPose = PoseUtils.Multiply(_trackedGripPose, _snapOffset); if (SelectedInteractable.ResetGrabOnGrabsUpdated) { if (SelectedInteractable.CalculateBestPose(toPose, Hand.Scale, Hand.Handedness, ref _cachedBestHandPose, ref _cachedBestSnapPoint, out bool usesHandPose, out float poseScore)) { bool usePinchPoint = _currentSnap.SnappedToPinch; HandPose handPose = usesHandPose ? _cachedBestHandPose : null; _currentSnap.Set(SelectedInteractable, handPose, _cachedBestSnapPoint, usePinchPoint); } } Pose fromPose = _currentSnap.WorldSnapPose; _movement = SelectedInteractable.GenerateMovement(fromPose, toPose); SelectedInteractable.PointableElement.ProcessPointerEvent( new PointerArgs(Identifier, PointerEvent.Move, fromPose)); } }
protected override void UpdateData() { _controllerDataAsset.Config = Config; var worldToTrackingSpace = CameraRigRef.CameraRig.transform.worldToLocalMatrix; Transform ovrController = _ovrControllerAnchor; _controllerDataAsset.IsDataValid = true; _controllerDataAsset.IsConnected = (OVRInput.GetConnectedControllers() & _ovrController) > 0; if (!_controllerDataAsset.IsConnected) { // revert state fields to their defaults _controllerDataAsset.IsTracked = default; _controllerDataAsset.ButtonUsageMask = default; _controllerDataAsset.RootPoseOrigin = default; return; } _controllerDataAsset.IsTracked = true; // Update button usages _controllerDataAsset.ButtonUsageMask = ControllerButtonUsage.None; OVRInput.Controller controllerMask = _ovrController; foreach (UsageMapping mapping in ControllerUsageMappings) { bool usageActive; if (mapping.IsTouch) { usageActive = OVRInput.Get(mapping.Touch, controllerMask); } else { Assert.IsTrue(mapping.IsButton); usageActive = OVRInput.Get(mapping.Button, controllerMask); } if (usageActive) { _controllerDataAsset.ButtonUsageMask |= mapping.Usage; } } // Update poses // Convert controller pose from world to tracking space. Pose worldRoot = new Pose(ovrController.position, ovrController.rotation); _controllerDataAsset.RootPose.position = worldToTrackingSpace.MultiplyPoint3x4(worldRoot.position); _controllerDataAsset.RootPose.rotation = worldToTrackingSpace.rotation * worldRoot.rotation; _controllerDataAsset.RootPoseOrigin = PoseOrigin.RawTrackedPose; // Convert controller pointer pose from local to tracking space. Pose pointerPose = PoseUtils.Multiply(worldRoot, _pointerPoseSelector.LocalPointerPose); _controllerDataAsset.PointerPose.position = worldToTrackingSpace.MultiplyPoint3x4(pointerPose.position); _controllerDataAsset.PointerPose.rotation = worldToTrackingSpace.rotation * pointerPose.rotation; _controllerDataAsset.PointerPoseOrigin = PoseOrigin.RawTrackedPose; }
protected override void Apply(HandDataAsset data) { Pose rootToPointer = PoseUtils.RelativeOffset(data.PointerPose, data.Root); rootToPointer.position = (rootToPointer.position / data.HandScale) * _scale; PoseUtils.Multiply(data.Root, rootToPointer, ref data.PointerPose); data.HandScale = _scale; }
private void UpdateWristJoint(HandJointId jointid, ref Pose pose) { int jointIndex = (int)jointid; if ((_dirtyWristJoints & (1 << jointIndex)) != 0)// its dirty { if (jointid > HandJointId.HandWristRoot) { UpdateWristJoint((HandJointId)_originalJoints[jointIndex].parent, ref pose); PoseUtils.Multiply(pose, _localPoses[jointIndex], ref _posesFromWrist[jointIndex]); } _dirtyWristJoints = _dirtyWristJoints & ~(1 << jointIndex); //set clean } pose.CopyFrom(_posesFromWrist[jointIndex]); }
public Pose WorldJointPose(HandJointId jointid, Pose rootPose, float handScale) { int jointIndex = (int)jointid; if ((_dirtyWorldJoints & (1 << jointIndex)) != 0) //its dirty { Pose wristPose = Pose.identity; UpdateWristJoint(jointid, ref wristPose); PoseUtils.Multiply(_localPoses[0], wristPose, ref _worldPoses[jointIndex]); _worldPoses[jointIndex].position *= handScale; _worldPoses[jointIndex].Postmultiply(rootPose); _dirtyWorldJoints = _dirtyWorldJoints & ~(1 << jointIndex); //set clean } return(_worldPoses[jointIndex]); }
/// <summary> /// Each call while the hand is selecting/grabbing an interactable, it moves the item to the /// new position while also attracting it towards the hand if the snapping mode requires it. /// /// In some cases the parameter can be null, for example if the selection was interrupted /// by another hand grabbing the object. In those cases it will come out of the release /// state once the grabbing gesture properly finishes. /// </summary> /// <param name="interactable">The selected item</param> protected override void DoSelectUpdate() { HandGrabInteractable interactable = _selectedInteractable; if (interactable == null) { _currentSnap.Clear(); ShouldUnselect = true; return; } Pose grabbingPoint = PoseUtils.Multiply(_trackedGripPose, _snapOffset); _movement.UpdateTarget(grabbingPoint); _movement.Tick(); HandGrab.StoreGrabData(this, interactable, ref _lastInteractableData); ShouldUnselect = HandGrab.ComputeShouldUnselect(this, interactable); }
/// <summary> /// When a new interactable is selected, start the grab at the ideal point. When snapping is /// involved that can be a point in the interactable offset from the hand /// which will be stored to progressively reduced it in the next updates, /// effectively attracting the object towards the hand. /// When no snapping is involved the point will be the grip point of the hand directly. /// Note: ideally this code would be in InteractableSelected but it needs /// to be called before the object is marked as active. /// </summary> /// <param name="snap">The selected Snap Data </param> protected override void InteractableSelected(HandGrabInteractable interactable) { if (SnapAddress.IsNullOrInvalid(_currentSnap)) { base.InteractableSelected(interactable); return; } if (_currentSnap.SnappedToPinch) { _snapOffset = PoseUtils.RelativeOffset(_trackedPinchPose, _trackedGripPose); } else { _snapOffset = Pose.identity; } Pose handGrabStartPose = PoseUtils.Multiply(_trackedGripPose, _snapOffset); Pose interactableGrabStartPose = _currentSnap.WorldSnapPose; _movement = interactable.GenerateMovement(interactableGrabStartPose, handGrabStartPose); base.InteractableSelected(interactable); }
private void UpdateAllPosesFromWrist() { if (_dirtyWristJoints == 0) //its completely clean { return; } for (int jointIndex = 0; jointIndex < Constants.NUM_HAND_JOINTS; ++jointIndex) { if ((_dirtyWristJoints & (1 << jointIndex)) == 0) //its clean { continue; } HandSkeletonJoint originalJoint = _originalJoints[jointIndex]; if (originalJoint.parent >= 0) { PoseUtils.Multiply(_posesFromWrist[originalJoint.parent], _localPoses[jointIndex], ref _posesFromWrist[jointIndex]); } } _dirtyWristJoints = 0; //set all clean }
protected override void UpdateData() { _handDataAsset.Config = Config; _handDataAsset.IsDataValid = true; _handDataAsset.IsConnected = (OVRInput.GetConnectedControllers() & _ovrController) > 0; if (!_handDataAsset.IsConnected) { // revert state fields to their defaults _handDataAsset.IsTracked = default; _handDataAsset.RootPoseOrigin = default; _handDataAsset.PointerPoseOrigin = default; _handDataAsset.IsHighConfidence = default; for (var fingerIdx = 0; fingerIdx < Constants.NUM_FINGERS; fingerIdx++) { _handDataAsset.IsFingerPinching[fingerIdx] = default; _handDataAsset.IsFingerHighConfidence[fingerIdx] = default; } return; } _handDataAsset.IsTracked = true; _handDataAsset.IsHighConfidence = true; _handDataAsset.HandScale = 1f; _handDataAsset.IsDominantHand = OVRInput.GetDominantHand() == OVRInput.Handedness.LeftHanded && _handedness == Handedness.Left || (OVRInput.GetDominantHand() == OVRInput.Handedness.RightHanded && _handedness == Handedness.Right); float indexStrength = _pinchCurve.Evaluate(OVRInput.Get(OVRInput.Axis1D.PrimaryIndexTrigger, _ovrController)); float gripStrength = _pinchCurve.Evaluate(OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, _ovrController)); _handDataAsset.IsFingerHighConfidence[(int)HandFinger.Thumb] = true; _handDataAsset.IsFingerPinching[(int)HandFinger.Thumb] = indexStrength >= 1f || gripStrength >= 1f; _handDataAsset.FingerPinchStrength[(int)HandFinger.Thumb] = Mathf.Max(indexStrength, gripStrength); _handDataAsset.IsFingerHighConfidence[(int)HandFinger.Index] = true; _handDataAsset.IsFingerPinching[(int)HandFinger.Index] = indexStrength >= 1f; _handDataAsset.FingerPinchStrength[(int)HandFinger.Index] = indexStrength; _handDataAsset.IsFingerHighConfidence[(int)HandFinger.Middle] = true; _handDataAsset.IsFingerPinching[(int)HandFinger.Middle] = gripStrength >= 1f; _handDataAsset.FingerPinchStrength[(int)HandFinger.Middle] = gripStrength; _handDataAsset.IsFingerHighConfidence[(int)HandFinger.Ring] = true; _handDataAsset.IsFingerPinching[(int)HandFinger.Ring] = gripStrength >= 1f; _handDataAsset.FingerPinchStrength[(int)HandFinger.Ring] = gripStrength; _handDataAsset.IsFingerHighConfidence[(int)HandFinger.Pinky] = true; _handDataAsset.IsFingerPinching[(int)HandFinger.Pinky] = gripStrength >= 1f; _handDataAsset.FingerPinchStrength[(int)HandFinger.Pinky] = gripStrength; _handDataAsset.PointerPoseOrigin = PoseOrigin.RawTrackedPose; _handDataAsset.PointerPose = new Pose( OVRInput.GetLocalControllerPosition(_ovrController), OVRInput.GetLocalControllerRotation(_ovrController)); for (int i = 0; i < _bones.Length; i++) { _handDataAsset.Joints[i] = _bones[i].localRotation; } _handDataAsset.Joints[0] = WristFixupRotation; // Convert controller pose from world to tracking space. Pose pose = new Pose(_ovrControllerAnchor.position, _ovrControllerAnchor.rotation); pose = Config.TrackingToWorldTransformer.ToTrackingPose(pose); PoseUtils.Multiply(pose, _poseOffset, ref _handDataAsset.Root); _handDataAsset.RootPoseOrigin = PoseOrigin.RawTrackedPose; }
public void UpdateTarget(Pose target) { Pose grabberDelta = PoseUtils.RelativeOffset(target, _originalTarget); PoseUtils.Multiply(_originalSource, grabberDelta, ref _current); }