public void UpdateState(SimulatedHandData handData)
        {
            for (int i = 0; i < jointCount; i++)
            {
                TrackedHandJoint handJoint = (TrackedHandJoint)i;

                if (!jointPoses.ContainsKey(handJoint))
                {
                    jointPoses.Add(handJoint, handData.Joints[i]);
                }
                else
                {
                    jointPoses[handJoint] = handData.Joints[i];
                }
            }

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

            UpdateVelocity();

            UpdateInteractions(handData);
        }
        public Transform RequestJointTransform(TrackedHandJoint joint, Handedness handedness)
        {
            IMixedRealityHand hand = null;
            Dictionary <TrackedHandJoint, Transform> fauxJoints = null;

            if (handedness == Handedness.Left)
            {
                hand       = leftHand;
                fauxJoints = leftHandFauxJoints;
            }
            else if (handedness == Handedness.Right)
            {
                hand       = rightHand;
                fauxJoints = rightHandFauxJoints;
            }
            else
            {
                return(null);
            }

            Transform jointTransform = null;

            if (fauxJoints != null && !fauxJoints.TryGetValue(joint, out jointTransform))
            {
                jointTransform = new GameObject().transform;
                // Since this service survives scene loading and unloading, the fauxJoints it manages need to as well.
                Object.DontDestroyOnLoad(jointTransform.gameObject);
                jointTransform.name = string.Format("Joint Tracker: {1} {0}", joint, handedness);

                if (hand != null && hand.TryGetJoint(joint, out MixedRealityPose pose))
                {
                    jointTransform.SetPositionAndRotation(pose.Position, pose.Rotation);
                }

                fauxJoints.Add(joint, jointTransform);
            }

            return(jointTransform);
        }
    public bool TryGetControllerPose(TrackedHandJoint handJointToTrack, out Vector3 position, out Quaternion rotation, bool getPointerOnly = false)
    {
        bool retrieved = false;

        position = Vector3.zero;
        rotation = Quaternion.identity;

        if (!XRSettings.enabled)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            position = ray.GetPoint(0.5f) + new Vector3(-0.01f, -0.015f, 0);
            rotation = Quaternion.Euler(Camera.main.transform.eulerAngles + new Vector3(-45, -45, 0));//Camera.main.transform.rotation + Quaternion.AngleAxis(90, Vector3.up) + Quaternion.AngleAxis(45, Vector3.left);

            retrieved = true;
        }
        else
        {
            if (getPointerOnly)
            {
                try
                {
                    position  = (detectedHand ?? detectedController).InputSource.Pointers[0].Position;
                    rotation  = (detectedHand ?? detectedController).InputSource.Pointers[0].Rotation;
                    retrieved = true;
                }
                catch (Exception)
                {
                    retrieved = false;
                }
            }
            else
            {
                retrieved = TryGetSpecificControllerPose(Handedness.None, handJointToTrack, out position, out rotation);
            }
        }

        return(retrieved);
    }
