예제 #1
0
        protected void UpdateHand(OVRHand ovrHand, OVRSkeleton ovrSkeleton, OVRMeshRenderer ovrMeshRenderer, Handedness handedness)
        {
            // Until the ovrMeshRenderer is initialized we do nothing with the hand
            // This is a bit of a hack because the Oculus Integration fails if we touch the renderer before it has initialized itself
            if (ovrMeshRenderer == null || !ovrMeshRenderer.IsInitialized)
            {
                return;
            }

            if (ovrHand.IsTracked)
            {
                var hand = GetOrAddHand(handedness, ovrHand);
                hand.UpdateController(ovrHand, ovrSkeleton, cameraRig.trackingSpace);
            }
            else
            {
                RemoveHandDevice(handedness);
            }
        }
        // Start is called before the first frame update
        void Start()
        {
            skeleton = trackedHand.GetComponent <OVRSkeleton>();
            mr       = trackedHand.GetComponent <OVRMeshRenderer>();
            smr      = trackedHand.GetComponent <SkinnedMeshRenderer>();

            foreach (OVRBone bone in skeleton.Bones)
            {
                if (bone.Id == OVRSkeleton.BoneId.Hand_IndexTip)
                {
                    indexTipBone = bone;
                }
                if (bone.Id == OVRSkeleton.BoneId.Hand_MiddleTip)
                {
                    middleTipBone = bone;
                }
                if (bone.Id == OVRSkeleton.BoneId.Hand_RingTip)
                {
                    ringTipBone = bone;
                }
                if (bone.Id == OVRSkeleton.BoneId.Hand_PinkyTip)
                {
                    pinkyTipBone = bone;
                }
                if (bone.Id == OVRSkeleton.BoneId.Hand_ThumbTip)
                {
                    thumbTipBone = bone;
                }
                if (bone.Id == OVRSkeleton.BoneId.Hand_Start)
                {
                    handBone = bone;
                }
            }

            for (int i = 0; i < smoothSteps; i++)
            {
                lastPositions.Add(IndexTipObject.transform.position);
            }
        }
예제 #3
0
        private void SetupInput()
        {
            cameraRig = GameObject.FindObjectOfType <OVRCameraRig>();
            if (cameraRig == null)
            {
                var       mainCamera   = Camera.main;
                Transform cameraParent = null;
                if (mainCamera != null)
                {
                    cameraParent = mainCamera.transform.parent;

                    // Destroy main camera
                    GameObject.Destroy(cameraParent.gameObject);
                }

                // Instantiate camera rig as a child of the MixedRealityPlayspace
                cameraRig = GameObject.Instantiate(MRTKOculusConfig.Instance.OVRCameraRigPrefab);
            }
            // Ensure all related game objects are configured
            cameraRig.EnsureGameObjectIntegrity();

            bool useAvatarHands = MRTKOculusConfig.Instance.RenderAvatarHandsInsteadOfController;

            // If using Avatar hands, de-activate ovr controller rendering
            foreach (var controllerHelper in cameraRig.gameObject.GetComponentsInChildren <OVRControllerHelper>())
            {
                controllerHelper.gameObject.SetActive(!useAvatarHands);
            }

            if (useAvatarHands && !MRTKOculusConfig.Instance.AllowDevToManageAvatarPrefab)
            {
                // Initialize the local avatar controller
                GameObject.Instantiate(MRTKOculusConfig.Instance.LocalAvatarPrefab, cameraRig.trackingSpace);
            }

            var ovrHands = cameraRig.GetComponentsInChildren <OVRHand>();

            foreach (var ovrHand in ovrHands)
            {
                // Manage Hand skeleton data
                var skeltonDataProvider = ovrHand as OVRSkeleton.IOVRSkeletonDataProvider;
                var skeltonType         = skeltonDataProvider.GetSkeletonType();
                var meshRenderer        = ovrHand.GetComponent <OVRMeshRenderer>();

                var ovrSkelton = ovrHand.GetComponent <OVRSkeleton>();
                if (ovrSkelton == null)
                {
                    continue;
                }

                switch (skeltonType)
                {
                case OVRSkeleton.SkeletonType.HandLeft:
                    leftHand         = ovrHand;
                    leftSkeleton     = ovrSkelton;
                    leftMeshRenderer = meshRenderer;
                    break;

                case OVRSkeleton.SkeletonType.HandRight:
                    rightHand        = ovrHand;
                    rightSkeleton    = ovrSkelton;
                    righMeshRenderer = meshRenderer;
                    break;
                }
            }
        }
