CAP5937 - Realtime Graphics for Simulation and Games

Lecture 9: DirectInput and Beyond

J. Michael Moshell

This lecture is based on two photocopied chapters:  Chapter 14 from "Windows Game Programming for Dummies" and an article on collision detection from Game Developer Magazine.

The DirectInput article describes the usual DirectX 'mess' which consists of two stages:

1) Do a bunch of stuff to set up the interfaces,
2) Gather data from them.

We aren't planning to work through the 'do a bunch of stuff' in detail. Let's just skim it and look for important ideas.

Key ideas to learn about:

- enumerating input devices
- setting cooperation levels
- getting the data


However the chapter doesn't take them in this order. So we'll follow the chapter's order.

Setting Cooperation Levels. The key issue here is how input events are routed. If your application wants to seize total control of a device so that events don't even go to the Windows system, this is how to do it. Such control might be appropriate for a joystick but probably not for the keyboard or mouse. Full-screen game applications don't (under ideal circumstances) need to provide the user with anything more than a known way of exiting the program. But ideal circumstances means that the game never crashes, and since it will be calling Microsoftware such as Direct3D, who can guarantee that?

The book is not very clear about the meanings of the different cooperation levels, except to point out that there are four options, constructed by ORing together one of (DISCL_BACKGROUND and DISCL_FOREGROUND) together with one of (DISCL_EXCLUSIVE) and (DISCL_NONEXCLUSIVE).

The Exclusive flags should, by the logic of the situation, relate to devices with OUTPUT capabilities, because what does it mean to have "exclusive access" to an input device if others can still have non-exclusive access. The only thing I can think of is that it might be possible to need your data from some kind of strobed input device so frequently that you don't want to let other processes even hit on the device, at all. But I don't see evidence of that here.

The Background vs. Foreground seems clearer. If your application is not in the currently active window, then it won't get input from devices whose access is set to Foreground.

Enumerating Input Devices. If we're working with a fixed set of known devices such as mouse and keyboard, your application doesn't require much variability. But if the choices are very large, as they are for joysticks, you may have the unpleasant task of having to respond to special features 'per species' (e. g. how many buttons do they have on them.)

DIJOYSTATE is a very generic joystick that provides a kind of universal data structure including x,y,z, xrotate, yrotate, zrotate, two sliders, four Point of View hat controls (what are those?) and 32 buttons.

But you would still need to be able to get a GUID (Globally Unique Identifier) for each joystick device, so you can bind your data structures to it. You have to provide a callback function which is called by EnumDevices() for each device it finds. You can ask for all devices whose drivers are installed; or just those that are physically attached; or just the force feedback devices. Or, you can OR this last flag in with the others as needed.

The text provides a simplified callback that just grabs the GUID of the first device that's found, and returns the code DIENUM_STOP to stop the enumeration at that point.

Reading the Data

You gotta strobe the device by sending lpdijoy2->Poll() as on page 352.

Then you gotta get the data with GetDeviceState() which returns one of those DIJOYSTATE objects with all the nice fields for x,y,z etc.

Bottom Line. If you want to use DirectInput, you will need to get more extensive docs and examples than this one chapter. But fundamentally it seems straightforward.

--------

Collision Detection

Game Developer, May 99.

The article summarizes basic issues in collision detection, including these:

1) Time Slice Problem. In a time sliced simulation, the collision might occur at time t which is between t1 and t2 the times of two successive frames.

2) Object-to-Object Problem. For n objects there are on the order of n2 possible collisions to check - unless you're clever.

Basic techniques listed include these:

1) Spatial Subdivision - e. g. octrees, uniform grids, etc.

Query 9.1: Explain the basic idea behind an octree, as presented in the lecture on 6 October.

2) Spherical Extents.

Query 9.2: Explain the basic idea between spherical extents. Outline an algorithm for computing a spherical extent for an object defined as a set of polygons which in turn are defined by a list of vertices. Why don't you have to take the square root in the Euclidean distance computation?

Axis-Aligned Bounding Boxes (AABB) stay parallel to world coordinates, and thus have to be recomputed as objects tumble or rescale.

Oriented Bounding Boxes (OBB) create a hierarchy of boxes, each layer of which has more boxes and more accuracy. The box rotates with the object, so that we will ultimately have to do box-to-box collision testing.

Query 9.3: Think through the problems of (a) efficiently representing "square 3d boxes", and (b) testing for collision between two arbitrary such boxes A and B.

I will give you a paper by Gottschalk et al, which is about how to compute the boxes themselves.

BSP Trees are based on a hierarchy of binary (what else could they be?) separating planes, and the use of the plane equation ax + by + cz + d = 0 . It's useful for finding fixed objects ,and thus for world/object collisions  - but doesn't help much with object/object collisions. DOOM uses this technology.

To the syllabus
To lecture 8
To lecture 10