smgr->init();
sgr = smgr->find("default", true);
smgr->set_volume(0.9);
- smgr->set_position( SGVec3d::fromGeod(SGGeod::fromDeg(0,0)) );
+ smgr->set_position_geod( SGGeod::fromDeg(0,0) );
smgr->activate();
printf("default position and orientation\n");
sleep(1);
printf("source at lat,lon = (10,-10), listener at (9.99,-9.99)\n");
- sample1->set_position( SGGeod::fromDeg(10,-10) );
- smgr->set_position( SGVec3d::fromGeod(SGGeod::fromDeg(9.99,-9.99)) );
+ sample1->set_position_geod( SGGeod::fromDeg(10,-10) );
+ smgr->set_position( SGGeod::fromDeg(9.99,-9.99) );
sample1->play_looped();
smgr->update(1.0);
printf("playing sample\n");
}
// set the source position of all managed sounds
-void SGSampleGroup::set_position( const SGGeod& pos ) {
+void SGSampleGroup::set_position_geod( const SGGeod& pos ) {
sample_map_iterator sample_current = _samples.begin();
sample_map_iterator sample_end = _samples.end();
for ( ; sample_current != sample_end; ++sample_current ) {
SGSoundSample *sample = sample_current->second;
- sample->set_position( pos );
+ sample->set_position_geod( pos );
}
_position = pos;
}
position = _smgr->get_position();
velocity = _smgr->get_velocity();
} else {
- sample->update_absolute_position();
+ sample->update_pos_and_orientation();
orientation = sample->get_orientation();
position = sample->get_position();
velocity = sample->get_velocity();
}
- if (dist(position, _smgr->get_position()) > 10000)
+ if (length(position -_smgr->get_position()) > 20000)
printf("source and listener distance greater than 20km!\n");
if (isNaN(toVec3f(position).data())) printf("NaN in source position\n");
if (isNaN(orientation.data())) printf("NaN in source orientation\n");
/**
* Set the velocity vector of this sample group.
- * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
+ * This is in the local frame coordinate system; x=north, y=east, z=down
* @param vel Velocity vector
*/
void set_velocity( const SGVec3f& vel );
* This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
* @param pos Base position
*/
- void set_position( const SGGeod& pos );
+ void set_position_geod( const SGGeod& pos );
/**
* Set the orientation of this sample group.
if (_data) free(_data);
}
-void SGSoundSample::update_absolute_position() {
+void SGSoundSample::update_pos_and_orientation() {
// The rotation rotating from the earth centerd frame to
// the horizontal local frame
SGQuatd hlOr = SGQuatd::fromLonLat(_base_pos);
SGVec3d position = SGVec3d::fromGeod(_base_pos);
_absolute_pos = position;
- if ( !(_relative_pos[0] == 0 && _relative_pos[1] == 0 &&
- _relative_pos[2] == 0) )
- {
+ if ( _relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) {
_absolute_pos += (sc2body*q).backTransform(_relative_pos);
}
- if ( !(_direction[0] == 0 && _direction[1] == 0 && _direction[2] == 0) ) {
+ if ( _direction[0] || _direction[1] || _direction[2] ) {
_orivec = toVec3f((sc2body*q).backTransform(toVec3d(_direction)));
}
}
* Set the base position of this sound in Geodetic coordinates.
* @param pos Geodetic position
*/
- inline void set_position( const SGGeod& pos ) {
+ inline void set_position_geod( const SGGeod& pos ) {
_base_pos = pos; _changed = true;
}
/**
* Set the velocity vector (in meters per second) of this sound.
- * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
+ * This is in the local frame coordinate system; x=north, y=east, z=down
* @param Velocity vector
*/
inline void set_velocity( const SGVec3f& vel ) {
*/
inline std::string get_sample_name() const { return _refname; }
- void update_absolute_position();
+ void update_pos_and_orientation();
private:
_volume(0.0),
_device(NULL),
_context(NULL),
- _position(SGVec3d::zeros()),
+ _position_geod(SGGeod::fromDeg(0,0)),
+ _position_offs(SGVec3d::zeros()),
+ _absolute_pos(SGVec3d::zeros()),
_velocity(SGVec3d::zeros()),
_orientation(SGQuatd::zeros()),
_orient_offs(SGQuatd::zeros()),
if (_changed) {
if (isNaN(_at_up_vec)) printf("NaN in listener orientation\n");
-if (isNaN(toVec3f(_position).data())) printf("NaN in listener position\n");
+if (isNaN(toVec3f(_absolute_pos).data())) printf("NaN in listener position\n");
if (isNaN(_velocity.data())) printf("NaN in listener velocity\n");
+ update_pos_and_orientation();
alListenerf( AL_GAIN, _volume );
alListenerfv( AL_ORIENTATION, _at_up_vec );
- alListenerfv( AL_POSITION, toVec3f(_position).data() );
+ alListenerfv( AL_POSITION, toVec3f(_absolute_pos).data() );
alListenerfv( AL_VELOCITY, _velocity.data() );
// alDopplerVelocity(340.3); // TODO: altitude dependent
testForALError("update");
_changed = true;
}
-/**
- * set the orientation of the listener (in opengl coordinates)
- *
- * Description: ORIENTATION is a pair of 3-tuples representing the
- * 'at' direction vector and 'up' direction of the Object in
- * Cartesian space. AL expects two vectors that are orthogonal to
- * each other. These vectors are not expected to be normalized. If
- * one or more vectors have zero length, implementation behavior
- * is undefined. If the two vectors are linearly dependent,
- * behavior is undefined.
- */
-void SGSoundMgr::set_orientation( const SGQuatd& ori, const SGQuatd& offs )
-{
- _orientation = ori;
- _orient_offs = offs;
-
- SGVec3d sgv_up = offs.rotate(SGVec3d::e2());
- SGVec3d sgv_at = offs.rotate(SGVec3d::e3());
- _at_up_vec[0] = sgv_at[0];
- _at_up_vec[1] = sgv_at[1];
- _at_up_vec[2] = sgv_at[2];
- _at_up_vec[3] = sgv_up[0];
- _at_up_vec[4] = sgv_up[1];
- _at_up_vec[5] = sgv_up[2];
- _changed = true;
-}
-
// Get an unused source id
//
// The Sound Manager should keep track of the sources in use, the distance
}
}
+void SGSoundMgr::update_pos_and_orientation() {
+ // The rotation rotating from the earth centerd frame to
+ // the horizontal local frame
+ SGQuatd hlOr = SGQuatd::fromLonLat( _position_geod );
+
+ // Compute the listeners orientation and position
+ // wrt the earth centered frame - that is global coorinates
+ SGQuatd lc2body = hlOr*_orientation;
+
+ // cartesian position of the listener
+ SGVec3d position = SGVec3d::fromGeod( _position_geod );
+
+ // This is rotates the x-forward, y-right, z-down coordinate system where
+ // simulation runs into the OpenGL camera system with x-right, y-up, z-back.
+ SGQuatd q(-0.5, -0.5, 0.5, 0.5);
+
+ _absolute_pos = position + (lc2body*q).backTransform( _position_offs );
+
+ /**
+ * Description: ORIENTATION is a pair of 3-tuples representing the
+ * 'at' direction vector and 'up' direction of the Object in
+ * Cartesian space. AL expects two vectors that are orthogonal to
+ * each other. These vectors are not expected to be normalized. If
+ * one or more vectors have zero length, implementation behavior
+ * is undefined. If the two vectors are linearly dependent,
+ * behavior is undefined.
+ * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
+ */
+ SGQuatd lViewOrientation = lc2body*_orient_offs*q;
+ SGVec3d sgv_up = lViewOrientation.rotate(SGVec3d::e2());
+ SGVec3d sgv_at = lViewOrientation.rotate(SGVec3d::e3());
+ _at_up_vec[0] = sgv_at[0];
+ _at_up_vec[1] = sgv_at[1];
+ _at_up_vec[2] = sgv_at[2];
+ _at_up_vec[3] = sgv_up[0];
+ _at_up_vec[4] = sgv_up[1];
+ _at_up_vec[5] = sgv_up[2];
+}
+
bool SGSoundMgr::load(string &samplepath, void **dbuf, int *fmt,
size_t *sz, int *frq )
{
SGSampleGroup *find( const string& refname, bool create = false );
/**
- * Set the position of the sound manager.
- * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
+ * Set the Geodetic position of the sound manager.
* @param pos OpenAL listener position
*/
- void set_position( const SGVec3d& pos ) {
- _position = pos;
- _changed = true;
+ void set_position_geod( const SGGeod& pos ) {
+ _position_geod = pos; _changed = true;
+ }
+
+ void set_position_offset( const SGVec3d& pos ) {
+ _position_offs = pos; _changed = true;
}
/**
* This is in the same coordinate system as OpenGL; y=up, z=back, x=right
* @return OpenAL listener position
*/
- SGVec3d& get_position() { return _position; }
+ SGVec3d& get_position() { return _absolute_pos; }
/**
- * Set the velocity vector of the sound manager
- * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
- * @param vel Velocity vector of the OpenAL listener
+ * Set the velocity vector (in meters per second) of the sound manager
+ * This is the horizontal local frame; x=north, y=east, z=down
+ * @param Velocity vector
*/
- void set_velocity( SGVec3f& vel ) {
+ void set_velocity( const SGVec3f& vel ) {
_velocity = vel; _changed = true;
}
* Set the orientation of the sound manager
* @param ori Quaternation containing the orientation information
*/
- void set_orientation( const SGQuatd& ori, const SGQuatd& offs );
+ void set_orientation( const SGQuatd& ori, const SGQuatd& offs ) {
+ _orientation = ori; _orient_offs = offs; _changed = true;
+ }
/**
* Get the orientation of the sound manager
ALCcontext *_context;
// Position of the listener.
- SGVec3d _position;
+ SGGeod _position_geod;
+ SGVec3d _position_offs;
+ SGVec3d _absolute_pos;
// Velocity of the listener.
SGVec3f _velocity;
bool testForALUTError(string s);
bool testForError(void *p, string s);
+ void update_pos_and_orientation();
void update_sample_config( SGSampleGroup *sound );
};