public override void HapticPulse(byte[] samples) { #if OVR OVRHapticsClip clip = new OVRHapticsClip(samples, samples.Length); OVRHaptics.OVRHapticsChannel channel = hand == XRHand.Left ? OVRHaptics.LeftChannel : OVRHaptics.RightChannel; channel.Mix(clip); #endif }
void RumbleSimple(OVRHaptics.OVRHapticsChannel channel) { if (channel == null) { return; } if (RumbleSimpleClip != null) { channel.Mix(RumbleSimpleClip); } }
public override void HapticPulse(AnimationCurve curve, float time) { #if OVR int count = (int)(time * 320); //Touch controllers sample at 320Hz. OVRHapticsClip clip = new OVRHapticsClip(count); for (int i = 0; i < count; i++) { float value = curve.Evaluate(i / (float)count) * 255f; value = Mathf.Clamp(value, 0, 255); clip.Samples[i] = (byte)(int)value; } clip = new OVRHapticsClip(clip.Samples, clip.Samples.Length); OVRHaptics.OVRHapticsChannel channel = hand == XRHand.Left ? OVRHaptics.LeftChannel : OVRHaptics.RightChannel; channel.Mix(clip); #endif }
/// <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 }
private void TriggerHapticFeedback(XRNode node, OVRHapticsClip clip) { OVRHaptics.OVRHapticsChannel channel = (node != XRNode.LeftHand) ? OVRHaptics.RightChannel : OVRHaptics.LeftChannel; channel.Mix(clip); }