public void OnPositionInputChanged(InputEventData <Vector2> eventData)
 {
 }
 public void OnInputPressed(InputEventData <float> eventData)
 {
 }
        /// <inheritdoc/>
        void IMixedRealityHandJointHandler.OnHandJointsUpdated(InputEventData <IDictionary <TrackedHandJoint, MixedRealityPose> > eventData)
        {
            var inputSystem = CoreServices.InputSystem;

            if (eventData.InputSource.SourceId != Controller.InputSource.SourceId)
            {
                return;
            }
            Debug.Assert(eventData.Handedness == Controller.ControllerHandedness);

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

            if (handTrackingProfile != null && handTrackingProfile.EnableHandJointVisualization)
            {
                foreach (TrackedHandJoint handJoint in eventData.InputData.Keys)
                {
                    Transform skeletonJointTransform;
                    if (skeletonJoints.TryGetValue(handJoint, out skeletonJointTransform))
                    {
                        skeletonJointTransform.position = eventData.InputData[handJoint].Position;
                        skeletonJointTransform.rotation = eventData.InputData[handJoint].Rotation;
                    }
                    else
                    {
                        GameObject prefab;
                        if (handJoint == TrackedHandJoint.None)
                        {
                            // No visible mesh for the "None" joint
                            prefab = null;
                        }
                        else 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.position = eventData.InputData[handJoint].Position;
                        jointObject.transform.rotation = eventData.InputData[handJoint].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
                Transform jointTransform;
                // Apply updated TrackedHandJoint pose data to the assigned transforms
                foreach (TrackedHandJoint handJoint in eventData.InputData.Keys)
                {
                    if (joints.TryGetValue(handJoint, out jointTransform))
                    {
                        if (jointTransform != null)
                        {
                            if (handJoint == TrackedHandJoint.Palm)
                            {
                                if (ModelPalmAtLeapWrist)
                                {
                                    Palm.position = eventData.InputData[TrackedHandJoint.Wrist].Position;
                                }
                                else
                                {
                                    Palm.position = eventData.InputData[TrackedHandJoint.Palm].Position;
                                }
                                Palm.rotation = eventData.InputData[TrackedHandJoint.Palm].Rotation * userBoneRotation;
                            }
                            else if (handJoint == TrackedHandJoint.Wrist)
                            {
                                if (!ModelPalmAtLeapWrist)
                                {
                                    Wrist.position = eventData.InputData[TrackedHandJoint.Wrist].Position;
                                }
                            }
                            else
                            {
                                // Finger joints
                                jointTransform.rotation = eventData.InputData[handJoint].Rotation * Reorientation();

                                if (DeformPosition)
                                {
                                    jointTransform.position = eventData.InputData[handJoint].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);
                    }
                    else
                    {
                        throw new Exception(String.Format("The property {0} for reacting to pinch strength was not found please provide a valid material property name", pinchStrengthMaterialProperty));
                    }
                }
            }
        }
 /// <summary>
 /// Visualize the movement of a dual axis input on the controller model, if supported
 /// </summary>
 /// <remarks>
 /// Reserved for future implementation
 /// </remarks>
 public override void OnInputChanged(InputEventData <Vector2> eventData)
 {
     base.OnInputChanged(eventData);
     // TODO Visualize dual axis controls
 }
 /// <summary>
 /// Visualize single axis controls on the controller model, if supported
 /// </summary>
 /// <remarks>
 /// Reserved for future implementation
 /// </remarks>
 public override void OnInputChanged(InputEventData <float> eventData)
 {
     base.OnInputChanged(eventData);
     // TODO Visualize single axis controls
 }
 /// <summary>
 /// Visualize digital and single axis controls up state on the controller model, if supported
 /// </summary>
 /// <remarks>
 /// Reserved for future implementation
 /// </remarks>
 public override void OnInputUp(InputEventData eventData)
 {
     base.OnInputUp(eventData);
     // TODO Visualize digital and single axis controls up state
 }