예제 #4
0
        private void SetupInput()
        {
            cameraRig = GameObject.FindObjectOfType <OVRCameraRig>();
            if (cameraRig == null)
            {
                var mainCamera = CameraCache.Main;

                // Instantiate camera rig as a child of the MixedRealityPlayspace

                var cameraRigObject = GameObject.Instantiate(SettingsProfile.OVRCameraRigPrefab);
                cameraRig = cameraRigObject.GetComponent <OVRCameraRig>();

                // Ensure all related game objects are configured
                cameraRig.EnsureGameObjectIntegrity();

                if (mainCamera != null)
                {
                    // We already had a main camera MRTK probably started using, let's replace the CenterEyeAnchor MainCamera with it
                    GameObject prefabMainCamera = cameraRig.trackingSpace.Find("CenterEyeAnchor").gameObject;
                    prefabMainCamera.SetActive(false);
                    mainCamera.transform.SetParent(cameraRig.trackingSpace.transform);
                    mainCamera.name = prefabMainCamera.name;
                    GameObject.Destroy(prefabMainCamera);
                }
                cameraRig.transform.SetParent(MixedRealityPlayspace.Transform);
            }
            else
            {
                // Ensure all related game objects are configured
                cameraRig.EnsureGameObjectIntegrity();
            }

            bool useAvatarHands = SettingsProfile.RenderAvatarHandsInsteadOfController;

            // If using Avatar hands, de-activate ovr controller rendering
            foreach (var controllerHelper in cameraRig.gameObject.GetComponentsInChildren <OVRControllerHelper>())
            {
                controllerHelper.gameObject.SetActive(!useAvatarHands);
            }

            if (useAvatarHands)
            {
                // Initialize the local avatar controller
                GameObject.Instantiate(SettingsProfile.LocalAvatarPrefab, cameraRig.trackingSpace);
            }

            var ovrHands = cameraRig.GetComponentsInChildren <OVRHand>();

            foreach (var ovrHand in ovrHands)
            {
                // Manage Hand skeleton data
                var skeletonDataProvider = ovrHand as OVRSkeleton.IOVRSkeletonDataProvider;
                var skeletonType         = skeletonDataProvider.GetSkeletonType();
                var meshRenderer         = ovrHand.GetComponent <OVRMeshRenderer>();

                var ovrSkeleton = ovrHand.GetComponent <OVRSkeleton>();
                if (ovrSkeleton == null)
                {
                    continue;
                }

                switch (skeletonType)
                {
                case OVRSkeleton.SkeletonType.HandLeft:
                    leftHand         = ovrHand;
                    leftSkeleton     = ovrSkeleton;
                    leftMeshRenderer = meshRenderer;
                    break;

                case OVRSkeleton.SkeletonType.HandRight:
                    rightHand        = ovrHand;
                    rightSkeleton    = ovrSkeleton;
                    righMeshRenderer = meshRenderer;
                    break;
                }
            }
        }
예제 #5
0
        protected bool UpdateHandData(OVRHand ovrHand, OVRSkeleton ovrSkeleton, OVRMeshRenderer ovrMeshRenderer)
        {
            bool isTracked = ovrHand.IsTracked;

            if (ovrHand.HandConfidence == OVRHand.TrackingConfidence.High)
            {
                _lastHighConfidenceTime = Time.unscaledTime;
            }
            if (ovrHand.HandConfidence == OVRHand.TrackingConfidence.Low)
            {
                if (settingsProfile.MinimumHandConfidence == OVRHand.TrackingConfidence.High)
                {
                    isTracked = false;
                }
                else
                {
                    float lowConfidenceTime = Time.time - _lastHighConfidenceTime;
                    if (settingsProfile.LowConfidenceTimeThreshold > 0 &&
                        settingsProfile.LowConfidenceTimeThreshold < lowConfidenceTime)
                    {
                        isTracked = false;
                    }
                }
            }

            if (ControllerHandedness == Handedness.Left)
            {
                settingsProfile.CurrentLeftHandTrackingConfidence = ovrHand.HandConfidence;
            }
            else
            {
                settingsProfile.CurrentRightHandTrackingConfidence = ovrHand.HandConfidence;
            }

            // Managing hand visuals based on the handtracking visualization profile and if the hand is tracked
            if (handRenderer != null)
            {
                bool showHandMesh   = handTrackingProfile.IsNull() ? false : handTrackingProfile.EnableHandMeshVisualization;
                bool showHandJoints = handTrackingProfile.IsNull() ? false : handTrackingProfile.EnableHandJointVisualization;

                ovrMeshRenderer.enabled = isTracked && showHandMesh;
                handRenderer.enabled    = isTracked && showHandMesh;
                Visualizer.GameObjectProxy.SetActive(isTracked && showHandJoints);
            }

            if (ovrSkeleton != null)
            {
                var bones = ovrSkeleton.Bones;
                foreach (var bone in bones)
                {
                    UpdateBone(bone);
                }

                UpdatePalm();
            }

            CoreServices.InputSystem?.RaiseHandJointsUpdated(InputSource, ControllerHandedness, jointPoses);

            // Note: After some testing, it seems when moving your hand fast, Oculus's pinch estimation data gets frozen, which leads to stuck pinches.
            // To counter this, we perform a distance check between thumb and index to determine if we should force the pinch to a false state.
            float pinchStrength;

            if (AreIndexAndThumbFarApart())
            {
                pinchStrength = 0f;
                IsPinching    = false;
            }
            else
            {
                pinchStrength = ovrHand.GetFingerPinchStrength(OVRHand.HandFinger.Index);
                if (IsPinching)
                {
                    // If we are already pinching, we make the pinch a bit sticky
                    IsPinching = ovrHand.GetFingerPinchStrength(OVRHand.HandFinger.Index) > 0.85f;
                }
                else
                {
                    // If not yet pinching, only consider pinching if finger confidence is high
                    IsPinching = ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Index) &&
                                 ovrHand.GetFingerConfidence(OVRHand.HandFinger.Index) == OVRHand.TrackingConfidence.High;
                }
            }

            isIndexGrabbing  = HandPoseUtils.IsIndexGrabbing(ControllerHandedness);
            isMiddleGrabbing = HandPoseUtils.IsMiddleGrabbing(ControllerHandedness);
            isThumbGrabbing  = HandPoseUtils.IsThumbGrabbing(ControllerHandedness);

            // Hand Curl Properties:
            float indexFingerCurl  = HandPoseUtils.IndexFingerCurl(ControllerHandedness);
            float middleFingerCurl = HandPoseUtils.MiddleFingerCurl(ControllerHandedness);
            float ringFingerCurl   = HandPoseUtils.RingFingerCurl(ControllerHandedness);
            float pinkyFingerCurl  = HandPoseUtils.PinkyFingerCurl(ControllerHandedness);

            // Pinch was also used as grab, we want to allow hand-curl grab not just pinch.
            // Determine pinch and grab separately
            if (isTracked)
            {
                IsGrabbing = isIndexGrabbing && isMiddleGrabbing;
            }

            if (settingsProfile.UpdateMaterialPinchStrengthValue && handMaterial != null)
            {
                float gripStrength = indexFingerCurl + middleFingerCurl + ringFingerCurl + pinkyFingerCurl;
                gripStrength /= 4.0f;
                gripStrength  = gripStrength > 0.8f ? 1.0f : gripStrength;

                pinchStrength = Mathf.Max(pinchStrength, gripStrength);
                handMaterial.SetFloat(pinchStrengthProp, pinchStrength);
            }
            return(isTracked);
        }
