00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <PVLE/Sound/AutoSoundNodeCallback.h>
00028
00029 #ifdef PVLE_AUDIO
00030
00031 #include <boost/cast.hpp>
00032
00033
00034 #include <osg/NodeVisitor>
00035 #include <osg/Group>
00036 #include <osgAL/SoundNode>
00037 #include <PVLE/Util/Assert.h>
00038
00039
00045 class DeleteNonPlayingSubgraphsVisitor : public osg::NodeVisitor {
00046 public:
00047 DeleteNonPlayingSubgraphsVisitor(bool deleteAllSubgraphs = true)
00048 : NodeVisitor(TRAVERSE_ALL_CHILDREN), foundSoundNode(false), foundSoundNodePlaying(false), deleteAllSubgraphs(deleteAllSubgraphs)
00049 {
00050 }
00051
00052 virtual void apply(osg::Group & node);
00053
00054 void apply(osgAL::SoundNode & node);
00055 virtual void apply(osg::Node & node) {
00056 if (std::string(node.className()) == "SoundNode") {
00057 ASSERT(dynamic_cast<osgAL::SoundNode *>(&node));
00058 apply(static_cast<osgAL::SoundNode &>(node));
00059 }
00060 traverse(node);
00061 }
00062
00063 inline bool soundNodeFound() const { return foundSoundNode; }
00064 inline bool playingSoundNodeFound() const { return foundSoundNodePlaying; }
00065
00066 protected:
00067 bool foundSoundNode;
00068 bool foundSoundNodePlaying;
00069 const bool deleteAllSubgraphs;
00070 };
00071
00072
00073 void DeleteNonPlayingSubgraphsVisitor::apply(osg::Group & node) {
00074
00075 for(int i=static_cast<int>(node.getNumChildren())-1; i>=0; --i) {
00076 DeleteNonPlayingSubgraphsVisitor v;
00077 node.getChild(i)->accept(v);
00078
00079
00080 foundSoundNodePlaying |= v.playingSoundNodeFound();
00081 foundSoundNode |= v.soundNodeFound();
00082
00083
00084
00085
00086
00087 if ((deleteAllSubgraphs || v.soundNodeFound()) && !v.playingSoundNodeFound()) {
00088
00089 node.removeChildren(i, 1);
00090 }
00091 }
00092
00093 }
00094
00095 void DeleteNonPlayingSubgraphsVisitor::apply(osgAL::SoundNode & node) {
00096 foundSoundNode = true;
00097 ASSERT(node.getSoundState());
00098 if (node.getSoundState()->isPlaying()) {
00099 foundSoundNodePlaying = true;
00100 setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
00101 }
00102 traverse(node);
00103 }
00104
00105
00106
00107 void AutoSoundNodeCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) {
00108 osg::Group * pGroup = boost::polymorphic_downcast<osg::Group *>(node);
00109 for(int i=static_cast<int>(pGroup->getNumChildren())-1; i>=0; --i) {
00110 osg::Node* pChild = pGroup->getChild(i);
00111 if (std::string(pChild->className()) == "SoundNode" && !boost::polymorphic_downcast<osgAL::SoundNode *>(pChild)->getSoundState()->isPlaying()) {
00112 pGroup->removeChildren(i, 1);
00113 }
00114 }
00115 traverse(node, nv);
00116 }
00117
00118
00119 void AutoSoundNodeGraphCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) {
00120 ASSERT(dynamic_cast<osg::Group *>(node));
00121 DeleteNonPlayingSubgraphsVisitor nv2;
00122 node->accept(nv2);
00123 traverse(node, nv);
00124 }
00125
00126 #endif // PVLE_AUDIO