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  */
232 write_datagram(BamWriter *manager, Datagram &dg) {
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 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
Indicates which faces should be culled based on their vertex ordering.
get_actual_mode
Returns the actual culling mode, without considering the effects of the reverse flag.
get_effective_mode
Returns the effective culling mode.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
get_reverse
Returns the 'reverse' flag.
A class to retrieve the individual data elements previously stored in a Datagram.
int8_t get_int8()
Extracts a signed 8-bit integer.
bool get_bool()
Extracts a boolean value.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:34
void add_int8(int8_t value)
Adds a signed 8-bit integer to the datagram.
Definition: datagram.I:42
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
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
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:101
CPT(RenderAttrib) CullFaceAttrib
Constructs a new CullFaceAttrib object that specifies how to cull geometry.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.