Panda3D
|
00001 // Filename: colorScaleAttrib.cxx 00002 // Created by: drose (14Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "colorScaleAttrib.h" 00016 #include "graphicsStateGuardianBase.h" 00017 #include "dcast.h" 00018 #include "bamReader.h" 00019 #include "bamWriter.h" 00020 #include "datagram.h" 00021 #include "datagramIterator.h" 00022 #include "config_pgraph.h" 00023 00024 TypeHandle ColorScaleAttrib::_type_handle; 00025 int ColorScaleAttrib::_attrib_slot; 00026 CPT(RenderAttrib) ColorScaleAttrib::_identity_attrib; 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: ColorScaleAttrib::Constructor 00030 // Access: Protected 00031 // Description: Use ColorScaleAttrib::make() to construct a new 00032 // ColorScaleAttrib object. 00033 //////////////////////////////////////////////////////////////////// 00034 ColorScaleAttrib:: 00035 ColorScaleAttrib(bool off, const LVecBase4 &scale) : 00036 _off(off), 00037 _scale(scale) 00038 { 00039 quantize_scale(); 00040 _has_scale = !_scale.almost_equal(LVecBase4(1.0f, 1.0f, 1.0f, 1.0f)); 00041 _has_rgb_scale = !LVecBase3(_scale[0], _scale[1], _scale[2]).almost_equal(LVecBase3(1.0f, 1.0f, 1.0f)); 00042 _has_alpha_scale = !IS_NEARLY_EQUAL(_scale[3], 1.0f); 00043 } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: ColorScaleAttrib::make_identity 00047 // Access: Published, Static 00048 // Description: Constructs an identity scale attrib. 00049 //////////////////////////////////////////////////////////////////// 00050 CPT(RenderAttrib) ColorScaleAttrib:: 00051 make_identity() { 00052 // We make identity a special case and store a pointer forever once 00053 // we find it the first time. 00054 if (_identity_attrib == (ColorScaleAttrib *)NULL) { 00055 ColorScaleAttrib *attrib = new ColorScaleAttrib(false, LVecBase4(1.0f, 1.0f, 1.0f, 1.0f));; 00056 _identity_attrib = return_new(attrib); 00057 } 00058 00059 return _identity_attrib; 00060 } 00061 00062 //////////////////////////////////////////////////////////////////// 00063 // Function: ColorScaleAttrib::make 00064 // Access: Published, Static 00065 // Description: Constructs a new ColorScaleAttrib object that indicates 00066 // geometry should be scaled by the indicated factor. 00067 //////////////////////////////////////////////////////////////////// 00068 CPT(RenderAttrib) ColorScaleAttrib:: 00069 make(const LVecBase4 &scale) { 00070 ColorScaleAttrib *attrib = new ColorScaleAttrib(false, scale); 00071 return return_new(attrib); 00072 } 00073 00074 //////////////////////////////////////////////////////////////////// 00075 // Function: ColorScaleAttrib::make_off 00076 // Access: Published, Static 00077 // Description: Constructs a new ColorScaleAttrib object that ignores 00078 // any ColorScaleAttrib inherited from above. You may 00079 // also specify an additional color scale to apply to 00080 // geometry below (using set_scale()). 00081 //////////////////////////////////////////////////////////////////// 00082 CPT(RenderAttrib) ColorScaleAttrib:: 00083 make_off() { 00084 ColorScaleAttrib *attrib = 00085 new ColorScaleAttrib(true, LVecBase4(1.0f, 1.0f, 1.0f, 1.0f)); 00086 return return_new(attrib); 00087 } 00088 00089 //////////////////////////////////////////////////////////////////// 00090 // Function: ColorScaleAttrib::make_default 00091 // Access: Published, Static 00092 // Description: Returns a RenderAttrib that corresponds to whatever 00093 // the standard default properties for render attributes 00094 // of this type ought to be. 00095 //////////////////////////////////////////////////////////////////// 00096 CPT(RenderAttrib) ColorScaleAttrib:: 00097 make_default() { 00098 return return_new(new ColorScaleAttrib(false, LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))); 00099 } 00100 00101 //////////////////////////////////////////////////////////////////// 00102 // Function: ColorScaleAttrib::set_scale 00103 // Access: Published 00104 // Description: Returns a new ColorScaleAttrib, just like this one, but 00105 // with the scale changed to the indicated value. 00106 //////////////////////////////////////////////////////////////////// 00107 CPT(RenderAttrib) ColorScaleAttrib:: 00108 set_scale(const LVecBase4 &scale) const { 00109 ColorScaleAttrib *attrib = new ColorScaleAttrib(*this); 00110 attrib->_scale = scale; 00111 attrib->quantize_scale(); 00112 attrib->_has_scale = !scale.almost_equal(LVecBase4(1.0f, 1.0f, 1.0f, 1.0f)); 00113 attrib->_has_rgb_scale = !LVecBase3(scale[0], scale[1], scale[2]).almost_equal(LVecBase3(1.0f, 1.0f, 1.0f)); 00114 attrib->_has_alpha_scale = !IS_NEARLY_EQUAL(scale[3], 1.0f); 00115 return return_new(attrib); 00116 } 00117 00118 //////////////////////////////////////////////////////////////////// 00119 // Function: ColorScaleAttrib::lower_attrib_can_override 00120 // Access: Public, Virtual 00121 // Description: Intended to be overridden by derived RenderAttrib 00122 // types to specify how two consecutive RenderAttrib 00123 // objects of the same type interact. 00124 // 00125 // This should return false if a RenderAttrib on a 00126 // higher node will compose into a RenderAttrib on a 00127 // lower node that has a higher override value, or false 00128 // if the lower RenderAttrib will completely replace the 00129 // state. 00130 // 00131 // The default behavior is false: normally, a 00132 // RenderAttrib in the graph cannot completely override 00133 // a RenderAttrib above it, regardless of its override 00134 // value--instead, the two attribs are composed. But 00135 // for some kinds of RenderAttribs, it is useful to 00136 // allow this kind of override. 00137 // 00138 // This method only handles the one special case of a 00139 // lower RenderAttrib with a higher override value. If 00140 // the higher RenderAttrib has a higher override value, 00141 // it always completely overrides. And if both 00142 // RenderAttribs have the same override value, they are 00143 // always composed. 00144 //////////////////////////////////////////////////////////////////// 00145 bool ColorScaleAttrib:: 00146 lower_attrib_can_override() const { 00147 // A ColorScaleAttrib doesn't compose through an override. This 00148 // allows us to meaningfully set an override on a lower node, which 00149 // prevents any color scales from coming in from above. 00150 return true; 00151 } 00152 00153 //////////////////////////////////////////////////////////////////// 00154 // Function: ColorScaleAttrib::output 00155 // Access: Public, Virtual 00156 // Description: 00157 //////////////////////////////////////////////////////////////////// 00158 void ColorScaleAttrib:: 00159 output(ostream &out) const { 00160 out << get_type() << ":"; 00161 if (is_off()) { 00162 out << "off"; 00163 } 00164 if (has_scale()) { 00165 out << "(" << get_scale() << ")"; 00166 00167 } else if (!is_off()) { 00168 out << "identity"; 00169 } 00170 } 00171 00172 //////////////////////////////////////////////////////////////////// 00173 // Function: ColorScaleAttrib::compare_to_impl 00174 // Access: Protected, Virtual 00175 // Description: Intended to be overridden by derived ColorScaleAttrib 00176 // types to return a unique number indicating whether 00177 // this ColorScaleAttrib is equivalent to the other one. 00178 // 00179 // This should return 0 if the two ColorScaleAttrib objects 00180 // are equivalent, a number less than zero if this one 00181 // should be sorted before the other one, and a number 00182 // greater than zero otherwise. 00183 // 00184 // This will only be called with two ColorScaleAttrib 00185 // objects whose get_type() functions return the same. 00186 //////////////////////////////////////////////////////////////////// 00187 int ColorScaleAttrib:: 00188 compare_to_impl(const RenderAttrib *other) const { 00189 const ColorScaleAttrib *ta; 00190 DCAST_INTO_R(ta, other, 0); 00191 00192 if (is_off() != ta->is_off()) { 00193 return (int)is_off() - (int)ta->is_off(); 00194 } 00195 00196 return _scale.compare_to(ta->_scale); 00197 } 00198 00199 //////////////////////////////////////////////////////////////////// 00200 // Function: ColorScaleAttrib::get_hash_impl 00201 // Access: Protected, Virtual 00202 // Description: Intended to be overridden by derived RenderAttrib 00203 // types to return a unique hash for these particular 00204 // properties. RenderAttribs that compare the same with 00205 // compare_to_impl(), above, should return the same 00206 // hash; RenderAttribs that compare differently should 00207 // return a different hash. 00208 //////////////////////////////////////////////////////////////////// 00209 size_t ColorScaleAttrib:: 00210 get_hash_impl() const { 00211 size_t hash = 0; 00212 hash = int_hash::add_hash(hash, (int)is_off()); 00213 hash = _scale.add_hash(hash); 00214 return hash; 00215 } 00216 00217 //////////////////////////////////////////////////////////////////// 00218 // Function: ColorScaleAttrib::compose_impl 00219 // Access: Protected, Virtual 00220 // Description: Intended to be overridden by derived RenderAttrib 00221 // types to specify how two consecutive RenderAttrib 00222 // objects of the same type interact. 00223 // 00224 // This should return the result of applying the other 00225 // RenderAttrib to a node in the scene graph below this 00226 // RenderAttrib, which was already applied. In most 00227 // cases, the result is the same as the other 00228 // RenderAttrib (that is, a subsequent RenderAttrib 00229 // completely replaces the preceding one). On the other 00230 // hand, some kinds of RenderAttrib (for instance, 00231 // ColorTransformAttrib) might combine in meaningful 00232 // ways. 00233 //////////////////////////////////////////////////////////////////// 00234 CPT(RenderAttrib) ColorScaleAttrib:: 00235 compose_impl(const RenderAttrib *other) const { 00236 const ColorScaleAttrib *ta; 00237 DCAST_INTO_R(ta, other, 0); 00238 00239 if (ta->is_off()) { 00240 return ta; 00241 } 00242 00243 LVecBase4 new_scale(ta->_scale[0] * _scale[0], 00244 ta->_scale[1] * _scale[1], 00245 ta->_scale[2] * _scale[2], 00246 ta->_scale[3] * _scale[3]); 00247 00248 ColorScaleAttrib *attrib = new ColorScaleAttrib(is_off(), new_scale); 00249 return return_new(attrib); 00250 } 00251 00252 //////////////////////////////////////////////////////////////////// 00253 // Function: ColorScaleAttrib::invert_compose_impl 00254 // Access: Protected, Virtual 00255 // Description: Intended to be overridden by derived RenderAttrib 00256 // types to specify how two consecutive RenderAttrib 00257 // objects of the same type interact. 00258 // 00259 // See invert_compose() and compose_impl(). 00260 //////////////////////////////////////////////////////////////////// 00261 CPT(RenderAttrib) ColorScaleAttrib:: 00262 invert_compose_impl(const RenderAttrib *other) const { 00263 if (is_off()) { 00264 return other; 00265 } 00266 const ColorScaleAttrib *ta; 00267 DCAST_INTO_R(ta, other, 0); 00268 LVecBase4 new_scale(_scale[0] == 0.0f ? 1.0f : ta->_scale[0] / _scale[0], 00269 _scale[1] == 0.0f ? 1.0f : ta->_scale[1] / _scale[1], 00270 _scale[2] == 0.0f ? 1.0f : ta->_scale[2] / _scale[2], 00271 _scale[3] == 0.0f ? 1.0f : ta->_scale[3] / _scale[3]); 00272 00273 ColorScaleAttrib *attrib = new ColorScaleAttrib(false, new_scale); 00274 return return_new(attrib); 00275 } 00276 00277 //////////////////////////////////////////////////////////////////// 00278 // Function: ColorScaleAttrib::get_auto_shader_attrib_impl 00279 // Access: Protected, Virtual 00280 // Description: 00281 //////////////////////////////////////////////////////////////////// 00282 CPT(RenderAttrib) ColorScaleAttrib:: 00283 get_auto_shader_attrib_impl(const RenderState *state) const { 00284 // A ColorScaleAttrib doesn't directly contribute to the auto-shader 00285 // contents--instead, the shader is always written to query 00286 // attr_colorscale at runtime. So the attrib itself means nothing 00287 // to the shader. 00288 return NULL; 00289 } 00290 00291 //////////////////////////////////////////////////////////////////// 00292 // Function: ColorScaleAttrib::quantize_scale 00293 // Access: Private 00294 // Description: Quantizes the color scale to the nearest multiple of 00295 // 1000, just to prevent runaway accumulation of 00296 // only slightly-different ColorScaleAttribs. 00297 //////////////////////////////////////////////////////////////////// 00298 void ColorScaleAttrib:: 00299 quantize_scale() { 00300 _scale[0] = cfloor(_scale[0] * 1000.0f + 0.5f) * 0.001f; 00301 _scale[1] = cfloor(_scale[1] * 1000.0f + 0.5f) * 0.001f; 00302 _scale[2] = cfloor(_scale[2] * 1000.0f + 0.5f) * 0.001f; 00303 _scale[3] = cfloor(_scale[3] * 1000.0f + 0.5f) * 0.001f; 00304 } 00305 00306 //////////////////////////////////////////////////////////////////// 00307 // Function: ColorScaleAttrib::register_with_read_factory 00308 // Access: Public, Static 00309 // Description: Tells the BamReader how to create objects of type 00310 // ColorScaleAttrib. 00311 //////////////////////////////////////////////////////////////////// 00312 void ColorScaleAttrib:: 00313 register_with_read_factory() { 00314 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00315 } 00316 00317 //////////////////////////////////////////////////////////////////// 00318 // Function: ColorScaleAttrib::write_datagram 00319 // Access: Public, Virtual 00320 // Description: Writes the contents of this object to the datagram 00321 // for shipping out to a Bam file. 00322 //////////////////////////////////////////////////////////////////// 00323 void ColorScaleAttrib:: 00324 write_datagram(BamWriter *manager, Datagram &dg) { 00325 RenderAttrib::write_datagram(manager, dg); 00326 00327 // We cheat, and modify the bam stream without upping the bam 00328 // version. We can do this since we know that no existing bam files 00329 // have a ColorScaleAttrib in them. 00330 dg.add_bool(_off); 00331 _scale.write_datagram(dg); 00332 } 00333 00334 //////////////////////////////////////////////////////////////////// 00335 // Function: ColorScaleAttrib::make_from_bam 00336 // Access: Protected, Static 00337 // Description: This function is called by the BamReader's factory 00338 // when a new object of type ColorScaleAttrib is encountered 00339 // in the Bam file. It should create the ColorScaleAttrib 00340 // and extract its information from the file. 00341 //////////////////////////////////////////////////////////////////// 00342 TypedWritable *ColorScaleAttrib:: 00343 make_from_bam(const FactoryParams ¶ms) { 00344 ColorScaleAttrib *attrib = new ColorScaleAttrib(false, LVecBase4(1.0f, 1.0f, 1.0f, 1.0f)); 00345 DatagramIterator scan; 00346 BamReader *manager; 00347 00348 parse_params(params, scan, manager); 00349 attrib->fillin(scan, manager); 00350 00351 return attrib; 00352 } 00353 00354 //////////////////////////////////////////////////////////////////// 00355 // Function: ColorScaleAttrib::fillin 00356 // Access: Protected 00357 // Description: This internal function is called by make_from_bam to 00358 // read in all of the relevant data from the BamFile for 00359 // the new ColorScaleAttrib. 00360 //////////////////////////////////////////////////////////////////// 00361 void ColorScaleAttrib:: 00362 fillin(DatagramIterator &scan, BamReader *manager) { 00363 RenderAttrib::fillin(scan, manager); 00364 00365 _off = scan.get_bool(); 00366 _scale.read_datagram(scan); 00367 quantize_scale(); 00368 _has_scale = !_scale.almost_equal(LVecBase4(1.0f, 1.0f, 1.0f, 1.0f)); 00369 _has_rgb_scale = !LVecBase3(_scale[0], _scale[1], _scale[2]).almost_equal(LVecBase3(1.0f, 1.0f, 1.0f)); 00370 _has_alpha_scale = !IS_NEARLY_EQUAL(_scale[3], 1.0f); 00371 }