Panda3D

colorScaleAttrib.cxx

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 &params) {
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 }
 All Classes Functions Variables Enumerations