351
for the noisiest inputs generated by an undisturbed control, but small enough
not to interfere with the player’s sense of the HID’s responsiveness.
8.5.3. Analog Signal Filtering
Signal noise is a problem even when the controls are not within their dead
zones. This noise can sometimes cause the in-game behaviors controlled by
the HID to appear jerky or unnatural. For this reason, many games fi lter the
raw inputs coming from the HID. A noise signal is usually of a high-frequency,
relative to the signal produced by the human player. Therefore, one solution
is to pass the raw input data through a simple low-pass fi lter , prior to it being
used by the game.
A discrete fi rst-order low-pass fi lter can be implemented by combining
the current unfi ltered input value with last frame’s fi ltered input. If we denote
the sequence of unfi ltered inputs by the time-varying function u(t) and the
fi ltered inputs by f(t), where t denotes time, then we can write
(8.1)
where the parameter a is determined by the frame duration Δt and a fi ltering
constant RC (which is just the product of the resistance and the capacitance in
a traditional analog RC low-pass fi lter circuit):
(8.2)
This can be implemented trivially in C or C++ as follows, where it is assumed
the calling code will keep track of last frame’s fi ltered input for use on the
subsequent frame. For more information, see htt p://en.wikipedia.org/wiki/
Low-pass_fi lter.
F32 lowPassFilter(F32 unfilteredInput,
F32 lastFramesFilteredInput,
F32 rc, F32 dt)
{
F32 a = dt / (rc + dt);
return (1 – a) * lastFramesFilteredInput
+ a * unfilteredInput;
}
Another way to fi lter HID input data is to calculate a simple moving av-
erage. For example, if we wish to average the input data over a 3/30 second
(3 frame) interval, we simply store the raw input values in a 3-element circular
8.5. Game Engine HID Systems
f() (1t= −aa) (ft−Δ +t) u(),t
a t.
RC t