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  */
257 write_datagram(BamWriter *manager, Datagram &dg) {
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 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
Applies a scale to colors in the scene graph and on vertices.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
has_scale
Returns true if the ColorScaleAttrib has a non-identity scale, false otherwise (in which case it migh...
get_scale
Returns the scale to be applied to colors.
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.
A class to retrieve the individual data elements previously stored in a Datagram.
bool get_bool()
Extracts a boolean value.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:34
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
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
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:101
CPT(RenderAttrib) ColorScaleAttrib
Constructs an identity scale attrib.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.