Exemplo n.º 4
0
        private void ScaleFingerTip(Transform jointTransform, TrackedHandJoint fingerTipJoint, Vector3 boneRootPos)
        {
            // Set fingertip base bone scale to match the bone length to the fingertip.
            // This will only scale correctly if the model was constructed to match
            // the standard "test" edit-time hand model from the LeapMotion TestHandFactory.
            if (!MixedRealityHand.TryGetJoint(fingerTipJoint, out MixedRealityPose pose))
            {
                return;
            }

            var boneTipPos = pose.Position;
            var boneVec    = boneTipPos - boneRootPos;

            if (transform.lossyScale.x != 0f && transform.lossyScale.x != 1f)
            {
                boneVec /= transform.lossyScale.x;
            }
            var newScale           = jointTransform.transform.localScale;
            var lengthComponentIdx = GetLargestComponentIndex(ModelFingerPointing);

            newScale[lengthComponentIdx]        = boneVec.magnitude / fingerTipLengths[fingerTipJoint];
            jointTransform.transform.localScale = newScale;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Get the pose of the metacarpal joints from the current frame of the LeapServiceProvider because the metacarpal joints
        /// are not included in AttachmentPointFlags.  The metacarpal joints are those located directly above the wrist.
        /// </summary>
        /// <param name="metacarpalJoint">A metacarpal TrackedHandJoint</param>
        /// <returns>The MixedRealityPose for the leap metacarpal joint</returns>
        private MixedRealityPose GetMetacarpalPose(TrackedHandJoint metacarpalJoint)
        {
            int metacarpalIndex = metacarpals.IndexOf(metacarpalJoint);

            // Get the joint poses of the hand each frame
            // A reference to the leap Hand cannot be cached and needs to be retrieved each frame
            List <Hand> leapHandsInCurrentFrame = leapServiceProvider.CurrentFrame.Hands;

            foreach (Hand hand in leapHandsInCurrentFrame)
            {
                if ((hand.IsLeft && ControllerHandedness == Handedness.Left) ||
                    (hand.IsRight && ControllerHandedness == Handedness.Right))
                {
                    // Leapmotion thumb metacarpal is stored at index 1
                    int        boneIndex = (metacarpalJoint == TrackedHandJoint.ThumbMetacarpalJoint) ? 1 : 0;
                    Vector3    position  = hand.Fingers[metacarpalIndex].bones[boneIndex].PrevJoint.ToVector3();
                    Quaternion rotation  = hand.Fingers[metacarpalIndex].bones[boneIndex].Rotation.ToQuaternion();

                    return(new MixedRealityPose(position, rotation));
                }
            }

            return(MixedRealityPose.ZeroIdentity);
        }
        protected void UpdateJointPose(TrackedHandJoint joint, Vector3 position, Quaternion rotation)
        {
            // TODO Figure out kalman filter coefficients to get good quality smoothing
#if LATER
            if (joint == TrackedHandJoint.IndexTip)
            {
                jointPosition = indexTipFilter.Update(position);
            }
            else if (joint == TrackedHandJoint.Palm)
            {
                jointPosition = palmFilter.Update(position);
            }
#endif

            MixedRealityPose pose = new MixedRealityPose(position, rotation);
            if (!jointPoses.ContainsKey(joint))
            {
                jointPoses.Add(joint, pose);
            }
            else
            {
                jointPoses[joint] = pose;
            }
        }
Exemplo n.º 7
0
        /// <inheritdoc/>
        void IMixedRealityHandJointHandler.OnHandJointsUpdated(InputEventData <IDictionary <TrackedHandJoint, MixedRealityPose> > eventData)
        {
            if (eventData.InputSource.SourceId != Controller.InputSource.SourceId)
            {
                return;
            }
            Debug.Assert(eventData.Handedness == Controller.ControllerHandedness);

            IMixedRealityInputSystem inputSystem = CoreServices.InputSystem;

            // Only runs if render skeleton joints is true
            MixedRealityHandTrackingProfile handTrackingProfile = inputSystem?.InputSystemProfile.HandTrackingProfile;

            if (handTrackingProfile != null && handTrackingProfile.EnableHandJointVisualization)
            {
                // This starts at 1 to skip over TrackedHandJoint.None.
                for (int i = 1; i < ArticulatedHandPose.JointCount; i++)
                {
                    TrackedHandJoint handJoint     = (TrackedHandJoint)i;
                    MixedRealityPose handJointPose = eventData.InputData[handJoint];

                    if (skeletonJoints.TryGetValue(handJoint, out Transform skeletonJointTransform))
                    {
                        skeletonJointTransform.SetPositionAndRotation(handJointPose.Position, handJointPose.Rotation);
                    }
                    else
                    {
                        GameObject prefab;
                        if (handJoint == TrackedHandJoint.Palm)
                        {
                            prefab = inputSystem.InputSystemProfile.HandTrackingProfile.PalmJointPrefab;
                        }
                        else if (handJoint == TrackedHandJoint.IndexTip)
                        {
                            prefab = inputSystem.InputSystemProfile.HandTrackingProfile.FingerTipPrefab;
                        }
                        else
                        {
                            prefab = inputSystem.InputSystemProfile.HandTrackingProfile.JointPrefab;
                        }

                        GameObject jointObject;
                        if (prefab != null)
                        {
                            jointObject = Instantiate(prefab);
                        }
                        else
                        {
                            jointObject = new GameObject();
                        }

                        jointObject.name = handJoint.ToString() + " Proxy Transform";
                        jointObject.transform.SetPositionAndRotation(handJointPose.Position, handJointPose.Rotation);
                        jointObject.transform.parent = transform;

                        skeletonJoints.Add(handJoint, jointObject.transform);
                    }
                }
            }
            else
            {
                // clear existing joint GameObjects / meshes
                foreach (var joint in skeletonJoints)
                {
                    Destroy(joint.Value.gameObject);
                }

                skeletonJoints.Clear();
            }

            // Only runs if render hand mesh is true
            bool renderHandmesh = handTrackingProfile != null && handTrackingProfile.EnableHandMeshVisualization;

            HandRenderer.enabled = renderHandmesh;
            if (renderHandmesh)
            {
                // Render the rigged hand mesh itself
                // Apply updated TrackedHandJoint pose data to the assigned transforms

                // This starts at 1 to skip over TrackedHandJoint.None.
                for (int i = 1; i < ArticulatedHandPose.JointCount; i++)
                {
                    TrackedHandJoint handJoint     = (TrackedHandJoint)i;
                    MixedRealityPose handJointPose = eventData.InputData[handJoint];

                    if (joints.TryGetValue(handJoint, out Transform jointTransform) && jointTransform != null)
                    {
                        if (handJoint == TrackedHandJoint.Palm)
                        {
                            if (ModelPalmAtLeapWrist)
                            {
                                Palm.position = eventData.InputData[TrackedHandJoint.Wrist].Position;
                            }
                            else
                            {
                                Palm.position = handJointPose.Position;
                            }
                            Palm.rotation = handJointPose.Rotation * UserBoneRotation;
                        }
                        else if (handJoint == TrackedHandJoint.Wrist)
                        {
                            if (!ModelPalmAtLeapWrist)
                            {
                                Wrist.position = handJointPose.Position;
                            }
                        }
                        else
                        {
                            // Finger joints
                            jointTransform.rotation = handJointPose.Rotation * Reorientation();

                            if (DeformPosition)
                            {
                                jointTransform.position = handJointPose.Position;
                            }

                            if (ScaleLastFingerBone &&
                                (handJoint == TrackedHandJoint.ThumbDistalJoint ||
                                 handJoint == TrackedHandJoint.IndexDistalJoint ||
                                 handJoint == TrackedHandJoint.MiddleDistalJoint ||
                                 handJoint == TrackedHandJoint.RingDistalJoint ||
                                 handJoint == TrackedHandJoint.PinkyDistalJoint))
                            {
                                ScaleFingerTip(eventData, jointTransform, handJoint + 1, jointTransform.position);
                            }
                        }
                    }
                }

                // Update the hand material
                float pinchStrength = HandPoseUtils.CalculateIndexPinch(Controller.ControllerHandedness);

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

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

                    pinchStrength = Mathf.Pow(Mathf.Max(pinchStrength, gripStrength), 2.0f);

                    if (handRenderer.sharedMaterial.HasProperty(pinchStrengthMaterialProperty))
                    {
                        handRenderer.sharedMaterial.SetFloat(pinchStrengthMaterialProperty, pinchStrength);
                    }
                    // Only show this warning once
                    else if (!displayedMaterialPropertyWarning)
                    {
                        Debug.LogWarning(String.Format("The property {0} for reacting to pinch strength was not found. A material with this property is required to visualize pinch strength.", pinchStrengthMaterialProperty));
                        displayedMaterialPropertyWarning = true;
                    }
                }
            }
        }
