diff --git a/simgear/sound/sample_group.cxx b/simgear/sound/sample_group.cxx index 82c4e6e7..43235d86 100644 --- a/simgear/sound/sample_group.cxx +++ b/simgear/sound/sample_group.cxx @@ -37,11 +37,14 @@ SGSampleGroup::SGSampleGroup () : _smgr(NULL), _refname(""), _active(false), + _changed(false), _pause(false), _tied_to_listener(false), _velocity(SGVec3d::zeros()), _orientation(SGQuatd::zeros()), - _position(SGGeod()) + _position(SGVec3d::zeros()), + _pos_offs(SGVec3d::zeros()), + _position_geod(SGGeod()) { _samples.clear(); } @@ -50,11 +53,14 @@ SGSampleGroup::SGSampleGroup ( SGSoundMgr *smgr, const string &refname ) : _smgr(smgr), _refname(refname), _active(false), + _changed(false), _pause(false), _tied_to_listener(false), _velocity(SGVec3d::zeros()), _orientation(SGQuatd::zeros()), - _position(SGGeod()) + _position(SGVec3d::zeros()), + _pos_offs(SGVec3d::zeros()), + _position_geod(SGGeod()) { _smgr->add(this, refname); _samples.clear(); @@ -111,6 +117,12 @@ void SGSampleGroup::update( double dt ) { i++; } + // Update the position and orientation information for all samples. + if ( _changed ) { + update_pos_and_orientation(); + _changed = false; + } + sample_map_iterator sample_current = _samples.begin(); sample_map_iterator sample_end = _samples.end(); for ( ; sample_current != sample_end; ++sample_current ) { @@ -327,29 +339,42 @@ void SGSampleGroup::set_velocity( const SGVec3f &vel ) { } // set the source position of all managed sounds -void SGSampleGroup::set_position_geod( const SGGeod& pos ) { +void SGSampleGroup::update_pos_and_orientation() { + + SGVec3d position = SGVec3d::fromGeod( _position_geod ); + SGVec3d pos_offs = SGVec3d::fromGeod( _smgr->get_position_geod() ); + + if (_position != position || _pos_offs != pos_offs) { + _position = position; + _pos_offs = pos_offs; + + 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( _position ); + sample->set_position_offset( _pos_offs ); + } + } + + // The rotation rotating from the earth centerd frame to + // the horizontal local frame + SGQuatd hlOr = SGQuatd::fromLonLat(_position_geod); + + // Rotate the x-forward, y-right, z-down coordinate system + // into the OpenGL camera system with x-right, y-up, z-back. + SGQuatd q(-0.5, -0.5, 0.5, 0.5); + + // Compute the sounds orientation and position + // wrt the earth centered frame - that is global coorinates + SGQuatd sc2body = hlOr*_orientation*q; 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_geod( pos ); - } - _position = pos; -} - - -// set the source orientation of all managed sounds -void SGSampleGroup::set_orientation( const SGQuatd& ori ) { - - if (_orientation != ori) { - 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_orientation( ori ); - } - _orientation = ori; + sample->set_orientation( _orientation ); + sample->set_rotation( sc2body ); } } @@ -382,11 +407,13 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample ) { velocity = sample->get_velocity(); } - if (length(position -_smgr->get_position()) > 20000) +#if 0 + if (length(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"); if (isNaN(velocity.data())) printf("NaN in source velocity\n"); +#endif unsigned int source = sample->get_source(); alSourcefv( source, AL_POSITION, toVec3f(position).data() ); diff --git a/simgear/sound/sample_group.hxx b/simgear/sound/sample_group.hxx index 645e18b8..316cb43e 100644 --- a/simgear/sound/sample_group.hxx +++ b/simgear/sound/sample_group.hxx @@ -196,13 +196,17 @@ public: * This is in the same coordinate system as OpenGL; y=up, z=back, x=right. * @param pos Base position */ - void set_position_geod( const SGGeod& pos ); + void set_position_geod( const SGGeod& pos ) { + _position_geod = pos; _changed = true; + } /** * Set the orientation of this sample group. * @param ori Quaternation containing the orientation information */ - void set_orientation( const SGQuatd& ori ); + void set_orientation( const SGQuatd& ori ) { + _orientation = ori; _changed = true; + } /** * Tie this sample group to the listener position, orientation and velocity @@ -215,13 +219,17 @@ protected: bool _active; private: + bool _changed; bool _pause; float _volume; bool _tied_to_listener; SGVec3f _velocity; SGQuatd _orientation; - SGGeod _position; + SGVec3d _position; + SGVec3d _pos_offs; + + SGGeod _position_geod; sample_map _samples; std::vector< SGSharedPtr > _removed_samples; @@ -229,6 +237,7 @@ private: bool testForALError(string s); bool testForError(void *p, string s); + void update_pos_and_orientation(); void update_sample_config( SGSoundSample *sound ); }; diff --git a/simgear/sound/sample_openal.cxx b/simgear/sound/sample_openal.cxx index 4be9d811..5c20c1c9 100644 --- a/simgear/sound/sample_openal.cxx +++ b/simgear/sound/sample_openal.cxx @@ -48,8 +48,10 @@ SGSoundSample::SGSoundSample() : _direction(SGVec3d::zeros()), _velocity(SGVec3f::zeros()), _orientation(SGQuatd::zeros()), + _rotation(SGQuatd::zeros()), _orivec(SGVec3f::zeros()), - _base_pos(SGGeod::fromDeg(0,0)), + _base_pos(SGVec3d::zeros()), + _base_offs(SGVec3d::zeros()), _refname(random_string()), _data(NULL), _format(AL_FORMAT_MONO8), @@ -82,8 +84,10 @@ SGSoundSample::SGSoundSample( const char *path, const char *file ) : _direction(SGVec3d::zeros()), _velocity(SGVec3f::zeros()), _orientation(SGQuatd::zeros()), + _rotation(SGQuatd::zeros()), _orivec(SGVec3f::zeros()), - _base_pos(SGGeod::fromDeg(0,0)), + _base_pos(SGVec3d::zeros()), + _base_offs(SGVec3d::zeros()), _refname(file), _data(NULL), _format(AL_FORMAT_MONO8), @@ -122,8 +126,10 @@ SGSoundSample::SGSoundSample( const unsigned char** data, _direction(SGVec3d::zeros()), _velocity(SGVec3f::zeros()), _orientation(SGQuatd::zeros()), + _rotation(SGQuatd::zeros()), _orivec(SGVec3f::zeros()), - _base_pos(SGGeod::fromDeg(0,0)), + _base_pos(SGVec3d::zeros()), + _base_offs(SGVec3d::zeros()), _refname(random_string()), _format(format), _size(len), @@ -157,8 +163,10 @@ SGSoundSample::SGSoundSample( void** data, int len, int freq, int format ) : _direction(SGVec3d::zeros()), _velocity(SGVec3f::zeros()), _orientation(SGQuatd::zeros()), + _rotation(SGQuatd::zeros()), _orivec(SGVec3f::zeros()), - _base_pos(SGGeod::fromDeg(0,0)), + _base_pos(SGVec3d::zeros()), + _base_offs(SGVec3d::zeros()), _refname(random_string()), _format(format), _size(len), @@ -192,30 +200,17 @@ SGSoundSample::~SGSoundSample() { } 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); - // Compute the sounds orientation and position - // wrt the earth centered frame - that is global coorinates - SGQuatd sc2body = hlOr*_orientation; - - // 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); - - // The cartesian position of the sounds base location - SGVec3d position = SGVec3d::fromGeod(_base_pos); - - _absolute_pos = position; -#if 0 + _absolute_pos = _base_pos - _base_offs; if ( _relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) { - _absolute_pos += (sc2body*q).backTransform(_relative_pos); + _absolute_pos += _rotation.backTransform(_relative_pos); } -#endif + if ( _direction[0] || _direction[1] || _direction[2] ) { - _orivec = toVec3f( (sc2body*q).backTransform(_direction) ); + _orivec = toVec3f( _rotation.rotate(_direction) ); } + else + _orivec = SGVec3f::zeros(); } string SGSoundSample::random_string() { diff --git a/simgear/sound/sample_openal.hxx b/simgear/sound/sample_openal.hxx index a0fb812e..56fc3d3a 100644 --- a/simgear/sound/sample_openal.hxx +++ b/simgear/sound/sample_openal.hxx @@ -315,11 +315,19 @@ public: } /** - * Set the base position of this sound in Geodetic coordinates. - * @param pos Geodetic position + * Set the base position in Cartesian coordinates + * @param pos position in Cartesian coordinates */ - inline void set_position_geod( const SGGeod& pos ) { - _base_pos = pos; _changed = true; + inline void set_position( const SGVec3d& pos ) { + _base_pos = pos; _changed = true; + } + + /** + * Set the base position offset in Cartesian coordinates + * @param offs offset in Cartesian coordinates + */ + inline void set_position_offset( const SGVec3d& offs ) { + _base_offs = offs; _changed = true; } /** @@ -337,6 +345,14 @@ public: _orientation = ori; _changed = true; } + /** + * Set the rotation quatgernion of this sound. + * @param rotation Quaternion containing the rotation information + */ + inline void set_rotation( const SGQuatd& rotation ) { + _rotation = rotation; _changed = true; + } + /** * Set direction of this sound relative to the orientation. * This is in the same coordinate system as OpenGL; y=up, z=back, x=right @@ -453,8 +469,10 @@ private: // The position and orientation of this sound SGQuatd _orientation; // base orientation + SGQuatd _rotation; // rotation vector for relative offsets SGVec3f _orivec; // orientation vector for OpenAL - SGGeod _base_pos; // base position + SGVec3d _base_pos; // base position + SGVec3d _base_offs; // base offset position std::string _refname; // name or file path unsigned char* _data; diff --git a/simgear/sound/soundmgr_openal.cxx b/simgear/sound/soundmgr_openal.cxx index b6177948..76b3f138 100644 --- a/simgear/sound/soundmgr_openal.cxx +++ b/simgear/sound/soundmgr_openal.cxx @@ -64,11 +64,9 @@ SGSoundMgr::SGSoundMgr() : _device(NULL), _context(NULL), _position_geod(SGGeod::fromDeg(0,0)), - _position_offs(SGVec3d::zeros()), _absolute_pos(SGVec3d::zeros()), _velocity(SGVec3d::zeros()), _orientation(SGQuatd::zeros()), - _orient_offs(SGQuatd::zeros()), _devname(NULL) { #if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1 @@ -255,13 +253,15 @@ void SGSoundMgr::update( double dt ) { } if (_changed) { +#if 0 if (isNaN(_at_up_vec)) printf("NaN in listener orientation\n"); if (isNaN(toVec3f(_absolute_pos).data())) printf("NaN in listener position\n"); if (isNaN(_velocity.data())) printf("NaN in listener velocity\n"); +#endif update_pos_and_orientation(); alListenerf( AL_GAIN, _volume ); alListenerfv( AL_ORIENTATION, _at_up_vec ); - alListenerfv( AL_POSITION, toVec3f(_absolute_pos).data() ); + // alListenerfv( AL_POSITION, toVec3f(_absolute_pos).data() ); alListenerfv( AL_VELOCITY, _velocity.data() ); // alDopplerVelocity(340.3); // TODO: altitude dependent testForALError("update"); @@ -462,27 +462,8 @@ void SGSoundMgr::release_buffer(SGSoundSample *sample) } 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; -#if 0 - if (_position_offs[0] || _position_offs[1] || _position_offs[2] ) { - _absolute_pos += (lc2body*q).backTransform( _position_offs ); - } -#endif + _absolute_pos = SGVec3d::fromGeod( _position_geod ); /** * Description: ORIENTATION is a pair of 3-tuples representing the @@ -494,9 +475,8 @@ void SGSoundMgr::update_pos_and_orientation() { * behavior is undefined. * This is in the same coordinate system as OpenGL; y=up, z=back, x=right. */ - SGQuatd lViewOrientation = hlOr*_orient_offs*q; - SGVec3d sgv_up = -lViewOrientation.rotate(SGVec3d::e2()); - SGVec3d sgv_at = lViewOrientation.rotate(SGVec3d::e3()); + SGVec3d sgv_at = _orientation.backTransform(-SGVec3d::e3()); + SGVec3d sgv_up = _orientation.backTransform(SGVec3d::e2()); _at_up_vec[0] = sgv_at[0]; _at_up_vec[1] = sgv_at[1]; _at_up_vec[2] = sgv_at[2]; diff --git a/simgear/sound/soundmgr_openal.hxx b/simgear/sound/soundmgr_openal.hxx index 8cba4ac7..1be7eebd 100644 --- a/simgear/sound/soundmgr_openal.hxx +++ b/simgear/sound/soundmgr_openal.hxx @@ -160,16 +160,13 @@ public: _position_geod = pos; _changed = true; } - void set_position_offset( const SGVec3d& pos ) { - _position_offs = pos; _changed = true; - } - /** * Get the position of the sound manager. * This is in the same coordinate system as OpenGL; y=up, z=back, x=right * @return OpenAL listener position */ SGVec3d& get_position() { return _absolute_pos; } + SGGeod& get_position_geod() { return _position_geod; } /** * Set the velocity vector (in meters per second) of the sound manager @@ -191,8 +188,8 @@ public: * Set the orientation of the sound manager * @param ori Quaternation containing the orientation information */ - void set_orientation( const SGQuatd& ori, const SGQuatd& offs ) { - _orientation = ori; _orient_offs = offs; _changed = true; + void set_orientation( const SGQuatd& ori ) { + _orientation = ori; _changed = true; } /** @@ -200,7 +197,6 @@ public: * @return Quaternation containing the orientation information */ inline const SGQuatd& get_orientation() { return _orientation; } - inline const SGQuatd& get_orientation_offset() { return _orient_offs; } /** * Get the direction vector of the sound manager @@ -286,7 +282,6 @@ private: // Position of the listener. SGGeod _position_geod; - SGVec3d _position_offs; SGVec3d _absolute_pos; // Velocity of the listener. @@ -295,7 +290,6 @@ private: // Orientation of the listener. // first 3 elements are "at" vector, second 3 are "up" vector SGQuatd _orientation; - SGQuatd _orient_offs; ALfloat _at_up_vec[6]; sample_group_map _sample_groups;