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
00857 INLINE void PandaNode::
00858 do_set_dirty_prev_transform() {
00859 nassertv(_dirty_prev_transforms._lock.debug_is_locked());
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 do_clear_dirty_prev_transform() {
00875 nassertv(_dirty_prev_transforms._lock.debug_is_locked());
00876 if (_dirty_prev_transform) {
00877 LinkedListNode::remove_from_list();
00878 _dirty_prev_transform = false;
00879 }
00880 }
00881
00882
00883
00884
00885
00886
00887 INLINE PandaNode::DownConnection::
00888 DownConnection(PandaNode *child, int sort) :
00889 _child(child),
00890 _sort(sort)
00891 {
00892 }
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902 INLINE bool PandaNode::DownConnection::
00903 operator < (const DownConnection &other) const {
00904 return _sort < other._sort;
00905 }
00906
00907
00908
00909
00910
00911
00912 INLINE PandaNode *PandaNode::DownConnection::
00913 get_child() const {
00914 return _child;
00915 }
00916
00917
00918
00919
00920
00921
00922 INLINE void PandaNode::DownConnection::
00923 set_child(PandaNode *child) {
00924 _child = child;
00925 }
00926
00927
00928
00929
00930
00931
00932 INLINE int PandaNode::DownConnection::
00933 get_sort() const {
00934 return _sort;
00935 }
00936
00937
00938
00939
00940
00941
00942 INLINE PandaNode::UpConnection::
00943 UpConnection(PandaNode *parent) :
00944 _parent(parent)
00945 {
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 INLINE bool PandaNode::UpConnection::
00959 operator < (const UpConnection &other) const {
00960 return _parent < other._parent;
00961 }
00962
00963
00964
00965
00966
00967
00968 INLINE PandaNode *PandaNode::UpConnection::
00969 get_parent() const {
00970 return _parent;
00971 }
00972
00973
00974
00975
00976
00977
00978 INLINE PandaNode::BoundsData::
00979 BoundsData() :
00980 _internal_bounds(NULL),
00981 _internal_vertices(0)
00982 {
00983 ++_internal_bounds_mark;
00984 }
00985
00986
00987
00988
00989
00990
00991 INLINE PandaNode::BoundsData::
00992 BoundsData(const PandaNode::BoundsData ©) :
00993 _internal_bounds(copy._internal_bounds),
00994 _internal_vertices(copy._internal_vertices),
00995 _internal_bounds_mark(copy._internal_bounds_mark),
00996 _internal_bounds_computed(copy._internal_bounds_computed)
00997 {
00998 }
00999
01000
01001
01002
01003
01004
01005 INLINE void PandaNode::BoundsData::
01006 copy_bounds(const PandaNode::BoundsData ©) {
01007 _internal_bounds = copy._internal_bounds;
01008 _internal_vertices = copy._internal_vertices;
01009 _internal_bounds_mark = copy._internal_bounds_mark;
01010 _internal_bounds_computed = copy._internal_bounds_computed;
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020 INLINE void PandaNode::CData::
01021 set_fancy_bit(int bits, bool value) {
01022 if (value) {
01023 _fancy_bits |= bits;
01024 } else {
01025 _fancy_bits &= ~bits;
01026 }
01027 }
01028
01029
01030
01031
01032
01033
01034 INLINE CPT(PandaNode::Down) PandaNode::CData::
01035 get_down() const {
01036 return _down.get_read_pointer();
01037 }
01038
01039
01040
01041
01042
01043
01044
01045 INLINE PT(PandaNode::Down) PandaNode::CData::
01046 modify_down() {
01047 return _down.get_write_pointer();
01048 }
01049
01050
01051
01052
01053
01054
01055 INLINE CPT(PandaNode::Down) PandaNode::CData::
01056 get_stashed() const {
01057 return _stashed.get_read_pointer();
01058 }
01059
01060
01061
01062
01063
01064
01065
01066 INLINE PT(PandaNode::Down) PandaNode::CData::
01067 modify_stashed() {
01068 return _stashed.get_write_pointer();
01069 }
01070
01071
01072
01073
01074
01075
01076 INLINE CPT(PandaNode::Up) PandaNode::CData::
01077 get_up() const {
01078 return _up.get_read_pointer();
01079 }
01080
01081
01082
01083
01084
01085
01086
01087 INLINE PT(PandaNode::Up) PandaNode::CData::
01088 modify_up() {
01089 return _up.get_write_pointer();
01090 }
01091
01092
01093
01094
01095
01096
01097 INLINE PandaNode::Children::
01098 Children() {
01099 }
01100
01101
01102
01103
01104
01105
01106 INLINE PandaNode::Children::
01107 Children(const PandaNode::CData *cdata) :
01108 _down(cdata->get_down())
01109 {
01110 }
01111
01112
01113
01114
01115
01116
01117 INLINE PandaNode::Children::
01118 Children(const PandaNode::Children ©) :
01119 _down(copy._down)
01120 {
01121 }
01122
01123
01124
01125
01126
01127
01128 INLINE void PandaNode::Children::
01129 operator = (const PandaNode::Children ©) {
01130 _down = copy._down;
01131 }
01132
01133
01134
01135
01136
01137
01138 INLINE int PandaNode::Children::
01139 get_num_children() const {
01140 nassertr(_down != (Down *)NULL, 0);
01141 return _down->size();
01142 }
01143
01144
01145
01146
01147
01148
01149 INLINE PandaNode *PandaNode::Children::
01150 get_child(int n) const {
01151 nassertr(_down != (Down *)NULL, NULL);
01152 nassertr(n >= 0 && n < (int)_down->size(), NULL);
01153 return (*_down)[n].get_child();
01154 }
01155
01156
01157
01158
01159
01160
01161
01162
01163 INLINE int PandaNode::Children::
01164 get_child_sort(int n) const {
01165 nassertr(_down != (Down *)NULL, -1);
01166 nassertr(n >= 0 && n < (int)_down->size(), -1);
01167 return (*_down)[n].get_sort();
01168 }
01169
01170
01171
01172
01173
01174
01175 INLINE PandaNode::Stashed::
01176 Stashed() {
01177 }
01178
01179
01180
01181
01182
01183
01184 INLINE PandaNode::Stashed::
01185 Stashed(const PandaNode::CData *cdata) :
01186 _stashed(cdata->get_stashed())
01187 {
01188 }
01189
01190
01191
01192
01193
01194
01195 INLINE PandaNode::Stashed::
01196 Stashed(const PandaNode::Stashed ©) :
01197 _stashed(copy._stashed)
01198 {
01199 }
01200
01201
01202
01203
01204
01205
01206 INLINE void PandaNode::Stashed::
01207 operator = (const PandaNode::Stashed ©) {
01208 _stashed = copy._stashed;
01209 }
01210
01211
01212
01213
01214
01215
01216 INLINE int PandaNode::Stashed::
01217 get_num_stashed() const {
01218 nassertr(_stashed != (Down *)NULL, 0);
01219 return _stashed->size();
01220 }
01221
01222
01223
01224
01225
01226
01227 INLINE PandaNode *PandaNode::Stashed::
01228 get_stashed(int n) const {
01229 nassertr(_stashed != (Down *)NULL, NULL);
01230 nassertr(n >= 0 && n < (int)_stashed->size(), NULL);
01231 return (*_stashed)[n].get_child();
01232 }
01233
01234
01235
01236
01237
01238
01239
01240
01241 INLINE int PandaNode::Stashed::
01242 get_stashed_sort(int n) const {
01243 nassertr(_stashed != (Down *)NULL, -1);
01244 nassertr(n >= 0 && n < (int)_stashed->size(), -1);
01245 return (*_stashed)[n].get_sort();
01246 }
01247
01248
01249
01250
01251
01252
01253 INLINE PandaNode::Parents::
01254 Parents() {
01255 }
01256
01257
01258
01259
01260
01261
01262 INLINE PandaNode::Parents::
01263 Parents(const PandaNode::CData *cdata) :
01264 _up(cdata->get_up())
01265 {
01266 }
01267
01268
01269
01270
01271
01272
01273 INLINE PandaNode::Parents::
01274 Parents(const PandaNode::Parents ©) :
01275 _up(copy._up)
01276 {
01277 }
01278
01279
01280
01281
01282
01283
01284 INLINE void PandaNode::Parents::
01285 operator = (const PandaNode::Parents ©) {
01286 _up = copy._up;
01287 }
01288
01289
01290
01291
01292
01293
01294 INLINE int PandaNode::Parents::
01295 get_num_parents() const {
01296 nassertr(_up != (Up *)NULL, 0);
01297 return _up->size();
01298 }
01299
01300
01301
01302
01303
01304
01305 INLINE PandaNode *PandaNode::Parents::
01306 get_parent(int n) const {
01307 nassertr(_up != (Up *)NULL, NULL);
01308 nassertr(n >= 0 && n < (int)_up->size(), NULL);
01309 return (*_up)[n].get_parent();
01310 }
01311
01312
01313
01314
01315
01316
01317 INLINE PandaNodePipelineReader::
01318 PandaNodePipelineReader(const PandaNode *object, Thread *current_thread) :
01319 _object(object),
01320 _current_thread(current_thread),
01321 _cdata(object->_cycler.read_unlocked(current_thread))
01322 {
01323 #ifdef _DEBUG
01324 nassertv(_object->test_ref_count_nonzero());
01325 #endif // _DEBUG
01326
01327 #ifdef DO_PIPELINING
01328
01329
01330
01331 _cdata->node_ref();
01332 #endif // DO_PIPELINING
01333 }
01334
01335
01336
01337
01338
01339
01340 INLINE PandaNodePipelineReader::
01341 PandaNodePipelineReader(const PandaNodePipelineReader ©) :
01342 _object(copy._object),
01343 _current_thread(copy._current_thread),
01344 _cdata(copy._cdata)
01345 {
01346 #ifdef DO_PIPELINING
01347 _cdata->node_ref();
01348 #endif // DO_PIPELINING
01349
01350
01351
01352
01353
01354
01355 }
01356
01357
01358
01359
01360
01361
01362 INLINE void PandaNodePipelineReader::
01363 operator = (const PandaNodePipelineReader ©) {
01364 nassertv(_current_thread == copy._current_thread);
01365
01366
01367
01368
01369
01370
01371
01372 #ifdef DO_PIPELINING
01373 node_unref_delete((CycleData *)_cdata);
01374 #endif // DO_PIPELINING
01375
01376 _object = copy._object;
01377 _cdata = copy._cdata;
01378
01379 #ifdef DO_PIPELINING
01380 _cdata->node_ref();
01381 #endif // DO_PIPELINING
01382
01383
01384
01385
01386
01387
01388 }
01389
01390
01391
01392
01393
01394
01395 INLINE PandaNodePipelineReader::
01396 ~PandaNodePipelineReader() {
01397
01398
01399
01400
01401
01402
01403 #ifdef DO_PIPELINING
01404 node_unref_delete((CycleData *)_cdata);
01405 #endif // DO_PIPELINING
01406
01407 #ifdef _DEBUG
01408 _object = NULL;
01409 _cdata = NULL;
01410 #endif // _DEBUG
01411 }
01412
01413
01414
01415
01416
01417
01418 INLINE const PandaNode *PandaNodePipelineReader::
01419 get_object() const {
01420 return _object;
01421 }
01422
01423
01424
01425
01426
01427
01428 INLINE Thread *PandaNodePipelineReader::
01429 get_current_thread() const {
01430 return _current_thread;
01431 }
01432
01433
01434
01435
01436
01437
01438
01439 INLINE void PandaNodePipelineReader::
01440 release() {
01441
01442
01443
01444
01445
01446
01447 }
01448
01449
01450
01451
01452
01453
01454
01455 INLINE void PandaNodePipelineReader::
01456 compose_draw_mask(DrawMask &running_draw_mask) const {
01457 nassertv(_cdata != (PandaNode::CData *)NULL);
01458 running_draw_mask = (running_draw_mask & ~_cdata->_draw_control_mask) |
01459 (_cdata->_draw_show_mask & _cdata->_draw_control_mask);
01460 }
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471 INLINE bool PandaNodePipelineReader::
01472 compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const {
01473 nassertr(_cdata != (PandaNode::CData *)NULL, false);
01474 nassertr(_cdata->_last_update == _cdata->_next_update, false);
01475
01476
01477
01478
01479
01480 if (_cdata->_net_draw_show_mask.is_zero()) {
01481 return false;
01482 }
01483
01484 DrawMask net_draw_control_mask, net_draw_show_mask;
01485 net_draw_control_mask = _cdata->_net_draw_control_mask;
01486 net_draw_show_mask = _cdata->_net_draw_show_mask;
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500 DrawMask compare_mask = (running_draw_mask & ~net_draw_control_mask) | (net_draw_show_mask & net_draw_control_mask);
01501
01502 return !((compare_mask & PandaNode::_overall_bit).is_zero()) && !((compare_mask & camera_mask).is_zero());
01503 }
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514 INLINE int PandaNodePipelineReader::
01515 get_num_parents() const {
01516 return _cdata->get_up()->size();
01517 }
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527 INLINE PandaNode *PandaNodePipelineReader::
01528 get_parent(int n) const {
01529 CPT(PandaNode::Up) up = _cdata->get_up();
01530 nassertr(n >= 0 && n < (int)up->size(), NULL);
01531 return (*up)[n].get_parent();
01532 }
01533
01534
01535
01536
01537
01538
01539
01540 INLINE int PandaNodePipelineReader::
01541 find_parent(PandaNode *node) const {
01542 return _object->do_find_parent(node, _cdata);
01543 }
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553 INLINE int PandaNodePipelineReader::
01554 get_num_children() const {
01555 return _cdata->get_down()->size();
01556 }
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566 INLINE PandaNode *PandaNodePipelineReader::
01567 get_child(int n) const {
01568 CPT(PandaNode::Down) down = _cdata->get_down();
01569 nassertr(n >= 0 && n < (int)down->size(), NULL);
01570 return (*down)[n].get_child();
01571 }
01572
01573
01574
01575
01576
01577
01578
01579
01580 INLINE int PandaNodePipelineReader::
01581 get_child_sort(int n) const {
01582 CPT(PandaNode::Down) down = _cdata->get_down();
01583 nassertr(n >= 0 && n < (int)down->size(), -1);
01584 return (*down)[n].get_sort();
01585 }
01586
01587
01588
01589
01590
01591
01592
01593 INLINE int PandaNodePipelineReader::
01594 find_child(PandaNode *node) const {
01595 return _object->do_find_child(node, _cdata->get_down());
01596 }
01597
01598
01599
01600
01601
01602
01603
01604
01605 INLINE int PandaNodePipelineReader::
01606 get_num_stashed() const {
01607 return _cdata->get_stashed()->size();
01608 }
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619 INLINE PandaNode *PandaNodePipelineReader::
01620 get_stashed(int n) const {
01621 CPT(PandaNode::Down) stashed = _cdata->get_stashed();
01622 nassertr(n >= 0 && n < (int)stashed->size(), NULL);
01623 return (*stashed)[n].get_child();
01624 }
01625
01626
01627
01628
01629
01630
01631
01632
01633 INLINE int PandaNodePipelineReader::
01634 get_stashed_sort(int n) const {
01635 CPT(PandaNode::Down) stashed = _cdata->get_stashed();
01636 nassertr(n >= 0 && n < (int)stashed->size(), -1);
01637 return (*stashed)[n].get_sort();
01638 }
01639
01640
01641
01642
01643
01644
01645
01646 INLINE int PandaNodePipelineReader::
01647 find_stashed(PandaNode *node) const {
01648 return _object->do_find_child(node, _cdata->get_stashed());
01649 }
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660 INLINE const RenderState *PandaNodePipelineReader::
01661 get_state() const {
01662 return _cdata->_state;
01663 }
01664
01665
01666
01667
01668
01669
01670
01671 INLINE const RenderEffects *PandaNodePipelineReader::
01672 get_effects() const {
01673 return _cdata->_effects;
01674 }
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684 INLINE const TransformState *PandaNodePipelineReader::
01685 get_transform() const {
01686 return _cdata->_transform;
01687 }
01688
01689
01690
01691
01692
01693
01694
01695
01696 const TransformState *PandaNodePipelineReader::
01697 get_prev_transform() const {
01698 return _cdata->_prev_transform;
01699 }
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709 INLINE string PandaNodePipelineReader::
01710 get_tag(const string &key) const {
01711 PandaNode::TagData::const_iterator ti;
01712 ti = _cdata->_tag_data.find(key);
01713 if (ti != _cdata->_tag_data.end()) {
01714 return (*ti).second;
01715 }
01716 return string();
01717 }
01718
01719
01720
01721
01722
01723
01724
01725
01726 INLINE bool PandaNodePipelineReader::
01727 has_tag(const string &key) const {
01728 PandaNode::TagData::const_iterator ti;
01729 ti = _cdata->_tag_data.find(key);
01730 return (ti != _cdata->_tag_data.end());
01731 }
01732
01733
01734
01735
01736
01737
01738
01739 INLINE CollideMask PandaNodePipelineReader::
01740 get_net_collide_mask() const {
01741 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_net_collide_mask);
01742 return _cdata->_net_collide_mask;
01743 }
01744
01745
01746
01747
01748
01749
01750
01751
01752 INLINE CPT(RenderAttrib) PandaNodePipelineReader::
01753 get_off_clip_planes() const {
01754 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_off_clip_planes);
01755 return _cdata->_off_clip_planes;
01756 }
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766 INLINE CPT(BoundingVolume) PandaNodePipelineReader::
01767 get_bounds() const {
01768 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_external_bounds);
01769 return _cdata->_external_bounds;
01770 }
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785 INLINE int PandaNodePipelineReader::
01786 get_nested_vertices() const {
01787 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_nested_vertices);
01788 return _cdata->_nested_vertices;
01789 }
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799 INLINE bool PandaNodePipelineReader::
01800 is_final() const {
01801 return _cdata->_final_bounds;
01802 }
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815 INLINE int PandaNodePipelineReader::
01816 get_fancy_bits() const {
01817 return _cdata->_fancy_bits;
01818 }
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837 INLINE PandaNode::Children PandaNodePipelineReader::
01838 get_children() const {
01839 return PandaNode::Children(_cdata);
01840 }
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859 INLINE PandaNode::Stashed PandaNodePipelineReader::
01860 get_stashed() const {
01861 return PandaNode::Stashed(_cdata);
01862 }
01863
01864
01865
01866
01867
01868
01869
01870
01871 INLINE PandaNode::Parents PandaNodePipelineReader::
01872 get_parents() const {
01873 return PandaNode::Parents(_cdata);
01874 }
01875
01876
01877
01878
01879
01880
01881 INLINE PandaNode::BamReaderAuxDataDown::
01882 BamReaderAuxDataDown() :
01883 _down_list(PandaNode::get_class_type())
01884 {
01885 }