Hello Laurent,
When I was playing around with listener rotation back in May, I noticed that sf::Sound::setRelativeToListener seemed to be inverted. I didn't mention it back then because I had my head in the rotation thing, and I wanted to test it properly and provide minimal code to show the problem, if there was one.
Now I finally did, and there seems to indeed be a problem. Here is the code to show it:
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
int main()
{
sf::RenderWindow window( sf::VideoMode( 800, 600 ), "Relative to listener oddity" );
window.setVerticalSyncEnabled( true );
// Setup listener
sf::Listener::setPosition( 0.f, 0.f, -1.f );
sf::Listener::setDirection( 1.f, 0.f, 0.f );
// Setup sound
sf::SoundBuffer soundResource;
soundResource.loadFromFile( "pling.wav" );
sf::Sound soundEmitter( soundResource );
soundEmitter.setPosition( 0.f, 0.f, 0.f );
soundEmitter.setLoop( true );
soundEmitter.play();
// Listener orientation clock
sf::Clock listenerOrientationClock;
// Instruction text
sf::Text instructionText( sf::String( "Press space to change listener relativity" ) );
instructionText.setPosition( 0.f, 50.f );
while( window.isOpen() )
{
// Handle events
sf::Event event;
while( window.pollEvent( event ) )
{
if( event.type == sf::Event::Closed )
window.close();
else if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space )
soundEmitter.setRelativeToListener( !soundEmitter.isRelativeToListener() );
}
if( listenerOrientationClock.getElapsedTime().asSeconds() > 1.f )
{
sf::Listener::setDirection( -sf::Listener::getDirection().x, 0.f, 0.f );
listenerOrientationClock.restart();
}
// Draw scene
window.clear();
if( soundEmitter.isRelativeToListener() )
window.draw( sf::Text( sf::String( "Emitter is relative to listener" ) ) );
else
window.draw( sf::Text( sf::String( "Emitter is not relative to listener" ) ) );
window.draw( instructionText );
window.display();
}
return EXIT_SUCCESS;
}
As you will notice, the sound will be affected by the listener's rotation when setRelativeToListener( false ), and vice versa.
setRelativeToListener(false) doesn't mean "no relation with the listener". It means that the sound position is given globally, not relatively to the listener position/rotation. And if it's not relative, when the listener moves the sound doesn't, therefore you can hear the difference.
When the sound is relative to the listener, moving the listener will move the sound too so you hear no difference in your speakers.
To summarize:
sound.setRelativeToListener(false) -> the sound is fixed in the 3D world
sound.setRelativeToListener(true) -> the sound is attached to the listener, it follows it
The default is false. You would activate it for example for the sound of the gun that your player carries, because the gun follows the player.
I thought that the API doc was clear enough :(