Exemplo n.º 8
0
        /// <inheritdoc/>
        public override void OnHandJointsUpdated(InputEventData <IDictionary <TrackedHandJoint, MixedRealityPose> > eventData)
        {
            using (OnHandJointsUpdatedPerfMarker.Auto())
            {
                // The base class takes care of updating all of the joint data
                base.OnHandJointsUpdated(eventData);

                // exit early and disable the rigged hand model if we've gotten a hand mesh from the underlying platform
                if (receivingPlatformHandMesh)
                {
                    HandRenderer.enabled = false;
                    return;
                }

                // Ensures that the hand only renders when the event data matches the controller this visualizer represents
                if (eventData.InputSource.SourceId != Controller.InputSource.SourceId)
                {
                    return;
                }
                Debug.Assert(eventData.Handedness == Controller.ControllerHandedness);

                IMixedRealityInputSystem        inputSystem         = CoreServices.InputSystem;
                MixedRealityHandTrackingProfile handTrackingProfile = inputSystem?.InputSystemProfile.HandTrackingProfile;

                // Only runs if render hand mesh is true
                bool renderHandmesh = handTrackingProfile != null && handTrackingProfile.EnableHandMeshVisualization;
                HandRenderer.enabled = renderHandmesh;
                if (renderHandmesh)
                {
                    // Render the rigged hand mesh itself
                    // Apply updated TrackedHandJoint pose data to the assigned transforms

                    // This starts at 1 to skip over TrackedHandJoint.None.
                    for (int i = 1; i < ArticulatedHandPose.JointCount; i++)
                    {
                        TrackedHandJoint handJoint = (TrackedHandJoint)i;
                        // Skip this hand joint if the event data doesn't have an entry for it
                        if (!eventData.InputData.ContainsKey(handJoint))
                        {
                            continue;
                        }
                        MixedRealityPose handJointPose  = eventData.InputData[handJoint];
                        Transform        jointTransform = riggedVisualJointsArray[i];

                        if (jointTransform != null)
                        {
                            if (handJoint == TrackedHandJoint.Palm)
                            {
                                if (ModelPalmAtLeapWrist)
                                {
                                    Palm.position = eventData.InputData[TrackedHandJoint.Wrist].Position;
                                }
                                else
                                {
                                    Palm.position = handJointPose.Position;
                                }
                                Palm.rotation = handJointPose.Rotation * UserBoneRotation;
                            }
                            else if (handJoint == TrackedHandJoint.Wrist)
                            {
                                if (!ModelPalmAtLeapWrist)
                                {
                                    Wrist.position = handJointPose.Position;
                                }
                            }
                            else
                            {
                                // Finger riggedVisualJointsArray
                                jointTransform.rotation = handJointPose.Rotation * Reorientation();

                                if (DeformPosition)
                                {
                                    jointTransform.position = handJointPose.Position;
                                }

                                if (ScaleLastFingerBone &&
                                    (handJoint == TrackedHandJoint.ThumbDistalJoint ||
                                     handJoint == TrackedHandJoint.IndexDistalJoint ||
                                     handJoint == TrackedHandJoint.MiddleDistalJoint ||
                                     handJoint == TrackedHandJoint.RingDistalJoint ||
                                     handJoint == TrackedHandJoint.PinkyDistalJoint))
                                {
                                    ScaleFingerTip(eventData, jointTransform, handJoint + 1, jointTransform.position);
                                }
                            }
                        }
                    }

                    // Update the hand material
                    float pinchStrength = HandPoseUtils.CalculateIndexPinch(Controller.ControllerHandedness);

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

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

                        pinchStrength = Mathf.Pow(Mathf.Max(pinchStrength, gripStrength), 2.0f);

                        if (handRenderer.sharedMaterial.HasProperty(pinchStrengthMaterialProperty))
                        {
                            handRenderer.sharedMaterial.SetFloat(pinchStrengthMaterialProperty, pinchStrength);
                        }
                        // Only show this warning once
                        else if (!displayedMaterialPropertyWarning)
                        {
                            Debug.LogWarning(String.Format("The property {0} for reacting to pinch strength was not found. A material with this property is required to visualize pinch strength.", pinchStrengthMaterialProperty));
                            displayedMaterialPropertyWarning = true;
                        }
                    }
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Instantiates <see cref="FingerTipKinematicBodyPrefab"/>s for all <see cref="fingerTipTypes"/>.
        /// </summary>
        /// <remarks>
        /// Optionally instantiates <see cref="PalmKinematicBodyPrefab"/>.
        /// </remarks>
        /// <param name="rigidBodyPrefab">The prefab to instantiate.</param>
        /// <param name="layer">the layer to put the prefab on.</param>
        /// <param name="handednessType">the specified <see cref="Handedness"/> for the joint.</param>
        /// <param name="jointType">the specified <see cref="TrackedHandJoint"/> to instantiate against.</param>
        /// <param name="parent">The root <see href="https://docs.unity3d.com/ScriptReference/GameObject.html"> for the joints.</param>
        /// <param name="jointKinematicBody">When successful, the generated <see cref="JointKinematicBody"/>.</param>
        /// <returns>True when able to successfully intantiate and create a <see cref="JointKinematicBody"/>.</returns>
        private static bool TryCreateJointKinematicBody(GameObject rigidBodyPrefab, int layer, Handedness handednessType, TrackedHandJoint jointType, Transform parent, out JointKinematicBody jointKinematicBody)
        {
            jointKinematicBody = null;

            GameObject currentGameObject = GameObject.Instantiate(rigidBodyPrefab, parent);

            currentGameObject.layer = layer;
            JointKinematicBody currentJoint = currentGameObject.GetComponent <JointKinematicBody>();

            if (currentJoint == null)
            {
                Debug.LogError("The HandPhysicsService assumes the FingerTipKinematicBodyPrefab has a JointKinematicBody component.");
                UnityEngine.Object.Destroy(currentGameObject);
                return(false);
            }

            currentJoint.JointType      = jointType;
            currentJoint.HandednessType = handednessType;
            currentGameObject.name      = handednessType + " " + jointType;

            if (currentGameObject.GetComponent <Collider>() == null)
            {
                Debug.LogError("The HandPhysicsService assumes the FingerTipKinematicBodyPrefab has a Collder component.");
                UnityEngine.Object.Destroy(currentGameObject);
                return(false);
            }

            Rigidbody rigidbody = currentGameObject.GetComponent <Rigidbody>();

            if (rigidbody == null)
            {
                Debug.LogError("The HandPhysicsService assumes the FingerTipKinematicBodyPrefab has a Rigidbody component.");
                UnityEngine.Object.Destroy(currentGameObject);
                return(false);
            }

            if (!rigidbody.isKinematic)
            {
                Debug.LogWarning("The HandPhysicsService FingerTipKinematicBodyPrefab rigidbody should be marked as kinematic, making kinematic.");
                rigidbody.isKinematic = true;
            }

            jointKinematicBody = currentJoint;
            return(true);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Update the hand data from the device.
        /// </summary>
        /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform.</param>
        private void UpdateHandData(InteractionSourceState interactionSourceState)
        {
#if WINDOWS_UWP || DOTNETWINRT_PRESENT
            // Articulated hand support is only present in the 18362 version and beyond Windows
            // SDK (which contains the V8 drop of the Universal API Contract). In particular,
            // the HandPose related APIs are only present on this version and above.
            if (!articulatedHandApiAvailable)
            {
                return;
            }

            PerceptionTimestamp perceptionTimestamp = PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now);
            IReadOnlyList <SpatialInteractionSourceState> sources = SpatialInteractionManager?.GetDetectedSourcesAtTimestamp(perceptionTimestamp);
            foreach (SpatialInteractionSourceState sourceState in sources)
            {
                if (sourceState.Source.Id.Equals(interactionSourceState.source.id))
                {
                    HandPose handPose = sourceState.TryGetHandPose();

#if WINDOWS_UWP
                    if (CoreServices.InputSystem.InputSystemProfile.HandTrackingProfile.EnableHandMeshVisualization)
                    {
                        // Accessing the hand mesh data involves copying quite a bit of data, so only do it if application requests it.
                        if (handMeshObserver == null && !hasRequestedHandMeshObserver)
                        {
                            SetHandMeshObserver(sourceState);
                            hasRequestedHandMeshObserver = true;
                        }

                        if (handMeshObserver != null && handMeshTriangleIndices == null)
                        {
                            uint     indexCount = handMeshObserver.TriangleIndexCount;
                            ushort[] indices    = new ushort[indexCount];
                            handMeshObserver.GetTriangleIndices(indices);
                            handMeshTriangleIndices = new int[indexCount];
                            Array.Copy(indices, handMeshTriangleIndices, (int)handMeshObserver.TriangleIndexCount);

                            // Compute neutral pose
                            Vector3[]           neutralPoseVertices = new Vector3[handMeshObserver.VertexCount];
                            HandPose            neutralPose         = handMeshObserver.NeutralPose;
                            var                 vertexAndNormals    = new HandMeshVertex[handMeshObserver.VertexCount];
                            HandMeshVertexState handMeshVertexState = handMeshObserver.GetVertexStateForPose(neutralPose);
                            handMeshVertexState.GetVertices(vertexAndNormals);

                            for (int i = 0; i < handMeshObserver.VertexCount; i++)
                            {
                                neutralPoseVertices[i] = WindowsMixedRealityUtilities.SystemVector3ToUnity(vertexAndNormals[i].Position);
                            }

                            // Compute UV mapping
                            InitializeUVs(neutralPoseVertices);
                        }

                        if (handPose != null && handMeshObserver != null && handMeshTriangleIndices != null)
                        {
                            var vertexAndNormals    = new HandMeshVertex[handMeshObserver.VertexCount];
                            var handMeshVertexState = handMeshObserver.GetVertexStateForPose(handPose);
                            handMeshVertexState.GetVertices(vertexAndNormals);

                            var meshTransform = handMeshVertexState.CoordinateSystem.TryGetTransformTo(WindowsMixedRealityUtilities.SpatialCoordinateSystem);
                            if (meshTransform.HasValue)
                            {
                                System.Numerics.Vector3    scale;
                                System.Numerics.Quaternion rotation;
                                System.Numerics.Vector3    translation;
                                System.Numerics.Matrix4x4.Decompose(meshTransform.Value, out scale, out rotation, out translation);

                                var handMeshVertices = new Vector3[handMeshObserver.VertexCount];
                                var handMeshNormals  = new Vector3[handMeshObserver.VertexCount];

                                for (int i = 0; i < handMeshObserver.VertexCount; i++)
                                {
                                    handMeshVertices[i] = WindowsMixedRealityUtilities.SystemVector3ToUnity(vertexAndNormals[i].Position);
                                    handMeshNormals[i]  = WindowsMixedRealityUtilities.SystemVector3ToUnity(vertexAndNormals[i].Normal);
                                }

                                /// Hands should follow the Playspace to accommodate teleporting, so fold in the Playspace transform.
                                Vector3 unityPosition = WindowsMixedRealityUtilities.SystemVector3ToUnity(translation);
                                unityPosition = MixedRealityPlayspace.TransformPoint(unityPosition);
                                Quaternion unityRotation = WindowsMixedRealityUtilities.SystemQuaternionToUnity(rotation);
                                unityRotation = MixedRealityPlayspace.Rotation * unityRotation;

                                HandMeshInfo handMeshInfo = new HandMeshInfo
                                {
                                    vertices  = handMeshVertices,
                                    normals   = handMeshNormals,
                                    triangles = handMeshTriangleIndices,
                                    uvs       = handMeshUVs,
                                    position  = unityPosition,
                                    rotation  = unityRotation
                                };

                                CoreServices.InputSystem?.RaiseHandMeshUpdated(InputSource, ControllerHandedness, handMeshInfo);
                            }
                        }
                    }
                    else
                    {
                        // if hand mesh visualization is disabled make sure to destroy our hand mesh observer if it has already been created
                        if (handMeshObserver != null)
                        {
                            // notify that hand mesh has been updated (cleared)
                            HandMeshInfo handMeshInfo = new HandMeshInfo();
                            CoreServices.InputSystem?.RaiseHandMeshUpdated(InputSource, ControllerHandedness, handMeshInfo);
                            hasRequestedHandMeshObserver = false;
                            handMeshObserver             = null;
                        }
                    }
#endif // WINDOWS_UWP

                    if (handPose != null && handPose.TryGetJoints(WindowsMixedRealityUtilities.SpatialCoordinateSystem, jointIndices, jointPoses))
                    {
                        for (int i = 0; i < jointPoses.Length; i++)
                        {
                            unityJointOrientations[i] = WindowsMixedRealityUtilities.SystemQuaternionToUnity(jointPoses[i].Orientation);
                            unityJointPositions[i]    = WindowsMixedRealityUtilities.SystemVector3ToUnity(jointPoses[i].Position);

                            // We want the controller to follow the Playspace, so fold in the playspace transform here to
                            // put the controller pose into world space.
                            unityJointPositions[i]    = MixedRealityPlayspace.TransformPoint(unityJointPositions[i]);
                            unityJointOrientations[i] = MixedRealityPlayspace.Rotation * unityJointOrientations[i];

                            if (jointIndices[i] == HandJointKind.IndexTip)
                            {
                                lastIndexTipRadius = jointPoses[i].Radius;
                            }

                            TrackedHandJoint handJoint = ConvertHandJointKindToTrackedHandJoint(jointIndices[i]);

                            if (!unityJointPoses.ContainsKey(handJoint))
                            {
                                unityJointPoses.Add(handJoint, new MixedRealityPose(unityJointPositions[i], unityJointOrientations[i]));
                            }
                            else
                            {
                                unityJointPoses[handJoint] = new MixedRealityPose(unityJointPositions[i], unityJointOrientations[i]);
                            }
                        }
                        CoreServices.InputSystem?.RaiseHandJointsUpdated(InputSource, ControllerHandedness, unityJointPoses);
                    }
                }
            }
#endif // WINDOWS_UWP || DOTNETWINRT_PRESENT
        }
Exemplo n.º 11
0
 public ArticulatedHandPoseItem(TrackedHandJoint joint, MixedRealityPose pose)
 {
     this.joint = jointNames[(int)joint];
     this.pose  = pose;
 }
Exemplo n.º 12
0
        void IMixedRealityHandJointHandler.OnHandJointsUpdated(InputEventData <IDictionary <TrackedHandJoint, MixedRealityPose> > eventData)
        {
            using (OnHandJointsUpdatedPerfMarker.Auto())
            {
                if (eventData.InputSource.SourceId != Controller.InputSource.SourceId)
                {
                    return;
                }
                Debug.Assert(eventData.Handedness == Controller.ControllerHandedness);

                IMixedRealityInputSystem        inputSystem         = CoreServices.InputSystem;
                MixedRealityHandTrackingProfile handTrackingProfile = inputSystem?.InputSystemProfile != null ? inputSystem.InputSystemProfile.HandTrackingProfile : null;
                if (handTrackingProfile != null && !handTrackingProfile.EnableHandJointVisualization)
                {
                    // clear existing joint GameObjects / meshes
                    foreach (Transform joint in jointsArray)
                    {
                        if (joint != null)
                        {
                            Destroy(joint.gameObject);
                        }
                    }

                    return;
                }

                // This starts at 1 to skip over TrackedHandJoint.None.
                for (int i = 1; i < ArticulatedHandPose.JointCount; i++)
                {
                    TrackedHandJoint handJoint      = (TrackedHandJoint)i;
                    MixedRealityPose handJointPose  = eventData.InputData[handJoint];
                    Transform        jointTransform = jointsArray[i];

                    if (jointTransform != null)
                    {
                        jointTransform.SetPositionAndRotation(handJointPose.Position, handJointPose.Rotation);
                    }
                    else
                    {
                        GameObject prefab;
                        if (handJoint == TrackedHandJoint.None || handTrackingProfile == null)
                        {
                            // No visible mesh for the "None" joint
                            prefab = null;
                        }
                        else if (handJoint == TrackedHandJoint.Palm)
                        {
                            prefab = handTrackingProfile.PalmJointPrefab;
                        }
                        else if (handJoint == TrackedHandJoint.IndexTip)
                        {
                            prefab = handTrackingProfile.FingerTipPrefab;
                        }
                        else
                        {
                            prefab = handTrackingProfile.JointPrefab;
                        }

                        GameObject jointObject;
                        if (prefab != null)
                        {
                            jointObject = Instantiate(prefab);
                        }
                        else
                        {
                            jointObject = new GameObject();
                        }

                        jointObject.name = handJoint.ToString() + " Proxy Transform";
                        jointObject.transform.SetPositionAndRotation(handJointPose.Position, handJointPose.Rotation);
                        jointObject.transform.parent = transform;

                        jointsArray[i] = jointObject.transform;
                    }
                }
            }
        }
        protected virtual bool UpdateHandJoints()
        {
            using (UpdateHandJointsPerfMarker.Auto())
            {
                if (!handJointsUpdated || MixedRealityHand.IsNull())
                {
                    return(false);
                }

                IMixedRealityInputSystem        inputSystem         = CoreServices.InputSystem;
                MixedRealityHandTrackingProfile handTrackingProfile = inputSystem?.InputSystemProfile != null ? inputSystem.InputSystemProfile.HandTrackingProfile : null;
                if (handTrackingProfile != null && !handTrackingProfile.EnableHandJointVisualization)
                {
                    // clear existing joint GameObjects / meshes
                    foreach (Transform joint in JointsArray)
                    {
                        if (joint != null)
                        {
                            Destroy(joint.gameObject);
                        }
                    }

                    JointsArray = System.Array.Empty <Transform>();

                    // Even though the base class isn't handling joint visualization, we still received new joints.
                    // Return true here in case any derived classes want to update.
                    return(true);
                }

                if (JointsArray.Length != ArticulatedHandPose.JointCount)
                {
                    JointsArray = new Transform[ArticulatedHandPose.JointCount];
                }

                // This starts at 1 to skip over TrackedHandJoint.None.
                for (int i = 1; i < ArticulatedHandPose.JointCount; i++)
                {
                    TrackedHandJoint handJoint = (TrackedHandJoint)i;

                    // Skip this hand joint if the event data doesn't have an entry for it
                    if (!MixedRealityHand.TryGetJoint(handJoint, out MixedRealityPose handJointPose))
                    {
                        continue;
                    }

                    Transform jointTransform = JointsArray[i];
                    if (jointTransform != null)
                    {
                        jointTransform.SetPositionAndRotation(handJointPose.Position, handJointPose.Rotation);
                    }
                    else
                    {
                        GameObject prefab;
                        if (handJoint == TrackedHandJoint.None || handTrackingProfile == null)
                        {
                            // No visible mesh for the "None" joint
                            prefab = null;
                        }
                        else if (handJoint == TrackedHandJoint.Palm)
                        {
                            prefab = handTrackingProfile.PalmJointPrefab;
                        }
                        else if (handJoint == TrackedHandJoint.IndexTip)
                        {
                            prefab = handTrackingProfile.FingerTipPrefab;
                        }
                        else
                        {
                            prefab = handTrackingProfile.JointPrefab;
                        }

                        GameObject jointObject;
                        if (prefab != null)
                        {
                            jointObject = Instantiate(prefab);
                        }
                        else
                        {
                            jointObject = new GameObject();
                        }

                        jointObject.name = handJoint.ToString() + " Proxy Transform";
                        jointObject.transform.SetPositionAndRotation(handJointPose.Position, handJointPose.Rotation);
                        jointObject.transform.parent = transform;

                        JointsArray[i] = jointObject.transform;
                    }
                }

                handJointsUpdated = false;
                return(true);
            }
        }
Exemplo n.º 14
0
 /// <summary>
 /// Constructs a new joint record.
 /// </summary>
 /// <param name="joint">The joint that was recorded.</param>
 /// <param name="pose">The joint pose that was recorded.</param>
 public RecordedHandJoint(TrackedHandJoint joint, MixedRealityPose pose)
 {
     this.joint = joint;
     this.pose  = pose;
 }
Exemplo n.º 15
0
 public abstract bool TryGetJoint(TrackedHandJoint joint, out MixedRealityPose pose);
Exemplo n.º 16
0
 /// <inheritdoc/>
 public override bool TryGetJoint(TrackedHandJoint joint, out MixedRealityPose pose)
 {
     return(jointPoses.TryGetValue(joint, out pose));
 }
Exemplo n.º 17
0
 /// <summary>
 /// Tries to get the pose of the requested joint for the first controller with the specified handedness.
 /// </summary>
 /// <param name="joint">The requested joint</param>
 /// <param name="handedness">The specific hand of interest. This should be either Handedness.Left or Handedness.Right</param>
 /// <param name="pose">The output pose data</param>
 public static bool TryGetJointPose(TrackedHandJoint joint, Handedness handedness, out MixedRealityPose pose)
 {
     return(TryGetJointPose <IMixedRealityHand>(joint, handedness, out pose));
 }
 /// <inheritdoc/>
 public bool TryGetJoint(TrackedHandJoint joint, out MixedRealityPose pose) => unityJointPoses.TryGetValue(joint, out pose);
Exemplo n.º 19
0
 private void GetJointPosition(Vector3[] positions, TrackedHandJoint jointId, Handedness handedness)
 {
     HandJointUtils.TryGetJointPose(jointId, handedness, out MixedRealityPose joint);
     positions[(int)jointId] = joint.Position;
 }