]> git.mxchange.org Git - simgear.git/commitdiff
Position and orientation fixes thanks to Tim Moore (finaly). Code optimizations by...
authorehofman <ehofman>
Mon, 2 Nov 2009 10:31:05 +0000 (10:31 +0000)
committerTim Moore <timoore@redhat.com>
Mon, 2 Nov 2009 22:20:58 +0000 (23:20 +0100)
simgear/sound/sample_group.cxx
simgear/sound/sample_group.hxx
simgear/sound/sample_openal.cxx
simgear/sound/sample_openal.hxx
simgear/sound/soundmgr_openal.cxx
simgear/sound/soundmgr_openal.hxx

index 82c4e6e70caffb95f4348f0c5fc4c19756541a52..43235d8684b7e48e1bc1b7de6c619095671c6662 100644 (file)
@@ -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() );
index 645e18b80c3ab6c28c2977770737d274b60ae195..316cb43e6675a7abc8cceb0404452445076eda7e 100644 (file)
@@ -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<SGSoundSample> > _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 );
 };
 
index 4be9d8113f02c9c068afd605e3c7926d58bded95..5c20c1c9493a4180428ebff8bf1d9e27b0c88f7e 100644 (file)
@@ -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() {
index a0fb812e75ae097edfa67506e2ae31f11e9da1e1..56fc3d3aea366f76ee718b575dfe1cca0dbb46d2 100644 (file)
@@ -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;
index b617794810ce0c765f5e019eadeb93a90a14e646..76b3f1381dcda5b5f766a841b27978de9034a56e 100644 (file)
@@ -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];
index 8cba4ac7b7b9a67cce93bf1c1e790d67c720afab..1be7eebdcd74700dc232aebc0e0c33e6e1dafbcc 100644 (file)
@@ -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;