//Internal Clip Player checks to see if it is always preempted is checked; //isLeft Which Controller | clip: The Haptics Clip to Play public void ClipPlayer(bool isLeft, OVRHapticsClip clip) { if (isLeft) { if (AlwaysPreempt) { m_hapticsChannelL.Preempt(clip); } else { m_hapticsChannelL.Queue(clip); } } else { if (AlwaysPreempt) { m_hapticsChannelR.Preempt(clip); } else { m_hapticsChannelR.Queue(clip); } } }
// Send haptic impulse based on intensity and hand options public void Vibrate(EHapticIntensity hapticIntensity, EHapticHand hapticHand) { switch (hapticHand) { case EHapticHand.LeftController: _channel = OVRHaptics.LeftChannel; break; case EHapticHand.RightController: _channel = OVRHaptics.RightChannel; break; case EHapticHand.NoHaptics: break; default: throw new ArgumentOutOfRangeException(nameof(hapticHand), hapticHand, null); } switch (hapticIntensity) { case EHapticIntensity.Light: _channel.Preempt(_clipLight); break; case EHapticIntensity.Medium: _channel.Preempt(_clipMedium); break; case EHapticIntensity.Strong: _channel.Preempt(_clipStrong); break; default: throw new ArgumentOutOfRangeException(nameof(hapticIntensity), hapticIntensity, null); } }
internal override void HapticPulse(Controller ctrl, int durationMicroSec) { /* mapping from durationMicroSec, which is a value up to ~500, down to bytes */ if (haptics_clip == null) { haptics_clip = new OVRHapticsClip(1); } int value = durationMicroSec / 2; if (value > 255) { value = 255; } haptics_clip.Reset(); haptics_clip.WriteSample((byte)value); OVRHaptics.OVRHapticsChannel channel = OVRHaptics.Channels[ctrl.index]; channel.Preempt(haptics_clip); }
public void VibrateLight() { StopAllCoroutines(); channel.Preempt(clipLight); }
/// <summary> /// Pulse haptic feedback /// </summary> /// <param name="node">Node on which to perform the pulse.</param> /// <param name="hapticPulse">Haptic pulse</param> /// <param name="durationMultiplier">(Optional) Multiplier value applied to the hapticPulse duration</param> /// <param name="intensityMultiplier">(Optional) Multiplier value applied to the hapticPulse intensity</param> public void Pulse(Node node, HapticPulse hapticPulse, float durationMultiplier = 1f, float intensityMultiplier = 1f) { // Clip buffer can hold up to 800 milliseconds of samples // At 320Hz, each sample is 3.125f milliseconds if (Mathf.Approximately(m_MasterIntensity, 0)) { return; } #if ENABLE_OVR_INPUT m_GeneratedHapticClip.Reset(); var duration = hapticPulse.duration * durationMultiplier; var intensity = hapticPulse.intensity * intensityMultiplier; var fadeIn = hapticPulse.fadeIn; var fadeOut = hapticPulse.fadeOut; if (duration > MaxDuration) { duration = Mathf.Clamp(duration, 0f, MaxDuration); // Clamp at maximum 800ms for sample buffer if (!m_SampleLengthWarningShown) { Debug.LogWarning("Pulse durations greater than 0.8f are not currently supported"); } m_SampleLengthWarningShown = true; } const int kSampleRateConversion = 490; // Samplerate conversion : 44100/90fps = 490 const int kIntensityIncreaseMultiplier = 255; // Maximum value of 255 for intensity const float kFadeInProportion = 0.25f; var fadeInSampleCount = duration * kSampleRateConversion * kFadeInProportion; var fadeOutSampleCount = fadeInSampleCount * 2; // FadeOut is less apparent than FadeIn unless FadeOut duration is increased duration *= kSampleRateConversion; var durationFadeOutPosition = duration - fadeOutSampleCount; intensity = Mathf.Clamp(Mathf.Clamp01(intensity) * kIntensityIncreaseMultiplier * m_MasterIntensity, 0, kIntensityIncreaseMultiplier); var hapticClipSample = Convert.ToByte(intensity); for (int i = 1; i < duration; ++i) { float sampleShaped = hapticClipSample; if (fadeIn && i < fadeInSampleCount) { sampleShaped = Mathf.Lerp(0, intensity, i / fadeInSampleCount); } else if (fadeOut && i > durationFadeOutPosition) { sampleShaped = Mathf.Lerp(0, intensity, (duration - i) / fadeOutSampleCount); } m_GeneratedHapticClip.WriteSample(Convert.ToByte(sampleShaped)); } const float kMaxSimultaneousClipDuration = 0.25f; var channel = GetTargetChannel(node); if (duration > kMaxSimultaneousClipDuration) { // Prevent multiple long clips from playing back simultaneously // If the new clip has a long duration, stop playback of any existing clips in order to prevent haptic feedback noise if (channel != null) { channel.Preempt(m_GeneratedHapticClip); } else { m_RHapticsChannel.Preempt(m_GeneratedHapticClip); m_LHapticsChannel.Preempt(m_GeneratedHapticClip); } } else { // Allow multiple short clips to play simultaneously if (channel != null) { channel.Mix(m_GeneratedHapticClip); } else { m_RHapticsChannel.Mix(m_GeneratedHapticClip); m_LHapticsChannel.Mix(m_GeneratedHapticClip); } } #endif }