3D positioning#
Goal: place sounds at coordinates in the scene, move the listener through them, and hear the panning and distance attenuation update in real time.
Walks through Demo02_3D, which moves two sounds and the listener
around a small console-driven 3D space.
Source: Demo02_3D.cpp.
The Pos class#
Every position in libYSE is a YSE::Pos — a simple struct with
public x, y, z floats. Construct one in-place, or use zero()
to reset:
void Demo3D::Reset()
{
// YSE has a very flexible vector class built in
YSE::Pos pos;
pos.zero(); YSE::Listener().pos(pos);
sound1.pos(YSE::Pos(-3,0,3));
sound2.pos(YSE::Pos(3,0,3));
}
This piece resets the demo:
Listener().pos(pos)puts the ear at the origin.sound1.pos(YSE::Pos(-3, 0, 3))places the drone three units left and three units in front of the listener.sound2.pos(YSE::Pos(3, 0, 3))places the kick three units right.
Reading a position#
The same method (overloaded) reads or writes. With no arguments it returns the current position:
void Demo3D::moveObject(direction d) {
if (selectedObject < 3) {
YSE::sound * s;
if (selectedObject == 1) s = &sound1;
else s = &sound2;
YSE::Pos pos = s->pos();
switch (d) {
case FORWARD: pos.z += 0.5f; s->pos(pos); break;
case BACKWARD: pos.z -= 0.5f; s->pos(pos); break;
case LEFT: pos.x -= 0.5f; s->pos(pos); break;
case RIGHT: pos.x += 0.5f; s->pos(pos); break;
}
}
else {
// you do not have to create the listener object, it's already there
YSE::Pos pos = YSE::Listener().pos();
switch (d) {
case FORWARD: pos.z += 0.5f; YSE::Listener().pos(pos); break;
case BACKWARD: pos.z -= 0.5f; YSE::Listener().pos(pos); break;
case LEFT: pos.x -= 0.5f; YSE::Listener().pos(pos); break;
case RIGHT: pos.x += 0.5f; YSE::Listener().pos(pos); break;
}
}
}
The pattern — fetch pos, modify it, write it back — is the idiomatic
way to nudge an object’s position by a delta. The Listener works the
same way: Listener().pos() reads, Listener().pos(p) writes.
Moving every frame#
In a real application, you would call Listener().pos(...) once per
frame with the camera’s current position. The engine derives velocity
from successive positions; the doppler effect kicks in automatically as
long as updates are frequent (typically alongside
YSE::System().update()).
If you also need orientation — for example to know which way the camera is
facing — call Listener().orient(forward, up). The default up
vector is (0, 1, 0), which constrains rotation to the horizontal
plane.
What you learned#
YSE::Posis the universal 3D coordinate.x/y/zare public floats; build withPos(x, y, z)orzero().sound.pos(p)writes,sound.pos()reads.The
YSE::Listener()singleton works the same way.Doppler is automatic — keep updates frequent.
Next#
Channels — group sounds for shared volume / FX.
Reverb — add positioned reverb zones.
YSE::listener— full listener API.