]> git.mxchange.org Git - simgear.git/commitdiff
Correct (and verrified) position, orientation and velocity vector. Todo: proper sound...
authorehofman <ehofman>
Sun, 11 Oct 2009 13:38:27 +0000 (13:38 +0000)
committerTim Moore <timoore@redhat.com>
Sun, 11 Oct 2009 22:01:07 +0000 (00:01 +0200)
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
simgear/sound/xmlsound.cxx

index dabf79bf0ea21411f1efc92dacbf2318908af3b1..22f9f9bfc615cf7489560cf52ea4940e055f5d52 100644 (file)
@@ -43,24 +43,27 @@ extern "C" int isinf (double);
 
 SGSampleGroup::SGSampleGroup () :
     _smgr(NULL),
+    _refname(""),
     _active(false),
-    _position(SGVec3d::zeros().data()),
-    _orientation(SGVec3f::zeros().data()),
-    _tied_to_listener(false)
+    _tied_to_listener(false),
+    _position(SGVec3d::zeros()),
+    _velocity(SGVec3f::zeros()),
+    _orientation(SGVec3f::zeros())
 {
     _samples.clear();
 }
 
 SGSampleGroup::SGSampleGroup ( SGSoundMgr *smgr, const string &refname ) :
     _smgr(smgr),
+    _refname(refname),
     _active(false), 
-    _position(SGVec3d::zeros().data()),
-    _orientation(SGVec3f::zeros().data()),
-    _tied_to_listener(false)
+    _tied_to_listener(false),
+    _position(SGVec3d::zeros()),
+    _velocity(SGVec3f::zeros()),
+    _orientation(SGVec3f::zeros())
 {
     _smgr->add(this, refname);
     _active = _smgr->is_working();
-    _refname = refname;
     _samples.clear();
 }
 
@@ -300,13 +303,14 @@ void SGSampleGroup::set_position( SGVec3d pos ) {
         return;
     }
 
-    if ( !_tied_to_listener ) {
+    if ( !_tied_to_listener && _position != 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_base_position( pos );
         }
+        _position = pos;
     }
 }
 
@@ -318,11 +322,13 @@ void SGSampleGroup::set_velocity( SGVec3f vel ) {
         return;
     }
 
-    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_velocity( vel );
+    if (_velocity != vel) {
+        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_velocity( vel );
+        }
     }
 }
 
@@ -334,11 +340,13 @@ void SGSampleGroup::set_orientation( SGVec3f ori ) {
         return;
     }
 
-    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 );
+    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 );
+        }
     }
 }
 
@@ -347,7 +355,7 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample ) {
         unsigned int source = sample->get_source();
 
         alSourcefv( source, AL_POSITION, sample->get_position());
-        alSourcefv( source, AL_DIRECTION, sample->get_direction() );
+        alSourcefv( source, AL_DIRECTION, sample->get_orientation() );
         alSourcefv( source, AL_VELOCITY, sample->get_velocity() );
         testForALError("position and orientation");
 
index b3170696389d808c14f155825e4f0a70a1e968df..1344df4493f4a5961ba11e6b348e7284731dec48 100644 (file)
@@ -35,6 +35,8 @@
 
 #if defined(__APPLE__)
 # include <OpenAL/al.h>
+#elif defined(_WIN32)
+# include <al.h>
 #else
 # include <AL/al.h>
 #endif
@@ -156,21 +158,22 @@ public:
 
 protected:
     SGSoundMgr *_smgr;
+    string _refname;
     bool _active;
 
 private:
     float _volume;
+    bool _tied_to_listener;
+
     SGVec3d _position;
+    SGVec3f _velocity;
     SGVec3f _orientation;
-    bool _tied_to_listener;
 
     sample_map _samples;
 
     bool testForALError(string s);
     bool testForError(void *p, string s);
 
-    string _refname;
-
     void update_sample_config( SGSoundSample *sound );
 };
 
index 011e0fd399a3bf56c51239bfd5818ad20279f20c..8eb83a68d981657325a2be3dfc8eab46b2e2222e 100644 (file)
@@ -42,6 +42,7 @@ SGSoundSample::SGSoundSample() :
     _absolute_pos(SGVec3d::zeros().data()),
     _relative_pos(SGVec3f::zeros().data()),
     _base_pos(SGVec3d::zeros().data()),
+    _orientation(SGVec3f::zeros().data()),
     _direction(SGVec3f::zeros().data()),
     _velocity(SGVec3f::zeros().data()),
     _sample_name(""),
