From 1ac944b7c1e7236e6d3493a7c23ea2c099109261 Mon Sep 17 00:00:00 2001 From: ehofman Date: Mon, 2 Nov 2009 10:31:05 +0000 Subject: [PATCH] Position and orientation fixes thanks to Tim Moore (finaly). Code optimizations by moving code over from SGSoundSample to SGSampleGroup which means it will only run once for every sample group instead of once for every sample. --- simgear/sound/sample_group.cxx | 63 ++++++++++++++++++++++--------- simgear/sound/sample_group.hxx | 15 ++++++-- simgear/sound/sample_openal.cxx | 41 +++++++++----------- simgear/sound/sample_openal.hxx | 28 +++++++++++--- simgear/sound/soundmgr_openal.cxx | 32 +++------------- simgear/sound/soundmgr_openal.hxx | 12 ++---- 6 files changed, 107 insertions(+), 84 deletions(-) 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 ) { - - 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; -} +void SGSampleGroup::update_pos_and_orientation() { + SGVec3d position = SGVec3d::fromGeod( _position_geod ); + SGVec3d pos_offs = SGVec3d::fromGeod( _smgr->get_position_geod() ); -// set the source orientation of all managed sounds -void SGSampleGroup::set_orientation( const SGQuatd& ori ) { + if (_position != position || _pos_offs != pos_offs) { + _position = position; + _pos_offs = pos_offs; - 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 ); + sample->set_position( _position ); + sample->set_position_offset( _pos_offs ); } - _orientation = ori; + } + + // 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_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; -- 2.39.5