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::compose_impl 00167 // Access: Protected, Virtual 00168 // Description: Intended to be overridden by derived RenderAttrib 00169 // types to specify how two consecutive RenderAttrib 00170 // objects of the same type interact. 00171 // 00172 // This should return the result of applying the other 00173 // RenderAttrib to a node in the scene graph below this 00174 // RenderAttrib, which was already applied. In most 00175 // cases, the result is the same as the other 00176 // RenderAttrib (that is, a subsequent RenderAttrib 00177 // completely replaces the preceding one). On the other 00178 // hand, some kinds of RenderAttrib (for instance, 00179 // ColorTransformAttrib) might combine in meaningful 00180 // ways. 00181 //////////////////////////////////////////////////////////////////// 00182 CPT(RenderAttrib) CullFaceAttrib:: 00183 compose_impl(const RenderAttrib *other) const { 00184 const CullFaceAttrib *ta; 00185 DCAST_INTO_R(ta, other, 0); 00186 00187 if (!_reverse && ta->_mode != M_cull_unchanged) { 00188 // The normal case (there is nothing funny going on): the second 00189 // attrib completely replaces this attrib. 00190 return other; 00191 } 00192 00193 // In the more complex case, the two attribs affect each other in 00194 // some way, and we must generate a new attrib from the result. 00195 Mode mode = _mode; 00196 if (ta->_mode != M_cull_unchanged) { 00197 mode = ta->_mode; 00198 } 00199 bool reverse = (_reverse && !ta->_reverse) || (!_reverse && ta->_reverse); 00200 00201 CullFaceAttrib *attrib = new CullFaceAttrib(mode, reverse); 00202 return return_new(attrib); 00203 } 00204 00205 //////////////////////////////////////////////////////////////////// 00206 // Function: CullFaceAttrib::invert_compose_impl 00207 // Access: Protected, Virtual 00208 // Description: Intended to be overridden by derived RenderAttrib 00209 // types to specify how two consecutive RenderAttrib 00210 // objects of the same type interact. 00211 // 00212 // See invert_compose() and compose_impl(). 00213 //////////////////////////////////////////////////////////////////// 00214 CPT(RenderAttrib) CullFaceAttrib:: 00215 invert_compose_impl(const RenderAttrib *other) const { 00216 const CullFaceAttrib *ta; 00217 DCAST_INTO_R(ta, other, 0); 00218 00219 // The invert case is the same as the normal case, except that the 00220 // meaning of _reverse is inverted. See compose_impl(), above. 00221 00222 if (_reverse && ta->_mode != M_cull_unchanged) { 00223 return other; 00224 } 00225 00226 Mode mode = _mode; 00227 if (ta->_mode != M_cull_unchanged) { 00228 mode = ta->_mode; 00229 } 00230 bool reverse = (!_reverse && !ta->_reverse) || (_reverse && ta->_reverse); 00231 00232 CullFaceAttrib *attrib = new CullFaceAttrib(mode, reverse); 00233 return return_new(attrib); 00234 } 00235 00236 //////////////////////////////////////////////////////////////////// 00237 // Function: CullFaceAttrib::register_with_read_factory 00238 // Access: Public, Static 00239 // Description: Tells the BamReader how to create objects of type 00240 // CullFaceAttrib. 00241 //////////////////////////////////////////////////////////////////// 00242 void CullFaceAttrib:: 00243 register_with_read_factory() { 00244 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00245 } 00246 00247 //////////////////////////////////////////////////////////////////// 00248 // Function: CullFaceAttrib::write_datagram 00249 // Access: Public, Virtual 00250 // Description: Writes the contents of this object to the datagram 00251 // for shipping out to a Bam file. 00252 //////////////////////////////////////////////////////////////////// 00253 void CullFaceAttrib:: 00254 write_datagram(BamWriter *manager, Datagram &dg) { 00255 RenderAttrib::write_datagram(manager, dg); 00256 00257 dg.add_int8(_mode); 00258 dg.add_bool(_reverse); 00259 } 00260 00261 //////////////////////////////////////////////////////////////////// 00262 // Function: CullFaceAttrib::make_from_bam 00263 // Access: Protected, Static 00264 // Description: This function is called by the BamReader's factory 00265 // when a new object of type CullFaceAttrib is encountered 00266 // in the Bam file. It should create the CullFaceAttrib 00267 // and extract its information from the file. 00268 //////////////////////////////////////////////////////////////////// 00269 TypedWritable *CullFaceAttrib:: 00270 make_from_bam(const FactoryParams ¶ms) { 00271 CullFaceAttrib *attrib = new CullFaceAttrib(M_cull_none, false); 00272 DatagramIterator scan; 00273 BamReader *manager; 00274 00275 parse_params(params, scan, manager); 00276 attrib->fillin(scan, manager); 00277 00278 return attrib; 00279 } 00280 00281 //////////////////////////////////////////////////////////////////// 00282 // Function: CullFaceAttrib::fillin 00283 // Access: Protected 00284 // Description: This internal function is called by make_from_bam to 00285 // read in all of the relevant data from the BamFile for 00286 // the new CullFaceAttrib. 00287 //////////////////////////////////////////////////////////////////// 00288 void CullFaceAttrib:: 00289 fillin(DatagramIterator &scan, BamReader *manager) { 00290 RenderAttrib::fillin(scan, manager); 00291 00292 _mode = (Mode)scan.get_int8(); 00293 _reverse = scan.get_bool(); 00294 }