Haptic events are received via IVRServerDriverHost::PollNextEvent with the event type vr::EVREventType::VREvent_Input_HapticVibration.
To correctly route the event, the driver must check the componentHandle property against the handle created via IVRDriverInput::CreateHapticComponent.
Haptic Event Properties
fDurationSeconds: The duration of the event in seconds.fFrequency: The frequency in Hz. Lower frequencies result in a "rumble" feel.fAmplitude: The intensity of the vibration (0 to 1).
Implementation Guidelines
Drivers should apply the following constraints:
- Amplitude: Clamp to the range
[0, 1]. If $\le 0$, do not trigger haptics. - Duration: Clamp to
[0, 10] seconds. If fDurationSeconds is 0, the driver should trigger a single pulse. - Frequency: Clamp to a minimum of
1000000.f / 65535.f and a maximum of 1000000.f / 300.f.
Pulse Calculation Logic
To convert a continuous haptic event into discrete pulses:
- Pulse Period:
1.f / fFrequency (in seconds). - Pulse Count:
fDurationSeconds * fFrequency. If fDurationSeconds is 0, the count is 1. - Pulse Duration: Interpolate
fAmplitude between a set minimum pulse duration and a maximum (which should be no more than half the total pulse duration or a set maximum, whichever is less).
switch (vrEvent.eventType) {
case vr::VREvent_Input_HapticVibration: {
if (vrEvent.data.hapticVibration.componentHandle == m_compMyHaptic) {
// This is where you would send a signal to your hardware to trigger actual haptic feedback
const float pulse_period = 1.f / vrEvent.data.hapticVibration.fFrequency
const float frequency = std::clamp(1000000.f / 65535.f, 1000000.f / 300.f, pulse_period);
const float amplitude = std::clamp(0.f, 1.f, vrEvent.data.hapticVibration.fAmplitude);
const float duration = std::clamp(0.f, 10.f, vrEvent.data.hapticVibration.fDurationSeconds);
if(duration == 0.f) {
// Trigger a single pulse of the haptic component
} else {
const float pulse_count = fDurationSeconds * fFrequency;
const float pulse_duration = Lerp(my_minimum_duration, my_maximum_duration, amplitude);
const float pulse_interval = pulse_period - pulse_duration;
}
}
}
break;
}