// Send haptic feedback that matches the selected waveform upon the button being clicked private void SendFeedback_Clicked(object sender, RoutedEventArgs e) { if (hapticsController == null) { return; } // Get feedback based on the user's selected waveform currentFeedback = GetSelectedFeedbackOrFallback(out string message); // Send the current feedback to the PenDevice's SimpleHapticsController. // Once sent, unlike inking feedback, this feedback will be played immediately. // Also, check to see if the current PenDevice's SimpleHapticsController supports // setting the intensity value of the tactile feedback. If so, set it based // on the slider. If not, send the feedback without custom intensity. if (hapticsController.IsIntensitySupported) { hapticsController.SendHapticFeedback(currentFeedback, intensitySlider.Value / 100); message += "\nIntensity set to " + intensitySlider.Value + "%"; } else { hapticsController.SendHapticFeedback(currentFeedback); message += "\nSetting intensity is not supported by this pen"; } statusText.Text = message; }
// The PointerEnter event will get fired as soon as Pointer input is received. // This event handler implementation will query the device providing input to see if it's a pen and // then check to see the pen supports tactile feedback and, if so, configure the PenDevice // to send the appropriate tactile signal based on what is selected in the dropdown. private void HapticCanvas_Entered(object sender, PointerRoutedEventArgs e) { // If the current Pointer device is not a pen, exit if (e.Pointer.PointerDeviceType != PointerDeviceType.Pen) { return; } // Attempt to retrieve the PenDevice from the current PointerId penDevice = PenDevice.GetFromPointerId(e.Pointer.PointerId); // If a PenDevice cannot be retrieved based on the PointerId, it does not support // advanced pen features, such as tactile feedback if (penDevice == null) { statusText.Text = "Advanced pen features not supported"; return; } // Check to see if the current PenDevice supports tactile feedback by seeing if it // has a SimpleHapticsController hapticsController = penDevice.SimpleHapticsController; if (hapticsController == null) { statusText.Text = "This pen does not provide tactile feedback"; return; } // Get feedback based on the user's selected waveform currentFeedback = GetSelectedFeedbackOrFallback(out string message); // Send the current feedback to the PenDevice's SimpleHapticsController. // Once sent, inking tactile feedback will be triggered as soon as the pen tip touches // the screen and will be stopped once the pen tip is lifted from the screen. // Also, check to see if the current PenDevice's SimpleHapticsController supports // setting the intensity value of the tactile feedback. If so, set it based // on the slider. If not, send the waveform without custom intensity. if (hapticsController.IsIntensitySupported) { hapticsController.SendHapticFeedback(currentFeedback, intensitySlider.Value / 100); message += "\nIntensity set to " + intensitySlider.Value + "%"; } else { hapticsController.SendHapticFeedback(currentFeedback); message += "\nSetting intensity is not supported by this pen"; } statusText.Text = message; }
// The PointerEnter event will get fired as soon as Pointer input is received in the movableRect. // This event handler implementation will query the device providing input to see if it's a pen and // then check to see the pen supports tactile feedback and, if so, configure the PenDevice // to send the InkContinuous tactile signal. private void MovableRect_Entered(object sender, PointerRoutedEventArgs e) { // If the current Pointer device is not a pen, exit if (e.Pointer.PointerDeviceType != PointerDeviceType.Pen) { return; } // Attempt to retrieve the PenDevice from the current PointerId penDevice = PenDevice.GetFromPointerId(e.Pointer.PointerId); // If a PenDevice cannot be retrieved based on the PointerId, it does not support // advanced pen features, such as tactile feedback if (penDevice == null) { statusText.Text = "Advanced pen features not supported"; return; } // Check to see if the current PenDevice supports tactile feedback by seeing if it // has a SimpleHapticsController hapticsController = penDevice.SimpleHapticsController; if (hapticsController == null) { statusText.Text = "This pen does not provide tactile feedback"; return; } // Send the InkContinuous waveform to the PenDevice's SimpleHapticsController. // Once sent, inking continuous tactile feedback will be triggered as soon as the pen tip touches // the screen and will be stopped once the pen tip is lifted from the screen. // Also, check to see if the current PenDevice's SimpleHapticsController supports // setting the intensity value of the tactile feedback. If so, set it to 0.75. // If not, send the waveform with the default intensity. foreach (var waveform in hapticsController.SupportedFeedback) { if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.InkContinuous) { if (hapticsController.IsIntensitySupported) { hapticsController.SendHapticFeedback(waveform, 0.75); } else { hapticsController.SendHapticFeedback(waveform); } } } }
/// <summary> /// Start haptic feedback on the interaction source with the specified intensity and continue for the specified amount of time. /// </summary> /// <param name="interactionSource">The source to start haptics on.</param> /// <param name="intensity">The strength of the haptic feedback from 0.0 (no haptics) to 1.0 (maximum strength).</param> /// <param name="durationInSeconds">The time period expressed in seconds.</param> public static bool StartHaptics(this InteractionSource interactionSource, float intensity, float durationInSeconds) { if (!IsHapticsAvailable) { return(false); } #if WINDOWS_UWP || DOTNETWINRT_PRESENT SimpleHapticsController simpleHapticsController = interactionSource.GetSpatialInteractionSource()?.Controller.SimpleHapticsController; foreach (SimpleHapticsControllerFeedback hapticsFeedback in simpleHapticsController?.SupportedFeedback) { if (hapticsFeedback.Waveform.Equals(ContinuousBuzzWaveform)) { if (UnityEngine.Mathf.Approximately(durationInSeconds, float.MaxValue)) { simpleHapticsController.SendHapticFeedback(hapticsFeedback, intensity); } else { simpleHapticsController.SendHapticFeedbackForDuration(hapticsFeedback, intensity, TimeSpan.FromSeconds(durationInSeconds)); } return(true); } } #endif // WINDOWS_UWP || DOTNETWINRT_PRESENT return(false); }
public static void StartHaptics(this InteractionSource interactionSource, float intensity, float durationInSeconds) { #if !UNITY_EDITOR UnityEngine.WSA.Application.InvokeOnUIThread(() => { IReadOnlyList <SpatialInteractionSourceState> sources = SpatialInteractionManager.GetForCurrentView().GetDetectedSourcesAtTimestamp(PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now)); foreach (SpatialInteractionSourceState sourceState in sources) { if (sourceState.Source.Id.Equals(interactionSource.id)) { SimpleHapticsController simpleHapticsController = sourceState.Source.Controller.SimpleHapticsController; foreach (SimpleHapticsControllerFeedback hapticsFeedback in simpleHapticsController.SupportedFeedback) { if (hapticsFeedback.Waveform.Equals(ContinuousBuzzWaveform)) { if (durationInSeconds.Equals(float.MaxValue)) { simpleHapticsController.SendHapticFeedback(hapticsFeedback, intensity); } else { simpleHapticsController.SendHapticFeedbackForDuration(hapticsFeedback, intensity, TimeSpan.FromSeconds(durationInSeconds)); } return; } } } } }, true); #endif }
/// <summary> /// Play a canned haptic pattern. /// </summary> /// <param name="expr"></param> public override void Play(HapticExpression expr) { if (controller != null) { if (expr == HapticExpression.Click) { controller.SendHapticFeedback(click); } else if (expr == HapticExpression.Press) { controller.SendHapticFeedback(press); } else if (expr == HapticExpression.Release) { controller.SendHapticFeedback(release); } else { base.Play(expr); } } }
private void SendHapticFeedback(SimpleHapticsController hapticController) { var feedbacks = hapticController.SupportedFeedback; foreach (SimpleHapticsControllerFeedback feedback in feedbacks) { if (feedback.Waveform == KnownSimpleHapticsControllerWaveforms.Click) { hapticController.SendHapticFeedback(feedback); return; } } }
// Update the visibilty or position of the previewRect based on the location // of the movableRect. // If the previewRect is snapped to a given gridline for the first time, // play the Click tactile signal. private void UpdatePreviewRect() { if (IsInSnapRange()) { previewRect.Visibility = Visibility.Visible; Point newPreviewTopLeft = GetSnappedPoint(); // Check to see if this is the first time that the previewRect is in range of a given gridline // and send the Click tactile signal if so bool sendHaptics = true; if ((previewTopLeft.X == newPreviewTopLeft.X && previewTopLeft.Y == newPreviewTopLeft.Y) || (previewTopLeft.X == newPreviewTopLeft.X && newPreviewTopLeft.Y == topLeft.Y) || (previewTopLeft.Y == newPreviewTopLeft.Y && newPreviewTopLeft.X == topLeft.X)) { sendHaptics = false; } if (previewTopLeft.X != newPreviewTopLeft.X || previewTopLeft.Y != newPreviewTopLeft.Y) { previewTopLeft = newPreviewTopLeft; previewRect.Translation = new Vector3((float)previewTopLeft.X, (float)previewTopLeft.Y, 0); if (hapticsController != null && sendHaptics) { foreach (var waveform in hapticsController.SupportedFeedback) { if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.Click) { hapticsController.SendHapticFeedback(waveform); } } } } } else { previewRect.Visibility = Visibility.Collapsed; previewTopLeft = new Point(-1, -1); } }