00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "clipPlaneAttrib.h"
00016 #include "pandaNode.h"
00017 #include "graphicsStateGuardianBase.h"
00018 #include "bamReader.h"
00019 #include "bamWriter.h"
00020 #include "datagram.h"
00021 #include "datagramIterator.h"
00022 #include "config_pgraph.h"
00023 #include "attribNodeRegistry.h"
00024 #include <iterator>
00025
00026 CPT(RenderAttrib) ClipPlaneAttrib::_empty_attrib;
00027 CPT(RenderAttrib) ClipPlaneAttrib::_all_off_attrib;
00028 TypeHandle ClipPlaneAttrib::_type_handle;
00029 int ClipPlaneAttrib::_attrib_slot;
00030
00031
00032
00033 class ComparePlaneNodePriorities {
00034 public:
00035 bool operator ()(const NodePath &a, const NodePath &b) const {
00036 nassertr(!a.is_empty() && !b.is_empty(), a < b);
00037 PlaneNode *pa = DCAST(PlaneNode, a.node());
00038 PlaneNode *pb = DCAST(PlaneNode, b.node());
00039 nassertr(pa != (PlaneNode *)NULL && pb != (PlaneNode *)NULL, a < b);
00040
00041 return pa->get_priority() > pb->get_priority();
00042 }
00043 };
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 CPT(RenderAttrib) ClipPlaneAttrib::
00055 make(ClipPlaneAttrib::Operation op, PlaneNode *plane) {
00056 pgraph_cat.warning()
00057 << "Using deprecated ClipPlaneAttrib interface.\n";
00058
00059 CPT(RenderAttrib) attrib;
00060
00061 switch (op) {
00062 case O_set:
00063 attrib = make_all_off();
00064 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane));
00065 return attrib;
00066
00067 case O_add:
00068 attrib = make();
00069 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane));
00070 return attrib;
00071
00072 case O_remove:
00073 attrib = make();
00074 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane));
00075 return attrib;
00076 }
00077
00078 nassertr(false, make());
00079 return make();
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 CPT(RenderAttrib) ClipPlaneAttrib::
00092 make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2) {
00093 pgraph_cat.warning()
00094 << "Using deprecated ClipPlaneAttrib interface.\n";
00095
00096 CPT(RenderAttrib) attrib;
00097
00098 switch (op) {
00099 case O_set:
00100 attrib = make_all_off();
00101 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
00102 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
00103 return attrib;
00104
00105 case O_add:
00106 attrib = make();
00107 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
00108 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
00109 return attrib;
00110
00111 case O_remove:
00112 attrib = make();
00113 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane1));
00114 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane2));
00115 return attrib;
00116 }
00117
00118 nassertr(false, make());
00119 return make();
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 CPT(RenderAttrib) ClipPlaneAttrib::
00132 make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
00133 PlaneNode *plane3) {
00134 pgraph_cat.warning()
00135 << "Using deprecated ClipPlaneAttrib interface.\n";
00136
00137 CPT(RenderAttrib) attrib;
00138
00139 switch (op) {
00140 case O_set:
00141 attrib = make_all_off();
00142 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
00143 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
00144 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane3));
00145 return attrib;
00146
00147 case O_add:
00148 attrib = make();
00149 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
00150 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
00151 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane3));
00152 return attrib;
00153
00154 case O_remove:
00155 attrib = make();
00156 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane1));
00157 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane2));
00158 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane3));
00159 return attrib;
00160 }
00161
00162 nassertr(false, make());
00163 return make();
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 CPT(RenderAttrib) ClipPlaneAttrib::
00176 make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
00177 PlaneNode *plane3, PlaneNode *plane4) {
00178 pgraph_cat.warning()
00179 << "Using deprecated ClipPlaneAttrib interface.\n";
00180
00181 CPT(RenderAttrib) attrib;
00182
00183 switch (op) {
00184 case O_set:
00185 attrib = make_all_off();
00186 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
00187 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
00188 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane3));
00189 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane4));
00190 return attrib;
00191
00192 case O_add:
00193 attrib = make();
00194 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane1));
00195 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane2));
00196 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane3));
00197 attrib = DCAST(ClipPlaneAttrib, attrib)->add_on_plane(NodePath(plane4));
00198 return attrib;
00199
00200 case O_remove:
00201 attrib = make();
00202 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane1));
00203 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane2));
00204 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane3));
00205 attrib = DCAST(ClipPlaneAttrib, attrib)->add_off_plane(NodePath(plane4));
00206 return attrib;
00207 }
00208
00209 nassertr(false, make());
00210 return make();
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 CPT(RenderAttrib) ClipPlaneAttrib::
00221 make_default() {
00222 return return_new(new ClipPlaneAttrib);
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 ClipPlaneAttrib::Operation ClipPlaneAttrib::
00242 get_operation() const {
00243 pgraph_cat.warning()
00244 << "Using deprecated ClipPlaneAttrib interface.\n";
00245
00246 if (has_all_off()) {
00247 return O_set;
00248
00249 } else if (get_num_off_planes() == 0) {
00250 return O_add;
00251
00252 } else {
00253 return O_remove;
00254 }
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 int ClipPlaneAttrib::
00268 get_num_planes() const {
00269 pgraph_cat.warning()
00270 << "Using deprecated ClipPlaneAttrib interface.\n";
00271
00272 if (get_num_off_planes() == 0) {
00273 return get_num_on_planes();
00274 } else {
00275 return get_num_off_planes();
00276 }
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 PlaneNode *ClipPlaneAttrib::
00290 get_plane(int n) const {
00291 pgraph_cat.warning()
00292 << "Using deprecated ClipPlaneAttrib interface.\n";
00293
00294 if (get_num_off_planes() == 0) {
00295 return DCAST(PlaneNode, get_on_plane(n).node());
00296 } else {
00297 return DCAST(PlaneNode, get_off_plane(n).node());
00298 }
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 bool ClipPlaneAttrib::
00313 has_plane(PlaneNode *plane) const {
00314 pgraph_cat.warning()
00315 << "Using deprecated ClipPlaneAttrib interface.\n";
00316
00317 if (get_num_off_planes() == 0) {
00318 return has_on_plane(NodePath(plane));
00319 } else {
00320 return has_off_plane(NodePath(plane));
00321 }
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 CPT(RenderAttrib) ClipPlaneAttrib::
00334 add_plane(PlaneNode *plane) const {
00335 pgraph_cat.warning()
00336 << "Using deprecated ClipPlaneAttrib interface.\n";
00337
00338 if (get_num_off_planes() == 0) {
00339 return add_on_plane(NodePath(plane));
00340 } else {
00341 return add_off_plane(NodePath(plane));
00342 }
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 CPT(RenderAttrib) ClipPlaneAttrib::
00356 remove_plane(PlaneNode *plane) const {
00357 pgraph_cat.warning()
00358 << "Using deprecated ClipPlaneAttrib interface.\n";
00359
00360 if (get_num_off_planes() == 0) {
00361 return remove_on_plane(NodePath(plane));
00362 } else {
00363 return remove_off_plane(NodePath(plane));
00364 }
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 CPT(RenderAttrib) ClipPlaneAttrib::
00374 make() {
00375
00376
00377 if (_empty_attrib == (RenderAttrib *)NULL) {
00378 _empty_attrib = return_new(new ClipPlaneAttrib);
00379 }
00380
00381 return _empty_attrib;
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 CPT(RenderAttrib) ClipPlaneAttrib::
00391 make_all_off() {
00392
00393
00394 if (_all_off_attrib == (RenderAttrib *)NULL) {
00395 ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
00396 attrib->_off_all_planes = true;
00397 _all_off_attrib = return_new(attrib);
00398 }
00399
00400 return _all_off_attrib;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410 CPT(RenderAttrib) ClipPlaneAttrib::
00411 add_on_plane(const NodePath &plane) const {
00412 nassertr(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()), this);
00413 ClipPlaneAttrib *attrib = new ClipPlaneAttrib(*this);
00414 attrib->_on_planes.insert(plane);
00415 attrib->_off_planes.erase(plane);
00416
00417 pair<Planes::iterator, bool> insert_result =
00418 attrib->_on_planes.insert(Planes::value_type(plane));
00419 if (insert_result.second) {
00420
00421 attrib->_off_planes.erase(plane);
00422 }
00423
00424 return return_new(attrib);
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434 CPT(RenderAttrib) ClipPlaneAttrib::
00435 remove_on_plane(const NodePath &plane) const {
00436 nassertr(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()), this);
00437 ClipPlaneAttrib *attrib = new ClipPlaneAttrib(*this);
00438 attrib->_on_planes.erase(plane);
00439 return return_new(attrib);
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449 CPT(RenderAttrib) ClipPlaneAttrib::
00450 add_off_plane(const NodePath &plane) const {
00451 nassertr(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()), this);
00452 ClipPlaneAttrib *attrib = new ClipPlaneAttrib(*this);
00453 if (!_off_all_planes) {
00454 attrib->_off_planes.insert(plane);
00455 }
00456 attrib->_on_planes.erase(plane);
00457 return return_new(attrib);
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467 CPT(RenderAttrib) ClipPlaneAttrib::
00468 remove_off_plane(const NodePath &plane) const {
00469 nassertr(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()), this);
00470 ClipPlaneAttrib *attrib = new ClipPlaneAttrib(*this);
00471 attrib->_off_planes.erase(plane);
00472 return return_new(attrib);
00473 }
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 CPT(ClipPlaneAttrib) ClipPlaneAttrib::
00484 filter_to_max(int max_clip_planes) const {
00485 if (max_clip_planes < 0 || (int)_on_planes.size() <= max_clip_planes) {
00486
00487 return this;
00488 }
00489
00490
00491
00492 check_filtered();
00493
00494 Filtered::const_iterator fi;
00495 fi = _filtered.find(max_clip_planes);
00496 if (fi != _filtered.end()) {
00497
00498
00499 return (*fi).second;
00500 }
00501
00502
00503
00504 Planes priority_planes = _on_planes;
00505
00506
00507 sort(priority_planes.begin(), priority_planes.end(),
00508 ComparePlaneNodePriorities());
00509
00510
00511 priority_planes.erase(priority_planes.begin() + max_clip_planes,
00512 priority_planes.end());
00513
00514
00515 priority_planes.sort();
00516
00517
00518 PT(ClipPlaneAttrib) attrib = new ClipPlaneAttrib;
00519 attrib->_on_planes.swap(priority_planes);
00520
00521 CPT(RenderAttrib) new_attrib = return_new(attrib);
00522
00523
00524
00525 CPT(ClipPlaneAttrib) planeNode_attrib = (const ClipPlaneAttrib *)new_attrib.p();
00526 ((ClipPlaneAttrib *)this)->_filtered[max_clip_planes] = planeNode_attrib;
00527 return planeNode_attrib;
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543 CPT(RenderAttrib) ClipPlaneAttrib::
00544 compose_off(const RenderAttrib *other) const {
00545 const ClipPlaneAttrib *ta;
00546 DCAST_INTO_R(ta, other, 0);
00547
00548 if (_off_all_planes || (!ta->_off_all_planes && ta->_off_planes.empty())) {
00549
00550
00551 return this;
00552 }
00553
00554 if (ta->_off_all_planes || _off_planes.empty()) {
00555
00556 return ta;
00557 }
00558
00559 Planes::const_iterator ai = _off_planes.begin();
00560 Planes::const_iterator bi = ta->_off_planes.begin();
00561
00562
00563 ClipPlaneAttrib *new_attrib = new ClipPlaneAttrib;
00564 back_insert_iterator<Planes> result =
00565 back_inserter(new_attrib->_on_planes);
00566
00567 while (ai != _off_planes.end() &&
00568 bi != ta->_off_planes.end()) {
00569 if ((*ai) < (*bi)) {
00570
00571
00572 *result = *ai;
00573 ++ai;
00574 ++result;
00575
00576 } else if ((*bi) < (*ai)) {
00577
00578
00579 *result = *bi;
00580 ++bi;
00581 ++result;
00582
00583 } else {
00584
00585 *result = *bi;
00586 ++ai;
00587 ++bi;
00588 ++result;
00589 }
00590 }
00591
00592 while (ai != _off_planes.end()) {
00593 *result = *ai;
00594 ++ai;
00595 ++result;
00596 }
00597
00598 while (bi != ta->_off_planes.end()) {
00599 *result = *bi;
00600 ++bi;
00601 ++result;
00602 }
00603
00604 return return_new(new_attrib);
00605 }
00606
00607
00608
00609
00610
00611
00612 void ClipPlaneAttrib::
00613 output(ostream &out) const {
00614 out << get_type() << ":";
00615 if (_off_planes.empty()) {
00616 if (_on_planes.empty()) {
00617 if (_off_all_planes) {
00618 out << "all off";
00619 } else {
00620 out << "identity";
00621 }
00622 } else {
00623 if (_off_all_planes) {
00624 out << "set";
00625 } else {
00626 out << "on";
00627 }
00628 }
00629
00630 } else {
00631 out << "off";
00632 Planes::const_iterator fi;
00633 for (fi = _off_planes.begin(); fi != _off_planes.end(); ++fi) {
00634 NodePath plane = (*fi);
00635 out << " " << plane;
00636 }
00637
00638 if (!_on_planes.empty()) {
00639 out << " on";
00640 }
00641 }
00642
00643 Planes::const_iterator li;
00644 for (li = _on_planes.begin(); li != _on_planes.end(); ++li) {
00645 NodePath plane = (*li);
00646 out << " " << plane;
00647 }
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 int ClipPlaneAttrib::
00666 compare_to_impl(const RenderAttrib *other) const {
00667 const ClipPlaneAttrib *ta;
00668 DCAST_INTO_R(ta, other, 0);
00669
00670 if (_off_all_planes != ta->_off_all_planes) {
00671 return (int)_off_all_planes - (int)ta->_off_all_planes;
00672 }
00673
00674 Planes::const_iterator li = _on_planes.begin();
00675 Planes::const_iterator oli = ta->_on_planes.begin();
00676
00677 while (li != _on_planes.end() && oli != ta->_on_planes.end()) {
00678 NodePath plane = (*li);
00679 NodePath other_plane = (*oli);
00680
00681 int compare = plane.compare_to(other_plane);
00682 if (compare != 0) {
00683 return compare;
00684 }
00685
00686 ++li;
00687 ++oli;
00688 }
00689
00690 if (li != _on_planes.end()) {
00691 return 1;
00692 }
00693 if (oli != ta->_on_planes.end()) {
00694 return -1;
00695 }
00696
00697 Planes::const_iterator fi = _off_planes.begin();
00698 Planes::const_iterator ofi = ta->_off_planes.begin();
00699
00700 while (fi != _off_planes.end() && ofi != ta->_off_planes.end()) {
00701 NodePath plane = (*fi);
00702 NodePath other_plane = (*ofi);
00703
00704 int compare = plane.compare_to(other_plane);
00705 if (compare != 0) {
00706 return compare;
00707 }
00708
00709 ++fi;
00710 ++ofi;
00711 }
00712
00713 if (fi != _off_planes.end()) {
00714 return 1;
00715 }
00716 if (ofi != ta->_off_planes.end()) {
00717 return -1;
00718 }
00719
00720 return 0;
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 size_t ClipPlaneAttrib::
00734 get_hash_impl() const {
00735 size_t hash = 0;
00736
00737 Planes::const_iterator li;
00738 for (li = _on_planes.begin(); li != _on_planes.end(); ++li) {
00739 NodePath plane = (*li);
00740 hash = plane.add_hash(hash);
00741 }
00742
00743
00744
00745 hash = int_hash::add_hash(hash, (int)_off_all_planes);
00746
00747 for (li = _off_planes.begin(); li != _off_planes.end(); ++li) {
00748 NodePath plane = (*li);
00749 hash = plane.add_hash(hash);
00750 }
00751
00752 return hash;
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 CPT(RenderAttrib) ClipPlaneAttrib::
00773 compose_impl(const RenderAttrib *other) const {
00774 const ClipPlaneAttrib *ta;
00775 DCAST_INTO_R(ta, other, 0);
00776
00777 if (ta->_off_all_planes) {
00778
00779
00780 return ta;
00781 }
00782
00783
00784
00785
00786 Planes::const_iterator ai = _on_planes.begin();
00787 Planes::const_iterator bi = ta->_on_planes.begin();
00788 Planes::const_iterator ci = ta->_off_planes.begin();
00789
00790
00791 ClipPlaneAttrib *new_attrib = new ClipPlaneAttrib;
00792 back_insert_iterator<Planes> result =
00793 back_inserter(new_attrib->_on_planes);
00794
00795 while (ai != _on_planes.end() &&
00796 bi != ta->_on_planes.end() &&
00797 ci != ta->_off_planes.end()) {
00798 if ((*ai) < (*bi)) {
00799 if ((*ai) < (*ci)) {
00800
00801
00802 *result = *ai;
00803 ++ai;
00804 ++result;
00805
00806 } else if ((*ci) < (*ai)) {
00807
00808
00809 ++ci;
00810
00811 } else {
00812
00813
00814 ++ai;
00815 ++ci;
00816 }
00817
00818 } else if ((*bi) < (*ai)) {
00819
00820
00821 *result = *bi;
00822 ++bi;
00823 ++result;
00824
00825 } else {
00826
00827 *result = *bi;
00828 ++ai;
00829 ++bi;
00830 ++result;
00831 }
00832 }
00833
00834 while (ai != _on_planes.end() && bi != ta->_on_planes.end()) {
00835 if ((*ai) < (*bi)) {
00836
00837
00838 *result = *ai;
00839 ++ai;
00840 ++result;
00841
00842 } else if ((*bi) < (*ai)) {
00843
00844
00845 *result = *bi;
00846 ++bi;
00847 ++result;
00848
00849 } else {
00850
00851 *result = *bi;
00852 ++ai;
00853 ++bi;
00854 ++result;
00855 }
00856 }
00857
00858 while (ai != _on_planes.end() && ci != ta->_off_planes.end()) {
00859 if ((*ai) < (*ci)) {
00860
00861
00862 *result = *ai;
00863 ++ai;
00864 ++result;
00865
00866 } else if ((*ci) < (*ai)) {
00867
00868
00869 ++ci;
00870
00871 } else {
00872
00873
00874 ++ai;
00875 ++ci;
00876 }
00877 }
00878
00879 while (ai != _on_planes.end()) {
00880 *result = *ai;
00881 ++ai;
00882 ++result;
00883 }
00884
00885 while (bi != ta->_on_planes.end()) {
00886 *result = *bi;
00887 ++bi;
00888 ++result;
00889 }
00890
00891 return return_new(new_attrib);
00892 }
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903 CPT(RenderAttrib) ClipPlaneAttrib::
00904 invert_compose_impl(const RenderAttrib *other) const {
00905
00906
00907
00908 return other;
00909 }
00910
00911
00912
00913
00914
00915
00916 CPT(RenderAttrib) ClipPlaneAttrib::
00917 get_auto_shader_attrib_impl(const RenderState *state) const {
00918 return this;
00919 }
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 void ClipPlaneAttrib::
00930 sort_on_planes() {
00931 _sort_seq = PlaneNode::get_sort_seq();
00932 _filtered.clear();
00933 }
00934
00935
00936
00937
00938
00939
00940
00941 void ClipPlaneAttrib::
00942 register_with_read_factory() {
00943 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00944 }
00945
00946
00947
00948
00949
00950
00951
00952 void ClipPlaneAttrib::
00953 write_datagram(BamWriter *manager, Datagram &dg) {
00954 RenderAttrib::write_datagram(manager, dg);
00955
00956 dg.add_bool(_off_all_planes);
00957
00958
00959 dg.add_uint16(get_num_off_planes());
00960
00961 Planes::const_iterator fi;
00962 for (fi = _off_planes.begin(); fi != _off_planes.end(); ++fi) {
00963 NodePath plane = (*fi);
00964
00965
00966
00967
00968 manager->write_pointer(dg, plane.node());
00969 }
00970
00971
00972 dg.add_uint16(get_num_on_planes());
00973
00974 Planes::const_iterator nti;
00975 for (nti = _on_planes.begin(); nti != _on_planes.end(); ++nti) {
00976 NodePath plane = (*nti);
00977 manager->write_pointer(dg, plane.node());
00978 }
00979 }
00980
00981
00982
00983
00984
00985
00986
00987
00988 int ClipPlaneAttrib::
00989 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00990 int pi = RenderAttrib::complete_pointers(p_list, manager);
00991 AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr();
00992
00993 Planes::iterator ci = _off_planes.begin();
00994 while (ci != _off_planes.end()) {
00995 PandaNode *node;
00996 DCAST_INTO_R(node, p_list[pi++], pi);
00997
00998
00999
01000
01001
01002 int ni = areg->find_node(node->get_type(), node->get_name());
01003 if (ni != -1) {
01004 (*ci) = areg->get_node(ni);
01005 } else {
01006 (*ci) = NodePath(node);
01007 }
01008 ++ci;
01009 }
01010 _off_planes.sort();
01011
01012 ci = _on_planes.begin();
01013 while (ci != _on_planes.end()) {
01014 PandaNode *node;
01015 DCAST_INTO_R(node, p_list[pi++], pi);
01016
01017 int ni = areg->find_node(node->get_type(), node->get_name());
01018 if (ni != -1) {
01019 (*ci) = areg->get_node(ni);
01020 } else {
01021 (*ci) = NodePath(node);
01022 }
01023 ++ci;
01024 }
01025 _on_planes.sort();
01026
01027 return pi;
01028 }
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040 bool ClipPlaneAttrib::
01041 require_fully_complete() const {
01042 return true;
01043 }
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053 TypedWritable *ClipPlaneAttrib::
01054 make_from_bam(const FactoryParams ¶ms) {
01055 ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
01056 DatagramIterator scan;
01057 BamReader *manager;
01058
01059 parse_params(params, scan, manager);
01060 attrib->fillin(scan, manager);
01061
01062 return attrib;
01063 }
01064
01065
01066
01067
01068
01069
01070
01071
01072 void ClipPlaneAttrib::
01073 fillin(DatagramIterator &scan, BamReader *manager) {
01074 RenderAttrib::fillin(scan, manager);
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 _off_all_planes = scan.get_bool();
01085
01086 int num_off_planes = scan.get_uint16();
01087
01088
01089
01090 _off_planes.reserve(num_off_planes);
01091 int i;
01092 for (i = 0; i < num_off_planes; i++) {
01093 manager->read_pointer(scan);
01094 _off_planes.push_back(NodePath());
01095 }
01096
01097 int num_on_planes = scan.get_uint16();
01098 _on_planes.reserve(num_on_planes);
01099 for (i = 0; i < num_on_planes; i++) {
01100 manager->read_pointer(scan);
01101 _on_planes.push_back(NodePath());
01102 }
01103 }