Hi, I have loaded up some footstep sounds into FMOD, but how would I go about knowing when to play them? Ie. Repeatedly play a footstep sound when moving and touching the floor, if you fall from a certain height or greater play the landing sound.
Not really sure how I would go about doing that...
Cheers.
Footstep sounds
If you use the collision response animator to keep your camera on the ground, it has an isFalling() method that will tell you if the camera is falling. It seems that you can use this and the camera position information to tell what to do.
This is rather primitive, but you could do something like this. Cache the current camera position, simulation time and isFalling flag. Then every cycle through the render loop check the camera position and falling flag. If you see that the isFalling flag is set on the animator, you cache the current camera position. Keep checking the isFalling flag to see if the camera has stopped falling. When it has stopped, find the distance it fell. Use that to determine how loud to play the landing sound. When the camera has travelled one stride length, you would play a step sound. You can use the elapsed time since the last step to determine how loud to play the step sound.
Travis
This is rather primitive, but you could do something like this. Cache the current camera position, simulation time and isFalling flag. Then every cycle through the render loop check the camera position and falling flag. If you see that the isFalling flag is set on the animator, you cache the current camera position. Keep checking the isFalling flag to see if the camera has stopped falling. When it has stopped, find the distance it fell. Use that to determine how loud to play the landing sound. When the camera has travelled one stride length, you would play a step sound. You can use the elapsed time since the last step to determine how loud to play the step sound.
Code: Select all
// setup the scene and camera
ICameraSceneNode* camera =
smgr->addCameraSceneNodeFPS();
ISceneNodeAnimatorCollisionResponse* animator =
smgr->createCollisionResponseAnimator(world, camera);
camera->addAnimator(animator);
animator->drop();
// cache stuff for initial state
u32 oldStepTime = timer->getTime();
core::vector3df oldStepPos(camera->getAbsolutePosition());
bool wasFalling(animator->isFalling());
// fall sound plays at min/max volume if fall distance suqared is less/greater than these values
const f32 minFallDistanceSQ = 9.f;
const f32 maxFallDistanceSQ = 100.f
// step sound plays at min/max volume if walk speed squared is less/greater than these values
const f32 minStepVelocitySQ = 4.f;
const f32 maxStepVelocitySQ = 16.f;
// after smgr->drawAll()
bool isFalling = animator->isFalling();
// we just started falling
if (!wasFalling && isFalling)
{
wasFalling = isFalling; // cache falling flag
oldStepPos = camera->getAbsolutePosition(); // and fall start position
}
// we have just stopped falling
else if (wasFalling && !isFalling)
{
// figure out how far we fell
core::vector3df newStepPos(camera->getAbsolutePosition());
f32 distanceFallenSQ = newStepPos.getDistanceFromSQ(oldStepPos);
wasFalling = false; // no longer falling
oldStepTime = timer->getTime(); // reset step timer
oldStepPos = newStepPos; // camera has new position
if (minFallDistanceSQ < distanceFallenSQ)
{
// use distance fallen to figure out how loud to play sound
f32 volume = (distanceFallenSQ - minFallDistanceSQ) / (maxFallDistanceSQ - minFallDistanceSQ);
volume = core::max_(volume, 1.f);
// play landing sound
}
}
// we are in freefall
else if (wasFalling && isFalling)
{
// do nothing, we are in freefall
}
// we are walking
else
{
core::vector3df newStepPos(camera->getAbsolutePosition());
f32 stepDistanceSQ = newStepPos.getDistanceFromSQ(oldStepPos);
if (strideLengthSQ < stepDistanceSQ)
{
// calculate walk/run velocity and use it to determine if we should play step sound
u32 newStepTime = timer->getTime();
f32 stepVelocitySQ = stepDistanceSQ / ((newStepTime - oldStepTime) / 1000.f);
if (minStepVelocitySQ < stepVelocitySQ)
{
// we should play the sound, but how loud?
f32 volume = (stepVelocitySQ - minStepVelocitySQ) / (maxStepVelocitySQ - minStepVelocitySQ);
volume = core::max_(volume, 1.f);
// volume should be between 0 and 1 based on movement speed
}
oldStepPos = newStepPos;
oldStepTime = newStepTime;
}
}
Hi, thanks for the help
I am getting some weird values though, I have set it to output the distanceFallenSQ each time, and this is the output I get when walking up some steps:
I am getting some weird values though, I have set it to output the distanceFallenSQ each time, and this is the output I get when walking up some steps:
As a result I hear the landing sound several times...11.1679
12.852
199.834
1.44009
2.25
42.7676
345.921
1.44
2.25
36.9274
10.8178
186.73
1.44002
2.25001
8.99443
12.6621
185.144
1.44
2.25005
2.25014
13.9011
178.698
2.25007
1.44
1.44
74.9097
26.8817
163.43
1.43999
59.1047
27.0839
177.383
1.44007
45.4732
27.301
160.816
1.44007
2.25006
60.8404
1.44007
1.44007
60.8404
1.44007
1.44007
51.8398
Ah, the collision animator flips between falling and not falling all of the time when the camera is looking up. I thought that it would only be falling if it was actually falling, but it keeps flipping from falling to not falling. You'll have to calculate the actual distance fallen, decide if it was a step or an actual fall and respond appropriately.
There is a small bug. The distanceFallenSQ should be calculated like this...
You should be able to figure out how to do what you need given the ideas provided. Just setting up a timer would work fine if you have a set of a few possible walk speeds. You would still need to handle the case that you have fallen off of a cliff, but that shouldn't be to difficult.
Travis
There is a small bug. The distanceFallenSQ should be calculated like this...
Code: Select all
f32 distanceFallenSQ = oldStepPos.Y - newStepPos.Y;
distanceFallenSQ *= distanceFallenSQ;
Travis