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;
        }
Beispiel #3
0
        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;
        }
Beispiel #4
0
        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]);
        }
Beispiel #5
0
        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);
        }
Beispiel #8
0
        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;
        }
Beispiel #10
0
        public void UpdateTarget(Pose target)
        {
            Pose grabberDelta = PoseUtils.RelativeOffset(target, _originalTarget);

            PoseUtils.Multiply(_originalSource, grabberDelta, ref _current);
        }