Panda3D
planeNode.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 planeNode.cxx
10  * @author drose
11  * @date 2002-07-11
12  */
13 
14 #include "planeNode.h"
16 #include "bamWriter.h"
17 #include "bamReader.h"
18 #include "datagram.h"
19 #include "datagramIterator.h"
20 #include "geomVertexWriter.h"
21 #include "geomVertexData.h"
22 #include "geomLines.h"
23 #include "geom.h"
24 #include "cullableObject.h"
25 #include "cullHandler.h"
26 #include "boundingPlane.h"
27 
28 UpdateSeq PlaneNode::_sort_seq;
29 
30 TypeHandle PlaneNode::_type_handle;
31 
32 /**
33  *
34  */
35 CycleData *PlaneNode::CData::
36 make_copy() const {
37  return new CData(*this);
38 }
39 
40 /**
41  * Writes the contents of this object to the datagram for shipping out to a
42  * Bam file.
43  */
44 void PlaneNode::CData::
45 write_datagram(BamWriter *, Datagram &dg) const {
46  _plane.write_datagram(dg);
47 }
48 
49 /**
50  * This internal function is called by make_from_bam to read in all of the
51  * relevant data from the BamFile for the new Light.
52  */
53 void PlaneNode::CData::
54 fillin(DatagramIterator &scan, BamReader *) {
55  _plane.read_datagram(scan);
56 }
57 
58 /**
59  *
60  */
61 PlaneNode::
62 PlaneNode(const std::string &name, const LPlane &plane) :
63  PandaNode(name),
64  _priority(0),
65  _clip_effect(~0)
66 {
67  set_cull_callback();
68 
69  // PlaneNodes are hidden by default.
70  set_overall_hidden(true);
71 
72  set_plane(plane);
73 }
74 
75 /**
76  *
77  */
78 PlaneNode::
79 PlaneNode(const PlaneNode &copy) :
80  PandaNode(copy),
81  _priority(copy._priority),
82  _clip_effect(copy._clip_effect),
83  _cycler(copy._cycler)
84 {
85 }
86 
87 /**
88  *
89  */
90 void PlaneNode::
91 output(std::ostream &out) const {
92  PandaNode::output(out);
93  out << " " << get_plane();
94 }
95 
96 /**
97  * Returns a newly-allocated Node that is a shallow copy of this one. It will
98  * be a different Node pointer, but its internal data may or may not be shared
99  * with that of the original Node.
100  */
102 make_copy() const {
103  return new PlaneNode(*this);
104 }
105 
106 /**
107  * Transforms the contents of this PandaNode by the indicated matrix, if it
108  * means anything to do so. For most kinds of PandaNodes, this does nothing.
109  */
110 void PlaneNode::
111 xform(const LMatrix4 &mat) {
112  PandaNode::xform(mat);
113  CDWriter cdata(_cycler);
114  cdata->_plane = cdata->_plane * mat;
115  cdata->_front_viz = nullptr;
116  cdata->_back_viz = nullptr;
117 }
118 
119 /**
120  * This function will be called during the cull traversal to perform any
121  * additional operations that should be performed at cull time. This may
122  * include additional manipulation of render state or additional
123  * visible/invisible decisions, or any other arbitrary operation.
124  *
125  * Note that this function will *not* be called unless set_cull_callback() is
126  * called in the constructor of the derived class. It is necessary to call
127  * set_cull_callback() to indicated that we require cull_callback() to be
128  * called.
129  *
130  * By the time this function is called, the node has already passed the
131  * bounding-volume test for the viewing frustum, and the node's transform and
132  * state have already been applied to the indicated CullTraverserData object.
133  *
134  * The return value is true if this node should be visible, or false if it
135  * should be culled.
136  */
137 bool PlaneNode::
139  // Normally, a PlaneNode is invisible. But if someone shows it, we will
140  // draw a visualization, a nice yellow wireframe.
141 
142  CullableObject *plane_viz =
143  new CullableObject(get_viz(trav, data), data._state,
144  data.get_internal_transform(trav));
145  trav->get_cull_handler()->record_object(plane_viz, trav);
146 
147  // Now carry on to render our child nodes.
148  return true;
149 }
150 
151 /**
152  * Returns true if there is some value to visiting this particular node during
153  * the cull traversal for any camera, false otherwise. This will be used to
154  * optimize the result of get_net_draw_show_mask(), so that any subtrees that
155  * contain only nodes for which is_renderable() is false need not be visited.
156  */
157 bool PlaneNode::
158 is_renderable() const {
159  return true;
160 }
161 
162 /**
163  * Returns a newly-allocated BoundingVolume that represents the internal
164  * contents of the node. Should be overridden by PandaNode classes that
165  * contain something internally.
166  */
167 void PlaneNode::
168 compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
169  int &internal_vertices,
170  int pipeline_stage,
171  Thread *current_thread) const {
172  CDStageReader cdata(_cycler, pipeline_stage, current_thread);
173  internal_bounds = new BoundingPlane(cdata->_plane);
174  internal_vertices = 0;
175 }
176 
177 /**
178  * Returns a Geom that represents the visualization of the PlaneNode.
179  */
180 PT(Geom) PlaneNode::
181 get_viz(CullTraverser *trav, CullTraverserData &data) {
182  CDLockedReader cdata(_cycler);
183 
184  // Figure out whether we are looking at the front or the back of the plane.
185  const Lens *lens = trav->get_scene()->get_lens();
186  LPlane eye_plane = cdata->_plane * data.get_modelview_transform(trav)->get_mat();
187  bool front = (eye_plane.dist_to_plane(lens->get_nodal_point()) >= 0.0f);
188 
189  if (cdata->_front_viz != nullptr) {
190  return front ? cdata->_front_viz : cdata->_back_viz;
191  }
192 
193  if (pgraph_cat.is_debug()) {
194  pgraph_cat.debug()
195  << "Recomputing viz for " << *this << "\n";
196  }
197 
198  CDWriter cdataw(_cycler, cdata, false);
199  const LPlane &plane = cdataw->_plane;
200 
201  PT(GeomVertexData) vdata = new GeomVertexData
202  (get_name(), GeomVertexFormat::get_v3cp(), Geom::UH_static);
203 
204  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
205  PT(GeomLines) lines = new GeomLines(Geom::UH_static);
206 
207  LVector3 a, b;
208 
209  if (fabs(plane[0]) > fabs(plane[1])) {
210  // X > Y
211  if (fabs(plane[0]) > fabs(plane[2])) {
212  // X > Y && X > Z. X is the largest.
213  a.set(0, 1, 0);
214  b.set(0, 0, 1);
215  } else {
216  // X > Y && Z > X. Z is the largest.
217  a.set(1, 0, 0);
218  b.set(0, 1, 0);
219  }
220  } else {
221  // Y > X
222  if (fabs(plane[1]) > fabs(plane[2])) {
223  // Y > X && Y > Z. Y is the largest.
224  a.set(1, 0, 0);
225  b.set(0, 0, 1);
226  } else {
227  // Y > X && Z > Y. Z is the largest.
228  a.set(1, 0, 0);
229  b.set(0, 1, 0);
230  }
231  }
232 
233  static const int num_segs = 10;
234  a *= cdataw->_viz_scale / (num_segs * 2);
235  b *= cdataw->_viz_scale / (num_segs * 2);
236 
237  for (int x = -num_segs; x <= num_segs; ++x) {
238  vertex.add_data3(plane.project(a * x - b * num_segs));
239  vertex.add_data3(plane.project(a * x + b * num_segs));
240  lines->add_next_vertices(2);
241  lines->close_primitive();
242  }
243  for (int y = -num_segs; y <= num_segs; ++y) {
244  vertex.add_data3(plane.project(b * y - a * num_segs));
245  vertex.add_data3(plane.project(b * y + a * num_segs));
246  lines->add_next_vertices(2);
247  lines->close_primitive();
248  }
249 
250  cdataw->_front_viz = new Geom(vdata->set_color(LColor(1.0f, 1.0f, 0.0f, 1.0f)));
251  cdataw->_front_viz->add_primitive(lines);
252 
253  cdataw->_back_viz = new Geom(vdata->set_color(LColor(0.4, 0.4, 0.0f, 1.0f)));
254  cdataw->_back_viz->add_primitive(lines);
255 
256  return front ? cdataw->_front_viz : cdataw->_back_viz;
257 }
258 
259 /**
260  * Tells the BamReader how to create objects of type PlaneNode.
261  */
262 void PlaneNode::
264  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
265 }
266 
267 /**
268  * Writes the contents of this object to the datagram for shipping out to a
269  * Bam file.
270  */
271 void PlaneNode::
273  PandaNode::write_datagram(manager, dg);
274  manager->write_cdata(dg, _cycler);
275  dg.add_int32(_priority);
276  dg.add_uint8(_clip_effect);
277 }
278 
279 /**
280  * This function is called by the BamReader's factory when a new object of
281  * type PlaneNode is encountered in the Bam file. It should create the
282  * PlaneNode and extract its information from the file.
283  */
284 TypedWritable *PlaneNode::
285 make_from_bam(const FactoryParams &params) {
286  PlaneNode *node = new PlaneNode("");
287  DatagramIterator scan;
288  BamReader *manager;
289 
290  parse_params(params, scan, manager);
291  node->fillin(scan, manager);
292 
293  return node;
294 }
295 
296 /**
297  * This internal function is called by make_from_bam to read in all of the
298  * relevant data from the BamFile for the new PlaneNode.
299  */
300 void PlaneNode::
301 fillin(DatagramIterator &scan, BamReader *manager) {
302  PandaNode::fillin(scan, manager);
303  manager->read_cdata(scan, _cycler);
304  _priority = scan.get_int32();
305 
306  if (manager->get_file_minor_ver() < 9) {
307  _clip_effect = ~0;
308  } else {
309  _clip_effect = scan.get_uint8();
310  }
311 }
static void register_with_read_factory()
Tells the BamReader how to create objects of type PlaneNode.
Definition: planeNode.cxx:263
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
CullHandler * get_cull_handler() const
Returns the object that will receive the culled Geoms.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data)
This function will be called during the cull traversal to perform any additional operations that shou...
Definition: planeNode.cxx:138
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
uint8_t get_uint8()
Extracts an unsigned 8-bit integer.
A base class for any number of different kinds of lenses, linear and otherwise.
Definition: lens.h:41
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: pandaNode.cxx:3589
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
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
Definition: bamReader.cxx:695
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static const GeomVertexFormat * get_v3cp()
Returns a standard vertex format with a packed color and a 3-component vertex position.
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:47
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
Definition: bamWriter.cxx:425
This collects together the pieces of data that are accumulated for each node while walking the scene ...
const Lens * get_lens() const
Returns the particular Lens used for rendering.
Definition: sceneSetup.I:131
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_primitive(const GeomPrimitive *primitive)
Inserts a new GeomPrimitive structure to the Geom object.
Definition: geom.I:116
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
int32_t get_int32()
Extracts a signed 32-bit integer.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:83
This funny bounding volume is an infinite plane that divides space into two regions: the part behind ...
Definition: boundingPlane.h:28
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this PandaNode by the indicated matrix, if it means anything to do so.
Definition: pandaNode.cxx:310
virtual bool is_renderable() const
Returns true if there is some value to visiting this particular node during the cull traversal for an...
Definition: planeNode.cxx:158
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
The smallest atom of cull.
virtual void record_object(CullableObject *object, const CullTraverser *traverser)
This callback function is intended to be overridden by a derived class.
Definition: cullHandler.cxx:43
const LPlane & get_plane() const
Returns the plane represented by the PlaneNode.
Definition: planeNode.I:54
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
Definition: geom.h:54
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 add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row.
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 template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_nodal_point
Returns the center point of the lens: the point from which the lens is viewing.
Definition: lens.h:129
Defines a series of disconnected line segments.
Definition: geomLines.h:23
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
Definition: datagram.I:67
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A thread; that is, a lightweight process.
Definition: thread.h:46
SceneSetup * get_scene() const
Returns the SceneSetup object.
Definition: cullTraverser.I:35
void add_uint8(uint8_t value)
Adds an unsigned 8-bit integer to the datagram.
Definition: datagram.I:50
PT(Geom) PlaneNode
Returns a Geom that represents the visualization of the PlaneNode.
Definition: planeNode.cxx:180
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
This is a sequence number that increments monotonically.
Definition: updateSeq.h:37
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: planeNode.cxx:272
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this PandaNode by the indicated matrix, if it means anything to do so.
Definition: planeNode.cxx:111
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node that contains a plane.
Definition: planeNode.h:36
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
Definition: planeNode.cxx:102
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.