27 CDReader cdata(_cycler, current_thread);
28 return cdata->get_up()->size();
41 CDReader cdata(_cycler, current_thread);
42 CPT(
Up) up = cdata->get_up();
43 nassertr(n >= 0 && n < (
int)up->size(), NULL);
44 return (*up)[n].get_parent();
55 CDReader cdata(_cycler, current_thread);
56 return do_find_parent(node, cdata);
69 CDReader cdata(_cycler, current_thread);
70 return cdata->get_down()->size();
83 CDReader cdata(_cycler, current_thread);
84 CPT(
Down) down = cdata->get_down();
85 nassertr(n >= 0 && n < (
int)down->size(), NULL);
86 return (*down)[n].get_child();
98 CDReader cdata(_cycler, current_thread);
99 CPT(
Down) down = cdata->get_down();
100 nassertr(n >= 0 && n < (
int)down->size(), -1);
101 return (*down)[n].get_sort();
112 CDReader cdata(_cycler, current_thread);
113 return do_find_child(node, cdata->get_down());
134 int child_index =
find_child(child_node, current_thread);
135 if (child_index < 0) {
160 int stashed_index =
find_stashed(child_node, current_thread);
161 if (stashed_index < 0) {
177 CDReader cdata(_cycler, current_thread);
178 return cdata->get_stashed()->size();
192 CDReader cdata(_cycler, current_thread);
193 CPT(
Down) stashed = cdata->get_stashed();
194 nassertr(n >= 0 && n < (
int)stashed->size(), NULL);
195 return (*stashed)[n].get_child();
207 CDReader cdata(_cycler, current_thread);
208 CPT(
Down) stashed = cdata->get_stashed();
209 nassertr(n >= 0 && n < (
int)stashed->size(), -1);
210 return (*stashed)[n].get_sort();
221 CDReader cdata(_cycler, current_thread);
222 return do_find_child(node, cdata->get_stashed());
237 return cdata->_state->get_attrib(type);
250 get_attrib(
int slot)
const {
252 return cdata->_state->get_attrib(slot);
262 INLINE
bool PandaNode::
265 return cdata->_state->has_attrib(type);
275 INLINE
bool PandaNode::
276 has_attrib(
int slot)
const {
278 return cdata->_state->has_attrib(slot);
289 INLINE
void PandaNode::
305 int index = cdata->_effects->find_effect(type);
307 return cdata->_effects->get_effect(index);
319 INLINE
bool PandaNode::
322 int index = cdata->_effects->find_effect(type);
336 get_state(
Thread *current_thread)
const {
337 CDReader cdata(_cycler, current_thread);
338 return cdata->_state.
p();
349 INLINE
void PandaNode::
350 clear_state(
Thread *current_thread) {
351 set_state(RenderState::make_empty(), current_thread);
361 get_effects(
Thread *current_thread)
const {
362 CDReader cdata(_cycler, current_thread);
363 return cdata->_effects;
371 INLINE
void PandaNode::
372 clear_effects(
Thread *current_thread) {
373 set_effects(RenderEffects::make_empty(), current_thread);
384 INLINE CPT(TransformState) PandaNode::
385 get_transform(
Thread *current_thread)
const {
386 CDReader cdata(_cycler, current_thread);
387 return cdata->_transform.
p();
396 INLINE
void PandaNode::
397 clear_transform(
Thread *current_thread) {
398 set_transform(TransformState::make_identity(), current_thread);
408 INLINE CPT(TransformState) PandaNode::
409 get_prev_transform(
Thread *current_thread)
const {
410 CDReader cdata(_cycler, current_thread);
411 return cdata->_prev_transform.
p();
423 INLINE
bool PandaNode::
424 has_dirty_prev_transform()
const {
425 return _dirty_prev_transform;
436 INLINE
string PandaNode::
437 get_tag(
const string &key,
Thread *current_thread)
const {
438 CDReader cdata(_cycler, current_thread);
439 TagData::const_iterator ti;
440 ti = cdata->_tag_data.find(key);
441 if (ti != cdata->_tag_data.end()) {
454 INLINE
bool PandaNode::
455 has_tag(
const string &key,
Thread *current_thread)
const {
456 CDReader cdata(_cycler, current_thread);
457 TagData::const_iterator ti;
458 ti = cdata->_tag_data.find(key);
459 return (ti != cdata->_tag_data.end());
468 INLINE
bool PandaNode::
471 if (!cdata->_tag_data.empty()) {
475 if (!cdata->_python_tag_data.empty()) {
478 #endif // HAVE_PYTHON 488 INLINE
void PandaNode::
489 ls(ostream &out,
int indent_level)
const {
490 r_list_descendants(out, indent_level);
514 return ~_overall_bit;
526 return ((cdata->_draw_show_mask | ~cdata->_draw_control_mask) & _overall_bit).is_zero();
561 return cdata->_draw_control_mask;
573 return cdata->_draw_show_mask;
584 return cdata->_into_collide_mask;
610 get_internal_bounds(
Thread *current_thread)
const {
625 INLINE
int PandaNode::
626 get_internal_vertices(
Thread *current_thread)
const {
640 is_bounds_stale()
const {
642 return (cdata->_last_bounds_update != cdata->_next_update);
662 INLINE
void PandaNode::
663 set_final(
bool flag) {
665 cdata->_final_bounds = flag;
679 CDReader cdata(_cycler, current_thread);
680 return cdata->_final_bounds;
695 CDReader cdata(_cycler, current_thread);
696 return cdata->_fancy_bits;
708 get_user_bounds(
int pipeline_stage,
Thread *current_thread)
const {
709 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
710 return cdata->_user_bounds;
722 INLINE
void PandaNode::
723 mark_bounds_stale(
int pipeline_stage,
Thread *current_thread)
const {
726 bool is_stale_bounds;
728 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
729 is_stale_bounds = (cdata->_last_update != cdata->_next_update);
733 if (!is_stale_bounds) {
734 ((
PandaNode *)
this)->force_bounds_stale(pipeline_stage, current_thread);
746 INLINE
void PandaNode::
747 mark_internal_bounds_stale(
int pipeline_stage,
Thread *current_thread) {
749 CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
750 ++cdata->_internal_bounds_mark;
752 mark_bounds_stale(pipeline_stage, current_thread);
774 CDReader cdata(_cycler, current_thread);
797 CDReader cdata(_cycler, current_thread);
810 CDReader cdata(_cycler, current_thread);
819 INLINE
int PandaNode::
820 do_find_parent(
PandaNode *node,
const CData *cdata)
const {
821 CPT(
Up) up = cdata->get_up();
822 Up::const_iterator ui = up->find(UpConnection(node));
823 if (ui == up->end()) {
826 return ui - up->begin();
837 INLINE
bool PandaNode::
838 verify_child_no_cycles(
PandaNode *child_node) {
840 if (detect_graph_cycles) {
841 if (!find_node_above(child_node)) {
844 report_cycle(child_node);
858 INLINE
void PandaNode::
859 do_set_dirty_prev_transform() {
861 if (!_dirty_prev_transform) {
862 LinkedListNode::insert_before(&_dirty_prev_transforms);
863 _dirty_prev_transform =
true;
874 INLINE
void PandaNode::
875 do_clear_dirty_prev_transform() {
877 if (_dirty_prev_transform) {
878 LinkedListNode::remove_from_list();
879 _dirty_prev_transform =
false;
888 INLINE PandaNode::DownConnection::
889 DownConnection(
PandaNode *child,
int sort) :
905 return _sort < other._sort;
913 INLINE
PandaNode *PandaNode::DownConnection::
933 INLINE
int PandaNode::DownConnection::
943 INLINE PandaNode::UpConnection::
959 INLINE
bool PandaNode::UpConnection::
960 operator < (
const UpConnection &other)
const {
961 return _parent < other._parent;
969 INLINE
PandaNode *PandaNode::UpConnection::
979 INLINE PandaNode::BoundsData::
981 _internal_bounds(NULL),
982 _internal_vertices(0)
984 ++_internal_bounds_mark;
992 INLINE PandaNode::BoundsData::
993 BoundsData(
const PandaNode::BoundsData ©) :
994 _internal_bounds(copy._internal_bounds),
995 _internal_vertices(copy._internal_vertices),
996 _internal_bounds_mark(copy._internal_bounds_mark),
997 _internal_bounds_computed(copy._internal_bounds_computed)
1006 INLINE
void PandaNode::BoundsData::
1007 copy_bounds(
const PandaNode::BoundsData ©) {
1008 _internal_bounds = copy._internal_bounds;
1009 _internal_vertices = copy._internal_vertices;
1010 _internal_bounds_mark = copy._internal_bounds_mark;
1011 _internal_bounds_computed = copy._internal_bounds_computed;
1021 INLINE
void PandaNode::CData::
1022 set_fancy_bit(
int bits,
bool value) {
1024 _fancy_bits |= bits;
1026 _fancy_bits &= ~bits;
1037 return _down.get_read_pointer();
1048 return _down.get_write_pointer();
1057 get_stashed()
const {
1058 return _stashed.get_read_pointer();
1069 return _stashed.get_write_pointer();
1079 return _up.get_read_pointer();
1090 return _up.get_write_pointer();
1098 INLINE PandaNode::Children::
1107 INLINE PandaNode::Children::
1108 Children(
const PandaNode::CData *cdata) :
1109 _down(cdata->get_down())
1118 INLINE PandaNode::Children::
1129 INLINE
void PandaNode::Children::
1134 #ifdef USE_MOVE_SEMANTICS 1140 INLINE PandaNode::Children::
1142 _down(move(from._down))
1151 INLINE
void PandaNode::Children::
1153 _down = move(from._down);
1155 #endif // USE_MOVE_SEMANTICS 1164 nassertr(_down != (
Down *)NULL, 0);
1165 return _down->size();
1175 nassertr(_down != (
Down *)NULL, NULL);
1176 nassertr(n >= 0 && n < (
int)_down->size(), NULL);
1177 return (*_down)[n].get_child();
1189 nassertr(_down != (
Down *)NULL, -1);
1190 nassertr(n >= 0 && n < (
int)_down->size(), -1);
1191 return (*_down)[n].get_sort();
1199 INLINE PandaNode::Stashed::
1208 INLINE PandaNode::Stashed::
1209 Stashed(
const PandaNode::CData *cdata) :
1210 _stashed(cdata->get_stashed())
1219 INLINE PandaNode::Stashed::
1221 _stashed(copy._stashed)
1230 INLINE
void PandaNode::Stashed::
1232 _stashed = copy._stashed;
1235 #ifdef USE_MOVE_SEMANTICS 1241 INLINE PandaNode::Stashed::
1243 _stashed(move(from._stashed))
1252 INLINE
void PandaNode::Stashed::
1254 _stashed = move(from._stashed);
1256 #endif // USE_MOVE_SEMANTICS 1265 nassertr(_stashed != (
Down *)NULL, 0);
1266 return _stashed->size();
1276 nassertr(_stashed != (
Down *)NULL, NULL);
1277 nassertr(n >= 0 && n < (
int)_stashed->size(), NULL);
1278 return (*_stashed)[n].get_child();
1290 nassertr(_stashed != (
Down *)NULL, -1);
1291 nassertr(n >= 0 && n < (
int)_stashed->size(), -1);
1292 return (*_stashed)[n].get_sort();
1300 INLINE PandaNode::Parents::
1309 INLINE PandaNode::Parents::
1310 Parents(
const PandaNode::CData *cdata) :
1311 _up(cdata->get_up())
1320 INLINE PandaNode::Parents::
1331 INLINE
void PandaNode::Parents::
1336 #ifdef USE_MOVE_SEMANTICS 1342 INLINE PandaNode::Parents::
1353 INLINE
void PandaNode::Parents::
1355 _up = move(from._up);
1357 #endif // USE_MOVE_SEMANTICS 1366 nassertr(_up != (
Up *)NULL, 0);
1377 nassertr(_up != (
Up *)NULL, NULL);
1378 nassertr(n >= 0 && n < (
int)_up->size(), NULL);
1379 return (*_up)[n].get_parent();
1387 INLINE PandaNodePipelineReader::
1388 PandaNodePipelineReader(
const PandaNode *node,
Thread *current_thread) :
1390 _current_thread(current_thread),
1394 nassertv(_node->test_ref_count_nonzero());
1397 #ifdef DO_PIPELINING 1402 #endif // DO_PIPELINING 1410 INLINE PandaNodePipelineReader::
1413 _current_thread(copy._current_thread),
1416 #ifdef DO_PIPELINING 1418 #endif // DO_PIPELINING 1432 INLINE
void PandaNodePipelineReader::
1434 nassertv(_current_thread == copy._current_thread);
1442 #ifdef DO_PIPELINING 1444 #endif // DO_PIPELINING 1447 _cdata = copy._cdata;
1449 #ifdef DO_PIPELINING 1451 #endif // DO_PIPELINING 1465 INLINE PandaNodePipelineReader::
1466 ~PandaNodePipelineReader() {
1473 #ifdef DO_PIPELINING 1475 #endif // DO_PIPELINING 1488 INLINE
const PandaNode *PandaNodePipelineReader::
1498 INLINE
Thread *PandaNodePipelineReader::
1499 get_current_thread()
const {
1500 return _current_thread;
1527 nassertv(_cdata != (PandaNode::CData *)NULL);
1528 running_draw_mask = (running_draw_mask & ~_cdata->_draw_control_mask) |
1529 (_cdata->_draw_show_mask & _cdata->_draw_control_mask);
1543 nassertr(_cdata != (PandaNode::CData *)NULL,
false);
1544 nassertr(_cdata->_last_update == _cdata->_next_update,
false);
1550 if (_cdata->_net_draw_show_mask.is_zero()) {
1554 DrawMask net_draw_control_mask, net_draw_show_mask;
1555 net_draw_control_mask = _cdata->_net_draw_control_mask;
1556 net_draw_show_mask = _cdata->_net_draw_show_mask;
1570 DrawMask compare_mask = (running_draw_mask & ~net_draw_control_mask) | (net_draw_show_mask & net_draw_control_mask);
1572 return !((compare_mask & PandaNode::_overall_bit).is_zero()) && !((compare_mask & camera_mask).is_zero());
1586 return _cdata->get_up()->size();
1600 nassertr(n >= 0 && n < (
int)up->size(), NULL);
1601 return (*up)[n].get_parent();
1612 return _node->do_find_parent(node, _cdata);
1625 return _cdata->get_down()->size();
1639 nassertr(n >= 0 && n < (
int)down->size(), NULL);
1640 return (*down)[n].get_child();
1653 nassertr(n >= 0 && n < (
int)down->size(), -1);
1654 return (*down)[n].get_sort();
1665 return _node->do_find_child(node, _cdata->get_down());
1677 return _cdata->get_stashed()->size();
1689 INLINE
PandaNode *PandaNodePipelineReader::
1690 get_stashed(
int n)
const {
1692 nassertr(n >= 0 && n < (
int)stashed->size(), NULL);
1693 return (*stashed)[n].get_child();
1706 nassertr(n >= 0 && n < (
int)stashed->size(), -1);
1707 return (*stashed)[n].get_sort();
1718 return _node->do_find_child(node, _cdata->
get_stashed());
1732 return _cdata->_state;
1743 return _cdata->_effects;
1756 return _cdata->_transform;
1768 return _cdata->_prev_transform;
1781 PandaNode::TagData::const_iterator ti;
1782 ti = _cdata->_tag_data.find(key);
1783 if (ti != _cdata->_tag_data.end()) {
1784 return (*ti).second;
1798 PandaNode::TagData::const_iterator ti;
1799 ti = _cdata->_tag_data.find(key);
1800 return (ti != _cdata->_tag_data.end());
1811 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_net_collide_mask);
1812 return _cdata->_net_collide_mask;
1823 get_off_clip_planes()
const {
1824 nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_off_clip_planes);
1825 return _cdata->_off_clip_planes;
1837 get_bounds()
const {
1838 nassertr(_cdata->_last_bounds_update == _cdata->_next_update, _cdata->_external_bounds);
1839 return _cdata->_external_bounds;
1855 INLINE
int PandaNodePipelineReader::
1856 get_nested_vertices()
const {
1857 nassertr(_cdata->_last_bounds_update == _cdata->_next_update, _cdata->_nested_vertices);
1858 return _cdata->_nested_vertices;
1869 INLINE
bool PandaNodePipelineReader::
1871 return _cdata->_final_bounds;
1885 INLINE
int PandaNodePipelineReader::
1886 get_fancy_bits()
const {
1887 return _cdata->_fancy_bits;
1908 get_children()
const {
1930 get_stashed()
const {
1942 get_parents()
const {
1951 INLINE PandaNode::BamReaderAuxDataDown::
1952 BamReaderAuxDataDown() :
1953 _down_list(PandaNode::get_class_type())
CollideMask get_into_collide_mask() const
Returns the "into" collide mask for this node.
int get_num_children() const
Returns the number of children of the node.
const CycleDataType * p() const
This allows the CycleDataReader to be passed to any function that expects a const CycleDataType point...
A basic node of the scene graph or data graph.
PandaNode * get_stashed(int n) const
Returns the nth stashed child of the node.
int get_num_parents() const
Returns the number of parents of the node.
bool debug_is_locked() const
Returns true if the current thread has locked the LightMutex, false otherwise.
const RenderEffects * get_effects() const
Returns the complete RenderEffects that will be applied to this node.
int get_num_stashed(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of stashed nodes this node has.
const TransformState * get_transform() const
Returns the transform that has been set on this particular node.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
int find_child(PandaNode *node) const
Returns the index of the indicated child node, if it is a child, or -1 if it is not.
int get_pipeline_stage() const
Returns the Pipeline stage number associated with this thread.
void set_effects(const RenderEffects *effects, Thread *current_thread=Thread::get_current_thread())
Sets the complete RenderEffects that will be applied this node.
int get_child_sort(int n) const
Returns the sort index of the nth child node of this node (that is, the number that was passed to add...
DrawMask get_draw_control_mask() const
Returns the set of bits in draw_show_mask that are considered meaningful.
void set_bounds(const BoundingVolume *volume)
Resets the bounding volume so that it is the indicated volume.
int get_num_children(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of child nodes this node has.
bool stash_child(PandaNode *child_node, Thread *current_thread=Thread::get_current_thread())
Stashes the indicated child node.
PandaNode * get_parent(int n) const
Returns the nth parent of the node.
bool unstash_child(PandaNode *child_node, Thread *current_thread=Thread::get_current_thread())
Returns the indicated stashed node to normal child status.
const RenderState * get_state() const
Returns the complete RenderState that will be applied to all nodes at this level and below...
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
A single page of data maintained by a PipelineCycler.
void compose_draw_mask(DrawMask &running_draw_mask) const
Computes the result of applying this node's draw masks to a running draw mask, as during a traversal...
PandaNode * get_child(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the nth child node of this node.
bool compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const
Compares the running draw mask computed during a traversal with this node's net draw masks...
const TransformState * get_prev_transform() const
Returns the transform that has been set as this node's "previous" position.
PandaNode * get_parent(int n) const
Returns the nth parent node of this node.
void adjust_draw_mask(DrawMask show_mask, DrawMask hide_mask, DrawMask clear_mask)
Adjusts the hide/show bits of this particular node.
static BitMask< PN_uint32, nbits > all_off()
Returns a BitMask whose bits are all off.
This is the base class for a number of special render effects that may be set on scene graph nodes to...
int get_stashed_sort(int n) const
Returns the sort index of the nth stashed node of this node (that is, the number that was passed to a...
Parents get_parents(Thread *current_thread=Thread::get_current_thread()) const
Returns an object that can be used to walk through the list of parents of the node, similar to get_children() and get_stashed().
bool is_overall_hidden() const
Returns true if the node has been hidden to all cameras by clearing its overall bit.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
bool operator<(const DownConnection &other) const
Provides a partial ordering on the children of a node so that they are ranked first in sort order...
PandaNode * get_stashed(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the nth stashed child of this node.
int find_parent(PandaNode *node) const
Returns the index of the indicated parent node, if it is a parent, or -1 if it is not...
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
DrawMask get_draw_show_mask() const
Returns the hide/show bits of this particular node.
int get_stashed_sort(int n) const
Returns the sort index of the nth child node of this node (that is, the number that was passed to add...
int find_stashed(PandaNode *node) const
Returns the index of the indicated stashed node, if it is a stashed child, or -1 if it is not...
bool is_final(Thread *current_thread=Thread::get_current_thread()) const
Returns the current state of the "final" flag.
void release()
Releases the lock on this object.
int get_child_sort(int n) const
Returns the sort index of the nth child node of this node (that is, the number that was passed to add...
string get_tag(const string &key) const
Retrieves the user-defined value that was previously set on this node for the particular key...
int get_slot(TypeHandle type_handle) const
Returns the slot number assigned to the indicated TypeHandle, or 0 if no slot number has been assigne...
int get_fancy_bits(Thread *current_thread=Thread::get_current_thread()) const
Returns the union of all of the enum FancyBits values corresponding to the various "fancy" attributes...
This class is used to associate each RenderAttrib with a different slot index at runtime, so we can store a list of RenderAttribs in the RenderState object, and very quickly look them up by type.
void clear_bounds()
Reverses the effect of a previous call to set_bounds(), and allows the node's bounding volume to be a...
void set_child(PandaNode *child)
This is only called by PandaNode::replace_child().
int find_parent(PandaNode *node, Thread *current_thread=Thread::get_current_thread()) const
Returns the index of the indicated parent node, if it is a parent, or -1 if it is not...
int find_child(PandaNode *node, Thread *current_thread=Thread::get_current_thread()) const
Returns the index of the indicated child node, if it is a child, or -1 if it is not.
void set_state(const RenderState *state, Thread *current_thread=Thread::get_current_thread())
Sets the complete RenderState that will be applied to all nodes at this level and below...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
int get_child_sort(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the sort index of the nth child node of this node (that is, the number that was passed to add...
void set_overall_hidden(bool overall_hidden)
Sets or clears the hidden flag.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
int get_num_parents(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of parent nodes this node has.
PandaNode * get_parent(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the nth parent node of this node.
This class is similar to CycleDataReader, except it allows reading from a particular stage of the pip...
int get_num_stashed() const
Returns the number of stashed children of the node.
int get_num_children() const
Returns the number of child nodes this node has.
const CycleDataType * read_unlocked(Thread *current_thread) const
See PipelineCyclerBase::read_unlocked().
Children get_children(Thread *current_thread=Thread::get_current_thread()) const
Returns an object that can be used to walk through the list of children of the node.
A thread; that is, a lightweight process.
int get_num_stashed() const
Returns the number of stashed nodes this node has.
int get_stashed_sort(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the sort index of the nth stashed node of this node (that is, the number that was passed to a...
Encapsulates the data from a PandaNode, pre-fetched for one stage of the pipeline.
PandaNode * get_child(int n) const
Returns the nth child node of this node.
PandaNode * get_child(int n) const
Returns the nth child of the node.
TypeHandle is the identifier used to differentiate C++ class types.
CollideMask get_net_collide_mask() const
Returns the union of all into_collide_mask() values set at CollisionNodes at this level and below...
bool has_tag(const string &key) const
Returns true if a value has been defined on this node for the particular key (even if that value is t...
int get_num_parents() const
Returns the number of parent nodes this node has.
int find_stashed(PandaNode *node, Thread *current_thread=Thread::get_current_thread()) const
Returns the index of the indicated stashed node, if it is a stashed child, or -1 if it is not...
static DrawMask get_all_camera_mask()
Returns a DrawMask that is appropriate for rendering to all cameras.
This represents a unique collection of RenderEffect objects that correspond to a particular renderabl...
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Sets the transform that will be applied to this node and below.
static RenderAttribRegistry * quick_get_global_ptr()
Returns the global_ptr without first ensuring it has been initialized.
void mark_bam_modified()
Increments the bam_modified counter, so that this object will be invalidated and retransmitted on any...