00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 INLINE int PandaNode::
00026 get_num_parents(Thread *current_thread) const {
00027 CDReader cdata(_cycler, current_thread);
00028 return cdata->get_up()->size();
00029 }
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 INLINE PandaNode *PandaNode::
00040 get_parent(int n, Thread *current_thread) const {
00041 CDReader cdata(_cycler, current_thread);
00042 CPT(Up) up = cdata->get_up();
00043 nassertr(n >= 0 && n < (int)up->size(), NULL);
00044 return (*up)[n].get_parent();
00045 }
00046
00047
00048
00049
00050
00051
00052
00053 INLINE int PandaNode::
00054 find_parent(PandaNode *node, Thread *current_thread) const {
00055 CDReader cdata(_cycler, current_thread);
00056 return do_find_parent(node, cdata);
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 INLINE int PandaNode::
00068 get_num_children(Thread *current_thread) const {
00069 CDReader cdata(_cycler, current_thread);
00070 return cdata->get_down()->size();
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 INLINE PandaNode *PandaNode::
00082 get_child(int n, Thread *current_thread) const {
00083 CDReader cdata(_cycler, current_thread);
00084 CPT(Down) down = cdata->get_down();
00085 nassertr(n >= 0 && n < (int)down->size(), NULL);
00086 return (*down)[n].get_child();
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096 INLINE int PandaNode::
00097 get_child_sort(int n, Thread *current_thread) const {
00098 CDReader cdata(_cycler, current_thread);
00099 CPT(Down) down = cdata->get_down();
00100 nassertr(n >= 0 && n < (int)down->size(), -1);
00101 return (*down)[n].get_sort();
00102 }
00103
00104
00105
00106
00107
00108
00109
00110 INLINE int PandaNode::
00111 find_child(PandaNode *node, Thread *current_thread) const {
00112 CDReader cdata(_cycler, current_thread);
00113 return do_find_child(node, cdata->get_down());
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 INLINE bool PandaNode::
00133 stash_child(PandaNode *child_node, Thread *current_thread) {
00134 int child_index = find_child(child_node, current_thread);
00135 if (child_index < 0) {
00136 return false;
00137 }
00138 stash_child(child_index, current_thread);
00139 return true;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 INLINE bool PandaNode::
00159 unstash_child(PandaNode *child_node, Thread *current_thread) {
00160 int stashed_index = find_stashed(child_node, current_thread);
00161 if (stashed_index < 0) {
00162 return false;
00163 }
00164 unstash_child(stashed_index, current_thread);
00165 return true;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175 INLINE int PandaNode::
00176 get_num_stashed(Thread *current_thread) const {
00177 CDReader cdata(_cycler, current_thread);
00178 return cdata->get_stashed()->size();
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 INLINE PandaNode *PandaNode::
00191 get_stashed(int n, Thread *current_thread) const {
00192 CDReader cdata(_cycler, current_thread);
00193 CPT(Down) stashed = cdata->get_stashed();
00194 nassertr(n >= 0 && n < (int)stashed->size(), NULL);
00195 return (*stashed)[n].get_child();
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205 INLINE int PandaNode::
00206 get_stashed_sort(int n, Thread *current_thread) const {
00207 CDReader cdata(_cycler, current_thread);
00208 CPT(Down) stashed = cdata->get_stashed();
00209 nassertr(n >= 0 && n < (int)stashed->size(), -1);
00210 return (*stashed)[n].get_sort();
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 INLINE int PandaNode::
00220 find_stashed(PandaNode *node, Thread *current_thread) const {
00221 CDReader cdata(_cycler, current_thread);
00222 return do_find_child(node, cdata->get_stashed());
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 INLINE const RenderAttrib *PandaNode::
00235 get_attrib(TypeHandle type) const {
00236 CDReader cdata(_cycler);
00237 return cdata->_state->get_attrib(type);
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 INLINE const RenderAttrib *PandaNode::
00250 get_attrib(int slot) const {
00251 CDReader cdata(_cycler);
00252 return cdata->_state->get_attrib(slot);
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262 INLINE bool PandaNode::
00263 has_attrib(TypeHandle type) const {
00264 CDReader cdata(_cycler);
00265 return cdata->_state->has_attrib(type);
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275 INLINE bool PandaNode::
00276 has_attrib(int slot) const {
00277 CDReader cdata(_cycler);
00278 return cdata->_state->has_attrib(slot);
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 INLINE void PandaNode::
00290 clear_attrib(TypeHandle type) {
00291 RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr();
00292 int slot = reg->get_slot(type);
00293 clear_attrib(slot);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302 INLINE const RenderEffect *PandaNode::
00303 get_effect(TypeHandle type) const {
00304 CDReader cdata(_cycler);
00305 int index = cdata->_effects->find_effect(type);
00306 if (index >= 0) {
00307 return cdata->_effects->get_effect(index);
00308 }
00309 return NULL;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319 INLINE bool PandaNode::
00320 has_effect(TypeHandle type) const {
00321 CDReader cdata(_cycler);
00322 int index = cdata->_effects->find_effect(type);
00323 return (index >= 0);
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 INLINE const RenderState *PandaNode::
00336 get_state(Thread *current_thread) const {
00337 CDReader cdata(_cycler, current_thread);
00338 return cdata->_state;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 INLINE void PandaNode::
00350 clear_state(Thread *current_thread) {
00351 set_state(RenderState::make_empty(), current_thread);
00352 }
00353
00354
00355
00356
00357
00358
00359
00360 INLINE const RenderEffects *PandaNode::
00361 get_effects(Thread *current_thread) const {
00362 CDReader cdata(_cycler, current_thread);
00363 return cdata->_effects;
00364 }
00365
00366
00367
00368
00369
00370
00371 INLINE void PandaNode::
00372 clear_effects(Thread *current_thread) {
00373 set_effects(RenderEffects::make_empty(), current_thread);
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 INLINE const TransformState *PandaNode::
00385 get_transform(Thread *current_thread) const {
00386 CDReader cdata(_cycler, current_thread);
00387 return cdata->_transform;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396 INLINE void PandaNode::
00397 clear_transform(Thread *current_thread) {
00398 set_transform(TransformState::make_identity(), current_thread);
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408 const TransformState *PandaNode::
00409 get_prev_transform(Thread *current_thread) const {
00410 CDReader cdata(_cycler, current_thread);
00411 return cdata->_prev_transform;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 INLINE bool PandaNode::
00424 has_dirty_prev_transform() const {
00425 return _dirty_prev_transform;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 INLINE string PandaNode::
00437 get_tag(const string &key, Thread *current_thread) const {
00438 CDReader cdata(_cycler, current_thread);
00439 TagData::const_iterator ti;
00440 ti = cdata->_tag_data.find(key);
00441 if (ti != cdata->_tag_data.end()) {
00442 return (*ti).second;
00443 }
00444 return string();
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454 INLINE bool PandaNode::
00455 has_tag(const string &key, Thread *current_thread) const {
00456 CDReader cdata(_cycler, current_thread);
00457 TagData::const_iterator ti;
00458 ti = cdata->_tag_data.find(key);
00459 return (ti != cdata->_tag_data.end());
00460 }
00461
00462
00463
00464
00465
00466
00467
00468 INLINE bool PandaNode::
00469 has_tags() const {
00470 CDReader cdata(_cycler);
00471 if (!cdata->_tag_data.empty()) {
00472 return true;
00473 }
00474 #ifdef HAVE_PYTHON
00475 if (!cdata->_python_tag_data.empty()) {
00476 return true;
00477 }
00478 #endif // HAVE_PYTHON
00479 return false;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488 INLINE void PandaNode::
00489 ls(ostream &out, int indent_level) const {
00490 r_list_descendants(out, indent_level);
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 INLINE DrawMask PandaNode::
00502 get_overall_bit() {
00503 return _overall_bit;
00504 }
00505
00506
00507
00508
00509
00510
00511
00512 INLINE DrawMask PandaNode::
00513 get_all_camera_mask() {
00514 return ~_overall_bit;
00515 }
00516
00517
00518
00519
00520
00521
00522
00523 INLINE bool PandaNode::
00524 is_overall_hidden() const {
00525 CDReader cdata(_cycler);
00526 return ((cdata->_draw_show_mask | ~cdata->_draw_control_mask) & _overall_bit).is_zero();
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543 INLINE void PandaNode::
00544 set_overall_hidden(bool hidden) {
00545 if (hidden) {
00546 adjust_draw_mask(DrawMask::all_off(), _overall_bit, DrawMask::all_off());
00547 } else {
00548 adjust_draw_mask(DrawMask::all_off(), DrawMask::all_off(), _overall_bit);
00549 }
00550 }
00551
00552
00553
00554
00555
00556
00557
00558 INLINE DrawMask PandaNode::
00559 get_draw_control_mask() const {
00560 CDReader cdata(_cycler);
00561 return cdata->_draw_control_mask;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570 INLINE DrawMask PandaNode::
00571 get_draw_show_mask() const {
00572 CDReader cdata(_cycler);
00573 return cdata->_draw_show_mask;
00574 }
00575
00576
00577
00578
00579
00580
00581 INLINE CollideMask PandaNode::
00582 get_into_collide_mask() const {
00583 CDReader cdata(_cycler);
00584 return cdata->_into_collide_mask;
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 INLINE void PandaNode::
00596 clear_bounds() {
00597 set_bounds((BoundingVolume *)NULL);
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 INLINE CPT(BoundingVolume) PandaNode::
00610 get_internal_bounds(Thread *current_thread) const {
00611 return get_internal_bounds(current_thread->get_pipeline_stage(),
00612 current_thread);
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 INLINE int PandaNode::
00626 get_internal_vertices(Thread *current_thread) const {
00627 return get_internal_vertices(current_thread->get_pipeline_stage(),
00628 current_thread);
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 bool PandaNode::
00640 is_bounds_stale() const {
00641 CDReader cdata(_cycler);
00642 return (cdata->_last_update != cdata->_next_update);
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 INLINE void PandaNode::
00663 set_final(bool flag) {
00664 CDWriter cdata(_cycler);
00665 cdata->_final_bounds = flag;
00666 mark_bam_modified();
00667 }
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 INLINE bool PandaNode::
00678 is_final(Thread *current_thread) const {
00679 CDReader cdata(_cycler, current_thread);
00680 return cdata->_final_bounds;
00681 }
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 INLINE int PandaNode::
00694 get_fancy_bits(Thread *current_thread) const {
00695 CDReader cdata(_cycler, current_thread);
00696 return cdata->_fancy_bits;
00697 }
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 INLINE CPT(BoundingVolume) PandaNode::
00708 get_user_bounds(int pipeline_stage, Thread *current_thread) const {
00709 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
00710 return cdata->_user_bounds;
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 INLINE void PandaNode::
00723 mark_bounds_stale(int pipeline_stage, Thread *current_thread) const {
00724
00725
00726 bool is_stale_bounds;
00727 {
00728 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
00729 is_stale_bounds = (cdata->_last_update != cdata->_next_update);
00730 }
00731 if (!is_stale_bounds) {
00732 ((PandaNode *)this)->force_bounds_stale(pipeline_stage, current_thread);
00733 }
00734 }
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 INLINE void PandaNode::
00746 mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread) {
00747 {
00748 CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
00749 ++cdata->_internal_bounds_mark;
00750 }
00751 mark_bounds_stale(pipeline_stage, current_thread);
00752 }
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 INLINE PandaNode::Children PandaNode::
00772 get_children(Thread *current_thread) const {
00773 CDReader cdata(_cycler, current_thread);
00774 return Children(cdata);
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794 INLINE PandaNode::Stashed PandaNode::
00795 get_stashed(Thread *current_thread) const {
00796 CDReader cdata(_cycler, current_thread);
00797 return Stashed(cdata);
00798 }
00799
00800
00801
00802
00803
00804
00805
00806
00807 INLINE PandaNode::Parents PandaNode::
00808 get_parents(Thread *current_thread) const {
00809 CDReader cdata(_cycler, current_thread);
00810 return Parents(cdata);
00811 }
00812
00813
00814
00815
00816
00817
00818 INLINE int PandaNode::
00819 do_find_parent(PandaNode *node, const CData *cdata) const {
00820 CPT(Up) up = cdata->get_up();
00821 Up::const_iterator ui = up->find(UpConnection(node));
00822 if (ui == up->end()) {
00823 return -1;
00824 }
00825 return ui - up->begin();
00826 }
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 INLINE bool PandaNode::
00837 verify_child_no_cycles(PandaNode *child_node) {
00838 #ifndef NDEBUG
00839 if (detect_graph_cycles) {
00840 if (!find_node_above(child_node)) {
00841 return true;
00842 }
00843 report_cycle(child_node);
00844 return false;
00845 }
00846 #endif // NDEBUG
00847 return true;
00848 }
00849
00850
00851
00852
00853
00854
00855
00856 INLINE void PandaNode::
00857 set_dirty_prev_transform() {
00858 if (!_dirty_prev_transform) {
00859 LightMutexHolder holder(_dirty_prev_transforms._lock);
00860 if (!_dirty_prev_transform) {
00861 LinkedListNode::insert_before(&_dirty_prev_transforms);
00862 _dirty_prev_transform = true;
00863 }
00864 }
00865 }
00866
00867
00868
00869
00870
00871
00872
00873 INLINE void PandaNode::
00874 clear_dirty_prev_transform() {
00875 if (_dirty_prev_transform) {
00876 LightMutexHolder holder(_dirty_prev_transforms._lock);
00877 if (_dirty_prev_transform) {
00878 LinkedListNode::remove_from_list();
00879 _dirty_prev_transform = false;
00880 }
00881 }
00882 }
00883
00884
00885
00886
00887
00888
00889 INLINE PandaNode::DownConnection::
00890 DownConnection(PandaNode *child, int sort) :
00891 _child(child),
00892 _sort(sort)
00893 {
00894 }
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 INLINE bool PandaNode::DownConnection::
00905 operator < (const DownConnection &other) const {
00906 return _sort < other._sort;
00907 }
00908
00909
00910
00911
00912
00913
00914 INLINE PandaNode *PandaNode::DownConnection::
00915 get_child() const {
00916 return _child;
00917 }
00918
00919
00920
00921
00922
00923
00924 INLINE void PandaNode::DownConnection::
00925 set_child(PandaNode *child) {
00926 _child = child;
00927 }
00928
00929
00930
00931
00932
00933
00934 INLINE int PandaNode::DownConnection::
00935 get_sort() const {
00936 return _sort;
00937 }
00938
00939
00940
00941
00942
00943
00944 INLINE PandaNode::UpConnection::
00945 UpConnection(PandaNode *parent) :
00946 _parent(parent)
00947 {
00948 }
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960 INLINE bool PandaNode::UpConnection::
00961 operator < (const UpConnection &other) const {
00962 return _parent < other._parent;
00963 }
00964
00965
00966
00967
00968
00969
00970 INLINE PandaNode *PandaNode::UpConnection::
00971 get_parent() const {
00972 return _parent;
00973 }
00974
00975
00976
00977
00978
00979
00980 INLINE PandaNode::BoundsData::
00981 BoundsData() :
00982 _internal_bounds(NULL),
00983 _internal_vertices(0)
00984 {
00985 ++_internal_bounds_mark;
00986 }
00987
00988
00989
00990
00991
00992
00993 INLINE PandaNode::BoundsData::
00994 BoundsData(const PandaNode::BoundsData ©) :
00995 _internal_bounds(copy._internal_bounds),
00996 _internal_vertices(copy._internal_vertices),
00997 _internal_bounds_mark(copy._internal_bounds_mark),
00998 _internal_bounds_computed(copy._internal_bounds_computed)
00999 {
01000 }
01001
01002
01003
01004
01005
01006
01007 INLINE void PandaNode::BoundsData::
01008 copy_bounds(const PandaNode::BoundsData ©) {
01009 _internal_bounds = copy._internal_bounds;
01010 _internal_vertices = copy._internal_vertices;
01011 _internal_bounds_mark = copy._internal_bounds_mark;
01012 _internal_bounds_computed = copy._internal_bounds_computed;
01013 }
01014
01015
01016
01017
01018
01019
01020
01021
01022 INLINE void PandaNode::CData::
01023 set_fancy_bit(int bits, bool value) {
01024 if (value) {
01025 _fancy_bits |= bits;
01026 } else {
01027 _fancy_bits &= ~bits;
01028 }
01029 }
01030
01031
01032
01033
01034
01035
01036 INLINE CPT(PandaNode::Down) PandaNode::CData::
01037 get_down() const {
01038 return _down.get_read_pointer();
01039 }
01040
01041
01042
01043
01044
01045
01046
01047 INLINE PT(PandaNode::Down) PandaNode::CData::
01048 modify_down() {
01049 return _down.get_write_pointer();
01050 }
01051
01052
01053
01054
01055
01056
01057 INLINE CPT(PandaNode::Down) PandaNode::CData::
01058 get_stashed() const {
01059 return _stashed.get_read_pointer();
01060 }
01061
01062
01063
01064
01065
01066
01067
01068 INLINE PT(PandaNode::Down) PandaNode::CData::
01069 modify_stashed() {
01070 return _stashed.get_write_pointer();
01071 }
01072
01073
01074
01075
01076
01077
01078 INLINE CPT(PandaNode::Up) PandaNode::CData::
01079 get_up() const {
01080 return _up.get_read_pointer();
01081 }
01082
01083
01084
01085
01086
01087
01088
01089 INLINE PT(PandaNode::Up) PandaNode::CData::
01090 modify_up() {
01091 return _up.get_write_pointer();
01092 }
01093
01094
01095
01096
01097
01098
01099 INLINE PandaNode::Children::
01100 Children() {
01101 }
01102
01103
01104
01105
01106
01107
01108 INLINE PandaNode::Children::
01109 Children(const PandaNode::CData *cdata) :
01110 _down(cdata->get_down())
01111 {
01112 }
01113
01114
01115
01116
01117
01118
01119 INLINE PandaNode::Children::
01120 Children(const PandaNode::Children ©) :
01121 _down(copy._down)
01122 {
01123 }
01124
01125
01126
01127
01128
01129
01130 INLINE void PandaNode::Children::
01131 operator = (const PandaNode::Children ©) {
01132 _down = copy._down;
01133 }
01134
01135
01136
01137
01138
01139
01140 INLINE int PandaNode::Children::
01141 get_num_children() const {
01142 nassertr(_down != (Down *)NULL, 0);
01143 return _down->size();
01144 }
01145
01146
01147
01148
01149
01150
01151 INLINE PandaNode *PandaNode::Children::
01152 get_child(int n) const {
01153 nassertr(_down != (Down *)NULL, NULL);
01154 nassertr(n >= 0 && n < (int)_down->size(), NULL);
01155 return (*_down)[n].get_child();
01156 }
01157
01158
01159
01160
01161
01162
01163
01164
01165 INLINE int PandaNode::Children::
01166 get_child_sort(int n) const {
01167 nassertr(_down != (Down *)NULL, -1);
01168 nassertr(n >= 0 && n < (int)_down->size(), -1);
01169 return (*_down)[n].get_sort();
01170 }
01171
01172
01173
01174
01175
01176
01177 INLINE PandaNode::Stashed::
01178 Stashed() {
01179 }
01180
01181
01182
01183
01184
01185
01186 INLINE PandaNode::Stashed::
01187 Stashed(const PandaNode::CData *cdata) :
01188 _stashed(cdata->get_stashed())
01189 {
01190 }
01191
01192
01193
01194
01195
01196
01197 INLINE PandaNode::Stashed::
01198 Stashed(const PandaNode::Stashed ©) :
01199 _stashed(copy._stashed)
01200 {
01201 }
01202
01203
01204
01205
01206
01207
01208 INLINE void PandaNode::Stashed::
01209 operator = (const PandaNode::Stashed ©) {
01210 _stashed = copy._stashed;
01211 }
01212
01213
01214
01215
01216
01217
01218 INLINE int PandaNode::Stashed::
01219 get_num_stashed() const {
01220 nassertr(_stashed != (Down *)NULL, 0);
01221 return _stashed->size();
01222 }
01223
01224
01225
01226
01227
01228
01229 INLINE PandaNode *PandaNode::Stashed::
01230 get_stashed(int n) const {
01231 nassertr(_stashed != (Down *)NULL, NULL);
01232 nassertr(n >= 0 && n < (int)_stashed->size(), NULL);
01233 return (*_stashed)[n].get_child();
01234 }
01235
01236
01237
01238
01239
01240
01241
01242
01243 INLINE int PandaNode::Stashed::
01244 get_stashed_sort(int n) const {
01245 nassertr(_stashed != (Down *)NULL, -1);
01246 nassertr(n >= 0 && n < (int)_stashed->size(), -1);
01247 return (*_stashed)[n].get_sort();
01248 }
01249
01250
01251
01252
01253
01254
01255 INLINE PandaNode::Parents::
01256 Parents() {
01257 }
01258
01259
01260
01261
01262
01263
01264 INLINE PandaNode::Parents::
01265 Parents(const PandaNode::CData *cdata) :
01266 _up(cdata->get_up())
01267 {
01268 }
01269
01270
01271
01272
01273
01274
01275 INLINE PandaNode::Parents::
01276 Parents(const PandaNode::Parents ©) :
01277 _up(copy._up)
01278 {
01279 }
01280
01281
01282
01283
01284
01285
01286 INLINE void PandaNode::Parents::
01287 operator = (const PandaNode::Parents ©) {
01288 _up = copy._up;
01289 }
01290
01291
01292
01293
01294
01295
01296 INLINE int PandaNode::Parents::
01297 get_num_parents() const {
01298 nassertr(_up != (Up *)NULL, 0);
01299 return _up->size();
01300 }
01301
01302
01303
01304
01305
01306
01307 INLINE PandaNode *PandaNode::Parents::
01308 get_parent(int n) const {
01309 nassertr(_up != (Up *)NULL, NULL);
01310 nassertr(n >= 0 && n < (int)_up->size(), NULL);
01311 return (*_up)[n].get_parent();
01312 }
01313
01314
01315
01316
01317
01318
01319 INLINE PandaNodePipelineReader::
01320 PandaNodePipelineReader(const PandaNode *object, Thread *current_thread) :
01321 _object(object),
01322 _current_thread(current_thread),
01323 _cdata(object->_cycler.read_unlocked(current_thread))
01324 {
01325 #ifdef _DEBUG
01326 nassertv(_object->test_ref_count_nonzero());
01327 #endif // _DEBUG
01328
01329 #ifdef DO_PIPELINING
01330
01331
01332
01333 _cdata->node_ref();
01334 #endif // DO_PIPELINING
01335 }
01336
01337
01338
01339
01340
01341
01342 INLINE PandaNodePipelineReader::
01343 PandaNodePipelineReader(const PandaNodePipelineReader ©) :
01344 _object(copy._object),
01345 _current_thread(copy._current_thread),
01346 _cdata(copy._cdata)
01347 {
01348 #ifdef DO_PIPELINING
01349 _cdata->node_ref();
01350 #endif // DO_PIPELINING
01351
01352
01353
01354
01355
01356
01357 }
01358
01359
01360
01361
01362
01363
01364 INLINE void PandaNodePipelineReader::
01365 operator = (const PandaNodePipelineReader ©) {
01366 nassertv(_current_thread == copy._current_thread);
01367
01368
01369
01370
01371
01372
01373
01374 #ifdef DO_PIPELINING
01375 node_unref_delete((CycleData *)_cdata);
01376 #endif // DO_PIPELINING
01377
01378 _object = copy._object;
01379 _cdata = copy._cdata;
01380
01381 #ifdef DO_PIPELINING
01382 _cdata->node_ref();
01383 #endif // DO_PIPELINING
01384
01385
01386
01387
01388
01389
01390 }
01391
01392
01393
01394
01395
01396
01397 INLINE PandaNodePipelineReader::
01398 ~PandaNodePipelineReader() {
01399
01400
01401
01402
01403
01404
01405 #ifdef DO_PIPELINING
01406 node_unref_delete((CycleData *)_cdata);
01407 #endif // DO_PIPELINING
01408
01409 #ifdef _DEBUG
01410 _object = NULL;
01411 _cdata = NULL;
01412 #endif // _DEBUG
01413 }
01414
01415
01416
01417
01418
01419
01420 INLINE const PandaNode *PandaNodePipelineReader::
01421 get_object() const {
01422 return _object;
01423 }
01424
01425
01426
01427
01428
01429
01430 INLINE Thread *PandaNodePipelineReader::
01431 get_current_thread() const {
01432 return _current_thread;
01433 }
01434
01435
01436
01437
01438
01439
01440
01441 INLINE void PandaNodePipelineReader::
01442 release() {
01443
01444
01445
01446
01447
01448
01449 }
01450
01451
01452
01453
01454
01455
01456
01457 INLINE void PandaNodePipelineReader::
01458 compose_draw_mask(DrawMask &running_draw_mask) const {
01459 nassertv(_cdata != (PandaNode::CData *)NULL);
01460 running_draw_mask = (running_draw_mask & ~_cdata->_draw_control_mask) |
01461 (_cdata->_draw_show_mask & _cdata->_draw_control_mask);
01462 }
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473 INLINE bool PandaNodePipelineReader::
01474 compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const {
01475 nassertr(_cdata != (PandaNode::CData *)NULL, false);
01476 nassertr(_cdata->_last_update == _cdata->_next_update, false);
01477
01478
01479
01480
01481
01482 if (_cdata->_net_draw_show_mask.is_zero()) {
01483 return false;
01484 }
01485
01486 DrawMask net_draw_control_mask, net_draw_show_mask;
01487 net_draw_control_mask = _cdata->_net_draw_control_mask;
01488 net_draw_show_mask = _cdata->_net_draw_show_mask;
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502 DrawMask compare_mask = (running_draw_mask & ~net_draw_control_mask) | (net_draw_show_mask & net_draw_control_mask);
01503
01504 return !((compare_mask & PandaNode::_overall_bit).is_zero()) && !((compare_mask & camera_mask).is_zero());
01505 }
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516 INLINE int PandaNodePipelineReader::
01517 get_num_parents() const {
01518 return _cdata->get_up()->size();
01519 }
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529 INLINE PandaNode *PandaNodePipelineReader::
01530 get_parent(int n) const {
01531 CPT(PandaNode::Up) up = _cdata->get_up();
01532 nassertr(n >= 0 && n < (int)up->size(), NULL);
01533 return (*up)[n].get_parent();
01534 }
01535
01536
01537
01538
01539
01540
01541
01542 INLINE int PandaNodePipelineReader::
01543 find_parent(PandaNode *node) const {
01544 return _object->do_find_parent(node, _cdata);
01545 }
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555 INLINE int PandaNodePipelineReader::
01556 get_num_children() const {
01557 return _cdata->get_down()->size();
01558 }
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568 INLINE PandaNode *PandaNodePipelineReader::
01569 get_child(int n) const {
01570 CPT(PandaNode::Down) down = _cdata->get_down();
01571 nassertr(n >= 0 && n < (int)down->size(), NULL);
01572 return (*down)[n].get_child();
01573 }
01574
01575
01576
01577
01578
01579
01580
01581
01582 INLINE int PandaNodePipelineReader::
01583 get_child_sort(int n) const {
01584 CPT(PandaNode::Down) down = _cdata->get_down();
01585 nassertr(n >= 0 && n < (int)down->size(), -1);
01586 return (*down)[n].get_sort();
01587 }
01588
01589
01590
01591
01592
01593
01594
01595 INLINE int PandaNodePipelineReader::
01596 find_child(PandaNode *node) const {
01597 return _object->do_find_child(node, _cdata->get_down());
01598 }
01599
01600
01601
01602
01603
01604
01605
01606
01607 INLINE int PandaNodePipelineReader::
01608 get_num_stashed() const {
01609 return _cdata->get_stashed()->size();
01610 }
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621 INLINE PandaNode *PandaNodePipelineReader::
01622 get_stashed(int n) const {
01623 CPT(PandaNode::Down) stashed = _cdata->get_stashed();
01624 nassertr(n >= 0 && n < (int)stashed->size(), NULL);
01625 return (*stashed)[n].get_child();
01626 }
01627
01628
01629
01630
01631
01632
01633
01634
01635 INLINE int PandaNodePipelineReader::
01636 get_stashed_sort(int n) const {
01637 CPT(PandaNode::Down) stashed = _cdata->get_stashed();
01638 nassertr(n >= 0 && n < (int)stashed->size(), -1);
01639 return (*stashed)[n].get_sort();
01640 }
01641
01642
01643
01644
01645
01646
01647
01648 INLINE int PandaNodePipelineReader::
01649 find_stashed(PandaNode *node) const {
01650 return _object->do_find_child(node, _cdata->get_stashed());
01651 }
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662 INLINE const RenderState *PandaNodePipelineReader::
01663 get_state() const {
01664 return _cdata->_state;
01665 }
01666
01667
01668
01669
01670
01671
01672
01673 INLINE const RenderEffects *PandaNodePipelineReader::
01674 get_effects() const {
01675 return _cdata->_effects;
01676 }
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686 INLINE const TransformState *PandaNodePipelineReader::
01687 get_transform() const {
01688 return _cdata->_transform;
01689 }
01690
01691
01692
01693
01694
01695
01696
01697
01698 const TransformState *PandaNodePipelineReader::
01699 get_prev_transform() const {
01700 return _cdata->_prev_transform;
01701 }
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711 INLINE string PandaNodePipelineReader::
01712 get_tag(const string &key) const {
01713 PandaNode::TagData::const_iterator ti;
01714 ti = _cdata->_tag_data.find(key);
01715 if (ti != _cdata->_tag_data.end()) {
01716 return (*ti).second;
01717 }
01718 return string();
01719 }
01720
01721
01722
01723
01724
01725
01726
01727
01728 INLINE bool PandaNodePipelineReader::
01729 has_tag(const string &key) const {
01730 PandaNode::TagData::const_iterator ti;
01731 ti = _cdata->_tag_data.find(key);
01732 return (ti != _cdata->_tag_data.end());
01733 }
01734
01735
01736
01737
01738
01739
01740
01741 INLINE CollideMask PandaNodePipelineReader::
01742 get_net_collide_mask() const {
01743 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_net_collide_mask);
01744 return _cdata->_net_collide_mask;
01745 }
01746
01747
01748
01749
01750
01751
01752
01753
01754 INLINE CPT(RenderAttrib) PandaNodePipelineReader::
01755 get_off_clip_planes() const {
01756 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_off_clip_planes);
01757 return _cdata->_off_clip_planes;
01758 }
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768 INLINE CPT(BoundingVolume) PandaNodePipelineReader::
01769 get_bounds() const {
01770 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_external_bounds);
01771 return _cdata->_external_bounds;
01772 }
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787 INLINE int PandaNodePipelineReader::
01788 get_nested_vertices() const {
01789 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_nested_vertices);
01790 return _cdata->_nested_vertices;
01791 }
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801 INLINE bool PandaNodePipelineReader::
01802 is_final() const {
01803 return _cdata->_final_bounds;
01804 }
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817 INLINE int PandaNodePipelineReader::
01818 get_fancy_bits() const {
01819 return _cdata->_fancy_bits;
01820 }
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839 INLINE PandaNode::Children PandaNodePipelineReader::
01840 get_children() const {
01841 return PandaNode::Children(_cdata);
01842 }
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861 INLINE PandaNode::Stashed PandaNodePipelineReader::
01862 get_stashed() const {
01863 return PandaNode::Stashed(_cdata);
01864 }
01865
01866
01867
01868
01869
01870
01871
01872
01873 INLINE PandaNode::Parents PandaNodePipelineReader::
01874 get_parents() const {
01875 return PandaNode::Parents(_cdata);
01876 }
01877
01878
01879
01880
01881
01882
01883 INLINE PandaNode::BamReaderAuxDataDown::
01884 BamReaderAuxDataDown() :
01885 _down_list(PandaNode::get_class_type())
01886 {
01887 }