Panda3D
|
00001 // Filename: cullFaceAttrib.cxx 00002 // Created by: drose (27Feb02) 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 "cullFaceAttrib.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 00023 TypeHandle CullFaceAttrib::_type_handle; 00024 int CullFaceAttrib::_attrib_slot; 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: CullFaceAttrib::make 00028 // Access: Published, Static 00029 // Description: Constructs a new CullFaceAttrib object that specifies 00030 // how to cull geometry. By Panda convention, vertices 00031 // are ordered counterclockwise when seen from the 00032 // front, so the M_cull_clockwise will cull backfacing 00033 // polygons. 00034 // 00035 // M_cull_unchanged is an identity attrib; if this is 00036 // applied to vertices without any other intervening 00037 // attrib, it is the same as applying the default 00038 // attrib. 00039 //////////////////////////////////////////////////////////////////// 00040 CPT(RenderAttrib) CullFaceAttrib:: 00041 make(CullFaceAttrib::Mode mode) { 00042 CullFaceAttrib *attrib = new CullFaceAttrib(mode, false); 00043 return return_new(attrib); 00044 } 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Function: CullFaceAttrib::make_reverse 00048 // Access: Published, Static 00049 // Description: Constructs a new CullFaceAttrib object that reverses 00050 // the effects of any other CullFaceAttrib objects in 00051 // the scene graph. M_cull_clockwise will be treated as 00052 // M_cull_counter_clockwise, and vice-versa. 00053 // M_cull_none is unchanged. 00054 //////////////////////////////////////////////////////////////////// 00055 CPT(RenderAttrib) CullFaceAttrib:: 00056 make_reverse() { 00057 CullFaceAttrib *attrib = new CullFaceAttrib(M_cull_unchanged, true); 00058 return return_new(attrib); 00059 } 00060 00061 //////////////////////////////////////////////////////////////////// 00062 // Function: CullFaceAttrib::make_default 00063 // Access: Published, Static 00064 // Description: Returns a RenderAttrib that corresponds to whatever 00065 // the standard default properties for render attributes 00066 // of this type ought to be. 00067 //////////////////////////////////////////////////////////////////// 00068 CPT(RenderAttrib) CullFaceAttrib:: 00069 make_default() { 00070 return return_new(new CullFaceAttrib(M_cull_clockwise, false)); 00071 } 00072 00073 //////////////////////////////////////////////////////////////////// 00074 // Function: CullFaceAttrib::get_effective_mode 00075 // Access: Published 00076 // Description: Returns the effective culling mode. This is the same 00077 // as the actual culling mode, unless the reverse flag 00078 // is set, which swaps CW for CCW and vice-versa. Also, 00079 // M_cull_unchanged is mapped to M_cull_none. 00080 //////////////////////////////////////////////////////////////////// 00081 CullFaceAttrib::Mode CullFaceAttrib:: 00082 get_effective_mode() const { 00083 if (_reverse) { 00084 switch (_mode) { 00085 case M_cull_clockwise: 00086 case M_cull_unchanged: 00087 return M_cull_counter_clockwise; 00088 00089 case M_cull_counter_clockwise: 00090 return M_cull_clockwise; 00091 00092 default: 00093 break; 00094 } 00095 00096 } else { 00097 switch (_mode) { 00098 case M_cull_clockwise: 00099 case M_cull_unchanged: 00100 return M_cull_clockwise; 00101 00102 case M_cull_counter_clockwise: 00103 return M_cull_counter_clockwise; 00104 00105 default: 00106 break; 00107 } 00108 } 00109 00110 return M_cull_none; 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function: CullFaceAttrib::output 00115 // Access: Public, Virtual 00116 // Description: 00117 //////////////////////////////////////////////////////////////////// 00118 void CullFaceAttrib:: 00119 output(ostream &out) const { 00120 out << get_type() << ":"; 00121 switch (get_actual_mode()) { 00122 case M_cull_none: 00123 out << "cull_none"; 00124 break; 00125 case M_cull_clockwise: 00126 out << "cull_clockwise"; 00127 break; 00128 case M_cull_counter_clockwise: 00129 out << "cull_counter_clockwise"; 00130 break; 00131 case M_cull_unchanged: 00132 out << "cull_unchanged"; 00133 break; 00134 } 00135 if (get_reverse()) { 00136 out << "(reverse)"; 00137 } 00138 } 00139 00140 //////////////////////////////////////////////////////////////////// 00141 // Function: CullFaceAttrib::compare_to_impl 00142 // Access: Protected, Virtual 00143 // Description: Intended to be overridden by derived CullFaceAttrib 00144 // types to return a unique number indicating whether 00145 // this CullFaceAttrib is equivalent to the other one. 00146 // 00147 // This should return 0 if the two CullFaceAttrib objects 00148 // are equivalent, a number less than zero if this one 00149 // should be sorted before the other one, and a number 00150 // greater than zero otherwise. 00151 // 00152 // This will only be called with two CullFaceAttrib 00153 // objects whose get_type() functions return the same. 00154 //////////////////////////////////////////////////////////////////// 00155 int CullFaceAttrib:: 00156 compare_to_impl(const RenderAttrib *other) const { 00157 const CullFaceAttrib *ta; 00158 DCAST_INTO_R(ta, other, 0); 00159 if (_mode != ta->_mode) { 00160 return (int)_mode - (int)ta->_mode; 00161 } 00162 return (int)_reverse - (int)ta->_reverse; 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: CullFaceAttrib::get_hash_impl 00167 // Access: Protected, Virtual 00168 // Description: Intended to be overridden by derived RenderAttrib 00169 // types to return a unique hash for these particular 00170 // properties. RenderAttribs that compare the same with 00171 // compare_to_impl(), above, should return the same 00172 // hash; RenderAttribs that compare differently should 00173 // return a different hash. 00174 //////////////////////////////////////////////////////////////////// 00175 size_t CullFaceAttrib:: 00176 get_hash_impl() const { 00177 size_t hash = 0; 00178 hash = int_hash::add_hash(hash, (int)_mode); 00179 hash = int_hash::add_hash(hash, (int)_reverse); 00180 return hash; 00181 } 00182 00183 //////////////////////////////////////////////////////////////////// 00184 // Function: CullFaceAttrib::compose_impl 00185 // Access: Protected, Virtual 00186 // Description: Intended to be overridden by derived RenderAttrib 00187 // types to specify how two consecutive RenderAttrib 00188 // objects of the same type interact. 00189 // 00190 // This should return the result of applying the other 00191 // RenderAttrib to a node in the scene graph below this 00192 // RenderAttrib, which was already applied. In most 00193 // cases, the result is the same as the other 00194 // RenderAttrib (that is, a subsequent RenderAttrib 00195 // completely replaces the preceding one). On the other 00196 // hand, some kinds of RenderAttrib (for instance, 00197 // ColorTransformAttrib) might combine in meaningful 00198 // ways. 00199 //////////////////////////////////////////////////////////////////// 00200 CPT(RenderAttrib) CullFaceAttrib:: 00201 compose_impl(const RenderAttrib *other) const { 00202 const CullFaceAttrib *ta; 00203 DCAST_INTO_R(ta, other, 0); 00204 00205 if (!_reverse && ta->_mode != M_cull_unchanged) { 00206 // The normal case (there is nothing funny going on): the second 00207 // attrib completely replaces this attrib. 00208 return other; 00209 } 00210 00211 // In the more complex case, the two attribs affect each other in 00212 // some way, and we must generate a new attrib from the result. 00213 Mode mode = _mode; 00214 if (ta->_mode != M_cull_unchanged) { 00215 mode = ta->_mode; 00216 } 00217 bool reverse = (_reverse && !ta->_reverse) || (!_reverse && ta->_reverse); 00218 00219 CullFaceAttrib *attrib = new CullFaceAttrib(mode, reverse); 00220 return return_new(attrib); 00221 } 00222 00223 //////////////////////////////////////////////////////////////////// 00224 // Function: CullFaceAttrib::invert_compose_impl 00225 // Access: Protected, Virtual 00226 // Description: Intended to be overridden by derived RenderAttrib 00227 // types to specify how two consecutive RenderAttrib 00228 // objects of the same type interact. 00229 // 00230 // See invert_compose() and compose_impl(). 00231 //////////////////////////////////////////////////////////////////// 00232 CPT(RenderAttrib) CullFaceAttrib:: 00233 invert_compose_impl(const RenderAttrib *other) const { 00234 const CullFaceAttrib *ta; 00235 DCAST_INTO_R(ta, other, 0); 00236 00237 // The invert case is the same as the normal case, except that the 00238 // meaning of _reverse is inverted. See compose_impl(), above. 00239 00240 if (_reverse && ta->_mode != M_cull_unchanged) { 00241 return other; 00242 } 00243 00244 Mode mode = _mode; 00245 if (ta->_mode != M_cull_unchanged) { 00246 mode = ta->_mode; 00247 } 00248 bool reverse = (!_reverse && !ta->_reverse) || (_reverse && ta->_reverse); 00249 00250 CullFaceAttrib *attrib = new CullFaceAttrib(mode, reverse); 00251 return return_new(attrib); 00252 } 00253 00254 //////////////////////////////////////////////////////////////////// 00255 // Function: CullFaceAttrib::register_with_read_factory 00256 // Access: Public, Static 00257 // Description: Tells the BamReader how to create objects of type 00258 // CullFaceAttrib. 00259 //////////////////////////////////////////////////////////////////// 00260 void CullFaceAttrib:: 00261 register_with_read_factory() { 00262 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00263 } 00264 00265 //////////////////////////////////////////////////////////////////// 00266 // Function: CullFaceAttrib::write_datagram 00267 // Access: Public, Virtual 00268 // Description: Writes the contents of this object to the datagram 00269 // for shipping out to a Bam file. 00270 //////////////////////////////////////////////////////////////////// 00271 void CullFaceAttrib:: 00272 write_datagram(BamWriter *manager, Datagram &dg) { 00273 RenderAttrib::write_datagram(manager, dg); 00274 00275 dg.add_int8(_mode); 00276 dg.add_bool(_reverse); 00277 } 00278 00279 //////////////////////////////////////////////////////////////////// 00280 // Function: CullFaceAttrib::make_from_bam 00281 // Access: Protected, Static 00282 // Description: This function is called by the BamReader's factory 00283 // when a new object of type CullFaceAttrib is encountered 00284 // in the Bam file. It should create the CullFaceAttrib 00285 // and extract its information from the file. 00286 //////////////////////////////////////////////////////////////////// 00287 TypedWritable *CullFaceAttrib:: 00288 make_from_bam(const FactoryParams ¶ms) { 00289 CullFaceAttrib *attrib = new CullFaceAttrib(M_cull_none, false); 00290 DatagramIterator scan; 00291 BamReader *manager; 00292 00293 parse_params(params, scan, manager); 00294 attrib->fillin(scan, manager); 00295 00296 return attrib; 00297 } 00298 00299 //////////////////////////////////////////////////////////////////// 00300 // Function: CullFaceAttrib::fillin 00301 // Access: Protected 00302 // Description: This internal function is called by make_from_bam to 00303 // read in all of the relevant data from the BamFile for 00304 // the new CullFaceAttrib. 00305 //////////////////////////////////////////////////////////////////// 00306 void CullFaceAttrib:: 00307 fillin(DatagramIterator &scan, BamReader *manager) { 00308 RenderAttrib::fillin(scan, manager); 00309 00310 _mode = (Mode)scan.get_int8(); 00311 _reverse = scan.get_bool(); 00312 }