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 LVecBase4f &scale) : 00036 _off(off), 00037 _scale(scale) 00038 { 00039 quantize_scale(); 00040 _has_scale = !_scale.almost_equal(LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f)); 00041 _has_rgb_scale = !LVecBase3f(_scale[0], _scale[1], _scale[2]).almost_equal(LVecBase3f(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, LVecBase4f(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 LVecBase4f &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, LVecBase4f(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, LVecBase4f(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 LVecBase4f &scale) const { 00109 ColorScaleAttrib *attrib = new ColorScaleAttrib(*this); 00110 attrib->_scale = scale; 00111 attrib->quantize_scale(); 00112 attrib->_has_scale = !scale.almost_equal(LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f)); 00113 attrib->_has_rgb_scale = !LVecBase3f(scale[0], scale[1], scale[2]).almost_equal(LVecBase3f(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 if (pgraph_cat.is_spam()) { 00194 pgraph_cat.spam() 00195 << "Comparing " << (int)is_off() << " to " << (int)ta->is_off() << " result = " 00196 << (int)is_off() - (int)ta->is_off() << "\n"; 00197 } 00198 00199 return (int)is_off() - (int)ta->is_off(); 00200 } 00201 00202 if (pgraph_cat.is_spam()) { 00203 pgraph_cat.spam() 00204 << "Comparing " << _scale << " to " << ta->_scale << " result = " 00205 << _scale.compare_to(ta->_scale) << "\n"; 00206 } 00207 00208 return _scale.compare_to(ta->_scale); 00209 } 00210 00211 //////////////////////////////////////////////////////////////////// 00212 // Function: ColorScaleAttrib::compose_impl 00213 // Access: Protected, Virtual 00214 // Description: Intended to be overridden by derived RenderAttrib 00215 // types to specify how two consecutive RenderAttrib 00216 // objects of the same type interact. 00217 // 00218 // This should return the result of applying the other 00219 // RenderAttrib to a node in the scene graph below this 00220 // RenderAttrib, which was already applied. In most 00221 // cases, the result is the same as the other 00222 // RenderAttrib (that is, a subsequent RenderAttrib 00223 // completely replaces the preceding one). On the other 00224 // hand, some kinds of RenderAttrib (for instance, 00225 // ColorTransformAttrib) might combine in meaningful 00226 // ways. 00227 //////////////////////////////////////////////////////////////////// 00228 CPT(RenderAttrib) ColorScaleAttrib:: 00229 compose_impl(const RenderAttrib *other) const { 00230 const ColorScaleAttrib *ta; 00231 DCAST_INTO_R(ta, other, 0); 00232 00233 if (ta->is_off()) { 00234 return ta; 00235 } 00236 00237 LVecBase4f new_scale(ta->_scale[0] * _scale[0], 00238 ta->_scale[1] * _scale[1], 00239 ta->_scale[2] * _scale[2], 00240 ta->_scale[3] * _scale[3]); 00241 00242 ColorScaleAttrib *attrib = new ColorScaleAttrib(is_off(), new_scale); 00243 return return_new(attrib); 00244 } 00245 00246 //////////////////////////////////////////////////////////////////// 00247 // Function: ColorScaleAttrib::invert_compose_impl 00248 // Access: Protected, Virtual 00249 // Description: Intended to be overridden by derived RenderAttrib 00250 // types to specify how two consecutive RenderAttrib 00251 // objects of the same type interact. 00252 // 00253 // See invert_compose() and compose_impl(). 00254 //////////////////////////////////////////////////////////////////// 00255 CPT(RenderAttrib) ColorScaleAttrib:: 00256 invert_compose_impl(const RenderAttrib *other) const { 00257 if (is_off()) { 00258 return other; 00259 } 00260 const ColorScaleAttrib *ta; 00261 DCAST_INTO_R(ta, other, 0); 00262 LVecBase4f new_scale(_scale[0] == 0.0f ? 1.0f : ta->_scale[0] / _scale[0], 00263 _scale[1] == 0.0f ? 1.0f : ta->_scale[1] / _scale[1], 00264 _scale[2] == 0.0f ? 1.0f : ta->_scale[2] / _scale[2], 00265 _scale[3] == 0.0f ? 1.0f : ta->_scale[3] / _scale[3]); 00266 00267 ColorScaleAttrib *attrib = new ColorScaleAttrib(false, new_scale); 00268 return return_new(attrib); 00269 } 00270 00271 //////////////////////////////////////////////////////////////////// 00272 // Function: ColorScaleAttrib::quantize_scale 00273 // Access: Private 00274 // Description: Quantizes the color scale to the nearest multiple of 00275 // 1000, just to prevent runaway accumulation of 00276 // only slightly-different ColorScaleAttribs. 00277 //////////////////////////////////////////////////////////////////// 00278 void ColorScaleAttrib:: 00279 quantize_scale() { 00280 _scale[0] = cfloor(_scale[0] * 1000.0f + 0.5f) * 0.001f; 00281 _scale[1] = cfloor(_scale[1] * 1000.0f + 0.5f) * 0.001f; 00282 _scale[2] = cfloor(_scale[2] * 1000.0f + 0.5f) * 0.001f; 00283 _scale[3] = cfloor(_scale[3] * 1000.0f + 0.5f) * 0.001f; 00284 } 00285 00286 //////////////////////////////////////////////////////////////////// 00287 // Function: ColorScaleAttrib::register_with_read_factory 00288 // Access: Public, Static 00289 // Description: Tells the BamReader how to create objects of type 00290 // ColorScaleAttrib. 00291 //////////////////////////////////////////////////////////////////// 00292 void ColorScaleAttrib:: 00293 register_with_read_factory() { 00294 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00295 } 00296 00297 //////////////////////////////////////////////////////////////////// 00298 // Function: ColorScaleAttrib::write_datagram 00299 // Access: Public, Virtual 00300 // Description: Writes the contents of this object to the datagram 00301 // for shipping out to a Bam file. 00302 //////////////////////////////////////////////////////////////////// 00303 void ColorScaleAttrib:: 00304 write_datagram(BamWriter *manager, Datagram &dg) { 00305 RenderAttrib::write_datagram(manager, dg); 00306 00307 // We cheat, and modify the bam stream without upping the bam 00308 // version. We can do this since we know that no existing bam files 00309 // have a ColorScaleAttrib in them. 00310 dg.add_bool(_off); 00311 _scale.write_datagram(dg); 00312 } 00313 00314 //////////////////////////////////////////////////////////////////// 00315 // Function: ColorScaleAttrib::make_from_bam 00316 // Access: Protected, Static 00317 // Description: This function is called by the BamReader's factory 00318 // when a new object of type ColorScaleAttrib is encountered 00319 // in the Bam file. It should create the ColorScaleAttrib 00320 // and extract its information from the file. 00321 //////////////////////////////////////////////////////////////////// 00322 TypedWritable *ColorScaleAttrib:: 00323 make_from_bam(const FactoryParams ¶ms) { 00324 ColorScaleAttrib *attrib = new ColorScaleAttrib(false, LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f)); 00325 DatagramIterator scan; 00326 BamReader *manager; 00327 00328 parse_params(params, scan, manager); 00329 attrib->fillin(scan, manager); 00330 00331 return attrib; 00332 } 00333 00334 //////////////////////////////////////////////////////////////////// 00335 // Function: ColorScaleAttrib::fillin 00336 // Access: Protected 00337 // Description: This internal function is called by make_from_bam to 00338 // read in all of the relevant data from the BamFile for 00339 // the new ColorScaleAttrib. 00340 //////////////////////////////////////////////////////////////////// 00341 void ColorScaleAttrib:: 00342 fillin(DatagramIterator &scan, BamReader *manager) { 00343 RenderAttrib::fillin(scan, manager); 00344 00345 _off = scan.get_bool(); 00346 _scale.read_datagram(scan); 00347 quantize_scale(); 00348 _has_scale = !_scale.almost_equal(LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f)); 00349 _has_rgb_scale = !LVecBase3f(_scale[0], _scale[1], _scale[2]).almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f)); 00350 _has_alpha_scale = !IS_NEARLY_EQUAL(_scale[3], 1.0f); 00351 }