Panda3D
 All Classes Functions Variables Enumerations
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 ////////////////////////////////////////////////////////////////////
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 ////////////////////////////////////////////////////////////////////
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 ////////////////////////////////////////////////////////////////////
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::
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 }
static void register_with_read_factory()
Tells the BamReader how to create objects of type OccluderEffect.
NodePath get_node(int n) const
Returns the nth NodePath recorded in the registry.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
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
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
This global object records NodePaths that are referenced by scene graph attribs, such as ClipPlaneAtt...
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.
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:284
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.
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager-&gt;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-&gt;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
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 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
virtual bool require_fully_complete() const
Some objects require all of their nested pointers to have been completed before the objects themselve...
int get_num_on_occluders() const
Returns the number of occluders that are enabled by the effectute.
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
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:652