Panda3D
cullFaceAttrib.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file cullFaceAttrib.cxx
10  * @author drose
11  * @date 2002-02-27
12  */
13 
14 #include "cullFaceAttrib.h"
16 #include "dcast.h"
17 #include "bamReader.h"
18 #include "bamWriter.h"
19 #include "datagram.h"
20 #include "datagramIterator.h"
21 
22 TypeHandle CullFaceAttrib::_type_handle;
23 int CullFaceAttrib::_attrib_slot;
24 
25 /**
26  * Constructs a new CullFaceAttrib object that specifies how to cull geometry.
27  * By Panda convention, vertices are ordered counterclockwise when seen from
28  * the front, so the M_cull_clockwise will cull backfacing polygons.
29  *
30  * M_cull_unchanged is an identity attrib; if this is applied to vertices
31  * without any other intervening attrib, it is the same as applying the
32  * default attrib.
33  */
34 CPT(RenderAttrib) CullFaceAttrib::
35 make(CullFaceAttrib::Mode mode) {
36  CullFaceAttrib *attrib = new CullFaceAttrib(mode, false);
37  return return_new(attrib);
38 }
39 
40 /**
41  * Constructs a new CullFaceAttrib object that reverses the effects of any
42  * other CullFaceAttrib objects in the scene graph. M_cull_clockwise will be
43  * treated as M_cull_counter_clockwise, and vice-versa. M_cull_none is
44  * unchanged.
45  */
46 CPT(RenderAttrib) CullFaceAttrib::
47 make_reverse() {
48  CullFaceAttrib *attrib = new CullFaceAttrib(M_cull_unchanged, true);
49  return return_new(attrib);
50 }
51 
52 /**
53  * Returns a RenderAttrib that corresponds to whatever the standard default
54  * properties for render attributes of this type ought to be.
55  */
56 CPT(RenderAttrib) CullFaceAttrib::
57 make_default() {
58  return return_new(new CullFaceAttrib(M_cull_clockwise, false));
59 }
60 
61 /**
62  * Returns the effective culling mode. This is the same as the actual culling
63  * mode, unless the reverse flag is set, which swaps CW for CCW and vice-
64  * versa. Also, M_cull_unchanged is mapped to M_cull_none.
65  */
66 CullFaceAttrib::Mode CullFaceAttrib::
67 get_effective_mode() const {
68  if (_reverse) {
69  switch (_mode) {
70  case M_cull_clockwise:
71  case M_cull_unchanged:
72  return M_cull_counter_clockwise;
73 
74  case M_cull_counter_clockwise:
75  return M_cull_clockwise;
76 
77  default:
78  break;
79  }
80 
81  } else {
82  switch (_mode) {
83  case M_cull_clockwise:
84  case M_cull_unchanged:
85  return M_cull_clockwise;
86 
87  case M_cull_counter_clockwise:
88  return M_cull_counter_clockwise;
89 
90  default:
91  break;
92  }
93  }
94 
95  return M_cull_none;
96 }
97 
98 /**
99  *
100  */
101 void CullFaceAttrib::
102 output(std::ostream &out) const {
103  out << get_type() << ":";
104  switch (get_actual_mode()) {
105  case M_cull_none:
106  out << "cull_none";
107  break;
108  case M_cull_clockwise:
109  out << "cull_clockwise";
110  break;
111  case M_cull_counter_clockwise:
112  out << "cull_counter_clockwise";
113  break;
114  case M_cull_unchanged:
115  out << "cull_unchanged";
116  break;
117  }
118  if (get_reverse()) {
119  out << "(reverse)";
120  }
121 }
122 
123 /**
124  * Intended to be overridden by derived CullFaceAttrib types to return a
125  * unique number indicating whether this CullFaceAttrib is equivalent to the
126  * other one.
127  *
128  * This should return 0 if the two CullFaceAttrib objects are equivalent, a
129  * number less than zero if this one should be sorted before the other one,
130  * and a number greater than zero otherwise.
131  *
132  * This will only be called with two CullFaceAttrib objects whose get_type()
133  * functions return the same.
134  */
135 int CullFaceAttrib::
136 compare_to_impl(const RenderAttrib *other) const {
137  const CullFaceAttrib *ta = (const CullFaceAttrib *)other;
138 
139  if (_mode != ta->_mode) {
140  return (int)_mode - (int)ta->_mode;
141  }
142  return (int)_reverse - (int)ta->_reverse;
143 }
144 
145 /**
146  * Intended to be overridden by derived RenderAttrib types to return a unique
147  * hash for these particular properties. RenderAttribs that compare the same
148  * with compare_to_impl(), above, should return the same hash; RenderAttribs
149  * that compare differently should return a different hash.
150  */
151 size_t CullFaceAttrib::
152 get_hash_impl() const {
153  size_t hash = 0;
154  hash = int_hash::add_hash(hash, (int)_mode);
155  hash = int_hash::add_hash(hash, (int)_reverse);
156  return hash;
157 }
158 
159 /**
160  * Intended to be overridden by derived RenderAttrib types to specify how two
161  * consecutive RenderAttrib objects of the same type interact.
162  *
163  * This should return the result of applying the other RenderAttrib to a node
164  * in the scene graph below this RenderAttrib, which was already applied. In
165  * most cases, the result is the same as the other RenderAttrib (that is, a
166  * subsequent RenderAttrib completely replaces the preceding one). On the
167  * other hand, some kinds of RenderAttrib (for instance, ColorTransformAttrib)
168  * might combine in meaningful ways.
169  */
170 CPT(RenderAttrib) CullFaceAttrib::
171 compose_impl(const RenderAttrib *other) const {
172  const CullFaceAttrib *ta = (const CullFaceAttrib *)other;
173 
174  if (!_reverse && ta->_mode != M_cull_unchanged) {
175  // The normal case (there is nothing funny going on): the second attrib
176  // completely replaces this attrib.
177  return other;
178  }
179 
180  // In the more complex case, the two attribs affect each other in some way,
181  // and we must generate a new attrib from the result.
182  Mode mode = _mode;
183  if (ta->_mode != M_cull_unchanged) {
184  mode = ta->_mode;
185  }
186  bool reverse = (_reverse && !ta->_reverse) || (!_reverse && ta->_reverse);
187 
188  CullFaceAttrib *attrib = new CullFaceAttrib(mode, reverse);
189  return return_new(attrib);
190 }
191 
192 /**
193  * Intended to be overridden by derived RenderAttrib types to specify how two
194  * consecutive RenderAttrib objects of the same type interact.
195  *
196  * See invert_compose() and compose_impl().
197  */
198 CPT(RenderAttrib) CullFaceAttrib::
199 invert_compose_impl(const RenderAttrib *other) const {
200  const CullFaceAttrib *ta = (const CullFaceAttrib *)other;
201 
202  // The invert case is the same as the normal case, except that the meaning
203  // of _reverse is inverted. See compose_impl(), above.
204 
205  if (_reverse && ta->_mode != M_cull_unchanged) {
206  return other;
207  }
208 
209  Mode mode = _mode;
210  if (ta->_mode != M_cull_unchanged) {
211  mode = ta->_mode;
212  }
213  bool reverse = (!_reverse && !ta->_reverse) || (_reverse && ta->_reverse);
214 
215  CullFaceAttrib *attrib = new CullFaceAttrib(mode, reverse);
216  return return_new(attrib);
217 }
218 
219 /**
220  * Tells the BamReader how to create objects of type CullFaceAttrib.
221  */
222 void CullFaceAttrib::
223 register_with_read_factory() {
224  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
225 }
226 
227 /**
228  * Writes the contents of this object to the datagram for shipping out to a
229  * Bam file.
230  */
231 void CullFaceAttrib::
233  RenderAttrib::write_datagram(manager, dg);
234 
235  dg.add_int8(_mode);
236  dg.add_bool(_reverse);
237 }
238 
239 /**
240  * This function is called by the BamReader's factory when a new object of
241  * type CullFaceAttrib is encountered in the Bam file. It should create the
242  * CullFaceAttrib and extract its information from the file.
243  */
244 TypedWritable *CullFaceAttrib::
245 make_from_bam(const FactoryParams &params) {
246  CullFaceAttrib *attrib = new CullFaceAttrib(M_cull_none, false);
247  DatagramIterator scan;
248  BamReader *manager;
249 
250  parse_params(params, scan, manager);
251  attrib->fillin(scan, manager);
252 
253  return attrib;
254 }
255 
256 /**
257  * This internal function is called by make_from_bam to read in all of the
258  * relevant data from the BamFile for the new CullFaceAttrib.
259  */
260 void CullFaceAttrib::
261 fillin(DatagramIterator &scan, BamReader *manager) {
262  RenderAttrib::fillin(scan, manager);
263 
264  _mode = (Mode)scan.get_int8();
265  _reverse = scan.get_bool();
266 }
bool get_bool()
Extracts a boolean value.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
CPT(RenderAttrib) CullFaceAttrib
Constructs a new CullFaceAttrib object that specifies how to cull geometry.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Indicates which faces should be culled based on their vertex ordering.
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:101
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_int8(int8_t value)
Adds a signed 8-bit integer to the datagram.
Definition: datagram.I:42
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:34
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:73
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_actual_mode
Returns the actual culling mode, without considering the effects of the reverse flag.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
A class to retrieve the individual data elements previously stored in a Datagram.
int8_t get_int8()
Extracts a signed 8-bit integer.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_reverse
Returns the 'reverse' flag.