@@ -74,6 +75,7 @@ SGSoundSample::SGSoundSample( const char *path, const char *file ) :
     _absolute_pos(SGVec3d::zeros().data()),
     _relative_pos(SGVec3f::zeros().data()),
     _base_pos(SGVec3d::zeros().data()),
+    _orientation(SGVec3f::zeros().data()),
     _direction(SGVec3f::zeros().data()),
     _velocity(SGVec3f::zeros().data()),
     _format(AL_FORMAT_MONO8),
@@ -112,6 +114,7 @@ SGSoundSample::SGSoundSample( unsigned char *data, int len, int freq, int format
     _absolute_pos(SGVec3d::zeros().data()),
     _relative_pos(SGVec3f::zeros().data()),
     _base_pos(SGVec3d::zeros().data()),
+    _orientation(SGVec3f::zeros().data()),
     _direction(SGVec3f::zeros().data()),
     _velocity(SGVec3f::zeros().data()),
     _data(data),
@@ -145,6 +148,16 @@ SGSoundSample::SGSoundSample( unsigned char *data, int len, int freq, int format
 SGSoundSample::~SGSoundSample() {
 }
 
+float *SGSoundSample::get_orientation() {
+#if 0
+    SGQuatf quat = SGQuatf::fromAngleAxis(_orientation);
+    SGVec3f orient = quat.transform(_direction);
+    return orient.data();
+#else
+    return _orientation.data();
+#endif
+}
+
 void SGSoundSample::set_base_position( SGVec3d pos ) {
     _base_pos = pos;
     update_absolute_position();
@@ -157,14 +170,24 @@ void SGSoundSample::set_relative_position( SGVec3f pos ) {
     _changed = true;
 }
 
-void SGSoundSample::set_orientation( SGVec3f dir ) {
+void SGSoundSample::set_orientation( SGVec3f ori ) {
+    _orientation = ori;
+    update_absolute_position();
+    _changed = true;
+}
+
+void SGSoundSample::set_direction( SGVec3f dir ) {
     _direction = dir;
     update_absolute_position();
     _changed = true;
 }
 
 void SGSoundSample::update_absolute_position() {
-    SGQuatf orient = SGQuatf::fromAngleAxis(_direction);
+#if 0
+    SGQuatf orient = SGQuatf::fromAngleAxis(_orientation);
     SGVec3f modified_relative_pos = orient.transform(_relative_pos);
     _absolute_pos = _base_pos + toVec3d(modified_relative_pos);
+#else
+    _absolute_pos = _base_pos;
+#endif
 }
index 5d4baf624886ef79261f2e617a5e29b9f96339e1..f44596a8bedcdec1df30864b944de159c044e19b 100644 (file)
@@ -58,7 +58,8 @@ private:
     SGVec3d _base_pos;         // base position
 
     // The orientation of the sound (direction and cut-off angles)
-    SGVec3f _direction;
+    SGVec3f _orientation;      // base orientation
+    SGVec3f _direction;                // orientation offset
 
     // Velocity of the source sound.
     SGVec3f _velocity;
@@ -337,7 +338,13 @@ public:
      * Set the orientation of the sound source, both for direction
      * and audio cut-off angles.
      */
-    void set_orientation( SGVec3f dir );
+    void set_orientation( SGVec3f ori );
+
+    /**
+     * Set the relative direction of the sound source, both for direction
+     * and audio cut-off angles.
+     */
+    void set_direction( SGVec3f dir );
 
     /**
      * Define the audio cone parameters for directional audio
@@ -353,8 +360,8 @@ public:
      * Get the orientation of the sound source, the inner or outer angle
      * or outer gain.
      */
-    inline float *get_orientation() { return _direction.data(); }
-    inline float *get_direction() { return _direction.data(); }
+    float *get_orientation();
+
     inline float get_innerangle() { return _inner_angle; }
     inline float get_outerangle() { return _outer_angle; }
     inline float get_outergain() { return _outer_gain; }
index 4f49416a507d627ec2f25fc26bd2ab78ca5cd4cc..d082d6c3cb132369ebf7c5101b465747314ef3db 100644 (file)
@@ -59,8 +59,8 @@ SGSoundMgr::SGSoundMgr() :
     _volume(0.0),
     _device(NULL),
     _context(NULL),
-    _listener_pos(SGVec3d::zeros().data()),
-    _listener_vel(SGVec3f::zeros().data()),
+    _position(SGVec3d::zeros().data()),
+    _velocity(SGVec3f::zeros().data()),
     _devname(NULL)
 {
 #if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
@@ -111,15 +111,15 @@ void SGSoundMgr::init() {
     _context = context;
     _working = true;
 
-    _listener_ori[0] = 0.0; _listener_ori[1] = 0.0; _listener_ori[2] = -1.0;
-    _listener_ori[3] = 0.0; _listener_ori[4] = 1.0; _listener_ori[5] = 0.0;
+    _orientation[0] = 0.0; _orientation[1] = 0.0; _orientation[2] = -1.0;
+    _orientation[3] = 0.0; _orientation[4] = 1.0; _orientation[5] = 0.0;
 
     alListenerf( AL_GAIN, 0.2f );
-    alListenerfv( AL_POSITION, toVec3f(_listener_pos).data() );
-    alListenerfv( AL_ORIENTATION, _listener_ori );
-    alListenerfv( AL_VELOCITY, _listener_vel.data() );
+    alListenerfv( AL_POSITION, toVec3f(_position).data() );
+    alListenerfv( AL_ORIENTATION, _orientation );
+    alListenerfv( AL_VELOCITY, _velocity.data() );
 
-    alDopplerFactor(1.0);
+    alDopplerFactor(0.5);
     alDopplerVelocity(340.3);   // speed of sound in meters per second.
 
     if ( alIsExtensionPresent((const ALchar*)"EXT_exponent_distance") ) {
@@ -227,9 +227,9 @@ void SGSoundMgr::update_late( double dt ) {
 
         if (_changed) {
             alListenerf( AL_GAIN, _volume );
-            alListenerfv( AL_VELOCITY, _listener_vel.data() );
-            alListenerfv( AL_ORIENTATION, _listener_ori );
-            alListenerfv( AL_POSITION, toVec3f(_listener_pos).data() );
+            alListenerfv( AL_VELOCITY, _velocity.data() );
+            alListenerfv( AL_ORIENTATION, _orientation );
+            alListenerfv( AL_POSITION, toVec3f(_position).data() );
             // alDopplerVelocity(340.3);       // TODO: altitude dependent
             testForALError("update");
             _changed = false;
@@ -321,6 +321,30 @@ void SGSoundMgr::set_volume( float v )
     _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( SGQuatd ori )
+{
+    SGVec3d sgv_up = ori.rotate(SGVec3d::e2());
+    SGVec3d sgv_at = ori.rotate(SGVec3d::e3());
+    _orientation[0] = sgv_at[0];
+    _orientation[1] = sgv_at[1];
+    _orientation[2] = sgv_at[2];
+    _orientation[3] = sgv_up[0];
+    _orientation[4] = sgv_up[1];
+    _orientation[5] = sgv_up[2];
+    _changed = true;
+}
+
 // Get an unused source id
 //
 // The Sound Manager should keep track of the sources in use, the distance
@@ -482,29 +506,6 @@ bool SGSoundMgr::load(string &samplepath, void **dbuf, int *fmt,
 }
 
 
-/**
- * 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( SGQuatd ori )
-{
-    SGVec3d sgv_up = ori.rotate(SGVec3d::e3());
-    SGVec3d sgv_at = ori.rotate(SGVec3d::e2());
-    for (int i=0; i<3; i++) {
-       _listener_ori[i] = sgv_at[i];
-       _listener_ori[i+3] = sgv_up[i];
-    }
-    _changed = true;
-}
-
-
 bool SGSoundMgr::testForError(void *p, string s)
 {
    if (p == NULL) {
index ef46df8f6a54a4df95f5a59d689732328cfb65f8..ba1e55224203cdbf485b0a9df5cc518be7c26846 100644 (file)
 # include <OpenAL/al.h>
 # include <OpenAL/alc.h>
 # include <OpenAL/alut.h>
+#elif defined(_WIN32)
+# include <al.h>
+# include <alc.h>
+# include <AL/alut.h>
 #else
 # include <AL/al.h>
 # include <AL/alc.h>
@@ -130,23 +134,27 @@ public:
     /**
      * set the position of the listener (in opengl coordinates)
      */
-    inline void set_position( SGVec3d pos ) {
-        _listener_pos = pos;
-        _changed = true;
+    void set_position( SGVec3d pos ) {
+        if (_position != pos) {
+            _position = pos;
+            _changed = true;
+        }
     }
 
-    inline double *get_position() { return _listener_pos.data(); }
-    inline SGVec3d get_position_vec() { return _listener_pos; };
+    inline double *get_position() { return _position.data(); }
+    inline SGVec3d get_position_vec() { return _position; };
 
     /**
      * set the velocity of the listener (in opengl coordinates)
      */
-    inline void set_velocity( SGVec3f vel ) {
-        _listener_vel = vel;
-        _changed = true;
+    void set_velocity( SGVec3f vel ) {
+        if (_velocity != vel) {
+            _velocity = vel;
+            _changed = true;
+        }
     }
 
-    inline SGVec3f get_velocity() { return _listener_vel; }
+    inline SGVec3f get_velocity() { return _velocity; }
 
     /**
      * set the orientation of the listener (in opengl coordinates)
@@ -154,7 +162,7 @@ public:
     void set_orientation( SGQuatd ori );
 
     inline SGVec3f get_direction() {
-        return SGVec3f(_listener_ori[0], _listener_ori[1], _listener_ori[2]);
+        return SGVec3f(_orientation[0], _orientation[1], _orientation[2]);
     }
 
     enum {
@@ -210,14 +218,14 @@ private:
     ALCcontext *_context;
 
     // Position of the listener.
-    SGVec3d _listener_pos;
+    SGVec3d _position;
 
     // Velocity of the listener.
-    SGVec3f _listener_vel;
+    SGVec3f _velocity;
 
     // Orientation of the listener. 
     // first 3 elements are "at" vector, second 3 are "up" vector
-    ALfloat _listener_ori[6];
+    ALfloat _orientation[6];
 
     sample_group_map _sample_groups;
     buffer_map _buffers;
index 919f08371669b9f8871db20178b09d7a05fac0f7..9fe4fdb1e92b407a169ed165e3c1165c23a2a02a 100644 (file)
@@ -230,11 +230,11 @@ SGXmlSound::init(SGPropertyNode *root, SGPropertyNode *node,
    // Relative position
    //
    SGVec3f offset_pos = SGVec3f::zeros();
-   SGPropertyNode_ptr pos = node->getChild("position");
-   if ( pos != NULL ) {
-       offset_pos[0] = pos->getDoubleValue("x", 0.0);
-       offset_pos[1] = -pos->getDoubleValue("y", 0.0);
-       offset_pos[2] = pos->getDoubleValue("z", 0.0);
+   SGPropertyNode_ptr prop = node->getChild("position");
+   if ( prop != NULL ) {
+       offset_pos[0] = prop->getDoubleValue("x", 0.0);
+       offset_pos[1] = -prop->getDoubleValue("y", 0.0);
+       offset_pos[2] = prop->getDoubleValue("z", 0.0);
    }
 
    //
@@ -244,40 +244,29 @@ SGXmlSound::init(SGPropertyNode *root, SGPropertyNode *node,
    float inner, outer, outer_gain;
    inner = outer = 360.0;
    outer_gain = 0.0;
-   pos = node->getChild("orientation");
-   if ( pos != NULL ) {
-      dir[0] = pos->getDoubleValue("x", 0.0);
-      dir[1] = -pos->getDoubleValue("y", 0.0);
-      dir[2] = pos->getDoubleValue("z", 0.0);
-      inner = pos->getDoubleValue("inner-angle", 360.0);
-      outer = pos->getDoubleValue("outer-angle", 360.0);
-      outer_gain = pos->getDoubleValue("outer-gain", 0.0);
+   prop = node->getChild("orientation");
+   if ( prop != NULL ) {
+      dir[0] = prop->getDoubleValue("x", 0.0);
+      dir[1] = -prop->getDoubleValue("y", 0.0);
+      dir[2] = prop->getDoubleValue("z", 0.0);
+      inner = prop->getDoubleValue("inner-angle", 360.0);
+      outer = prop->getDoubleValue("outer-angle", 360.0);
+      outer_gain = prop->getDoubleValue("outer-gain", 0.0);
    }
    
    //
    // Initialize the sample
    //
    _sgrp = sgrp;
-   if ( (_sample = _sgrp->find(_name)) == NULL ) {
-       // FIXME: Does it make sense to overwrite a previous entry's
-       // configuration just because a new entry has the same name?
-       // Note that we can't match on identical "path" because we the
-       // new entry could be at a different location with different
-       // configuration so we need a new sample which creates a new
-       // "alSource".  The semantics of what is going on here seems
-       // confused and needs to be thought through more carefully.
-        _sample = new SGSoundSample( path.c_str(),
-                                    node->getStringValue("path", "") );
-       _sgrp->add( _sample, _name );
-   }
-
+   _sample = new SGSoundSample( path.c_str(), node->getStringValue("path", ""));
    _sample->set_relative_position( offset_pos );
-   _sample->set_orientation( dir );
+   _sample->set_direction( dir );
    _sample->set_audio_cone(inner, outer, outer_gain);
    _sample->set_reference_dist( reference_dist );
    _sample->set_max_dist( max_dist );
    _sample->set_volume(v);
    _sample->set_pitch(p);
+   _sgrp->add( _sample, _name );
 }
 
 void