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