Collision detection and audio

Tags

, , , , , , , , , , , , ,

‘What happens to my crusty shell when I die?’ Arkwood spoke like a child. But he was a woodlouse.

I told him that I did not have time for mortal musing. ‘While you scurry about the walls of your bedroom, I am adding audio to the table.’

I had already created a 3D table in Blender and loaded it into my virtual world. I took care only to load the image for my wood texture once using Assimp and SOIL, though it is used five times (for each of the four legs of the table and its surface). It’s all in my post Loading textures in OpenGL.

Arkwood put the Oculus Rift virtual reality headset over his bug eyes, grasped the Oculus Touch controllers with two of his many leggy arms, and strolled about the table. But there is more to do.

‘First I must add collision detection to the table,’ I said, ‘so that you can not stroll through it.’

That was easy. See my posts 3D collision detection with C++ and Collision detection and animation in C++.

const Vector3f TableMin = { -4.5f, 0.0f, 9.3f };
const Vector3f TableMax = { -1.5f, 1.0f, 10.7f };

We set the ‘box’ space in our virtual world that our table occupies.

if ((Pos.x >= TableMin.x && Pos.x <= TableMax.x) &&
    (Pos.y >= TableMin.y && Pos.y <= TableMax.y) &&
    (Pos.z >= TableMin.z && Pos.z <= TableMax.z)) {
    currentCollision = Table;
    return PrevPos;
}

And check whether we have strolled into the ‘box’ space.

‘But what we really need, Arkwood, is a nice woody sound when we hit the table.’ My chum was not listening. He was on the ceiling, inching towards the light bulb.

In my post Oculus spatializer plugin for FMOD I explain how to pipe 3D audio into the headphones on the Oculus Rift headset.

We set up a sound event in FMOD Studio (I have used the action_large_wood_drop.wav sound from the Oculus Audio Pack):

oculusrift_virtualtable_fmodstudio

Using the Oculus spatializer plugin for FMOD from the Oculus Audio SDK, we can target the FMOD API in our Microsoft Visual Studio C++ code and play our sound event.

bool tableCollision = collisionClient->currentCollision == Table; 

Our previous collision detection posts show how easy it is to figure whether we have hit our table on every render cycle.

But we need to extend our previous audio post to check whether the wood sound is already playing (as we don’t want to play sounds on top of each other).

FMOD_STUDIO_PLAYBACK_STATE * state = new FMOD_STUDIO_PLAYBACK_STATE();

We set up an FMOD playback state pointer.

getPlaybackState(state);

And pass it to the event’s getPlaybackState function.

if (* state == FMOD_STUDIO_PLAYBACK_PLAYING) {
    return true;
}

We can then simply check the state to determine if our sound event is currently playing.

Great. Now that we know how to detect table collision and whether a sound is currently playing, we can play the wood sound when we hit the table. Here’s a video of the 3D audio when we collide with the table:

We tell FMOD our position in the virtual world on every render cycle as the sound is playing, so as to get true 3D audio. If we turn around during repeated collision we can hear the wood sound in our left ear, behind us and then in our right ear. The audio comes from the centre of the table, no matter what side of the table we hit. Actually, we could set the position of the audio to the part of the table we collide against – as an offset of our own position – but for now I will simply set the audio to a fixed position at the centre of the table on application initialization.

One other thing, before we use OpenGL graphics library and the Oculus SDK for Windows to render our room to the Rift headset. We need to tell FMOD to target the Rift headphones for audio output – not just whatever audio output our OS is configured for. Thankfully the Oculus PC SDK Developer Guide has a Rift Audio section to explain the steps.

GUID guid;
ovr_GetAudioDeviceOutGuid(&guid);

Indeed, getting the guid of the Rift headphones is a cinch.

‘We’re done!’ I announced to Arkwood. But he was stuck on some mould, growing over in the corner of the ceiling. About to perish. So I fashioned a tiny coffin for his crusty shell. This is what happens.

Ciao!