Panda3D
audioVolumeAttrib.cxx
1 // Filename: audioVolumeAttrib.cxx
2 // Created by: darren (15Dec06)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "audioVolumeAttrib.h"
16 #include "graphicsStateGuardianBase.h"
17 #include "dcast.h"
18 #include "bamReader.h"
19 #include "bamWriter.h"
20 #include "datagram.h"
21 #include "datagramIterator.h"
22 #include "config_pgraph.h"
23 
24 CPT(RenderAttrib) AudioVolumeAttrib::_identity_attrib;
25 TypeHandle AudioVolumeAttrib::_type_handle;
26 int AudioVolumeAttrib::_attrib_slot;
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: AudioVolumeAttrib::Constructor
30 // Access: Protected
31 // Description: Use AudioVolumeAttrib::make() to construct a new
32 // AudioVolumeAttrib object.
33 ////////////////////////////////////////////////////////////////////
34 AudioVolumeAttrib::
35 AudioVolumeAttrib(bool off, PN_stdfloat volume) :
36  _off(off),
37  _volume(volume)
38 {
39  nassertv(_volume >= 0.f);
40  _has_volume = !IS_NEARLY_EQUAL(_volume, 1.0f);
41 }
42 
43 ////////////////////////////////////////////////////////////////////
44 // Function: AudioVolumeAttrib::make_identity
45 // Access: Published, Static
46 // Description: Constructs an identity audio volume attrib.
47 ////////////////////////////////////////////////////////////////////
48 CPT(RenderAttrib) AudioVolumeAttrib::
49 make_identity() {
50  // We make identity a special case and store a pointer forever once
51  // we find it the first time.
52  if (_identity_attrib == (AudioVolumeAttrib *)NULL) {
53  AudioVolumeAttrib *attrib = new AudioVolumeAttrib(false, 1.0f);;
54  _identity_attrib = return_new(attrib);
55  }
56 
57  return _identity_attrib;
58 }
59 
60 ////////////////////////////////////////////////////////////////////
61 // Function: AudioVolumeAttrib::make
62 // Access: Published, Static
63 // Description: Constructs a new AudioVolumeAttrib object that indicates
64 // audio volume should be scaled by the indicated factor.
65 ////////////////////////////////////////////////////////////////////
66 CPT(RenderAttrib) AudioVolumeAttrib::
67 make(PN_stdfloat volume) {
68  AudioVolumeAttrib *attrib = new AudioVolumeAttrib(false, volume);
69  return return_new(attrib);
70 }
71 
72 ////////////////////////////////////////////////////////////////////
73 // Function: AudioVolumeAttrib::make_off
74 // Access: Published, Static
75 // Description: Constructs a new AudioVolumeAttrib object that ignores
76 // any AudioVolumeAttrib inherited from above. You may
77 // also specify an additional volume scale to apply to
78 // geometry below (using set_volume()).
79 ////////////////////////////////////////////////////////////////////
80 CPT(RenderAttrib) AudioVolumeAttrib::
81 make_off() {
82  AudioVolumeAttrib *attrib =
83  new AudioVolumeAttrib(true, 1.0f);
84  return return_new(attrib);
85 }
86 
87 ////////////////////////////////////////////////////////////////////
88 // Function: AudioVolumeAttrib::make_default
89 // Access: Published, Static
90 // Description: Returns a RenderAttrib that corresponds to whatever
91 // the standard default properties for render attributes
92 // of this type ought to be.
93 ////////////////////////////////////////////////////////////////////
94 CPT(RenderAttrib) AudioVolumeAttrib::
95 make_default() {
96  return return_new(new AudioVolumeAttrib(false, 1.0f));
97 }
98 
99 ////////////////////////////////////////////////////////////////////
100 // Function: AudioVolumeAttrib::set_volume
101 // Access: Published
102 // Description: Returns a new AudioVolumeAttrib, just like this one, but
103 // with the volume changed to the indicated value.
104 ////////////////////////////////////////////////////////////////////
105 CPT(RenderAttrib) AudioVolumeAttrib::
106 set_volume(PN_stdfloat volume) const {
107  AudioVolumeAttrib *attrib = new AudioVolumeAttrib(*this);
108  assert(volume >= 0.f);
109  attrib->_volume = volume;
110  attrib->_has_volume = !IS_NEARLY_EQUAL(volume, 1.0f);
111  return return_new(attrib);
112 }
113 
114 ////////////////////////////////////////////////////////////////////
115 // Function: AudioVolumeAttrib::output
116 // Access: Public, Virtual
117 // Description:
118 ////////////////////////////////////////////////////////////////////
119 void AudioVolumeAttrib::
120 output(ostream &out) const {
121  out << get_type() << ":";
122  if (is_off()) {
123  out << "off";
124  }
125  if (has_volume()) {
126  out << "(" << get_volume() << ")";
127 
128  } else if (!is_off()) {
129  out << "identity";
130  }
131 }
132 
133 ////////////////////////////////////////////////////////////////////
134 // Function: AudioVolumeAttrib::compare_to_impl
135 // Access: Protected, Virtual
136 // Description: Intended to be overridden by derived AudioVolumeAttrib
137 // types to return a unique number indicating whether
138 // this AudioVolumeAttrib is equivalent to the other one.
139 //
140 // This should return 0 if the two AudioVolumeAttrib objects
141 // are equivalent, a number less than zero if this one
142 // should be sorted before the other one, and a number
143 // greater than zero otherwise.
144 //
145 // This will only be called with two AudioVolumeAttrib
146 // objects whose get_type() functions return the same.
147 ////////////////////////////////////////////////////////////////////
148 int AudioVolumeAttrib::
149 compare_to_impl(const RenderAttrib *other) const {
150  const AudioVolumeAttrib *ta;
151  DCAST_INTO_R(ta, other, 0);
152 
153  if (_off != ta->_off) {
154  return (int)_off - (int)ta->_off;
155  }
156 
157  if (_volume != ta->_volume) {
158  return _volume < ta->_volume ? -1 : 1;
159  }
160 
161  return 0;
162 }
163 
164 ////////////////////////////////////////////////////////////////////
165 // Function: AudioVolumeAttrib::get_hash_impl
166 // Access: Protected, Virtual
167 // Description: Intended to be overridden by derived RenderAttrib
168 // types to return a unique hash for these particular
169 // properties. RenderAttribs that compare the same with
170 // compare_to_impl(), above, should return the same
171 // hash; RenderAttribs that compare differently should
172 // return a different hash.
173 ////////////////////////////////////////////////////////////////////
174 size_t AudioVolumeAttrib::
175 get_hash_impl() const {
176  size_t hash = 0;
177  hash = int_hash::add_hash(hash, (int)_off);
178  hash = float_hash().add_hash(hash, _volume);
179  return hash;
180 }
181 
182 ////////////////////////////////////////////////////////////////////
183 // Function: AudioVolumeAttrib::compose_impl
184 // Access: Protected, Virtual
185 // Description: Intended to be overridden by derived RenderAttrib
186 // types to specify how two consecutive RenderAttrib
187 // objects of the same type interact.
188 //
189 // This should return the result of applying the other
190 // RenderAttrib to a node in the scene graph below this
191 // RenderAttrib, which was already applied. In most
192 // cases, the result is the same as the other
193 // RenderAttrib (that is, a subsequent RenderAttrib
194 // completely replaces the preceding one). On the other
195 // hand, some kinds of RenderAttrib (for instance,
196 // ColorTransformAttrib) might combine in meaningful
197 // ways.
198 ////////////////////////////////////////////////////////////////////
199 CPT(RenderAttrib) AudioVolumeAttrib::
200 compose_impl(const RenderAttrib *other) const {
201  const AudioVolumeAttrib *ta;
202  DCAST_INTO_R(ta, other, 0);
203 
204  if (ta->is_off()) {
205  return ta;
206  }
207 
208  AudioVolumeAttrib *attrib = new AudioVolumeAttrib(is_off(), ta->_volume * _volume);
209  return return_new(attrib);
210 }
211 
212 ////////////////////////////////////////////////////////////////////
213 // Function: AudioVolumeAttrib::invert_compose_impl
214 // Access: Protected, Virtual
215 // Description: Intended to be overridden by derived RenderAttrib
216 // types to specify how two consecutive RenderAttrib
217 // objects of the same type interact.
218 //
219 // See invert_compose() and compose_impl().
220 ////////////////////////////////////////////////////////////////////
221 CPT(RenderAttrib) AudioVolumeAttrib::
222 invert_compose_impl(const RenderAttrib *other) const {
223  if (is_off()) {
224  return other;
225  }
226  const AudioVolumeAttrib *ta;
227  DCAST_INTO_R(ta, other, 0);
228  PN_stdfloat new_volume = _volume == 0.0f ? 1.0f : ta->_volume / _volume;
229 
230  AudioVolumeAttrib *attrib = new AudioVolumeAttrib(false, new_volume);
231  return return_new(attrib);
232 }
233 
234 ////////////////////////////////////////////////////////////////////
235 // Function: AudioVolumeAttrib::register_with_read_factory
236 // Access: Public, Static
237 // Description: Tells the BamReader how to create objects of type
238 // AudioVolumeAttrib.
239 ////////////////////////////////////////////////////////////////////
240 void AudioVolumeAttrib::
241 register_with_read_factory() {
242  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
243 }
244 
245 ////////////////////////////////////////////////////////////////////
246 // Function: AudioVolumeAttrib::write_datagram
247 // Access: Public, Virtual
248 // Description: Writes the contents of this object to the datagram
249 // for shipping out to a Bam file.
250 ////////////////////////////////////////////////////////////////////
253  RenderAttrib::write_datagram(manager, dg);
254 
255  // We cheat, and modify the bam stream without upping the bam
256  // version. We can do this since we know that no existing bam files
257  // have an AudioVolumeAttrib in them.
258  dg.add_bool(_off);
259  dg.add_stdfloat(_volume);
260 }
261 
262 ////////////////////////////////////////////////////////////////////
263 // Function: AudioVolumeAttrib::make_from_bam
264 // Access: Protected, Static
265 // Description: This function is called by the BamReader's factory
266 // when a new object of type AudioVolumeAttrib is encountered
267 // in the Bam file. It should create the AudioVolumeAttrib
268 // and extract its information from the file.
269 ////////////////////////////////////////////////////////////////////
270 TypedWritable *AudioVolumeAttrib::
271 make_from_bam(const FactoryParams &params) {
272  AudioVolumeAttrib *attrib = new AudioVolumeAttrib(false, 1.0f);
273  DatagramIterator scan;
274  BamReader *manager;
275 
276  parse_params(params, scan, manager);
277  attrib->fillin(scan, manager);
278 
279  return attrib;
280 }
281 
282 ////////////////////////////////////////////////////////////////////
283 // Function: AudioVolumeAttrib::fillin
284 // Access: Protected
285 // Description: This internal function is called by make_from_bam to
286 // read in all of the relevant data from the BamFile for
287 // the new AudioVolumeAttrib.
288 ////////////////////////////////////////////////////////////////////
289 void AudioVolumeAttrib::
290 fillin(DatagramIterator &scan, BamReader *manager) {
291  RenderAttrib::fillin(scan, manager);
292 
293  _off = scan.get_bool();
294  _volume = scan.get_stdfloat();
295  nassertv(_volume >= 0.f);
296  _has_volume = !IS_NEARLY_EQUAL(_volume, 1.0f);
297 }
bool get_bool()
Extracts a boolean value.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:60
bool is_off() const
Returns true if the AudioVolumeAttrib will ignore any color scales inherited from above...
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
bool has_volume() const
Returns true if the AudioVolumeAttrib has a non-identity volume, false otherwise (in which case it mi...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition: datagram.I:240
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:122
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
This hash_compare class hashes a float or a double.
Definition: stl_compares.h:158
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:118
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
PN_stdfloat get_volume() const
Returns the volume to be applied to sounds.
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
size_t add_hash(size_t start, const Key &key) const
Adds the indicated key into a running hash.
Definition: stl_compares.I:180
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
Applies a scale to audio volume for positional sounds in the scene graph.