diff --git a/simgear/sound/sample_openal.cxx b/simgear/sound/sample_openal.cxx index 1fc11661..95a60775 100644 --- a/simgear/sound/sample_openal.cxx +++ b/simgear/sound/sample_openal.cxx @@ -28,6 +28,7 @@ #include // rand(), free() #include +#include #include #include @@ -78,8 +79,12 @@ SGSoundSample::SGSoundSample() : _playing(false), _static_changed(true), _out_of_range(false), - _is_file(false) + _is_file(false), + _use_pos_props(false) { + _pos_prop[0] = 0; + _pos_prop[1] = 0; + _pos_prop[2] = 0; } // constructor @@ -114,10 +119,14 @@ SGSoundSample::SGSoundSample(const char *file, const SGPath& currentDir) : _playing(false), _static_changed(true), _out_of_range(false), - _is_file(true) + _is_file(true), + _use_pos_props(false) { SGPath p = simgear::ResourceManager::instance()->findPath(file, currentDir); _refname = p.str(); + _pos_prop[0] = 0; + _pos_prop[1] = 0; + _pos_prop[2] = 0; } // constructor @@ -152,10 +161,14 @@ SGSoundSample::SGSoundSample( const unsigned char** data, _playing(false), _static_changed(true), _out_of_range(false), - _is_file(false) + _is_file(false), + _use_pos_props(false) { SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" ); _data = (unsigned char*)*data; *data = NULL; + _pos_prop[0] = 0; + _pos_prop[1] = 0; + _pos_prop[2] = 0; } // constructor @@ -189,10 +202,14 @@ SGSoundSample::SGSoundSample( void** data, int len, int freq, int format ) : _playing(false), _static_changed(true), _out_of_range(false), - _is_file(false) + _is_file(false), + _use_pos_props(false) { SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" ); _data = (unsigned char*)*data; *data = NULL; + _pos_prop[0] = 0; + _pos_prop[1] = 0; + _pos_prop[2] = 0; } @@ -203,9 +220,16 @@ SGSoundSample::~SGSoundSample() { void SGSoundSample::update_pos_and_orientation() { - _absolute_pos = _base_pos; - if (_relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) { - _absolute_pos += _rotation.rotate( _relative_pos ); + if (_use_pos_props) { + if (_pos_prop[0]) _absolute_pos[0] = _pos_prop[0]->getDoubleValue(); + if (_pos_prop[1]) _absolute_pos[1] = _pos_prop[1]->getDoubleValue(); + if (_pos_prop[2]) _absolute_pos[2] = _pos_prop[2]->getDoubleValue(); + } + else { + _absolute_pos = _base_pos; + if (_relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) { + _absolute_pos += _rotation.rotate( _relative_pos ); + } } _orivec = SGVec3f::zeros(); diff --git a/simgear/sound/sample_openal.hxx b/simgear/sound/sample_openal.hxx index 1266c249..fe3887ef 100644 --- a/simgear/sound/sample_openal.hxx +++ b/simgear/sound/sample_openal.hxx @@ -30,6 +30,7 @@ #include #include #include +#include class SGPath; @@ -334,7 +335,13 @@ public: * @param pos position in Cartesian coordinates */ inline void set_position( const SGVec3d& pos ) { - _base_pos = pos; _changed = true; + _base_pos = pos; _changed = true; + } + + inline void set_position_properties(SGPropertyNode_ptr pos[3]) { + _pos_prop[0] = pos[0]; _pos_prop[1] = pos[1]; _pos_prop[2] = pos[2]; + if (pos[0] || pos[1] || pos[2]) _use_pos_props = true; + _changed = true; } /** @@ -477,6 +484,7 @@ protected: private: // Position of the source sound. + SGPropertyNode_ptr _pos_prop[3]; // always absolute SGVec3d _absolute_pos; // absolute position SGVec3d _relative_pos; // position relative to the base position SGVec3d _direction; // orientation offset @@ -514,6 +522,7 @@ private: bool _static_changed; bool _out_of_range; bool _is_file; + bool _use_pos_props; std::string random_string(); }; diff --git a/simgear/sound/xmlsound.cxx b/simgear/sound/xmlsound.cxx index 7891bf78..fb3e7d73 100644 --- a/simgear/sound/xmlsound.cxx +++ b/simgear/sound/xmlsound.cxx @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -249,10 +250,27 @@ SGXmlSound::init( SGPropertyNode *root, // SGVec3f offset_pos = SGVec3f::zeros(); SGPropertyNode_ptr prop = node->getChild("position"); + SGPropertyNode_ptr pos_prop[3]; 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); + + pos_prop[0] = prop->getChild("x"); + if (pos_prop[0]) pos_prop[0] = pos_prop[0]->getNode("property"); + if (pos_prop[0]) { + pos_prop[0] = root->getNode(pos_prop[0]->getStringValue(), true); + } + pos_prop[1] = prop->getChild("y"); + if (pos_prop[1]) pos_prop[1] = pos_prop[1]->getNode("property"); + if (pos_prop[1]) { + pos_prop[1] = root->getNode(pos_prop[1]->getStringValue(), true); + } + pos_prop[2] = prop->getChild("z"); + if (pos_prop[2]) pos_prop[2] = pos_prop[1]->getNode("property"); + if (pos_prop[2]) { + pos_prop[2] = root->getNode(pos_prop[2]->getStringValue(), true); + } } // @@ -284,9 +302,11 @@ SGXmlSound::init( SGPropertyNode *root, _sample = new SGSoundSample(soundFileStr.c_str(), path); if (!_sample->file_path().exists()) { throw sg_io_exception("XML sound: couldn't find file: '" + soundFileStr + "'"); + return; } _sample->set_relative_position( offset_pos ); + _sample->set_position_properties( pos_prop ); _sample->set_direction( dir ); _sample->set_audio_cone( inner, outer, outer_gain ); _sample->set_reference_dist( reference_dist );