00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "planeNode.h"
00016 #include "geometricBoundingVolume.h"
00017 #include "bamWriter.h"
00018 #include "bamReader.h"
00019 #include "datagram.h"
00020 #include "datagramIterator.h"
00021 #include "geomVertexWriter.h"
00022 #include "geomVertexData.h"
00023 #include "geomLines.h"
00024 #include "geom.h"
00025 #include "cullableObject.h"
00026 #include "cullHandler.h"
00027 #include "boundingPlane.h"
00028
00029 UpdateSeq PlaneNode::_sort_seq;
00030
00031 TypeHandle PlaneNode::_type_handle;
00032
00033
00034
00035
00036
00037
00038 CycleData *PlaneNode::CData::
00039 make_copy() const {
00040 return new CData(*this);
00041 }
00042
00043
00044
00045
00046
00047
00048
00049 void PlaneNode::CData::
00050 write_datagram(BamWriter *, Datagram &dg) const {
00051 _plane.write_datagram(dg);
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061 void PlaneNode::CData::
00062 fillin(DatagramIterator &scan, BamReader *) {
00063 _plane.read_datagram(scan);
00064 }
00065
00066
00067
00068
00069
00070
00071 PlaneNode::
00072 PlaneNode(const string &name, const LPlane &plane) :
00073 PandaNode(name),
00074 _priority(0),
00075 _clip_effect(~0)
00076 {
00077 set_cull_callback();
00078
00079
00080 set_overall_hidden(true);
00081
00082 set_plane(plane);
00083 }
00084
00085
00086
00087
00088
00089
00090 PlaneNode::
00091 PlaneNode(const PlaneNode ©) :
00092 PandaNode(copy),
00093 _priority(copy._priority),
00094 _clip_effect(copy._clip_effect),
00095 _cycler(copy._cycler)
00096 {
00097 }
00098
00099
00100
00101
00102
00103
00104 void PlaneNode::
00105 output(ostream &out) const {
00106 PandaNode::output(out);
00107 out << " " << get_plane();
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 PandaNode *PlaneNode::
00119 make_copy() const {
00120 return new PlaneNode(*this);
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130 void PlaneNode::
00131 xform(const LMatrix4 &mat) {
00132 PandaNode::xform(mat);
00133 CDWriter cdata(_cycler);
00134 cdata->_plane = cdata->_plane * mat;
00135 cdata->_front_viz = NULL;
00136 cdata->_back_viz = NULL;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 bool PlaneNode::
00165 cull_callback(CullTraverser *trav, CullTraverserData &data) {
00166
00167
00168
00169 CullableObject *plane_viz =
00170 new CullableObject(get_viz(trav, data), data._state,
00171 data.get_net_transform(trav),
00172 data.get_modelview_transform(trav),
00173 trav->get_gsg());
00174 trav->get_cull_handler()->record_object(plane_viz, trav);
00175
00176
00177 return true;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 bool PlaneNode::
00191 is_renderable() const {
00192 return true;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 void PlaneNode::
00204 compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
00205 int &internal_vertices,
00206 int pipeline_stage,
00207 Thread *current_thread) const {
00208 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
00209 internal_bounds = new BoundingPlane(cdata->_plane);
00210 internal_vertices = 0;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 PT(Geom) PlaneNode::
00220 get_viz(CullTraverser *trav, CullTraverserData &data) {
00221 CDLockedReader cdata(_cycler);
00222
00223
00224
00225 const Lens *lens = trav->get_scene()->get_lens();
00226 LPlane eye_plane = cdata->_plane * data.get_modelview_transform(trav)->get_mat();
00227 bool front = (eye_plane.dist_to_plane(lens->get_nodal_point()) >= 0.0f);
00228
00229 if (cdata->_front_viz != (Geom *)NULL) {
00230 return front ? cdata->_front_viz : cdata->_back_viz;
00231 }
00232
00233 if (pgraph_cat.is_debug()) {
00234 pgraph_cat.debug()
00235 << "Recomputing viz for " << *this << "\n";
00236 }
00237
00238 CDWriter cdataw(_cycler, cdata, false);
00239 const LPlane &plane = cdataw->_plane;
00240
00241 PT(GeomVertexData) vdata = new GeomVertexData
00242 (get_name(), GeomVertexFormat::get_v3cp(), Geom::UH_static);
00243
00244 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00245 PT(GeomLines) lines = new GeomLines(Geom::UH_static);
00246
00247 LVector3 a, b;
00248
00249 if (fabs(plane[0]) > fabs(plane[1])) {
00250
00251 if (fabs(plane[0]) > fabs(plane[2])) {
00252
00253 a.set(0, 1, 0);
00254 b.set(0, 0, 1);
00255 } else {
00256
00257 a.set(1, 0, 0);
00258 b.set(0, 1, 0);
00259 }
00260 } else {
00261
00262 if (fabs(plane[1]) > fabs(plane[2])) {
00263
00264 a.set(1, 0, 0);
00265 b.set(0, 0, 1);
00266 } else {
00267
00268 a.set(1, 0, 0);
00269 b.set(0, 1, 0);
00270 }
00271 }
00272
00273 static const int num_segs = 10;
00274 a *= cdataw->_viz_scale / (num_segs * 2);
00275 b *= cdataw->_viz_scale / (num_segs * 2);
00276
00277 for (int x = -num_segs; x <= num_segs; ++x) {
00278 vertex.add_data3(plane.project(a * x - b * num_segs));
00279 vertex.add_data3(plane.project(a * x + b * num_segs));
00280 lines->add_next_vertices(2);
00281 lines->close_primitive();
00282 }
00283 for (int y = -num_segs; y <= num_segs; ++y) {
00284 vertex.add_data3(plane.project(b * y - a * num_segs));
00285 vertex.add_data3(plane.project(b * y + a * num_segs));
00286 lines->add_next_vertices(2);
00287 lines->close_primitive();
00288 }
00289
00290 cdataw->_front_viz = new Geom(vdata->set_color(LColor(1.0f, 1.0f, 0.0f, 1.0f)));
00291 cdataw->_front_viz->add_primitive(lines);
00292
00293 cdataw->_back_viz = new Geom(vdata->set_color(LColor(0.4, 0.4, 0.0f, 1.0f)));
00294 cdataw->_back_viz->add_primitive(lines);
00295
00296 return front ? cdataw->_front_viz : cdataw->_back_viz;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305 void PlaneNode::
00306 register_with_read_factory() {
00307 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 void PlaneNode::
00317 write_datagram(BamWriter *manager, Datagram &dg) {
00318 PandaNode::write_datagram(manager, dg);
00319 manager->write_cdata(dg, _cycler);
00320 dg.add_int32(_priority);
00321 dg.add_uint8(_clip_effect);
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 TypedWritable *PlaneNode::
00333 make_from_bam(const FactoryParams ¶ms) {
00334 PlaneNode *node = new PlaneNode("");
00335 DatagramIterator scan;
00336 BamReader *manager;
00337
00338 parse_params(params, scan, manager);
00339 node->fillin(scan, manager);
00340
00341 return node;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351 void PlaneNode::
00352 fillin(DatagramIterator &scan, BamReader *manager) {
00353 PandaNode::fillin(scan, manager);
00354 manager->read_cdata(scan, _cycler);
00355 _priority = scan.get_int32();
00356
00357 if (manager->get_file_minor_ver() < 9) {
00358 _clip_effect = ~0;
00359 } else {
00360 _clip_effect = scan.get_uint8();
00361 }
00362 }