From 2a6b1cb4797ac853b4e9658bccc100439d92983c Mon Sep 17 00:00:00 2001 From: Darren Ranalli Date: Thu, 21 Dec 2006 23:40:22 +0000 Subject: [PATCH] added audioVolumeAttrib --- panda/src/pgraph/Sources.pp | 3 + panda/src/pgraph/attribSlots.h | 2 + panda/src/pgraph/audioVolumeAttrib.I | 68 ++++++ panda/src/pgraph/audioVolumeAttrib.cxx | 307 +++++++++++++++++++++++++ panda/src/pgraph/audioVolumeAttrib.h | 94 ++++++++ panda/src/pgraph/config_pgraph.cxx | 3 + panda/src/pgraph/nodePath.cxx | 115 +++++++++ panda/src/pgraph/nodePath.h | 8 + panda/src/pgraph/pgraph_composite1.cxx | 1 + panda/src/pgraph/renderState.I | 19 ++ panda/src/pgraph/renderState.cxx | 21 ++ panda/src/pgraph/renderState.h | 7 +- 12 files changed, 647 insertions(+), 1 deletion(-) create mode 100755 panda/src/pgraph/audioVolumeAttrib.I create mode 100755 panda/src/pgraph/audioVolumeAttrib.cxx create mode 100755 panda/src/pgraph/audioVolumeAttrib.h diff --git a/panda/src/pgraph/Sources.pp b/panda/src/pgraph/Sources.pp index c1d9e1133f..883d21eacc 100644 --- a/panda/src/pgraph/Sources.pp +++ b/panda/src/pgraph/Sources.pp @@ -17,6 +17,7 @@ ambientLight.I ambientLight.h \ antialiasAttrib.I antialiasAttrib.h \ attribSlots.h attribSlots.I \ + audioVolumeAttrib.I audioVolumeAttrib.h \ auxSceneData.I auxSceneData.h \ bamFile.I bamFile.h \ billboardEffect.I billboardEffect.h \ @@ -124,6 +125,7 @@ ambientLight.cxx \ antialiasAttrib.cxx \ attribSlots.cxx \ + audioVolumeAttrib.cxx \ auxSceneData.cxx \ bamFile.cxx \ billboardEffect.cxx \ @@ -226,6 +228,7 @@ ambientLight.I ambientLight.h \ antialiasAttrib.I antialiasAttrib.h \ attribSlots.h attribSlots.I \ + audioVolumeAttrib.I audioVolumeAttrib.h \ auxSceneData.I auxSceneData.h \ bamFile.I bamFile.h \ billboardEffect.I billboardEffect.h \ diff --git a/panda/src/pgraph/attribSlots.h b/panda/src/pgraph/attribSlots.h index 2174e8e962..e96d293cbb 100644 --- a/panda/src/pgraph/attribSlots.h +++ b/panda/src/pgraph/attribSlots.h @@ -48,6 +48,7 @@ #include "texGenAttrib.h" #include "textureAttrib.h" #include "transparencyAttrib.h" +#include "audioVolumeAttrib.h" //////////////////////////////////////////////////////////////////// // Class : AttribSlots @@ -82,6 +83,7 @@ class EXPCL_PANDA AttribSlots CPT(TexMatrixAttrib) _tex_matrix; CPT(TextureAttrib) _texture; CPT(TransparencyAttrib) _transparency; + CPT(AudioVolumeAttrib) _audio_volume; public: AttribSlots(); diff --git a/panda/src/pgraph/audioVolumeAttrib.I b/panda/src/pgraph/audioVolumeAttrib.I new file mode 100755 index 0000000000..316dce4c8b --- /dev/null +++ b/panda/src/pgraph/audioVolumeAttrib.I @@ -0,0 +1,68 @@ +// Filename: audioVolumeAttrib.I +// Created by: darren (15Dec06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::Copy Constructor +// Access: Protected +// Description: Use AudioVolumeAttrib::make() to construct a new +// AudioVolumeAttrib object. +//////////////////////////////////////////////////////////////////// +INLINE AudioVolumeAttrib:: +AudioVolumeAttrib(const AudioVolumeAttrib ©) : + _off(copy._off), + _has_volume(copy._has_volume), + _volume(copy._volume) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::is_off +// Access: Published +// Description: Returns true if the AudioVolumeAttrib will ignore any +// color scales inherited from above, false otherwise. +// This is not the same thing as !has_scale(); a +// AudioVolumeAttrib may have the "off" flag set and also +// have another scale specified. +//////////////////////////////////////////////////////////////////// +INLINE bool AudioVolumeAttrib:: +is_off() const { + return _off; +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::has_volume +// Access: Published +// Description: Returns true if the AudioVolumeAttrib has a +// non-identity volume, false otherwise (in which case it +// might be an off attrib or an identity attrib). +//////////////////////////////////////////////////////////////////// +INLINE bool AudioVolumeAttrib:: +has_volume() const { + return _has_volume; +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::get_volume +// Access: Published +// Description: Returns the volume to be applied to sounds. +//////////////////////////////////////////////////////////////////// +INLINE float AudioVolumeAttrib:: +get_volume() const { + return _volume; +} diff --git a/panda/src/pgraph/audioVolumeAttrib.cxx b/panda/src/pgraph/audioVolumeAttrib.cxx new file mode 100755 index 0000000000..423927f4eb --- /dev/null +++ b/panda/src/pgraph/audioVolumeAttrib.cxx @@ -0,0 +1,307 @@ +// Filename: audioVolumeAttrib.cxx +// Created by: darren (15Dec06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "audioVolumeAttrib.h" +#include "attribSlots.h" +#include "graphicsStateGuardianBase.h" +#include "dcast.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "config_pgraph.h" + +TypeHandle AudioVolumeAttrib::_type_handle; +CPT(RenderAttrib) AudioVolumeAttrib::_identity_attrib; + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::Constructor +// Access: Protected +// Description: Use AudioVolumeAttrib::make() to construct a new +// AudioVolumeAttrib object. +//////////////////////////////////////////////////////////////////// +AudioVolumeAttrib:: +AudioVolumeAttrib(bool off, float volume) : + _off(off), + _volume(volume) +{ + nassertv(_volume >= 0.f); + _has_volume = !IS_NEARLY_EQUAL(_volume, 1.0f); +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::make_identity +// Access: Published, Static +// Description: Constructs an identity audio volume attrib. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AudioVolumeAttrib:: +make_identity() { + // We make identity a special case and store a pointer forever once + // we find it the first time. + if (_identity_attrib == (AudioVolumeAttrib *)NULL) { + AudioVolumeAttrib *attrib = new AudioVolumeAttrib(false, 1.0f);; + _identity_attrib = return_new(attrib); + } + + return _identity_attrib; +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::make +// Access: Published, Static +// Description: Constructs a new AudioVolumeAttrib object that indicates +// audio volume should be scaled by the indicated factor. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AudioVolumeAttrib:: +make(float volume) { + AudioVolumeAttrib *attrib = new AudioVolumeAttrib(false, volume); + return return_new(attrib); +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::make_off +// Access: Published, Static +// Description: Constructs a new AudioVolumeAttrib object that ignores +// any AudioVolumeAttrib inherited from above. You may +// also specify an additional volume scale to apply to +// geometry below (using set_volume()). +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AudioVolumeAttrib:: +make_off() { + AudioVolumeAttrib *attrib = + new AudioVolumeAttrib(true, 1.0f); + return return_new(attrib); +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::set_volume +// Access: Published +// Description: Returns a new AudioVolumeAttrib, just like this one, but +// with the volume changed to the indicated value. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AudioVolumeAttrib:: +set_volume(float volume) const { + AudioVolumeAttrib *attrib = new AudioVolumeAttrib(*this); + assert(volume >= 0.f); + attrib->_volume = volume; + attrib->_has_volume = !IS_NEARLY_EQUAL(volume, 1.0f); + return return_new(attrib); +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::output +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void AudioVolumeAttrib:: +output(ostream &out) const { + out << get_type() << ":"; + if (is_off()) { + out << "off"; + } + if (has_volume()) { + out << "(" << get_volume() << ")"; + + } else if (!is_off()) { + out << "identity"; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::compare_to_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived AudioVolumeAttrib +// types to return a unique number indicating whether +// this AudioVolumeAttrib is equivalent to the other one. +// +// This should return 0 if the two AudioVolumeAttrib objects +// are equivalent, a number less than zero if this one +// should be sorted before the other one, and a number +// greater than zero otherwise. +// +// This will only be called with two AudioVolumeAttrib +// objects whose get_type() functions return the same. +//////////////////////////////////////////////////////////////////// +int AudioVolumeAttrib:: +compare_to_impl(const RenderAttrib *other) const { + const AudioVolumeAttrib *ta; + DCAST_INTO_R(ta, other, 0); + + if (is_off() != ta->is_off()) { + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() + << "Comparing " << (int)is_off() << " to " << (int)ta->is_off() << " result = " + << (int)is_off() - (int)ta->is_off() << "\n"; + } + + return (int)is_off() - (int)ta->is_off(); + } + + int result = int(_volume * 1000.0f) - int(ta->_volume * 1000.0f); + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() + << "Comparing " << _volume << " to " << ta->_volume << " result = " + << result << "\n"; + } + + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::compose_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived RenderAttrib +// types to specify how two consecutive RenderAttrib +// objects of the same type interact. +// +// This should return the result of applying the other +// RenderAttrib to a node in the scene graph below this +// RenderAttrib, which was already applied. In most +// cases, the result is the same as the other +// RenderAttrib (that is, a subsequent RenderAttrib +// completely replaces the preceding one). On the other +// hand, some kinds of RenderAttrib (for instance, +// ColorTransformAttrib) might combine in meaningful +// ways. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AudioVolumeAttrib:: +compose_impl(const RenderAttrib *other) const { + const AudioVolumeAttrib *ta; + DCAST_INTO_R(ta, other, 0); + + if (ta->is_off()) { + return ta; + } + + AudioVolumeAttrib *attrib = new AudioVolumeAttrib(is_off(), ta->_volume * _volume); + return return_new(attrib); +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::invert_compose_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived RenderAttrib +// types to specify how two consecutive RenderAttrib +// objects of the same type interact. +// +// See invert_compose() and compose_impl(). +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AudioVolumeAttrib:: +invert_compose_impl(const RenderAttrib *other) const { + if (is_off()) { + return other; + } + const AudioVolumeAttrib *ta; + DCAST_INTO_R(ta, other, 0); + float new_volume = _volume == 0.0f ? 1.0f : ta->_volume / _volume; + + AudioVolumeAttrib *attrib = new AudioVolumeAttrib(false, new_volume); + return return_new(attrib); +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::make_default_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived AudioVolumeAttrib +// types to specify what the default property for a +// AudioVolumeAttrib of this type should be. +// +// This should return a newly-allocated AudioVolumeAttrib of +// the same type that corresponds to whatever the +// standard default for this kind of AudioVolumeAttrib is. +//////////////////////////////////////////////////////////////////// +RenderAttrib *AudioVolumeAttrib:: +make_default_impl() const { + return new AudioVolumeAttrib(false, 1.0f); +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::store_into_slot +// Access: Public, Virtual +// Description: Stores this attrib into the appropriate slot of +// an object of class AttribSlots. +//////////////////////////////////////////////////////////////////// +void AudioVolumeAttrib:: +store_into_slot(AttribSlots *slots) const { + slots->_audio_volume = this; +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// AudioVolumeAttrib. +//////////////////////////////////////////////////////////////////// +void AudioVolumeAttrib:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void AudioVolumeAttrib:: +write_datagram(BamWriter *manager, Datagram &dg) { + RenderAttrib::write_datagram(manager, dg); + + // We cheat, and modify the bam stream without upping the bam + // version. We can do this since we know that no existing bam files + // have an AudioVolumeAttrib in them. + dg.add_bool(_off); + dg.add_float32(_volume); +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type AudioVolumeAttrib is encountered +// in the Bam file. It should create the AudioVolumeAttrib +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *AudioVolumeAttrib:: +make_from_bam(const FactoryParams ¶ms) { + AudioVolumeAttrib *attrib = new AudioVolumeAttrib(false, 1.0f); + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + attrib->fillin(scan, manager); + + return attrib; +} + +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::fillin +// Access: Protected +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new AudioVolumeAttrib. +//////////////////////////////////////////////////////////////////// +void AudioVolumeAttrib:: +fillin(DatagramIterator &scan, BamReader *manager) { + RenderAttrib::fillin(scan, manager); + + _off = scan.get_bool(); + _volume = scan.get_float32(); + nassertv(_volume >= 0.f); + _has_volume = !IS_NEARLY_EQUAL(_volume, 1.0f); +} diff --git a/panda/src/pgraph/audioVolumeAttrib.h b/panda/src/pgraph/audioVolumeAttrib.h new file mode 100755 index 0000000000..83739ffc22 --- /dev/null +++ b/panda/src/pgraph/audioVolumeAttrib.h @@ -0,0 +1,94 @@ +// Filename: audioVolumeAttrib.h +// Created by: darren (15Dec06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef AUDIOVOLUMEATTRIB_H +#define AUDIOVOLUMEATTRIB_H + +#include "pandabase.h" + +#include "renderAttrib.h" +#include "luse.h" + +class FactoryParams; + +//////////////////////////////////////////////////////////////////// +// Class : AudioVolumeAttrib +// Description : Applies a scale to audio volume for positional sounds +// in the scene graph. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA AudioVolumeAttrib : public RenderAttrib { +protected: + AudioVolumeAttrib(bool off, float volume); + INLINE AudioVolumeAttrib(const AudioVolumeAttrib ©); + +PUBLISHED: + static CPT(RenderAttrib) make_identity(); + static CPT(RenderAttrib) make(float volume); + static CPT(RenderAttrib) make_off(); + + INLINE bool is_off() const; + INLINE bool has_volume() const; + INLINE float get_volume() const; + CPT(RenderAttrib) set_volume(float volume) const; + +public: + virtual void output(ostream &out) const; + virtual void store_into_slot(AttribSlots *slots) const; + +protected: + virtual int compare_to_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; + virtual RenderAttrib *make_default_impl() const; + +private: + bool _off; + bool _has_volume; + float _volume; + static CPT(RenderAttrib) _identity_attrib; + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &dg); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + RenderAttrib::init_type(); + register_type(_type_handle, "AudioVolumeAttrib", + RenderAttrib::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "audioVolumeAttrib.I" + +#endif + diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index 220b3e0899..1e668301b0 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -19,6 +19,7 @@ #include "config_pgraph.h" #include "alphaTestAttrib.h" +#include "audioVolumeAttrib.h" #include "ambientLight.h" #include "antialiasAttrib.h" #include "auxSceneData.h" @@ -296,6 +297,7 @@ init_libpgraph() { AlphaTestAttrib::init_type(); AmbientLight::init_type(); AntialiasAttrib::init_type(); + AudioVolumeAttrib::init_type(); AuxSceneData::init_type(); BillboardEffect::init_type(); Camera::init_type(); @@ -381,6 +383,7 @@ init_libpgraph() { AlphaTestAttrib::register_with_read_factory(); AmbientLight::register_with_read_factory(); AntialiasAttrib::register_with_read_factory(); + AudioVolumeAttrib::register_with_read_factory(); BillboardEffect::register_with_read_factory(); Camera::register_with_read_factory(); ClipPlaneAttrib::register_with_read_factory(); diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 7bbc717c92..caea8ab2a9 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -45,6 +45,7 @@ #include "showBoundsEffect.h" #include "transparencyAttrib.h" #include "antialiasAttrib.h" +#include "audioVolumeAttrib.h" #include "texProjectorEffect.h" #include "texturePool.h" #include "planeNode.h" @@ -5241,6 +5242,120 @@ get_antialias() const { return AntialiasAttrib::M_none; } +//////////////////////////////////////////////////////////////////// +// Function: NodePath::has_audio_volume +// Access: Published +// Description: Returns true if an audio volume has been applied +// to the referenced node, false otherwise. It is still +// possible that volume at this node might have been +// scaled by an ancestor node. +//////////////////////////////////////////////////////////////////// +bool NodePath:: +has_audio_volume() const { + nassertr_always(!is_empty(), false); + return node()->has_attrib(AudioVolumeAttrib::get_class_type()); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::clear_audio_volume +// Access: Published +// Description: Completely removes any audio volume from the +// referenced node. This is preferable to simply +// setting the audio volume to identity, as it also +// removes the overhead associated with having an audio +// volume at all. +//////////////////////////////////////////////////////////////////// +void NodePath:: +clear_audio_volume() { + nassertv_always(!is_empty()); + node()->clear_attrib(AudioVolumeAttrib::get_class_type()); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::set_audio_volume +// Access: Published +// Description: Sets the audio volume component of the transform +//////////////////////////////////////////////////////////////////// +void NodePath:: +set_audio_volume(float volume, int priority) { + nassertv_always(!is_empty()); + + const RenderAttrib *attrib = + node()->get_attrib(AudioVolumeAttrib::get_class_type()); + if (attrib != (const RenderAttrib *)NULL) { + priority = max(priority, + node()->get_state()->get_override(AudioVolumeAttrib::get_class_type())); + CPT(AudioVolumeAttrib) ava = DCAST(AudioVolumeAttrib, attrib); + + // Modify the existing AudioVolumeAttrib to add the indicated + // volume. + node()->set_attrib(ava->set_volume(volume), priority); + + } else { + // Create a new AudioVolumeAttrib for this node. + node()->set_attrib(AudioVolumeAttrib::make(volume), priority); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::set_audio_volume_off +// Access: Published +// Description: Disables any audio volume attribute inherited from +// above. This is not the same thing as +// clear_audio_volume(), which undoes any previous +// set_audio_volume() operation on this node; rather, +// this actively disables any set_audio_volume() that +// might be inherited from a parent node. +// +// It is legal to specify a new volume on the same +// node with a subsequent call to set_audio_volume(); +// this new scale will apply to lower nodes. +//////////////////////////////////////////////////////////////////// +void NodePath:: +set_audio_volume_off(int priority) { + nassertv_always(!is_empty()); + node()->set_attrib(AudioVolumeAttrib::make_off(), priority); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::get_audio_volume +// Access: Published +// Description: Returns the complete audio volume that has been +// applied to this node via a previous call to +// set_audio_volume(), or 1. (identity) if no volume has +// been applied to this particular node. +//////////////////////////////////////////////////////////////////// +float NodePath:: +get_audio_volume() const { + const RenderAttrib *attrib = + node()->get_attrib(AudioVolumeAttrib::get_class_type()); + if (attrib != (const RenderAttrib *)NULL) { + const AudioVolumeAttrib *ava = DCAST(AudioVolumeAttrib, attrib); + return ava->get_volume(); + } + + return 1.0f; +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::get_net_audio_volume +// Access: Published +// Description: Returns the complete audio volume for this node +// taking highers nodes in the graph into account. +//////////////////////////////////////////////////////////////////// +float NodePath:: +get_net_audio_volume() const { + CPT(RenderState) net_state = get_net_state(); + const RenderAttrib *attrib = net_state->get_audio_volume(); + if (attrib != (const RenderAttrib *)NULL) { + const AudioVolumeAttrib *ava = DCAST(AudioVolumeAttrib, attrib); + if (ava != (const AudioVolumeAttrib *)NULL) { + return ava->get_volume(); + } + } + + return 1.0f; +} //////////////////////////////////////////////////////////////////// // Function: NodePath::get_hidden_ancestor diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index ab64bcd76f..193225deb4 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -747,6 +747,14 @@ PUBLISHED: bool has_antialias() const; unsigned short get_antialias() const; + bool has_audio_volume() const; + void clear_audio_volume(); + void set_audio_volume(float volume, + int priority = 0); + void set_audio_volume_off(int priority = 0); + float get_audio_volume() const; + float get_net_audio_volume() const; + INLINE void adjust_all_priorities(int adjustment); // Variants on show and hide diff --git a/panda/src/pgraph/pgraph_composite1.cxx b/panda/src/pgraph/pgraph_composite1.cxx index 5b3902327d..7a0052ed6d 100644 --- a/panda/src/pgraph/pgraph_composite1.cxx +++ b/panda/src/pgraph/pgraph_composite1.cxx @@ -1,6 +1,7 @@ #include "accumulatedAttribs.cxx" #include "ambientLight.cxx" #include "antialiasAttrib.cxx" +#include "audioVolumeAttrib.cxx" #include "auxSceneData.cxx" #include "attribSlots.cxx" #include "bamFile.cxx" diff --git a/panda/src/pgraph/renderState.I b/panda/src/pgraph/renderState.I index aaeaa4683a..e2a23cd4fe 100644 --- a/panda/src/pgraph/renderState.I +++ b/panda/src/pgraph/renderState.I @@ -389,6 +389,25 @@ get_shader() const { return _shader; } +//////////////////////////////////////////////////////////////////// +// Function: RenderState::get_audio_volume +// Access: Published +// Description: This function is provided as an optimization, to +// speed up the render-time checking for the existance +// of an AudioVolumeAttrib on this state. It returns a +// pointer to the AudioVolumeAttrib, if there is one, or +// NULL if there is not. +//////////////////////////////////////////////////////////////////// +INLINE const AudioVolumeAttrib *RenderState:: +get_audio_volume() const { + if ((_flags & F_checked_audio_volume) == 0) { + // We pretend this function is const, even though it transparently + // modifies the internal audio_volume cache. + ((RenderState *)this)->determine_audio_volume(); + } + return _audio_volume; +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::determine_bin // Access: Private diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 43708928c6..82604226c1 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -1775,6 +1775,27 @@ determine_cull_callback() { _flags |= F_checked_cull_callback; } +//////////////////////////////////////////////////////////////////// +// Function: RenderState::determine_audio_volume +// Access: Private +// Description: This is the private implementation of has_audio_volume(). +//////////////////////////////////////////////////////////////////// +void RenderState:: +determine_audio_volume() { + MutexHolder holder(_lock); + if ((_flags & F_checked_audio_volume) != 0) { + // Someone else checked it first. + return; + } + + const RenderAttrib *attrib = get_attrib(AudioVolumeAttrib::get_class_type()); + _audio_volume = (const AudioVolumeAttrib *)NULL; + if (attrib != (const RenderAttrib *)NULL) { + _audio_volume = DCAST(AudioVolumeAttrib, attrib); + } + _flags |= F_checked_audio_volume; +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::update_pstats // Access: Private diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index 12858f12d9..4b541ce60d 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -47,6 +47,7 @@ class TexGenAttrib; class ClipPlaneAttrib; class ShaderAttrib; class FactoryParams; +class AudioVolumeAttrib; //////////////////////////////////////////////////////////////////// // Class : RenderState @@ -147,6 +148,7 @@ PUBLISHED: INLINE const RenderModeAttrib *get_render_mode() const; INLINE const ClipPlaneAttrib *get_clip_plane() const; INLINE const ShaderAttrib *get_shader() const; + INLINE const AudioVolumeAttrib *get_audio_volume() const; int get_geom_rendering(int geom_rendering) const; @@ -197,6 +199,7 @@ private: void determine_clip_plane(); void determine_shader(); void determine_cull_callback(); + void determine_audio_volume(); INLINE void set_destructing(); INLINE bool is_destructing() const; @@ -308,6 +311,7 @@ private: const RenderModeAttrib *_render_mode; const ClipPlaneAttrib *_clip_plane; const ShaderAttrib *_shader; + const AudioVolumeAttrib *_audio_volume; enum Flags { F_checked_bin_index = 0x0001, @@ -323,7 +327,8 @@ private: F_checked_clip_plane = 0x0400, F_checked_shader = 0x0800, F_checked_cull_callback = 0x1000, - F_has_cull_callback = 0x2000, + F_checked_audio_volume = 0x2000, + F_has_cull_callback = 0x4000, F_is_destructing = 0x8000, }; unsigned short _flags;