44 SourceRef(
const SharedPtr<Source> &src,
const SharedPtr<Scene> &scn) :
64 typedef std::map<std::string, SharedPtr<Scene> >
SceneMap;
96 maxDistance(std::numeric_limits<double>::infinity()),
114 using namespace __impl;
127 if (!data->renderer.get())
129 return data->renderer;
135 if (!internalRenderer()->owns(sound))
136 throw Exception(
"Invalid sound: incompatible renderers used");
138 return SharedPtr<Source>(
new SimpleSource(sound, looping) );
144 return createSource(tpl, tpl->getSoundName());
150 SharedPtr<Source> source = createSource(
151 internalRenderer()->getSound(
154 tpl->isStreaming() ),
157 source->setCosAngleRange( tpl->getCosAngleRange() );
158 source->setPerFrequencyRadiusRatios( tpl->getPerFrequencyRadiusRatios() );
159 source->setReferenceFreqs( tpl->getReferenceFreqs() );
160 source->setGain( tpl->getGain() );
161 source->setAttenuated( tpl->isAttenuated() );
162 source->setRelative( tpl->isRelative() );
175 if (source->isPlaying())
176 source->stopPlaying();
179 SceneManagerData::SceneMap::iterator it;
180 for (it = data->activeScenes.begin(); it != data->activeScenes.end(); ++it)
181 it->second->remove(source);
182 for (it = data->inactiveScenes.begin(); it != data->inactiveScenes.end(); ++it)
183 it->second->remove(source);
189 if ( data->activeScenes.count(scene->getName())
190 || data->inactiveScenes.count(scene->getName()) )
193 data->inactiveScenes[scene->getName()] = scene;
207 SceneManagerData::SceneMap::const_iterator it;
209 it = data->activeScenes.find(name);
210 if (it != data->activeScenes.end())
213 it = data->inactiveScenes.find(name);
214 if (it != data->inactiveScenes.end())
227 data->activeScenes.erase(name);
228 data->inactiveScenes.erase(name);
236 SharedPtr<Scene> scene = getScene(name);
238 data->inactiveScenes.erase(name);
239 data->activeScenes[name] = scene;
241 data->activeScenes.erase(name);
242 data->inactiveScenes[name] = scene;
249 return data->activeScenes.count(name) > 0;
255 if (data->renderer.get()) {
257 for (SceneManagerData::SourceRefSet::const_iterator it = data->activeSources.begin(); it != data->activeSources.end(); ++it)
258 data->renderer->detach(it->source);
261 data->renderer->detach(data->rootListener);
265 data->renderer.swap(renderer);
267 if (data->renderer.get()) {
269 data->renderer->attach(data->rootListener);
272 for (SceneManagerData::SourceRefSet::const_iterator it = data->activeSources.begin(); it != data->activeSources.end(); ++it)
273 data->renderer->attach(it->source);
280 return data->renderer;
286 return data->maxSources;
292 data->maxSources = n;
296 SharedPtr<SourceTemplate> tpl,
297 const std::string &sceneName,
303 if (tpl->isLooping())
304 throw(
Exception(
"Cannot fire a looping source and forget!"));
306 SharedPtr<Source> src = createSource(tpl);
308 src->setPosition(position);
309 src->setDirection(direction);
310 src->setVelocity(velocity);
311 src->setRadius(radius);
313 getScene(sceneName)->add(src);
319 SharedPtr<SourceTemplate> tpl,
320 const std::string &soundName,
321 const std::string &sceneName,
327 if (tpl->isLooping())
328 throw(
Exception(
"Cannot fire a looping source and forget!"));
330 SharedPtr<Source> src = createSource(tpl, soundName);
332 src->setPosition(position);
333 src->setDirection(direction);
334 src->setVelocity(velocity);
335 src->setRadius(radius);
337 getScene(sceneName)->add(src);
345 return data->minGain;
352 data->minGain = gain;
358 return data->maxDistance;
364 assert(distance >= 0.
f);
365 data->maxDistance = distance;
371 return SharedPtr<SceneIterator>(
374 data->activeScenes.begin(),
375 data->activeScenes.end() ),
377 data->inactiveScenes.begin(),
378 data->inactiveScenes.end() )
386 return SharedPtr<SceneIterator>(
388 data->activeScenes.begin(),
389 data->activeScenes.end() ) );
395 bool needActivation = ((realTime - getActivationFrequency()) >= data->lastActivationTime);
396 bool needPosUpdates = ((realTime - getPositionUpdateFrequency()) >= data->lastPositionUpdateTime);
397 bool needAttUpdates = ((realTime - getAttributeUpdateFrequency()) >= data->lastAttributeUpdateTime);
398 bool needListenerUpdate = ((realTime - getListenerUpdateFrequency()) >= data->lastListenerUpdateTime);
399 bool needListenerAttUpdate = ((realTime - getAttributeUpdateFrequency()) >= data->lastListenerAttUpdateTime);
403 needPosUpdates = needPosUpdates || needActivation;
405 internalRenderer()->beginTransaction();
407 if (needActivation) {
408 activationPhaseImpl();
410 data->lastActivationTime =
realTime;
413 if (needListenerUpdate) {
414 updateListenerImpl(needListenerAttUpdate);
416 data->lastListenerUpdateTime =
realTime;
417 if (needListenerAttUpdate)
418 data->lastListenerAttUpdateTime =
realTime;
421 if (needPosUpdates || needAttUpdates) {
422 updateSourcesImpl(needAttUpdates);
424 data->lastPositionUpdateTime =
realTime;
426 data->lastAttributeUpdateTime =
realTime;
429 internalRenderer()->commitTransaction();
450 return gain > o.
gain;
463 const SharedPtr<Renderer> &renderer = internalRenderer();
465 LScalar maxDistanceSq = data->maxDistance * data->maxDistance;
467 std::vector<SourcePriorityRef> selection;
468 bool heapified =
false;
469 selection.reserve(data->maxSources+1);
471 for (SceneManagerData::SceneMap::iterator it = data->activeScenes.begin();
472 it != data->activeScenes.end();
483 if ( (*sit)->getSourceListener().get() ) {
490 if (ref.
gain > data->minGain) {
491 selection.push_back(ref);
492 if (selection.size() > data->maxSources) {
494 make_heap(selection.begin(), selection.end());
497 push_heap(selection.begin(), selection.end());
499 while (selection.size() > data->maxSources) {
500 pop_heap(selection.begin(), selection.end());
501 selection.resize( selection.size()-1 );
510 for (std::vector<SourcePriorityRef>::const_iterator it = selection.begin(); it != selection.end(); ++it) {
514 dynamic_cast<SimpleScene*>(it->scene)->shared_from_this()
519 for (SceneManagerData::SourceRefSet::iterator sit = data->activeSources.begin(); sit != data->activeSources.end(); ++sit) {
520 if (newSources.find(*sit) == newSources.end())
521 renderer->detach(sit->source);
525 for (SceneManagerData::SourceRefSet::iterator nit = newSources.begin(); nit != newSources.end(); ) {
527 if (data->activeSources.find(*nit) == data->activeSources.end()) {
529 renderer->attach(nit->source);
530 nit->needsActivation =
true;
533 if (!nit->source->getRenderable()->isPlaying()) {
536 nit->source->getRenderable()->update(0, nit->scene->getListener());
538 if (!nit->source->getRenderable()->isPlaying()) {
540 renderer->detach(nit->source);
541 nit->source->stopPlaying();
545 SharedPtr<SourceListener> listener = nit->source->getSourceListener();
546 if (listener.get() != NULL && listener->wantPlayEvents()) {
547 listener->onEndOfStream(*nit->source);
553 newSources.erase(nit++);
559 data->activeSources.swap(newSources);
572 for (SceneManagerData::SourceRefSet::const_iterator it = data->activeSources.begin(); it != data->activeSources.end(); ++it) {
574 it->source->updateRenderable(
576 it->scene->getListener());
579 if (it->needsActivation) {
580 it->source->getRenderable()->startPlaying(
581 it->source->getWouldbePlayingTime() );
582 it->needsActivation =
false;
595 if (data->rootListener.get())
596 data->rootListener->update(updateFlags);
599 for (SceneManagerData::SceneMap::const_iterator
i = data->activeScenes.begin();
i != data->activeScenes.end(); ++
i)
600 i->second->getListener().update(updateFlags);
606 return data->positionUpdateFrequency;
612 return data->listenerUpdateFrequency;
618 return data->attributeUpdateFrequency;
624 return data->activationFrequency;
630 data->positionUpdateFrequency = interval;
636 data->listenerUpdateFrequency = interval;
642 data->attributeUpdateFrequency = interval;
648 data->activationFrequency = interval;
654 return data->rootListener;
662 double maxDistanceSq = getMaxDistance();
663 maxDistanceSq *= maxDistanceSq;
665 if (scene->getListener().getPosition().distanceSquared(source->getPosition()) <= maxDistanceSq)
666 data->lastActivationTime = -std::numeric_limits<Timestamp>::infinity();