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