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  */
139 void OccluderEffect::
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  */
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  */
206 bool OccluderEffect::
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.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NodePath()
This constructs an empty NodePath with no nodes.
Definition: nodePath.I:18
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
size_type_0 size() const
Returns the number of elements in the ordered vector.
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:1955
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
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being written.
Definition: bamWriter.I:59
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
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
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
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.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:83
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
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:85
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 ...
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.
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
Definition: bamReader.cxx:653
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: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_num_on_occluders
Returns the number of occluders that are enabled by the effectute.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:227
CPT(RenderEffect) OccluderEffect
Constructs a new OccluderEffect object that does nothing.
get_node
Returns the nth NodePath recorded in the registry.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
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:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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:317