Panda3D
 All Classes Functions Variables Enumerations
colorScaleAttrib.cxx
1 // Filename: colorScaleAttrib.cxx
2 // Created by: drose (14Mar02)
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 "colorScaleAttrib.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 TypeHandle ColorScaleAttrib::_type_handle;
25 int ColorScaleAttrib::_attrib_slot;
26 CPT(RenderAttrib) ColorScaleAttrib::_identity_attrib;
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: ColorScaleAttrib::Constructor
30 // Access: Protected
31 // Description: Use ColorScaleAttrib::make() to construct a new
32 // ColorScaleAttrib object.
33 ////////////////////////////////////////////////////////////////////
35 ColorScaleAttrib(bool off, const LVecBase4 &scale) :
36  _off(off),
37  _scale(scale)
38 {
39  quantize_scale();
40  _has_scale = !_scale.almost_equal(LVecBase4(1.0f, 1.0f, 1.0f, 1.0f));
41  _has_rgb_scale = !LVecBase3(_scale[0], _scale[1], _scale[2]).almost_equal(LVecBase3(1.0f, 1.0f, 1.0f));
42  _has_alpha_scale = !IS_NEARLY_EQUAL(_scale[3], 1.0f);
43 }
44 
45 ////////////////////////////////////////////////////////////////////
46 // Function: ColorScaleAttrib::make_identity
47 // Access: Published, Static
48 // Description: Constructs an identity scale attrib.
49 ////////////////////////////////////////////////////////////////////
51 make_identity() {
52  // We make identity a special case and store a pointer forever once
53  // we find it the first time.
54  if (_identity_attrib == (ColorScaleAttrib *)NULL) {
55  ColorScaleAttrib *attrib = new ColorScaleAttrib(false, LVecBase4(1.0f, 1.0f, 1.0f, 1.0f));;
56  _identity_attrib = return_new(attrib);
57  }
58 
59  return _identity_attrib;
60 }
61 
62 ////////////////////////////////////////////////////////////////////
63 // Function: ColorScaleAttrib::make
64 // Access: Published, Static
65 // Description: Constructs a new ColorScaleAttrib object that indicates
66 // geometry should be scaled by the indicated factor.
67 ////////////////////////////////////////////////////////////////////
69 make(const LVecBase4 &scale) {
70  ColorScaleAttrib *attrib = new ColorScaleAttrib(false, scale);
71  return return_new(attrib);
72 }
73 
74 ////////////////////////////////////////////////////////////////////
75 // Function: ColorScaleAttrib::make_off
76 // Access: Published, Static
77 // Description: Constructs a new ColorScaleAttrib object that ignores
78 // any ColorScaleAttrib inherited from above. You may
79 // also specify an additional color scale to apply to
80 // geometry below (using set_scale()).
81 ////////////////////////////////////////////////////////////////////
83 make_off() {
84  ColorScaleAttrib *attrib =
85  new ColorScaleAttrib(true, LVecBase4(1.0f, 1.0f, 1.0f, 1.0f));
86  return return_new(attrib);
87 }
88 
89 ////////////////////////////////////////////////////////////////////
90 // Function: ColorScaleAttrib::make_default
91 // Access: Published, Static
92 // Description: Returns a RenderAttrib that corresponds to whatever
93 // the standard default properties for render attributes
94 // of this type ought to be.
95 ////////////////////////////////////////////////////////////////////
97 make_default() {
98  return return_new(new ColorScaleAttrib(false, LVecBase4(1.0f, 1.0f, 1.0f, 1.0f)));
99 }
100 
101 ////////////////////////////////////////////////////////////////////
102 // Function: ColorScaleAttrib::set_scale
103 // Access: Published
104 // Description: Returns a new ColorScaleAttrib, just like this one, but
105 // with the scale changed to the indicated value.
106 ////////////////////////////////////////////////////////////////////
108 set_scale(const LVecBase4 &scale) const {
109  ColorScaleAttrib *attrib = new ColorScaleAttrib(*this);
110  attrib->_scale = scale;
111  attrib->quantize_scale();
112  attrib->_has_scale = !scale.almost_equal(LVecBase4(1.0f, 1.0f, 1.0f, 1.0f));
113  attrib->_has_rgb_scale = !LVecBase3(scale[0], scale[1], scale[2]).almost_equal(LVecBase3(1.0f, 1.0f, 1.0f));
114  attrib->_has_alpha_scale = !IS_NEARLY_EQUAL(scale[3], 1.0f);
115  return return_new(attrib);
116 }
117 
118 ////////////////////////////////////////////////////////////////////
119 // Function: ColorScaleAttrib::lower_attrib_can_override
120 // Access: Public, Virtual
121 // Description: Intended to be overridden by derived RenderAttrib
122 // types to specify how two consecutive RenderAttrib
123 // objects of the same type interact.
124 //
125 // This should return false if a RenderAttrib on a
126 // higher node will compose into a RenderAttrib on a
127 // lower node that has a higher override value, or false
128 // if the lower RenderAttrib will completely replace the
129 // state.
130 //
131 // The default behavior is false: normally, a
132 // RenderAttrib in the graph cannot completely override
133 // a RenderAttrib above it, regardless of its override
134 // value--instead, the two attribs are composed. But
135 // for some kinds of RenderAttribs, it is useful to
136 // allow this kind of override.
137 //
138 // This method only handles the one special case of a
139 // lower RenderAttrib with a higher override value. If
140 // the higher RenderAttrib has a higher override value,
141 // it always completely overrides. And if both
142 // RenderAttribs have the same override value, they are
143 // always composed.
144 ////////////////////////////////////////////////////////////////////
147  // A ColorScaleAttrib doesn't compose through an override. This
148  // allows us to meaningfully set an override on a lower node, which
149  // prevents any color scales from coming in from above.
150  return true;
151 }
152 
153 ////////////////////////////////////////////////////////////////////
154 // Function: ColorScaleAttrib::output
155 // Access: Public, Virtual
156 // Description:
157 ////////////////////////////////////////////////////////////////////
158 void ColorScaleAttrib::
159 output(ostream &out) const {
160  out << get_type() << ":";
161  if (is_off()) {
162  out << "off";
163  }
164  if (has_scale()) {
165  out << "(" << get_scale() << ")";
166 
167  } else if (!is_off()) {
168  out << "identity";
169  }
170 }
171 
172 ////////////////////////////////////////////////////////////////////
173 // Function: ColorScaleAttrib::compare_to_impl
174 // Access: Protected, Virtual
175 // Description: Intended to be overridden by derived ColorScaleAttrib
176 // types to return a unique number indicating whether
177 // this ColorScaleAttrib is equivalent to the other one.
178 //
179 // This should return 0 if the two ColorScaleAttrib objects
180 // are equivalent, a number less than zero if this one
181 // should be sorted before the other one, and a number
182 // greater than zero otherwise.
183 //
184 // This will only be called with two ColorScaleAttrib
185 // objects whose get_type() functions return the same.
186 ////////////////////////////////////////////////////////////////////
187 int ColorScaleAttrib::
188 compare_to_impl(const RenderAttrib *other) const {
189  const ColorScaleAttrib *ta;
190  DCAST_INTO_R(ta, other, 0);
191 
192  if (is_off() != ta->is_off()) {
193  return (int)is_off() - (int)ta->is_off();
194  }
195 
196  return _scale.compare_to(ta->_scale);
197 }
198 
199 ////////////////////////////////////////////////////////////////////
200 // Function: ColorScaleAttrib::get_hash_impl
201 // Access: Protected, Virtual
202 // Description: Intended to be overridden by derived RenderAttrib
203 // types to return a unique hash for these particular
204 // properties. RenderAttribs that compare the same with
205 // compare_to_impl(), above, should return the same
206 // hash; RenderAttribs that compare differently should
207 // return a different hash.
208 ////////////////////////////////////////////////////////////////////
209 size_t ColorScaleAttrib::
210 get_hash_impl() const {
211  size_t hash = 0;
212  hash = int_hash::add_hash(hash, (int)is_off());
213  hash = _scale.add_hash(hash);
214  return hash;
215 }
216 
217 ////////////////////////////////////////////////////////////////////
218 // Function: ColorScaleAttrib::compose_impl
219 // Access: Protected, Virtual
220 // Description: Intended to be overridden by derived RenderAttrib
221 // types to specify how two consecutive RenderAttrib
222 // objects of the same type interact.
223 //
224 // This should return the result of applying the other
225 // RenderAttrib to a node in the scene graph below this
226 // RenderAttrib, which was already applied. In most
227 // cases, the result is the same as the other
228 // RenderAttrib (that is, a subsequent RenderAttrib
229 // completely replaces the preceding one). On the other
230 // hand, some kinds of RenderAttrib (for instance,
231 // ColorTransformAttrib) might combine in meaningful
232 // ways.
233 ////////////////////////////////////////////////////////////////////
235 compose_impl(const RenderAttrib *other) const {
236  const ColorScaleAttrib *ta;
237  DCAST_INTO_R(ta, other, 0);
238 
239  if (ta->is_off()) {
240  return ta;
241  }
242 
243  LVecBase4 new_scale(ta->_scale[0] * _scale[0],
244  ta->_scale[1] * _scale[1],
245  ta->_scale[2] * _scale[2],
246  ta->_scale[3] * _scale[3]);
247 
248  ColorScaleAttrib *attrib = new ColorScaleAttrib(is_off(), new_scale);
249  return return_new(attrib);
250 }
251 
252 ////////////////////////////////////////////////////////////////////
253 // Function: ColorScaleAttrib::invert_compose_impl
254 // Access: Protected, Virtual
255 // Description: Intended to be overridden by derived RenderAttrib
256 // types to specify how two consecutive RenderAttrib
257 // objects of the same type interact.
258 //
259 // See invert_compose() and compose_impl().
260 ////////////////////////////////////////////////////////////////////
262 invert_compose_impl(const RenderAttrib *other) const {
263  if (is_off()) {
264  return other;
265  }
266  const ColorScaleAttrib *ta;
267  DCAST_INTO_R(ta, other, 0);
268  LVecBase4 new_scale(_scale[0] == 0.0f ? 1.0f : ta->_scale[0] / _scale[0],
269  _scale[1] == 0.0f ? 1.0f : ta->_scale[1] / _scale[1],
270  _scale[2] == 0.0f ? 1.0f : ta->_scale[2] / _scale[2],
271  _scale[3] == 0.0f ? 1.0f : ta->_scale[3] / _scale[3]);
272 
273  ColorScaleAttrib *attrib = new ColorScaleAttrib(false, new_scale);
274  return return_new(attrib);
275 }
276 
277 ////////////////////////////////////////////////////////////////////
278 // Function: ColorScaleAttrib::get_auto_shader_attrib_impl
279 // Access: Protected, Virtual
280 // Description:
281 ////////////////////////////////////////////////////////////////////
283 get_auto_shader_attrib_impl(const RenderState *state) const {
284  // A ColorScaleAttrib doesn't directly contribute to the auto-shader
285  // contents--instead, the shader is always written to query
286  // attr_colorscale at runtime. So the attrib itself means nothing
287  // to the shader.
288  return NULL;
289 }
290 
291 ////////////////////////////////////////////////////////////////////
292 // Function: ColorScaleAttrib::quantize_scale
293 // Access: Private
294 // Description: Quantizes the color scale to the nearest multiple of
295 // 1000, just to prevent runaway accumulation of
296 // only slightly-different ColorScaleAttribs.
297 ////////////////////////////////////////////////////////////////////
298 void ColorScaleAttrib::
299 quantize_scale() {
300  _scale[0] = cfloor(_scale[0] * 1000.0f + 0.5f) * 0.001f;
301  _scale[1] = cfloor(_scale[1] * 1000.0f + 0.5f) * 0.001f;
302  _scale[2] = cfloor(_scale[2] * 1000.0f + 0.5f) * 0.001f;
303  _scale[3] = cfloor(_scale[3] * 1000.0f + 0.5f) * 0.001f;
304 }
305 
306 ////////////////////////////////////////////////////////////////////
307 // Function: ColorScaleAttrib::register_with_read_factory
308 // Access: Public, Static
309 // Description: Tells the BamReader how to create objects of type
310 // ColorScaleAttrib.
311 ////////////////////////////////////////////////////////////////////
314  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
315 }
316 
317 ////////////////////////////////////////////////////////////////////
318 // Function: ColorScaleAttrib::write_datagram
319 // Access: Public, Virtual
320 // Description: Writes the contents of this object to the datagram
321 // for shipping out to a Bam file.
322 ////////////////////////////////////////////////////////////////////
325  RenderAttrib::write_datagram(manager, dg);
326 
327  // We cheat, and modify the bam stream without upping the bam
328  // version. We can do this since we know that no existing bam files
329  // have a ColorScaleAttrib in them.
330  dg.add_bool(_off);
331  _scale.write_datagram(dg);
332 }
333 
334 ////////////////////////////////////////////////////////////////////
335 // Function: ColorScaleAttrib::make_from_bam
336 // Access: Protected, Static
337 // Description: This function is called by the BamReader's factory
338 // when a new object of type ColorScaleAttrib is encountered
339 // in the Bam file. It should create the ColorScaleAttrib
340 // and extract its information from the file.
341 ////////////////////////////////////////////////////////////////////
342 TypedWritable *ColorScaleAttrib::
343 make_from_bam(const FactoryParams &params) {
344  ColorScaleAttrib *attrib = new ColorScaleAttrib(false, LVecBase4(1.0f, 1.0f, 1.0f, 1.0f));
345  DatagramIterator scan;
346  BamReader *manager;
347 
348  parse_params(params, scan, manager);
349  attrib->fillin(scan, manager);
350 
351  return attrib;
352 }
353 
354 ////////////////////////////////////////////////////////////////////
355 // Function: ColorScaleAttrib::fillin
356 // Access: Protected
357 // Description: This internal function is called by make_from_bam to
358 // read in all of the relevant data from the BamFile for
359 // the new ColorScaleAttrib.
360 ////////////////////////////////////////////////////////////////////
361 void ColorScaleAttrib::
362 fillin(DatagramIterator &scan, BamReader *manager) {
363  RenderAttrib::fillin(scan, manager);
364 
365  _off = scan.get_bool();
366  _scale.read_datagram(scan);
367  quantize_scale();
368  _has_scale = !_scale.almost_equal(LVecBase4(1.0f, 1.0f, 1.0f, 1.0f));
369  _has_rgb_scale = !LVecBase3(_scale[0], _scale[1], _scale[2]).almost_equal(LVecBase3(1.0f, 1.0f, 1.0f));
370  _has_alpha_scale = !IS_NEARLY_EQUAL(_scale[3], 1.0f);
371 }
int compare_to(const LVecBase4f &other) const
This flavor of compare_to uses a default threshold value based on the numeric type.
Definition: lvecBase4.h:971
bool almost_equal(const LVecBase4f &other, float threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
Definition: lvecBase4.h:1323
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
bool get_bool()
Extracts a boolean value.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:60
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h: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.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
bool has_scale() const
Returns true if the ColorScaleAttrib has a non-identity scale, false otherwise (in which case it migh...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:122
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.
const LVecBase4 & get_scale() const
Returns the scale to be applied to colors.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void read_datagram(DatagramIterator &source)
Reads the vector from the Datagram using get_stdfloat().
Definition: lvecBase4.h:1442
static void register_with_read_factory()
Tells the BamReader how to create objects of type ColorScaleAttrib.
Applies a scale to colors in the scene graph and on vertices.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
void write_datagram(Datagram &destination) const
Writes the vector to the Datagram using add_stdfloat().
Definition: lvecBase4.h:1422
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
bool almost_equal(const LVecBase3f &other, float threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
Definition: lvecBase3.h:1264
bool is_off() const
Returns true if the ColorScaleAttrib will ignore any color scales inherited from above, false otherwise.
A class to retrieve the individual data elements previously stored in a Datagram. ...
virtual bool lower_attrib_can_override() const
Intended to be overridden by derived RenderAttrib types to specify how two consecutive RenderAttrib o...
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
size_t add_hash(size_t hash) const
Adds the vector into the running hash.
Definition: lvecBase4.h:1009