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