nuclear@48: #include nuclear@48: #include nuclear@48: #include "auman.h" nuclear@48: nuclear@48: AudioManager::AudioManager() nuclear@48: { nuclear@48: if(!(sources = kd_create(3))) { nuclear@48: fprintf(stderr, "failed to create kd tree\n"); nuclear@48: throw std::bad_alloc(); nuclear@48: } nuclear@51: kd_data_destructor(sources, [](void *s) { delete (AudioSource*)s; }); nuclear@48: } nuclear@48: nuclear@48: AudioManager::~AudioManager() nuclear@48: { nuclear@48: kd_free(sources); nuclear@48: } nuclear@48: nuclear@48: void AudioManager::clear() nuclear@48: { nuclear@48: for(auto s : active_set) { nuclear@48: s->stop(); nuclear@48: } nuclear@48: active_set.clear(); nuclear@51: nuclear@51: kd_clear(sources); nuclear@48: } nuclear@48: nuclear@48: void AudioManager::add_source(AudioSource *s) nuclear@48: { nuclear@48: Vector3 pos = s->get_position(); nuclear@48: if(kd_insert3f(sources, pos.x, pos.y, pos.z, s) == -1) { nuclear@48: fprintf(stderr, "AudioManager: failed to add source!\n"); nuclear@48: } nuclear@48: } nuclear@48: nuclear@48: void AudioManager::active_range(const Vector3 &pos, float range) nuclear@48: { nuclear@48: std::set newset; nuclear@48: nuclear@48: // find all the sources in the given range and construct newset. nuclear@48: struct kdres *results = kd_nearest_range3f(sources, pos.x, pos.y, pos.z, range); nuclear@48: while(!kd_res_end(results)) { nuclear@48: newset.insert((AudioSource*)kd_res_item_data(results)); nuclear@48: kd_res_next(results); nuclear@48: } nuclear@48: kd_res_free(results); nuclear@48: nuclear@48: /* for each of the currently active sources, if they're not in the nuclear@48: * new set, stop the playback. nuclear@48: */ nuclear@48: for(auto s : active_set) { nuclear@48: if(newset.find(s) == newset.end()) { nuclear@48: s->stop(); nuclear@48: } nuclear@48: } nuclear@48: nuclear@48: /* for each of the new active sources not found in the currently active nuclear@48: * set, start the playback. nuclear@48: */ nuclear@48: for(auto s : newset) { nuclear@48: if(active_set.find(s) == active_set.end()) { nuclear@48: s->play(); nuclear@48: } nuclear@48: } nuclear@48: nuclear@48: // swap the current with the new, previous current will be destroyed at end of scope nuclear@48: std::swap(active_set, newset); nuclear@48: }