/// <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; } } } }
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; } } } }
/// <summary> /// Get the game object that represents the joint transforms /// <param name="joint">Joint to fetch</param> /// </summary> public GameObject GetJointObject(TrackedHandJoint joint) { GameObject retVal = null; int index = (int)joint; if ((index >= 0 && index < jointObjects.Length)) { retVal = jointObjects[index]; } if (retVal == null) { Debug.Log("Failed to get Joint Object" + " " + Hand.ToString() + " " + joint.ToString()); } return(retVal); }
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); } }