i
i
i
i
i
i
i
i
17
Programming
Input and
Force
Feedback
So far in Part II, everything that we have discussed has essentially been asso-
ciated with the sense of sight. But, whilst it is probably true that the visual
element is the most important component of any VR system, without the
ability to interact with the virtual elements, the experience and sense of re-
ality is diminished. We have seen in Section 4.2 that input to a VR system
can come from a whole range of devices, not just the keyboard or the mouse.
These nonstandard input devices are now indispensable components of any
VR system. However, even equipping our VR systems with devices such as
joysticks, two-handed game consoles or custom hardware such as automobile
steering consoles, we dont come close to simulating real-world interaction.
To be really realistic, our devices need to kick back; they need to resist when
we push them and ideally stimulate our sense of touch and feeling. Again,
looking back at Section 4.2, we saw that haptic devices can provide variable
resistance when you try to push something and force feedback when it tries
to push you, thus mediating our sense of touch within the VR.
In this chapter, we will look at how the concepts of nonstandard input,
custom input and haptics can be driven in practice from a VR application
program. Unfortunately for VR system designers on a budget, it is difficult to
obtain any devices that, for touch and feel, come close to proving the equiv-
477
i
i
i
i
i
i
i
i
478 17. Programming Input and Force Feedback
alent of the fabulously realistic visuals that even a modestly priced graphics
adapter can deliver. But in Section 17.5, we will offer some ideas as to how
you can, with a modest degree of electronic circuit design skills, start some
custom interactive experiments of your own.
From the software developer’s perspective, there are four strategies open
to us so that we can use other forms of input apart from the basic keyboard
and mouse. These are:
1. DirectX, which was previously introduced in the context of real-time
3D graphics and interactive multimedia. Another component of the
DirectX system, DirectInput, has been designed to meet the need that
we seek to address in this chapter. We will look at how it works in
Section 17.1.
2. Use a proprietary software development kit provided by the manufac-
turer of consoles and haptic devices. We shall comment specifically on
one these in Section 17.3.1 because it attempts to do for haptics what
OpenGL has done for graphics.
3. There is a class of software called middleware that delivers system in-
dependence by acting as a link between the hardware devices and the
application software. The middleware software often follows a client-
server model in which a server program communicates with the input
or sensing hardware, formats the data into a device-independent struc-
ture and sends it to a client program. The client program receives the
data, possibly from several servers, and presents it to the VR appli-
cation, again in a device-independent manner. Often the servers run
on independent host computers that are dedicated to data acquisition
from a single device. Communication between client and server is usu-
ally done via a local area network. We explore middleware in a little
more detail in Section 17.4.
4. Design your own custom interface and build your own hardware. This
is not as crazy as it seems, because haptics and force feedback are still
the subject of active R&D and there are no absolutes or universally
agreed standards. We shall look at an outline of how you might do this
and provide a simple but versatile software interface for custom input
devices in Section 17.5.
We begin this chapter by describing the most familiar way (on a Windows
PC) in which to program multi-faceted input and force feedback devices; that
is, using DirectInput.
i
i
i
i
i
i
i
i
17.1. DirectInput 479
17.1 DirectInput
DirectInput is part of DirectX and it has been stable since the release of Di-
rectX 8. It uses the same programming paradigm as the other components of
DirectX; that is:
Methods of COM interfaces provide the connection between
application programs and the hardware drivers. An application
program enumerates the attached input devices and selects the
ones it wants to use. It determines the capabilities of the de-
vices. It configures the devices by sending them parameters, and
it reads the current state of a device (such as joystick button
presses or handle orientation) by again calling an appropriate in-
terface method.
DirectInput not only provides comprehensive interfaces for acquiring data
from most types of input devices, it also has interfaces and methods for send-
ing feedback information to the devices, to wrestle the user to the ground or
give him the sensation of stroking the cat. We will give an example of using
DirectInput to send force feedback in Section 17.2, but first we start with an
example program to illustrate how two joystick devices might be used in a VR
application requiring two-handed input. Since DirectInput supports a wide
array of input devices, one could easily adapt the example to work with two
mice or two steering-wheel consoles.
DirectInput follows the philosophy of running the data acquisition pro-
cess in a separate thread. Therefore, an application program is able to obtain
the state and settings of any input device, for example the mouses position,
by polling for them through a COM interface method.
In the remainder of this section, we will develop a small collection of
functions that can be used by any application program to enable it to acquire
(x, y, z) coordinate input from one, two or more joystick devices. The ex-
ample will offer a set of global variables to hold input device data, and three
functions to:
1. initialize DirectInput and find joysticks with
InitDirectInput(..);
2. release the DirectInput COM interfaces with
FreeDirectInput(..);
3. update the global variables by polling for the input devices position
and button state with
UpdateInputState(..).
All the DirectInput code will be placed in a separate file for convenience.
i
i
i
i
i
i
i
i
480 17. Programming Input and Force Feedback
A minimal joystick device will have two position movements, left to right
(along an x-axis) and front to back (along a y-axis), along with a number of
buttons. A different device may have a twist grip or slider to represent a z-axis
rotation. It is the function of the DirectInput initialization stage to determine
the capability of, and number of, installed joystick-like devices. Other devices,
mice for example or mice with force feedback, should also be identified and
configured. It is one of the tasks of a well designed DirectInput application
program to be able to adapt to different levels of hardware capability.
17.1.1 Configuring DirectInput and Finding Devices
Since DirectInput uses COM to access its API, a DirectInput device object
is created in a similar way to the Direct3D device. In the function
InitDirectInput(..), the main task is to enumerate all joystick devices
and pick the first two for use b y the application. Device enumeration is stan-
dard practice in DirectX. It allows an application program to find out the
capabilities of peripheral devices. In the case of joystick devices, enumera-
tion is also used to provide information about the ax es that it supports; for
example, moving the stick to the left and right may be returned as an x-axis.
Listing 17.1 sets up the framework for device initialization and enumeration,
and Listing 17.2 tells DirectInput the name of the callback functions which
permit the application to select the most appropriate joystick, or in this case
the first two found.
During axis enumeration, the callback function takes the opportunity
to set the range and dead zone. If, for example, we set the x-axis range to
// minimim header files for direct input
#include <windows.h>
#include <dinput.h>
// pointer to the DirectInput Object
LPDIRECTINPUT8 g_pDI = NULL;
// Pointer to the first two joystick devices
LPDIRECTINPUTDEVICE8 g_pJoystick1 = NULL;
// found attached to the machine.
LPDIRECTINPUTDEVICE8 g_pJoystick2 = NULL;
Listing 17.1. The DirectInput COM interface is created, all attached joysticks are
found and their properties determin ed.
i
i
i
i
i
i
i
i
17.1. DirectInput 481
[1000, 1000] then when our program asks for the current x-coordinate,
DirectInput will report a value of 1000 if it is fully pushed over to the left.
A dead zone value of 100 tells DirectX to report as zero any axis position de-
termined to be less than 100. In theory, a dead zone should be unnecessary,
but in practice the imperfections in cheap hardware can mean that the spring
HRESULT InitDirectInput(HWND hDlg, HINSTANCE g_hInst){
HRESULT hr;
// create the DirectInput object and obtain pointer to its interfaces
hr = DirectInput8Create(g_hInst,DIRECTINPUT_VERSION,IID_IDirectInput8,
(VOID
**
)&g_pDI,NULL);
// Check all the joystick devices attached to the PC
// a process called enumeration
// we provide the callback function which assigns the global pointers.
hr = g_pDI->EnumDevices(DI8DEVCLASS_GAMECTRL,EnumJoysticksCallback,
NULL,DIEDFL_ATTACHEDONLY);
// do the things specifically for joystick 1 - set its data format to
// the default
hr = g_pJoystick1->SetDataFormat(&c_dfDIJoystick2);
// our application program will have exclusive access
// when it is running in the foreground
hr = g_pJoystick1->SetCooperativeLevel(hDlg,DISCL_EXCLUSIVE|DISCL_FOREGROUND);
// enumerate all axes for Joystick 1
g_pJoystick1->EnumObjects(EnumAxesCallback,(VOID
*
)g_pJoystick1,DIDFT_AXIS);
// enumerate to get any sliders
g_pJoystick1->EnumObjects(EnumObjectsCallback,(VOID
*
)g_pJoystick1,DIDFT_ALL);
// repeat for second joystick
if( NULL != g_pJoystick2 ){ ... //
}
return S_OK;
}
HRESULT FreeDirectInput(){ // release the interfaces for the joysticks
if( NULL != g_pJoystick1 ) {
// before releasing the joystick tell DI we don’t neet it.
g_pJoystick1->Unacquire();
g_pJoystick1->Release();
g_pJoystick1 = NULL;
}
// repeat here for second joystick ..
..//
if( g_pDI ){ g_pDI->Release(); g_pDI = NULL; } // relase the DI interface
return S_OK;
}
Listing 17.1. (continued).
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.125.108