Panda3D
Loading...
Searching...
No Matches
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
23TypeHandle ColorScaleAttrib::_type_handle;
24int ColorScaleAttrib::_attrib_slot;
25CPT(RenderAttrib) ColorScaleAttrib::_identity_attrib;
26
27/**
28 * Use ColorScaleAttrib::make() to construct a new ColorScaleAttrib object.
29 */
30ColorScaleAttrib::
31ColorScaleAttrib(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 */
44CPT(RenderAttrib) ColorScaleAttrib::
45make_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 */
60CPT(RenderAttrib) ColorScaleAttrib::
61make(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 */
71CPT(RenderAttrib) ColorScaleAttrib::
72make_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 */
82CPT(RenderAttrib) ColorScaleAttrib::
83make_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 */
91CPT(RenderAttrib) ColorScaleAttrib::
92set_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 */
131void ColorScaleAttrib::
132output(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 */
157int ColorScaleAttrib::
158compare_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 */
174size_t ColorScaleAttrib::
175get_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 */
193CPT(RenderAttrib) ColorScaleAttrib::
194compose_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 */
216CPT(RenderAttrib) ColorScaleAttrib::
217invert_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 */
236void ColorScaleAttrib::
237quantize_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 */
257write_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 */
272TypedWritable *ColorScaleAttrib::
273make_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 */
288void ColorScaleAttrib::
289fillin(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...
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...
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.
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
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.