Panda3D
occluderEffect.cxx
1 // Filename: occluderEffect.cxx
2 // Created by: drose (17Mar11)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "occluderEffect.h"
16 #include "pandaNode.h"
17 #include "graphicsStateGuardianBase.h"
18 #include "bamReader.h"
19 #include "bamWriter.h"
20 #include "datagram.h"
21 #include "datagramIterator.h"
22 #include "config_pgraph.h"
23 #include "attribNodeRegistry.h"
24 
25 CPT(RenderEffect) OccluderEffect::_empty_effect;
26 TypeHandle OccluderEffect::_type_handle;
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: OccluderEffect::make
30 // Access: Published, Static
31 // Description: Constructs a new OccluderEffect object that does
32 // nothing.
33 ////////////////////////////////////////////////////////////////////
34 CPT(RenderEffect) OccluderEffect::
35 make() {
36  // We make it a special case and store a pointer to the empty effect
37  // forever once we find it the first time, as an optimization.
38  if (_empty_effect == (RenderEffect *)NULL) {
39  _empty_effect = return_new(new OccluderEffect);
40  }
41 
42  return _empty_effect;
43 }
44 
45 ////////////////////////////////////////////////////////////////////
46 // Function: OccluderEffect::add_on_occluder
47 // Access: Published
48 // Description: Returns a new OccluderEffect, just like this one, but
49 // with the indicated occluder added to the list of occluders
50 // enabled by this effect.
51 ////////////////////////////////////////////////////////////////////
52 CPT(RenderEffect) OccluderEffect::
53 add_on_occluder(const NodePath &occluder) const {
54  nassertr(!occluder.is_empty() && occluder.node()->is_of_type(OccluderNode::get_class_type()), this);
55  OccluderEffect *effect = new OccluderEffect(*this);
56  effect->_on_occluders.insert(occluder);
57 
58  pair<Occluders::iterator, bool> insert_result =
59  effect->_on_occluders.insert(Occluders::value_type(occluder));
60 
61  return return_new(effect);
62 }
63 
64 ////////////////////////////////////////////////////////////////////
65 // Function: OccluderEffect::remove_on_occluder
66 // Access: Published
67 // Description: Returns a new OccluderEffect, just like this one, but
68 // with the indicated occluder removed from the list of
69 // occluders enabled by this effect.
70 ////////////////////////////////////////////////////////////////////
71 CPT(RenderEffect) OccluderEffect::
72 remove_on_occluder(const NodePath &occluder) const {
73  nassertr(!occluder.is_empty() && occluder.node()->is_of_type(OccluderNode::get_class_type()), this);
74  OccluderEffect *effect = new OccluderEffect(*this);
75  effect->_on_occluders.erase(occluder);
76  return return_new(effect);
77 }
78 
79 ////////////////////////////////////////////////////////////////////
80 // Function: OccluderEffect::output
81 // Access: Public, Virtual
82 // Description:
83 ////////////////////////////////////////////////////////////////////
84 void OccluderEffect::
85 output(ostream &out) const {
86  out << get_type() << ":";
87  if (_on_occluders.empty()) {
88  out << "identity";
89  } else {
90  out << "on";
91 
92  Occluders::const_iterator li;
93  for (li = _on_occluders.begin(); li != _on_occluders.end(); ++li) {
94  NodePath occluder = (*li);
95  out << " " << occluder;
96  }
97  }
98 }
99 
100 ////////////////////////////////////////////////////////////////////
101 // Function: OccluderEffect::compare_to_impl
102 // Access: Protected, Virtual
103 // Description: Intended to be overridden by derived OccluderEffect
104 // types to return a unique number indicating whether
105 // this OccluderEffect is equivalent to the other one.
106 //
107 // This should return 0 if the two OccluderEffect
108 // objects are equivalent, a number less than zero if
109 // this one should be sorted before the other one, and a
110 // number greater than zero otherwise.
111 //
112 // This will only be called with two OccluderEffect
113 // objects whose get_type() functions return the same.
114 ////////////////////////////////////////////////////////////////////
115 int OccluderEffect::
116 compare_to_impl(const RenderEffect *other) const {
117  const OccluderEffect *ta;
118  DCAST_INTO_R(ta, other, 0);
119 
120  Occluders::const_iterator li = _on_occluders.begin();
121  Occluders::const_iterator oli = ta->_on_occluders.begin();
122 
123  while (li != _on_occluders.end() && oli != ta->_on_occluders.end()) {
124  NodePath occluder = (*li);
125  NodePath other_occluder = (*oli);
126 
127  int compare = occluder.compare_to(other_occluder);
128  if (compare != 0) {
129  return compare;
130  }
131 
132  ++li;
133  ++oli;
134  }
135 
136  if (li != _on_occluders.end()) {
137  return 1;
138  }
139  if (oli != ta->_on_occluders.end()) {
140  return -1;
141  }
142 
143  return 0;
144 }
145 
146 ////////////////////////////////////////////////////////////////////
147 // Function: OccluderEffect::register_with_read_factory
148 // Access: Public, Static
149 // Description: Tells the BamReader how to create objects of type
150 // OccluderEffect.
151 ////////////////////////////////////////////////////////////////////
152 void OccluderEffect::
153 register_with_read_factory() {
154  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
155 }
156 
157 ////////////////////////////////////////////////////////////////////
158 // Function: OccluderEffect::write_datagram
159 // Access: Public, Virtual
160 // Description: Writes the contents of this object to the datagram
161 // for shipping out to a Bam file.
162 ////////////////////////////////////////////////////////////////////
163 void OccluderEffect::
165  RenderEffect::write_datagram(manager, dg);
166 
167  // write the number of on occluders
169  // write the on occluders pointers if any
170  Occluders::const_iterator nti;
171  for (nti = _on_occluders.begin(); nti != _on_occluders.end(); ++nti) {
172  NodePath occluder = (*nti);
173  manager->write_pointer(dg, occluder.node());
174  }
175 }
176 
177 ////////////////////////////////////////////////////////////////////
178 // Function: OccluderEffect::complete_pointers
179 // Access: Public, Virtual
180 // Description: Receives an array of pointers, one for each time
181 // manager->read_pointer() was called in fillin().
182 // Returns the number of pointers processed.
183 ////////////////////////////////////////////////////////////////////
186  int pi = RenderEffect::complete_pointers(p_list, manager);
187  AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr();
188 
189  Occluders::iterator ci;
190  ci = _on_occluders.begin();
191  while (ci != _on_occluders.end()) {
192  PandaNode *node;
193  DCAST_INTO_R(node, p_list[pi++], pi);
194 
195  int ni = areg->find_node(node->get_type(), node->get_name());
196  if (ni != -1) {
197  (*ci) = areg->get_node(ni);
198  } else {
199  (*ci) = NodePath(node);
200  }
201  ++ci;
202  }
203  _on_occluders.sort();
204 
205  return pi;
206 }
207 
208 ////////////////////////////////////////////////////////////////////
209 // Function: OccluderEffect::require_fully_complete
210 // Access: Public, Virtual
211 // Description: Some objects require all of their nested pointers to
212 // have been completed before the objects themselves can
213 // be completed. If this is the case, override this
214 // method to return true, and be careful with circular
215 // references (which would make the object unreadable
216 // from a bam file).
217 ////////////////////////////////////////////////////////////////////
218 bool OccluderEffect::
220  return true;
221 }
222 
223 ////////////////////////////////////////////////////////////////////
224 // Function: OccluderEffect::make_from_bam
225 // Access: Protected, Static
226 // Description: This function is called by the BamReader's factory
227 // when a new object of type OccluderEffect is encountered
228 // in the Bam file. It should create the OccluderEffect
229 // and extract its information from the file.
230 ////////////////////////////////////////////////////////////////////
231 TypedWritable *OccluderEffect::
232 make_from_bam(const FactoryParams &params) {
233  OccluderEffect *effect = new OccluderEffect;
234  DatagramIterator scan;
235  BamReader *manager;
236 
237  parse_params(params, scan, manager);
238  effect->fillin(scan, manager);
239 
240  return effect;
241 }
242 
243 ////////////////////////////////////////////////////////////////////
244 // Function: OccluderEffect::fillin
245 // Access: Protected
246 // Description: This internal function is called by make_from_bam to
247 // read in all of the relevant data from the BamFile for
248 // the new OccluderEffect.
249 ////////////////////////////////////////////////////////////////////
250 void OccluderEffect::
251 fillin(DatagramIterator &scan, BamReader *manager) {
252  RenderEffect::fillin(scan, manager);
253 
254  // Push back an empty NodePath for each Occluder for now, until we
255  // get the actual list of pointers later in complete_pointers().
256  int num_on_occluders = scan.get_uint16();
257  _on_occluders.reserve(num_on_occluders);
258  for (int i = 0; i < num_on_occluders; i++) {
259  manager->read_pointer(scan);
260  _on_occluders.push_back(NodePath());
261  }
262 }
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:236
This global object records NodePaths that are referenced by scene graph attribs, such as ClipPlaneAtt...
int compare_to(const NodePath &other) const
Returns a number less than zero if this NodePath sorts before the other one, greater than zero if it ...
Definition: nodePath.I:2412
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
This is the base class for a number of special render effects that may be set on scene graph nodes to...
Definition: renderEffect.h:56
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
void reserve(size_type_0 n)
Informs the vector of a planned change in size; ensures that the capacity of the vector is greater th...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
int find_node(const NodePath &attrib_node) const
Returns the index number of the indicated NodePath in the registry (assuming its name hasn&#39;t changed ...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
This functions similarly to a LightAttrib or ClipPlaneAttrib.
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
void sort()
Maps to sort_unique().
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void push_back(const value_type_0 &key)
Adds the new element to the end of the vector without regard for proper sorting.
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
void add_uint16(PN_uint16 value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:181
NodePath get_node(int n) const
Returns the nth NodePath recorded in the registry.
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:213
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:284
int get_num_on_occluders() const
Returns the number of occluders that are enabled by the effectute.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:63
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165
virtual bool require_fully_complete() const
Some objects require all of their nested pointers to have been completed before the objects themselve...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:279
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:658