예제 #6
0
        /// <summary>
        /// Update the controller data from the provided platform state
        /// </summary>
        /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform</param>
        public void UpdateController(OVRHand hand, OVRSkeleton ovrSkeleton, OVRMeshRenderer ovrMeshRenderer, Transform trackingOrigin)
        {
            if (!Enabled || hand == null || ovrSkeleton == null)
            {
                return;
            }

            bool isTracked = UpdateHandData(hand, ovrSkeleton, ovrMeshRenderer);

            IsPositionAvailable = IsRotationAvailable = isTracked;

            if (isTracked)
            {
                // Leverage Oculus Platform Hand Ray - instead of simulating it in a crummy way
                currentPointerPose.Position = trackingOrigin.TransformPoint(hand.PointerPose.position);

                Vector3 pointerForward = trackingOrigin.TransformDirection(hand.PointerPose.forward);
                Vector3 pointerUp      = trackingOrigin.TransformDirection(hand.PointerPose.up);

                currentPointerPose.Rotation = Quaternion.LookRotation(pointerForward, pointerUp);

                currentGripPose = jointPoses[TrackedHandJoint.Palm];

                CoreServices.InputSystem?.RaiseSourcePoseChanged(InputSource, this, currentGripPose);

                UpdateVelocity();
            }

            UpdateTeleport();

            for (int i = 0; i < Interactions?.Length; i++)
            {
                switch (Interactions[i].InputType)
                {
                case DeviceInputType.SpatialPointer:
                    Interactions[i].PoseData = currentPointerPose;
                    if (Interactions[i].Changed)
                    {
                        CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction, currentPointerPose);
                    }
                    break;

                case DeviceInputType.SpatialGrip:
                    Interactions[i].PoseData = currentGripPose;
                    if (Interactions[i].Changed)
                    {
                        CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction, currentGripPose);
                    }
                    break;

                case DeviceInputType.Select:
                    Interactions[i].BoolData = IsPinching || IsGrabbing;

                    if (Interactions[i].Changed)
                    {
                        if (Interactions[i].BoolData)
                        {
                            CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                        else
                        {
                            CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                    }
                    break;

                case DeviceInputType.TriggerPress:
                    Interactions[i].BoolData = IsPinching || IsGrabbing;

                    if (Interactions[i].Changed)
                    {
                        if (Interactions[i].BoolData)
                        {
                            CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                        else
                        {
                            CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                    }
                    break;

                case DeviceInputType.IndexFinger:
                    UpdateIndexFingerData(Interactions[i]);
                    break;
                }
            }
        }