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