79 using std::ostringstream;
84 int NodePath::_max_search_depth = 7000;
87 PStatCollector NodePath::_get_transform_pcollector(
"*:NodePath:get_transform");
88 PStatCollector NodePath::_verify_complete_pcollector(
"*:NodePath:verify_complete");
99 nassertv(child_node !=
nullptr);
104 _head = PandaNode::get_top_component(child_node,
true,
105 pipeline_stage, current_thread);
108 _head = PandaNode::get_component(parent._head, child_node, pipeline_stage,
111 nassertv(_head !=
nullptr);
113 if (_head !=
nullptr) {
124 operator bool ()
const {
137 return _head->get_length(pipeline_stage, current_thread);
162 nassertr(comp !=
nullptr,
nullptr);
163 comp = comp->
get_next(pipeline_stage, current_thread);
169 nassertr(comp !=
nullptr,
nullptr);
191 comp = comp->
get_next(pipeline_stage, current_thread);
217 while (!comp->
is_top_node(pipeline_stage, current_thread)) {
218 comp = comp->
get_next(pipeline_stage, current_thread);
234 nassertr_always(!
is_empty(), result);
242 for (
int i = 0; i < num_children; i++) {
244 child._head = PandaNode::get_component(_head, cr.
get_child(i),
245 pipeline_stage, current_thread);
260 nassertr_always(!
is_empty(), result);
267 for (
int i = 0; i < num_stashed; i++) {
269 stashed._head = PandaNode::get_component(_head, bottom_node->
get_stashed(i),
270 pipeline_stage, current_thread);
291 PandaNode *parent = _head->get_next(pipeline_stage, current_thread)->get_node();
293 nassertr(parent !=
nullptr && child !=
nullptr, 0);
295 if (child_index != -1) {
300 if (child_index != -1) {
314 find(
const string &path)
const {
318 find_matches(col, path, 1);
340 find_matches(col, approx_path, 1);
358 find_matches(col, path, -1);
371 nassertr(
node !=
nullptr, col);
375 find_matches(col, approx_path, -1);
395 nassertv(other._error_type == ET_ok);
401 bool reparented = PandaNode::reparent(other._head, _head, sort,
false,
402 pipeline_stage, current_thread);
403 nassertv(reparented);
416 nassertv(other._error_type == ET_ok);
422 bool reparented = PandaNode::reparent(other._head, _head, sort,
true,
423 pipeline_stage, current_thread);
424 nassertv(reparented);
437 nassertv(other._error_type == ET_ok);
481 new_instance._head = PandaNode::attach(
nullptr,
node(), sort, pipeline_stage,
485 bool reparented = PandaNode::reparent(other._head, new_instance._head,
486 sort,
false, pipeline_stage,
501 nassertr(reparented, new_instance);
519 Thread *current_thread)
const {
539 nassertr(other._error_type == ET_ok,
fail());
543 PT(
PandaNode) copy_node = source_node->r_copy_subgraph(inst_map, current_thread);
544 nassertr(copy_node !=
nullptr,
fail());
546 copy_node->reset_prev_transform(current_thread);
552 const RenderState *state = source_node->get_state();
554 if (state->get_attrib(lattr)) {
561 if (light2.replace_copied_nodes(*
this, result, inst_map, current_thread)) {
562 new_lattr = DCAST(
LightAttrib, new_lattr->replace_off_light(light, light2));
570 if (light2.replace_copied_nodes(*
this, result, inst_map, current_thread)) {
571 new_lattr = DCAST(
LightAttrib, new_lattr->replace_on_light(light, light2));
575 if (new_lattr != lattr) {
576 result.
set_state(state->set_attrib(std::move(new_lattr)));
603 new_path._head = PandaNode::attach(_head,
node, sort, pipeline_stage,
625 nassertv(_error_type != ET_not_found);
633 PandaNode::detach(_head, pipeline_stage, current_thread);
636 if (
is_empty() || _head->has_key()) {
665 nassertv(_error_type != ET_not_found);
669 PandaNode::detach(_head, pipeline_stage, current_thread);
677 reverse_ls(ostream &out,
int indent_level)
const {
682 indent_level =
get_parent().reverse_ls(out, indent_level);
684 node()->write(out, indent_level);
685 return indent_level + 2;
693 output(ostream &out)
const {
694 switch (_error_type) {
696 out <<
"**not found**";
699 out <<
"**removed**";
708 if (_head ==
nullptr) {
722 nassertr_always(!
is_empty(), RenderState::make_empty());
723 return node()->get_state(current_thread);
732 nassertr(_error_type == ET_ok && other._error_type == ET_ok, RenderState::make_empty());
735 return get_net_state(current_thread);
738 return other.get_net_state(current_thread)->invert_compose(RenderState::make_empty());
741 #if defined(_DEBUG) || (defined(HAVE_THREADS) && defined(SIMPLE_THREADS))
743 nassertr(other.
verify_complete(current_thread), RenderState::make_empty());
746 int a_count, b_count;
747 if (find_common_ancestor(*
this, other, a_count, b_count, current_thread) ==
nullptr) {
748 if (allow_unrelated_wrt) {
750 << *
this <<
" is not related to " << other <<
"\n";
753 << *
this <<
" is not related to " << other <<
"\n";
754 nassert_raise(
"unrelated nodes");
755 return RenderState::make_empty();
759 CPT(
RenderState) a_state = r_get_partial_state(_head, a_count, current_thread);
760 CPT(
RenderState) b_state = r_get_partial_state(other._head, b_count, current_thread);
761 return b_state->invert_compose(a_state);
772 nassertv(_error_type == ET_ok && other._error_type == ET_ok);
783 CPT(
RenderState) new_state = rel_state->compose(state);
794 nassertr_always(!
is_empty(), TransformState::make_identity());
795 return node()->get_transform(current_thread);
804 nassertr(_error_type == ET_ok && other._error_type == ET_ok, TransformState::make_identity());
808 return get_net_transform(current_thread);
811 return other.get_net_transform(current_thread)->invert_compose(TransformState::make_identity());
814 #if defined(_DEBUG) || (defined(HAVE_THREADS) && defined(SIMPLE_THREADS))
815 nassertr(
verify_complete(current_thread), TransformState::make_identity());
816 nassertr(other.
verify_complete(current_thread), TransformState::make_identity());
819 int a_count, b_count;
820 if (find_common_ancestor(*
this, other, a_count, b_count, current_thread) ==
nullptr) {
821 if (allow_unrelated_wrt) {
822 if (pgraph_cat.is_debug()) {
824 << *
this <<
" is not related to " << other <<
"\n";
828 << *
this <<
" is not related to " << other <<
"\n";
829 nassert_raise(
"unrelated nodes");
830 return TransformState::make_identity();
836 a_transform = r_get_partial_transform(_head, a_count, current_thread);
837 if (a_transform !=
nullptr) {
838 b_transform = r_get_partial_transform(other._head, b_count, current_thread);
840 if (b_transform ==
nullptr) {
844 a_transform = r_get_net_transform(_head, current_thread);
845 b_transform = r_get_net_transform(other._head, current_thread);
848 return b_transform->invert_compose(a_transform);
859 nassertv(_error_type == ET_ok && other._error_type == ET_ok);
882 nassertr_always(!
is_empty(), TransformState::make_identity());
883 return node()->get_prev_transform(current_thread);
893 nassertr(_error_type == ET_ok && other._error_type == ET_ok, TransformState::make_identity());
896 return get_net_prev_transform(current_thread);
899 return other.get_net_prev_transform(current_thread)->invert_compose(TransformState::make_identity());
902 #if defined(_DEBUG) || (defined(HAVE_THREADS) && defined(SIMPLE_THREADS))
903 nassertr(
verify_complete(current_thread), TransformState::make_identity());
904 nassertr(other.
verify_complete(current_thread), TransformState::make_identity());
907 int a_count, b_count;
908 if (find_common_ancestor(*
this, other, a_count, b_count, current_thread) ==
nullptr) {
909 if (allow_unrelated_wrt) {
911 << *
this <<
" is not related to " << other <<
"\n";
914 << *
this <<
" is not related to " << other <<
"\n";
915 nassert_raise(
"unrelated nodes");
916 return TransformState::make_identity();
920 CPT(
TransformState) a_prev_transform = r_get_partial_prev_transform(_head, a_count, current_thread);
921 CPT(
TransformState) b_prev_transform = r_get_partial_prev_transform(other._head, b_count, current_thread);
922 return b_prev_transform->invert_compose(a_prev_transform);
933 nassertv(_error_type == ET_ok && other._error_type == ET_ok);
945 set_prev_transform(new_trans, current_thread);
956 set_pos(
const LVecBase3 &pos) {
963 set_x(PN_stdfloat x) {
971 set_y(PN_stdfloat y) {
979 set_z(PN_stdfloat z) {
998 set_fluid_x(PN_stdfloat x) {
1006 set_fluid_y(PN_stdfloat y) {
1014 set_fluid_z(PN_stdfloat z) {
1026 nassertr_always(!
is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
1041 nassertr_always(!
is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
1050 set_hpr(
const LVecBase3 &hpr) {
1053 nassertv(transform->
has_hpr());
1058 set_h(PN_stdfloat h) {
1061 nassertv(transform->
has_hpr());
1062 LVecBase3 hpr = transform->
get_hpr();
1068 set_p(PN_stdfloat p) {
1071 nassertv(transform->
has_hpr());
1072 LVecBase3 hpr = transform->
get_hpr();
1078 set_r(PN_stdfloat r) {
1081 nassertv(transform->
has_hpr());
1082 LVecBase3 hpr = transform->
get_hpr();
1092 nassertr_always(!
is_empty(), LVecBase3(0.0f, 0.0f, 0.0f));
1094 nassertr(transform->
has_hpr(), LVecBase3(0.0f, 0.0f, 0.0f));
1103 set_quat(
const LQuaternion &quat) {
1114 nassertr_always(!
is_empty(), LQuaternion::ident_quat());
1131 set_sx(PN_stdfloat sx) {
1134 LVecBase3 scale = transform->
get_scale();
1140 set_sy(PN_stdfloat sy) {
1143 LVecBase3 scale = transform->
get_scale();
1149 set_sz(PN_stdfloat sz) {
1152 LVecBase3 scale = transform->
get_scale();
1162 nassertr_always(!
is_empty(), LVecBase3(0.0f, 0.0f, 0.0f));
1179 set_shxy(PN_stdfloat shxy) {
1182 LVecBase3 shear = transform->
get_shear();
1188 set_shxz(PN_stdfloat shxz) {
1191 LVecBase3 shear = transform->
get_shear();
1197 set_shyz(PN_stdfloat shyz) {
1200 LVecBase3 shear = transform->
get_shear();
1210 nassertr_always(!
is_empty(), LVecBase3(0.0f, 0.0f, 0.0f));
1220 set_pos_hpr(
const LVecBase3 &pos,
const LVecBase3 &hpr) {
1223 transform = TransformState::make_pos_hpr_scale_shear
1234 set_pos_quat(
const LVecBase3 &pos,
const LQuaternion &quat) {
1237 transform = TransformState::make_pos_quat_scale_shear
1248 set_hpr_scale(
const LVecBase3 &hpr,
const LVecBase3 &scale) {
1251 transform = TransformState::make_pos_hpr_scale_shear
1261 set_quat_scale(
const LQuaternion &quat,
const LVecBase3 &scale) {
1264 transform = TransformState::make_pos_quat_scale_shear
1275 const LVecBase3 &scale) {
1288 const LVecBase3 &scale) {
1291 (pos, quat, scale));
1301 const LVecBase3 &scale,
const LVecBase3 &shear) {
1304 (pos, hpr, scale, shear));
1314 const LVecBase3 &scale,
const LVecBase3 &shear) {
1317 (pos, quat, scale, shear));
1325 set_mat(
const LMatrix4 &mat) {
1336 look_at(
const LPoint3 &point,
const LVector3 &up) {
1351 heads_up(
const LPoint3 &point,
const LVector3 &up) {
1366 set_pos(
const NodePath &other,
const LVecBase3 &pos) {
1371 if (orig_transform->has_components()) {
1376 const LVecBase3 &orig_hpr = orig_transform->get_hpr();
1377 const LVecBase3 &orig_scale = orig_transform->get_scale();
1378 const LVecBase3 &orig_shear = orig_transform->get_shear();
1391 set_x(
const NodePath &other, PN_stdfloat x) {
1395 set_pos(other, pos);
1399 set_y(
const NodePath &other, PN_stdfloat y) {
1403 set_pos(other, pos);
1407 set_z(
const NodePath &other, PN_stdfloat z) {
1411 set_pos(other, pos);
1424 if (orig_transform->has_components()) {
1429 const LVecBase3 &orig_hpr = orig_transform->get_hpr();
1430 const LVecBase3 &orig_scale = orig_transform->get_scale();
1431 const LVecBase3 &orig_shear = orig_transform->get_shear();
1446 set_fluid_x(
const NodePath &other, PN_stdfloat x) {
1454 set_fluid_y(
const NodePath &other, PN_stdfloat y) {
1462 set_fluid_z(
const NodePath &other, PN_stdfloat z) {
1475 nassertr_always(!
is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
1490 nassertr_always(!
is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
1501 nassertv(rel_transform->has_hpr());
1509 const LVecBase3 &orig_pos = transform->
get_pos();
1510 const LVecBase3 &orig_scale = transform->
get_scale();
1511 const LVecBase3 &orig_shear = transform->
get_shear();
1517 (orig_pos, transform->
get_hpr(), orig_scale, orig_shear));
1527 set_h(
const NodePath &other, PN_stdfloat h) {
1529 LVecBase3 hpr =
get_hpr(other);
1535 set_p(
const NodePath &other, PN_stdfloat p) {
1537 LVecBase3 hpr =
get_hpr(other);
1543 set_r(
const NodePath &other, PN_stdfloat r) {
1545 LVecBase3 hpr =
get_hpr(other);
1556 nassertr_always(!
is_empty(), LVecBase3(0.0f, 0.0f, 0.0f));
1558 nassertr(transform->
has_hpr(), LVecBase3(0.0f, 0.0f, 0.0f));
1576 const LVecBase3 &orig_pos = transform->
get_pos();
1577 const LVecBase3 &orig_scale = transform->
get_scale();
1578 const LVecBase3 &orig_shear = transform->
get_shear();
1584 (orig_pos, transform->
get_quat(), orig_scale, orig_shear));
1599 nassertr_always(!
is_empty(), LQuaternion::ident_quat());
1618 const LVecBase3 &orig_pos = transform->
get_pos();
1619 const LVecBase3 &orig_hpr = transform->
get_hpr();
1620 const LVecBase3 &orig_shear = transform->
get_shear();
1626 (orig_pos, orig_hpr, transform->
get_scale(), orig_shear));
1636 set_sx(
const NodePath &other, PN_stdfloat sx) {
1644 set_sy(
const NodePath &other, PN_stdfloat sy) {
1652 set_sz(
const NodePath &other, PN_stdfloat sz) {
1664 nassertr_always(!
is_empty(), LVecBase3(0.0f, 0.0f, 0.0f));
1683 const LVecBase3 &orig_pos = transform->
get_pos();
1684 const LVecBase3 &orig_hpr = transform->
get_hpr();
1685 const LVecBase3 &orig_scale = transform->
get_scale();
1691 (orig_pos, orig_hpr, orig_scale, transform->
get_shear()));
1701 set_shxy(
const NodePath &other, PN_stdfloat shxy) {
1709 set_shxz(
const NodePath &other, PN_stdfloat shxz) {
1717 set_shyz(
const NodePath &other, PN_stdfloat shyz) {
1729 nassertr_always(!
is_empty(), LVecBase3(0.0f, 0.0f, 0.0f));
1740 const LVecBase3 &hpr) {
1750 const LVecBase3 &orig_scale = transform->
get_scale();
1751 const LVecBase3 &orig_shear = transform->
get_shear();
1753 set_transform(other, TransformState::make_pos_hpr_scale_shear
1754 (pos, hpr, rel_transform->get_scale(), rel_transform->get_shear()));
1758 orig_scale, orig_shear);
1763 set_transform(other, TransformState::make_pos_hpr_scale_shear
1764 (pos, hpr, rel_transform->get_scale(), rel_transform->get_shear()));
1775 const LQuaternion &quat) {
1785 const LVecBase3 &orig_scale = transform->
get_scale();
1786 const LVecBase3 &orig_shear = transform->
get_shear();
1788 set_transform(other, TransformState::make_pos_quat_scale_shear
1789 (pos, quat, rel_transform->get_scale(), rel_transform->get_shear()));
1793 orig_scale, orig_shear);
1798 set_transform(other, TransformState::make_pos_quat_scale_shear
1799 (pos, quat, rel_transform->get_scale(), rel_transform->get_shear()));
1816 transform = TransformState::make_pos_hpr_scale_shear
1828 const LVecBase3 &scale) {
1834 transform = TransformState::make_pos_quat_scale_shear
1845 const LVecBase3 &pos,
const LVecBase3 &hpr,
1846 const LVecBase3 &scale) {
1859 const LVecBase3 &pos,
const LQuaternion &quat,
1860 const LVecBase3 &scale) {
1863 (pos, quat, scale));
1873 const LVecBase3 &pos,
const LVecBase3 &hpr,
1874 const LVecBase3 &scale,
const LVecBase3 &shear) {
1876 set_transform(other, TransformState::make_pos_hpr_scale_shear
1877 (pos, hpr, scale, shear));
1887 const LVecBase3 &pos,
const LQuaternion &quat,
1888 const LVecBase3 &scale,
const LVecBase3 &shear) {
1890 set_transform(other, TransformState::make_pos_quat_scale_shear
1891 (pos, quat, scale, shear));
1927 LPoint3 rel_point = LPoint3(point) * transform->
get_mat();
1938 LVector3 rel_vector = LVector3(vec) * transform->
get_mat();
1947 look_at(
const NodePath &other,
const LPoint3 &point,
const LVector3 &up) {
1951 LPoint3 rel_point = point * transform->
get_mat();
1965 heads_up(
const NodePath &other,
const LPoint3 &point,
const LVector3 &up) {
1969 LPoint3 rel_point = point * transform->
get_mat();
1985 set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a,
1987 set_color(LColor(r, g, b, a), priority);
1996 set_color(
const LColor &color,
int priority) {
2021 node()->clear_attrib(ColorAttrib::get_class_slot());
2030 nassertr_always(!
is_empty(),
false);
2031 return node()->has_attrib(ColorAttrib::get_class_slot());
2040 nassertr_always(!
is_empty(),
false);
2042 node()->get_attrib(ColorAttrib::get_class_slot());
2043 if (attrib !=
nullptr) {
2050 pgraph_cat.warning()
2051 <<
"get_color() called on " << *
this <<
" which has no color set.\n";
2053 return LColor(1.0f, 1.0f, 1.0f, 1.0f);
2063 nassertr_always(!
is_empty(),
false);
2064 return node()->has_attrib(ColorScaleAttrib::get_class_slot());
2075 node()->clear_attrib(ColorScaleAttrib::get_class_slot());
2087 node()->get_attrib(ColorScaleAttrib::get_class_slot());
2088 if (attrib !=
nullptr) {
2089 priority = max(priority,
2090 node()->
get_state()->get_override(ColorScaleAttrib::get_class_slot()));
2095 LVecBase4 prev_color_scale = csa->
get_scale();
2096 LVecBase4 new_color_scale(prev_color_scale[0]*scale[0],
2097 prev_color_scale[1]*scale[1],
2098 prev_color_scale[2]*scale[2],
2099 prev_color_scale[3]*scale[3]);
2117 node()->get_attrib(ColorScaleAttrib::get_class_slot());
2118 if (attrib !=
nullptr) {
2119 priority = max(priority,
2120 node()->
get_state()->get_override(ColorScaleAttrib::get_class_slot()));
2159 node()->get_attrib(ColorScaleAttrib::get_class_slot());
2160 if (attrib !=
nullptr) {
2161 priority = max(priority,
2162 node()->
get_state()->get_override(ColorScaleAttrib::get_class_slot()));
2167 node()->
set_attrib(csa->set_scale(LVecBase4(sc[0], sc[1], sc[2], scale)), priority);
2171 node()->
set_attrib(ColorScaleAttrib::make(LVecBase4(1.0f, 1.0f, 1.0f, scale)), priority);
2185 node()->get_attrib(ColorScaleAttrib::get_class_slot());
2186 if (attrib !=
nullptr) {
2187 priority = max(priority,
2188 node()->
get_state()->get_override(ColorScaleAttrib::get_class_slot()));
2193 node()->
set_attrib(csa->set_scale(LVecBase4(scale, scale, scale, sc[3])), priority);
2197 node()->
set_attrib(ColorScaleAttrib::make(LVecBase4(scale, scale, scale, 1.0f)), priority);
2208 static const LVecBase4 ident_scale(1.0f, 1.0f, 1.0f, 1.0f);
2209 nassertr_always(!
is_empty(), ident_scale);
2211 node()->get_attrib(ColorScaleAttrib::get_class_slot());
2212 if (attrib !=
nullptr) {
2231 if (light_obj !=
nullptr) {
2234 node()->get_attrib(LightAttrib::get_class_slot());
2235 if (attrib !=
nullptr) {
2236 priority = max(priority,
2237 node()->
get_state()->get_override(LightAttrib::get_class_slot()));
2250 }
else if (light.
node()->
is_of_type(PolylightNode::get_class_type())) {
2252 if (priority != 0) {
2255 pgraph_cat.warning()
2256 <<
"Ignoring priority on set_light(" << light <<
")\n";
2260 node()->get_effect(PolylightEffect::get_class_type());
2261 if (effect !=
nullptr) {
2275 nassert_raise(
"Not a Light object.");
2309 if (light_obj !=
nullptr) {
2311 node()->get_attrib(LightAttrib::get_class_slot());
2312 if (attrib !=
nullptr) {
2313 priority = max(priority,
2314 node()->
get_state()->get_override(LightAttrib::get_class_slot()));
2331 nassert_raise(
"Not a Light object.");
2341 node()->clear_attrib(LightAttrib::get_class_slot());
2355 if (light_obj !=
nullptr) {
2357 node()->get_attrib(LightAttrib::get_class_slot());
2358 if (attrib !=
nullptr) {
2360 la = DCAST(
LightAttrib, la->remove_on_light(light));
2361 la = DCAST(
LightAttrib, la->remove_off_light(light));
2363 if (la->is_identity()) {
2364 node()->clear_attrib(LightAttrib::get_class_slot());
2367 int priority =
node()->get_state()->get_override(LightAttrib::get_class_slot());
2373 }
else if (light.
node()->
is_of_type(PolylightNode::get_class_type())) {
2375 node()->get_effect(PolylightEffect::get_class_type());
2376 if (effect !=
nullptr) {
2384 nassert_raise(
"Not a Light object.");
2394 nassertr_always(!
is_empty(),
false);
2398 if (light_obj !=
nullptr) {
2400 node()->get_attrib(LightAttrib::get_class_slot());
2401 if (attrib !=
nullptr) {
2407 }
else if (light.
node()->
is_of_type(PolylightNode::get_class_type())) {
2409 node()->get_effect(PolylightEffect::get_class_type());
2410 if (effect !=
nullptr) {
2412 return ple->has_light(light);
2417 nassert_raise(
"Not a Light object.");
2428 nassertr_always(!
is_empty(),
false);
2431 node()->get_attrib(LightAttrib::get_class_slot());
2432 if (attrib !=
nullptr) {
2450 nassertr_always(!
is_empty(),
false);
2453 if (light_obj !=
nullptr) {
2455 node()->get_attrib(LightAttrib::get_class_slot());
2456 if (attrib !=
nullptr) {
2462 nassert_raise(
"Not a Light object.");
2478 node()->get_attrib(ClipPlaneAttrib::get_class_slot());
2479 if (attrib !=
nullptr) {
2480 priority = max(priority,
2481 node()->
get_state()->get_override(ClipPlaneAttrib::get_class_slot()));
2494 nassert_raise(
"Not a PlaneNode object.");
2526 node()->get_attrib(ClipPlaneAttrib::get_class_slot());
2527 if (attrib !=
nullptr) {
2528 priority = max(priority,
2529 node()->
get_state()->get_override(ClipPlaneAttrib::get_class_slot()));
2545 nassert_raise(
"Not a PlaneNode object.");
2555 node()->clear_attrib(ClipPlaneAttrib::get_class_slot());
2567 node()->get_attrib(ClipPlaneAttrib::get_class_slot());
2568 if (attrib !=
nullptr) {
2573 if (la->is_identity()) {
2574 node()->clear_attrib(ClipPlaneAttrib::get_class_slot());
2577 int priority =
node()->get_state()->get_override(ClipPlaneAttrib::get_class_slot());
2583 nassert_raise(
"Not a PlaneNode object.");
2593 nassertr_always(!
is_empty(),
false);
2597 node()->get_attrib(ClipPlaneAttrib::get_class_slot());
2598 if (attrib !=
nullptr) {
2604 nassert_raise(
"Not a PlaneNode object.");
2615 nassertr_always(!
is_empty(),
false);
2618 node()->get_attrib(ClipPlaneAttrib::get_class_slot());
2619 if (attrib !=
nullptr) {
2634 nassertr_always(!
is_empty(),
false);
2637 node()->get_attrib(ClipPlaneAttrib::get_class_slot());
2638 if (attrib !=
nullptr) {
2643 nassert_raise(
"Not a PlaneNode object.");
2659 node()->get_effect(OccluderEffect::get_class_type());
2660 if (effect !=
nullptr) {
2673 nassert_raise(
"Not an OccluderNode object.");
2695 node()->get_effect(OccluderEffect::get_class_type());
2696 if (effect !=
nullptr) {
2700 if (la->is_identity()) {
2709 nassert_raise(
"Not an OccluderNode object.");
2719 nassertr_always(!
is_empty(),
false);
2723 node()->get_effect(OccluderEffect::get_class_type());
2724 if (effect !=
nullptr) {
2730 nassert_raise(
"Not an OccluderNode object.");
2742 set_scissor(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top) {
2743 set_effect(ScissorEffect::make_screen(LVecBase4(left, right, bottom, top)));
2766 const LPoint3 &c,
const LPoint3 &d) {
2767 set_effect(ScissorEffect::make_node(a, b, c, d));
2778 set_effect(ScissorEffect::make_node(a, b, other));
2790 const LPoint3 &a,
const LPoint3 &b,
2791 const LPoint3 &c,
const LPoint3 &d) {
2792 set_effect(ScissorEffect::make_node(a, b, c, d, other));
2813 return has_effect(ScissorEffect::get_class_type());
2834 set_bin(
const string &bin_name,
int draw_order,
int priority) {
2836 node()->
set_attrib(CullBinAttrib::make(bin_name, draw_order), priority);
2846 node()->clear_attrib(CullBinAttrib::get_class_slot());
2855 nassertr_always(!
is_empty(),
false);
2856 return node()->has_attrib(CullBinAttrib::get_class_slot());
2866 nassertr_always(!
is_empty(),
string());
2868 node()->get_attrib(CullBinAttrib::get_class_slot());
2869 if (attrib !=
nullptr) {
2884 nassertr_always(!
is_empty(),
false);
2886 node()->get_attrib(CullBinAttrib::get_class_slot());
2887 if (attrib !=
nullptr) {
2922 node()->get_attrib(TextureAttrib::get_class_slot());
2923 if (attrib !=
nullptr) {
2925 int sg_priority =
node()->get_state()->get_override(TextureAttrib::get_class_slot());
2928 node()->
set_attrib(tsa->add_on_stage(stage, tex, priority), sg_priority);
2972 node()->get_attrib(TextureAttrib::get_class_slot());
2973 if (attrib !=
nullptr) {
2975 int sg_priority =
node()->get_state()->get_override(TextureAttrib::get_class_slot());
2978 node()->
set_attrib(tsa->add_on_stage(stage, tex, sampler, priority), sg_priority);
2983 node()->
set_attrib(tsa->add_on_stage(stage, tex, sampler, priority));
3010 node()->get_attrib(TextureAttrib::get_class_slot());
3011 if (attrib !=
nullptr) {
3013 int sg_priority =
node()->get_state()->get_override(TextureAttrib::get_class_slot());
3018 node()->
set_attrib(tsa->add_off_stage(stage, priority), sg_priority);
3037 node()->clear_attrib(TextureAttrib::get_class_slot());
3048 node()->get_attrib(TextureAttrib::get_class_slot());
3049 if (attrib !=
nullptr) {
3054 if (tsa->is_identity()) {
3055 node()->clear_attrib(TextureAttrib::get_class_slot());
3058 int priority =
node()->get_state()->get_override(TextureAttrib::get_class_slot());
3083 nassertr_always(!
is_empty(),
false);
3086 node()->get_attrib(TextureAttrib::get_class_slot());
3087 if (attrib !=
nullptr) {
3103 nassertr_always(!
is_empty(),
false);
3105 node()->get_attrib(TextureAttrib::get_class_slot());
3106 if (attrib !=
nullptr) {
3122 nassertr_always(!
is_empty(),
false);
3125 node()->get_attrib(TextureAttrib::get_class_slot());
3126 if (attrib !=
nullptr) {
3144 nassertr_always(!
is_empty(),
nullptr);
3146 node()->get_attrib(TextureAttrib::get_class_slot());
3147 if (attrib !=
nullptr) {
3161 nassertr_always(!
is_empty(),
nullptr);
3163 node()->get_attrib(TextureAttrib::get_class_slot());
3164 if (attrib !=
nullptr) {
3181 nassertv(tex !=
nullptr);
3182 nassertv(new_tex !=
nullptr);
3184 r_replace_texture(
node(), tex, new_tex);
3212 node()->get_attrib(TextureAttrib::get_class_slot());
3223 set_shader(
const Shader *sha,
int priority) {
3227 node()->get_attrib(ShaderAttrib::get_class_slot());
3228 if (attrib !=
nullptr) {
3229 priority = max(priority,
3230 node()->
get_state()->get_override(ShaderAttrib::get_class_slot()));
3244 set_shader_off(
int priority) {
3245 set_shader(
nullptr, priority);
3252 set_shader_auto(
int priority) {
3256 node()->get_attrib(ShaderAttrib::get_class_slot());
3257 if (attrib !=
nullptr) {
3258 priority = max(priority,
3259 node()->
get_state()->get_override(ShaderAttrib::get_class_slot()));
3273 set_shader_auto(
BitMask32 shader_switch,
int priority) {
3277 node()->get_attrib(ShaderAttrib::get_class_slot());
3278 if (attrib !=
nullptr) {
3279 priority = max(priority,
3280 node()->
get_state()->get_override(ShaderAttrib::get_class_slot()));
3282 node()->
set_attrib(sa->set_shader_auto(shader_switch, priority));
3286 node()->
set_attrib(sa->set_shader_auto(shader_switch, priority));
3297 node()->get_attrib(ShaderAttrib::get_class_slot());
3298 if (attrib !=
nullptr) {
3308 get_shader()
const {
3309 nassertr_always(!
is_empty(),
nullptr);
3311 node()->get_attrib(ShaderAttrib::get_class_slot());
3312 if (attrib !=
nullptr) {
3314 return sa->get_shader();
3328 pnode->get_attrib(ShaderAttrib::get_class_slot());
3329 if (attrib !=
nullptr) {
3331 pnode->
set_attrib(sa->set_shader_input(inp));
3335 pnode->
set_attrib(sa->set_shader_input(inp));
3348 pnode->get_attrib(ShaderAttrib::get_class_slot());
3349 if (attrib !=
nullptr) {
3351 pnode->
set_attrib(sa->set_shader_input(move(inp)));
3355 pnode->
set_attrib(sa->set_shader_input(move(inp)));
3367 node()->get_attrib(ShaderAttrib::get_class_slot());
3368 if (attrib !=
nullptr) {
3370 return sa->get_shader_input(
id);
3384 node()->get_attrib(ShaderAttrib::get_class_slot());
3386 if (attrib !=
nullptr) {
3402 node()->get_attrib(ShaderAttrib::get_class_slot());
3403 if (attrib !=
nullptr) {
3419 node()->get_attrib(ShaderAttrib::get_class_slot());
3420 if (attrib !=
nullptr) {
3439 node()->get_attrib(TexMatrixAttrib::get_class_slot());
3440 if (attrib !=
nullptr) {
3458 node()->clear_attrib(TexMatrixAttrib::get_class_slot());
3469 node()->get_attrib(TexMatrixAttrib::get_class_slot());
3470 if (attrib !=
nullptr) {
3474 if (tma->is_empty()) {
3475 node()->clear_attrib(TexMatrixAttrib::get_class_slot());
3489 nassertr_always(!
is_empty(),
false);
3492 node()->get_attrib(TexMatrixAttrib::get_class_slot());
3493 if (attrib !=
nullptr) {
3495 return tma->has_stage(stage);
3508 nassertr_always(!
is_empty(),
nullptr);
3511 node()->get_attrib(TexMatrixAttrib::get_class_slot());
3512 if (attrib !=
nullptr) {
3514 return tma->get_transform(stage);
3517 return TransformState::make_identity();
3526 nassertv(_error_type == ET_ok && other._error_type == ET_ok);
3531 state->get_attrib(TexMatrixAttrib::get_class_slot());
3532 if (attrib !=
nullptr) {
3536 state = state->add_attrib(tma->add_stage(stage, transform));
3540 state = state->add_attrib(TexMatrixAttrib::make(stage, transform));
3550 CPT(
RenderState) new_state = rel_state->compose(state);
3554 node()->
set_attrib(new_state->get_attrib(TexMatrixAttrib::get_class_slot()));
3563 nassertr(_error_type == ET_ok && other._error_type == ET_ok, TransformState::make_identity());
3567 state->get_attrib(TexMatrixAttrib::get_class_slot());
3568 if (attrib !=
nullptr) {
3570 return tma->get_transform(stage);
3573 return TransformState::make_identity();
3581 set_tex_gen(
TextureStage *stage, RenderAttrib::TexGenMode mode,
int priority) {
3585 node()->get_attrib(TexGenAttrib::get_class_slot());
3589 if (attrib !=
nullptr) {
3590 priority = max(priority,
3591 node()->
get_state()->get_override(TextureAttrib::get_class_slot()));
3607 set_tex_gen(
TextureStage *stage, RenderAttrib::TexGenMode mode,
3608 const LTexCoord3 &constant_value,
int priority) {
3612 node()->get_attrib(TexGenAttrib::get_class_slot());
3616 if (attrib !=
nullptr) {
3617 priority = max(priority,
3618 node()->
get_state()->get_override(TextureAttrib::get_class_slot()));
3625 node()->
set_attrib(tga->add_stage(stage, mode, constant_value), priority);
3635 node()->clear_attrib(TexGenAttrib::get_class_slot());
3647 node()->get_attrib(TexGenAttrib::get_class_slot());
3648 if (attrib !=
nullptr) {
3652 if (tga->is_empty()) {
3653 node()->clear_attrib(TexGenAttrib::get_class_slot());
3667 nassertr_always(!
is_empty(),
false);
3670 node()->get_attrib(TexGenAttrib::get_class_slot());
3671 if (attrib !=
nullptr) {
3673 return tga->has_stage(stage);
3685 nassertr_always(!
is_empty(), TexGenAttrib::M_off);
3688 node()->get_attrib(TexGenAttrib::get_class_slot());
3689 if (attrib !=
nullptr) {
3691 return tga->get_mode(stage);
3694 return TexGenAttrib::M_off;
3714 node()->get_effect(TexProjectorEffect::get_class_type());
3718 if (effect !=
nullptr) {
3736 node()->get_effect(TexProjectorEffect::get_class_type());
3737 if (effect !=
nullptr) {
3741 if (tpe->is_empty()) {
3765 nassertr_always(!
is_empty(),
false);
3768 node()->get_effect(TexProjectorEffect::get_class_type());
3769 if (effect !=
nullptr) {
3771 return tpe->has_stage(stage);
3787 node()->get_effect(TexProjectorEffect::get_class_type());
3788 if (effect !=
nullptr) {
3790 return tpe->get_from(stage);
3806 node()->get_effect(TexProjectorEffect::get_class_type());
3807 if (effect !=
nullptr) {
3809 return tpe->get_to(stage);
3824 set_tex_gen(stage, TexGenAttrib::M_world_position);
3838 nassertr_always(!
is_empty(),
false);
3839 return r_has_vertex_column(
node(), name);
3849 InternalNames vertex_columns;
3850 r_find_all_vertex_columns(
node(), vertex_columns);
3853 InternalNames::iterator ti;
3854 for (ti = vertex_columns.begin(); ti != vertex_columns.end(); ++ti) {
3868 InternalNames vertex_columns;
3869 r_find_all_vertex_columns(
node(), vertex_columns);
3874 InternalNames::iterator ti;
3875 for (ti = vertex_columns.begin(); ti != vertex_columns.end(); ++ti) {
3891 InternalNames vertex_columns;
3892 r_find_all_vertex_columns(
node(), vertex_columns);
3894 CPT(
InternalName) texcoord_name = InternalName::get_texcoord();
3897 InternalNames::iterator ti;
3898 for (ti = vertex_columns.begin(); ti != vertex_columns.end(); ++ti) {
3899 if ((*ti)->get_top() == texcoord_name) {
3914 InternalNames vertex_columns;
3915 r_find_all_vertex_columns(
node(), vertex_columns);
3921 InternalNames::iterator ti;
3922 for (ti = vertex_columns.begin(); ti != vertex_columns.end(); ++ti) {
3924 if (name->
get_top() == texcoord_name) {
3931 if (glob.
matches(net_basename)) {
3946 nassertr_always(!
is_empty(),
nullptr);
3948 return r_find_texture(
node(), get_net_state(), glob);
3958 nassertr_always(!
is_empty(),
nullptr);
3959 return r_find_texture(
node(), stage);
3969 r_find_all_textures(
node(), get_net_state(), textures);
3972 Textures::iterator ti;
3973 for (ti = textures.begin(); ti != textures.end(); ++ti) {
3987 r_find_all_textures(
node(), get_net_state(), textures);
3992 Textures::iterator ti;
3993 for (ti = textures.begin(); ti != textures.end(); ++ti) {
3995 if (glob.
matches(texture->get_name())) {
4010 r_find_all_textures(
node(), stage, textures);
4013 Textures::iterator ti;
4014 for (ti = textures.begin(); ti != textures.end(); ++ti) {
4028 nassertr_always(!
is_empty(),
nullptr);
4030 return r_find_texture_stage(
node(), get_net_state(), glob);
4040 TextureStages texture_stages;
4041 r_find_all_texture_stages(
node(), get_net_state(), texture_stages);
4044 TextureStages::iterator ti;
4045 for (ti = texture_stages.begin(); ti != texture_stages.end(); ++ti) {
4061 r_unify_texture_stages(
node(), stage);
4072 TextureStages texture_stages;
4073 r_find_all_texture_stages(
node(), get_net_state(), texture_stages);
4078 TextureStages::iterator ti;
4079 for (ti = texture_stages.begin(); ti != texture_stages.end(); ++ti) {
4095 nassertr_always(!
is_empty(),
nullptr);
4097 return r_find_material(
node(), get_net_state(), glob);
4106 Materials materials;
4107 r_find_all_materials(
node(), get_net_state(), materials);
4110 Materials::iterator ti;
4111 for (ti = materials.begin(); ti != materials.end(); ++ti) {
4124 Materials materials;
4125 r_find_all_materials(
node(), get_net_state(), materials);
4130 Materials::iterator ti;
4131 for (ti = materials.begin(); ti != materials.end(); ++ti) {
4133 if (glob.
matches(material->get_name())) {
4150 nassertv(mat !=
nullptr);
4173 node()->clear_attrib(MaterialAttrib::get_class_slot());
4182 nassertr_always(!
is_empty(),
false);
4184 node()->get_attrib(MaterialAttrib::get_class_slot());
4185 if (attrib !=
nullptr) {
4202 get_material()
const {
4203 nassertr_always(!
is_empty(),
nullptr);
4205 node()->get_attrib(MaterialAttrib::get_class_slot());
4206 if (attrib !=
nullptr) {
4221 nassertv(mat !=
nullptr);
4222 nassertv(new_mat !=
nullptr);
4224 CPT(
RenderAttrib) new_attrib = MaterialAttrib::make(new_mat);
4258 node()->clear_attrib(FogAttrib::get_class_slot());
4269 nassertr_always(!
is_empty(),
false);
4271 node()->get_attrib(FogAttrib::get_class_slot());
4272 if (attrib !=
nullptr) {
4288 nassertr_always(!
is_empty(),
false);
4290 node()->get_attrib(FogAttrib::get_class_slot());
4291 if (attrib !=
nullptr) {
4307 nassertr_always(!
is_empty(),
nullptr);
4309 node()->get_attrib(FogAttrib::get_class_slot());
4310 if (attrib !=
nullptr) {
4326 node()->get_state()->get_attrib_def(rma);
4338 node()->get_state()->get_attrib_def(rma);
4351 node()->get_state()->get_attrib_def(rma);
4369 node()->get_state()->get_attrib_def(rma);
4385 node()->get_state()->get_attrib_def(rma);
4394 set_render_mode(RenderModeAttrib::Mode mode, PN_stdfloat thickness,
int priority) {
4397 node()->
set_attrib(RenderModeAttrib::make(mode, thickness), priority);
4407 node()->clear_attrib(RenderModeAttrib::get_class_slot());
4417 nassertr_always(!
is_empty(),
false);
4418 return node()->has_attrib(RenderModeAttrib::get_class_slot());
4427 nassertr_always(!
is_empty(), RenderModeAttrib::M_unchanged);
4429 node()->get_attrib(RenderModeAttrib::get_class_slot());
4430 if (attrib !=
nullptr) {
4435 return RenderModeAttrib::M_unchanged;
4444 nassertr_always(!
is_empty(), 0.0f);
4446 node()->get_attrib(RenderModeAttrib::get_class_slot());
4447 if (attrib !=
nullptr) {
4461 nassertr_always(!
is_empty(), 0.0f);
4463 node()->get_attrib(RenderModeAttrib::get_class_slot());
4464 if (attrib !=
nullptr) {
4481 CullFaceAttrib::Mode mode =
4483 CullFaceAttrib::M_cull_none :
4484 CullFaceAttrib::M_cull_clockwise;
4499 node()->clear_attrib(CullFaceAttrib::get_class_slot());
4509 nassertr_always(!
is_empty(),
false);
4510 return node()->has_attrib(CullFaceAttrib::get_class_slot());
4522 nassertr_always(!
is_empty(),
false);
4524 node()->get_attrib(CullFaceAttrib::get_class_slot());
4525 if (attrib !=
nullptr) {
4542 DepthTestAttrib::PandaCompareFunc mode =
4544 DepthTestAttrib::M_less :
4545 DepthTestAttrib::M_none;
4557 node()->clear_attrib(DepthTestAttrib::get_class_slot());
4567 nassertr_always(!
is_empty(),
false);
4568 return node()->has_attrib(DepthTestAttrib::get_class_slot());
4579 nassertr_always(!
is_empty(),
false);
4581 node()->get_attrib(DepthTestAttrib::get_class_slot());
4582 if (attrib !=
nullptr) {
4584 return (dta->
get_mode() != DepthTestAttrib::M_none);
4599 DepthWriteAttrib::Mode mode =
4601 DepthWriteAttrib::M_on :
4602 DepthWriteAttrib::M_off;
4614 node()->clear_attrib(DepthWriteAttrib::get_class_slot());
4624 nassertr_always(!
is_empty(),
false);
4625 return node()->has_attrib(DepthWriteAttrib::get_class_slot());
4636 nassertr_always(!
is_empty(),
false);
4638 node()->get_attrib(DepthWriteAttrib::get_class_slot());
4639 if (attrib !=
nullptr) {
4641 return (dta->
get_mode() != DepthWriteAttrib::M_off);
4670 node()->clear_attrib(DepthOffsetAttrib::get_class_slot());
4680 nassertr_always(!
is_empty(),
false);
4681 return node()->has_attrib(DepthOffsetAttrib::get_class_slot());
4692 node()->get_attrib(DepthOffsetAttrib::get_class_slot());
4693 if (attrib !=
nullptr) {
4711 const LMatrix4 &rel_mat = transform->
get_mat();
4713 LVector3 up = LVector3::up();
4714 LVector3 rel_pos = -rel_mat.get_row3(3);
4722 if (offset != 0.0f) {
4723 LVector3 translate = rel_mat.get_row3(3);
4724 translate.normalize();
4725 translate *= offset;
4741 const LMatrix4 &rel_mat = transform->
get_mat();
4743 LVector3 up = LVector3::up() * rel_mat;
4744 LVector3 rel_pos = LVector3::forward() * rel_mat;
4752 if (offset != 0.0f) {
4753 LVector3 translate = rel_mat.get_row3(3);
4754 translate.normalize();
4755 translate *= offset;
4770 const LMatrix4 &rel_mat = transform->
get_mat();
4772 LVector3 up = LVector3::up();
4773 LVector3 rel_pos = -rel_mat.get_row3(3);
4781 if (offset != 0.0f) {
4782 LVector3 translate = rel_mat.get_row3(3);
4783 translate.normalize();
4784 translate *= offset;
4798 (LVector3::up(),
false,
true,
4799 offset, camera, LPoint3(0.0f, 0.0f, 0.0f));
4812 (LVector3::up(),
true,
false,
4813 offset, camera, LPoint3(0.0f, 0.0f, 0.0f), fixed_depth);
4826 (LVector3::up(),
false,
false,
4827 offset, camera, LPoint3(0.0f, 0.0f, 0.0f));
4845 nassertr_always(!
is_empty(),
false);
4846 return node()->has_effect(BillboardEffect::get_class_type());
4874 nassertr_always(!
is_empty(),
false);
4875 return node()->has_effect(CompassEffect::get_class_type());
4899 node()->clear_attrib(TransparencyAttrib::get_class_slot());
4910 nassertr_always(!
is_empty(),
false);
4911 return node()->has_attrib(TransparencyAttrib::get_class_slot());
4924 nassertr_always(!
is_empty(), TransparencyAttrib::M_none);
4926 node()->get_attrib(TransparencyAttrib::get_class_slot());
4927 if (attrib !=
nullptr) {
4932 return TransparencyAttrib::M_none;
4941 set_logic_op(LogicOpAttrib::Operation op,
int priority) {
4955 node()->clear_attrib(LogicOpAttrib::get_class_slot());
4966 nassertr_always(!
is_empty(),
false);
4967 return node()->has_attrib(LogicOpAttrib::get_class_slot());
4980 nassertr_always(!
is_empty(), LogicOpAttrib::O_none);
4982 node()->get_attrib(LogicOpAttrib::get_class_slot());
4983 if (attrib !=
nullptr) {
4988 return LogicOpAttrib::O_none;
5009 node()->clear_attrib(AntialiasAttrib::get_class_slot());
5019 nassertr_always(!
is_empty(),
false);
5020 return node()->has_attrib(AntialiasAttrib::get_class_slot());
5029 nassertr_always(!
is_empty(), AntialiasAttrib::M_none);
5031 node()->get_attrib(AntialiasAttrib::get_class_slot());
5032 if (attrib !=
nullptr) {
5037 return AntialiasAttrib::M_none;
5047 nassertr_always(!
is_empty(),
false);
5048 return node()->has_attrib(AudioVolumeAttrib::get_class_slot());
5059 node()->clear_attrib(AudioVolumeAttrib::get_class_slot());
5070 node()->get_attrib(AudioVolumeAttrib::get_class_slot());
5071 if (attrib !=
nullptr) {
5072 priority = max(priority,
5073 node()->
get_state()->get_override(AudioVolumeAttrib::get_class_slot()));
5108 node()->get_attrib(AudioVolumeAttrib::get_class_slot());
5109 if (attrib !=
nullptr) {
5124 const RenderAttrib *attrib = net_state->get_attrib(AudioVolumeAttrib::get_class_slot());
5125 if (attrib !=
nullptr) {
5127 if (ava !=
nullptr) {
5147 comp = comp->
get_next(pipeline_stage, current_thread)) {
5152 result._head = comp;
5176 bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage, current_thread),
5177 _head, sort,
true, pipeline_stage,
5179 nassertv(reparented);
5193 bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage, current_thread),
5194 _head, sort,
false, pipeline_stage,
5196 nassertv(reparented);
5205 stashed_descendents.
unstash();
5217 if (comp !=
nullptr) {
5221 while (next !=
nullptr) {
5227 result._head = comp;
5232 next = next->
get_next(pipeline_stage, current_thread);
5245 return (other == *
this);
5253 return (other != *
this);
5264 return other.compare_to(*
this) > 0;
5279 return -other.compare_to(*
this);
5300 #endif // HAVE_THREADS
5302 PStatTimer timer(_verify_complete_pcollector);
5305 nassertr(comp !=
nullptr,
false);
5310 nassertr(
node !=
nullptr,
false);
5311 int length = comp->
get_length(pipeline_stage, current_thread);
5313 comp = comp->
get_next(pipeline_stage, current_thread);
5315 while (comp !=
nullptr) {
5317 nassertr(next_node !=
nullptr,
false);
5320 pgraph_cat.warning()
5321 << *
this <<
" is incomplete; " << *
node <<
" is not a child of "
5322 << *next_node <<
"\n";
5326 if (comp->
get_length(pipeline_stage, current_thread) != length) {
5327 pgraph_cat.warning()
5328 << *
this <<
" is incomplete; length at " << *next_node
5329 <<
" indicates " << comp->
get_length(pipeline_stage, current_thread)
5330 <<
" while length at " << *
node <<
" indicates " << length <<
"\n";
5335 comp = comp->
get_next(pipeline_stage, current_thread);
5355 CPT(
RenderState) state = RenderState::make_empty();
5378 node()->prepare_scene(gsg, get_net_state());
5420 get_bounds(
Thread *current_thread)
const {
5437 force_recompute_bounds() {
5439 r_force_recompute_bounds(
node());
5448 get_bounds()->write(out);
5469 min_point.set(0.0f, 0.0f, 0.0f);
5470 max_point.set(0.0f, 0.0f, 0.0f);
5471 nassertr_always(!
is_empty(),
false);
5478 bool found_any =
false;
5479 node()->calc_tight_bounds(min_point, max_point, found_any,
5480 move(transform), current_thread);
5569 if (flatten_geoms) {
5597 if (flatten_geoms) {
5599 gr.
collect_vertex_data(
node(), ~(SceneGraphReducer::CVD_format | SceneGraphReducer::CVD_name | SceneGraphReducer::CVD_animation_type));
5624 gr.
apply_attribs(
node(), SceneGraphReducer::TT_apply_texture_color | SceneGraphReducer::TT_tex_matrix | SceneGraphReducer::TT_other);
5650 nassertr_always(!
is_empty(),
false);
5654 bool okflag =
false;
5674 nassertr_always(!
is_empty(),
false);
5678 bool okflag =
false;
5717 ostringstream stream;
5721 bool used_local_writer =
false;
5722 if (writer ==
nullptr) {
5728 writer = &local_writer;
5729 used_local_writer =
true;
5735 if (used_local_writer && num_nodes > 1) {
5758 for (
int i = 0; i < num_nodes; ++i) {
5760 nassertr(
node !=
nullptr,
false);
5783 if (reader ==
nullptr) {
5787 if (!buffer.
read_header(head, _bam_header.size())) {
5791 if (head != _bam_header) {
5795 reader = &local_reader;
5807 ErrorType error_type = (ErrorType)dgi.
get_uint8();
5809 if (num_nodes == 0) {
5811 result._error_type = error_type;
5815 for (
int i = 0; i < num_nodes; ++i) {
5818 if (
object ==
nullptr ||
5819 !object->
is_of_type(PandaNode::get_class_type())) {
5848 Thread *current_thread) {
5856 while (comp !=
nullptr && comp != source._head) {
5859 comp = comp->
get_next(pipeline_stage, current_thread);
5862 if (comp ==
nullptr) {
5870 for (it = nodes.rbegin(); it != nodes.rend(); ++it) {
5871 PandaNode::InstanceMap::const_iterator iit = inst_map.find(*it);
5872 nassertr_always(iit != inst_map.end(),
false);
5873 new_comp = PandaNode::get_component(new_comp, iit->second, pipeline_stage, current_thread);
5876 nassertr(new_comp !=
nullptr,
false);
5877 _head = std::move(new_comp);
5891 int &a_count,
int &b_count,
Thread *current_thread) {
5901 while (ac->
get_length(pipeline_stage, current_thread) > bc->
get_length(pipeline_stage, current_thread)) {
5902 nassertr(ac !=
nullptr,
nullptr);
5903 ac = ac->
get_next(pipeline_stage, current_thread);
5906 while (bc->
get_length(pipeline_stage, current_thread) > ac->
get_length(pipeline_stage, current_thread)) {
5907 nassertr(bc !=
nullptr,
nullptr);
5908 bc = bc->
get_next(pipeline_stage, current_thread);
5915 nassertr(ac !=
nullptr,
nullptr);
5916 nassertr(bc !=
nullptr,
nullptr);
5917 ac = ac->
get_next(pipeline_stage, current_thread);
5919 bc = bc->
get_next(pipeline_stage, current_thread);
5932 if (comp ==
nullptr) {
5933 return RenderState::make_empty();
5937 return r_get_net_state(comp->
get_next(pipeline_stage, current_thread), current_thread)->compose(state);
5948 Thread *current_thread)
const {
5949 if (n == 0 || comp ==
nullptr) {
5950 return RenderState::make_empty();
5954 return r_get_partial_state(comp->
get_next(pipeline_stage, current_thread), n - 1, current_thread)->compose(state);
5964 if (comp ==
nullptr) {
5965 return TransformState::make_identity();
5969 CPT(
TransformState) net_transform = r_get_net_transform(comp->
get_next(pipeline_stage, current_thread), current_thread);
5972 if (!node_cdata->_effects->has_adjust_transform()) {
5973 if (node_cdata->_transform->is_identity()) {
5974 return net_transform;
5976 return net_transform->compose(node_cdata->_transform);
5980 node_cdata->_effects->adjust_transform(net_transform, transform,
node);
5981 return net_transform->compose(transform);
5996 Thread *current_thread)
const {
5997 if (n == 0 || comp ==
nullptr) {
5998 return TransformState::make_identity();
6002 if (node_cdata->_effects->has_adjust_transform()) {
6006 CPT(
TransformState) partial = r_get_partial_transform(comp->
get_next(pipeline_stage, current_thread), n - 1, current_thread);
6007 if (partial ==
nullptr) {
6010 if (node_cdata->_transform->is_identity()) {
6013 return partial->compose(node_cdata->_transform);
6024 if (comp ==
nullptr) {
6025 return TransformState::make_identity();
6029 return r_get_net_prev_transform(comp->
get_next(pipeline_stage, current_thread), current_thread)->compose(transform);
6040 if (n == 0 || comp ==
nullptr) {
6041 return TransformState::make_identity();
6045 return r_get_partial_prev_transform(comp->
get_next(pipeline_stage, current_thread), n - 1, current_thread)->compose(transform);
6056 int max_matches)
const {
6058 pgraph_cat.warning()
6059 <<
"Attempt to extend an empty NodePath by '" << path
6065 find_matches(result, approx_path, max_matches);
6076 int max_matches)
const {
6078 pgraph_cat.warning()
6079 <<
"Attempt to extend an empty NodePath by: " << approx_path <<
".\n";
6086 nassertv(level->_node_path.
is_valid());
6088 find_matches(result, level, max_matches);
6097 int max_matches)
const {
6099 int num_levels_remaining = _max_search_depth;
6103 while (num_levels_remaining > 0 && level !=
nullptr) {
6104 if (pgraph_cat.is_spam()) {
6106 <<
"find_matches pass: " << result <<
", "
6107 << max_matches <<
", " << num_levels_remaining <<
"\n";
6111 num_levels_remaining--;
6118 while (entry !=
nullptr) {
6119 if (entry->
consider_node(result, next_level, max_matches, 0)) {
6123 while (entry !=
nullptr) {
6128 while (next_level !=
nullptr) {
6133 while (deleted_entries !=
nullptr) {
6135 delete deleted_entries;
6136 deleted_entries = next;
6146 entry->_next = deleted_entries;
6147 deleted_entries = entry;
6154 while (entry !=
nullptr) {
6156 entry->_next = deleted_entries;
6157 deleted_entries = entry;
6166 while (deleted_entries !=
nullptr) {
6168 delete deleted_entries;
6169 deleted_entries = next;
6183 DCAST_INTO_R(mnode,
node, count);
6190 for (
int i = 0; i < num_children; i++) {
6191 count += r_clear_model_nodes(cr.
get_child(i));
6202 r_adjust_all_priorities(
PandaNode *node,
int adjustment) {
6206 DCAST_INTO_V(gnode,
node);
6209 for (
int i = 0; i < num_geoms; i++) {
6216 for (
int i = 0; i < num_children; i++) {
6217 r_adjust_all_priorities(cr.
get_child(i), adjustment);
6225 r_force_recompute_bounds(
PandaNode *node) {
6228 DCAST_INTO_V(gnode,
node);
6231 for (
int i = 0; i < num_geoms; i++) {
6232 const Geom *geom = gnode->get_geom(i);
6233 geom->mark_bounds_stale();
6237 node->mark_bounds_stale();
6242 for (
int i = 0; i < num_children; i++) {
6243 r_force_recompute_bounds(cr.
get_child(i));
6257 into_collide_mask = (into_collide_mask & and_mask) | or_mask;
6263 for (
int i = 0; i < num_children; i++) {
6264 r_set_collide_mask(cr.
get_child(i), and_mask, or_mask, node_type);
6275 DCAST_INTO_R(gnode,
node,
false);
6278 for (
int i = 0; i < num_geoms; i++) {
6279 const Geom *geom = gnode->get_geom(i);
6281 if (vdata->has_column(name)) {
6290 for (
int i = 0; i < num_children; i++) {
6292 if (r_has_vertex_column(child, name)) {
6304 r_find_all_vertex_columns(
PandaNode *node,
6305 NodePath::InternalNames &vertex_columns)
const {
6308 DCAST_INTO_V(gnode,
node);
6311 for (
int i = 0; i < num_geoms; ++i) {
6312 const Geom *geom = gnode->get_geom(i);
6315 for (
int j = 0; j < num_arrays; ++j) {
6318 for (
int k = 0; k < num_columns; ++k) {
6320 vertex_columns.insert(column->
get_name());
6329 for (
int i = 0; i < num_children; i++) {
6331 r_find_all_vertex_columns(child, vertex_columns);
6343 DCAST_INTO_R(gnode,
node,
nullptr);
6346 for (
int i = 0; i < num_geoms; i++) {
6352 geom_state->get_attrib(TextureAttrib::get_class_slot());
6353 if (attrib !=
nullptr) {
6357 if (texture !=
nullptr) {
6358 if (glob.
matches(texture->get_name())) {
6370 for (
int i = 0; i < num_children; i++) {
6372 CPT(
RenderState) next_state = state->compose(child->get_state());
6374 Texture *result = r_find_texture(child, next_state, glob);
6375 if (result !=
nullptr) {
6388 NodePath::Textures &textures)
const {
6391 DCAST_INTO_V(gnode,
node);
6394 for (
int i = 0; i < num_geoms; i++) {
6400 geom_state->get_attrib(TextureAttrib::get_class_slot());
6401 if (attrib !=
nullptr) {
6405 if (texture !=
nullptr) {
6406 textures.insert(texture);
6416 for (
int i = 0; i < num_children; i++) {
6418 CPT(
RenderState) next_state = state->compose(child->get_state());
6419 r_find_all_textures(child, next_state, textures);
6430 node->get_attrib(TextureAttrib::get_class_slot());
6431 if (attrib !=
nullptr) {
6440 DCAST_INTO_R(gnode,
node,
nullptr);
6443 for (
int i = 0; i < num_geoms; i++) {
6448 geom_state->get_attrib(TextureAttrib::get_class_slot());
6449 if (attrib !=
nullptr) {
6461 for (
int i = 0; i < num_children; i++) {
6464 Texture *result = r_find_texture(child, stage);
6465 if (result !=
nullptr) {
6478 NodePath::Textures &textures)
const {
6481 node->get_attrib(TextureAttrib::get_class_slot());
6482 if (attrib !=
nullptr) {
6491 DCAST_INTO_V(gnode,
node);
6494 for (
int i = 0; i < num_geoms; i++) {
6499 geom_state->get_attrib(TextureAttrib::get_class_slot());
6500 if (attrib !=
nullptr) {
6512 for (
int i = 0; i < num_children; i++) {
6514 r_find_all_textures(child, stage, textures);
6528 if (node_state->get_attrib(ta)) {
6529 CPT(
RenderAttrib) new_ta = ta->replace_texture(tex, new_tex);
6539 DCAST_INTO_V(gnode,
node);
6542 for (
int i = 0; i < num_geoms; i++) {
6547 if (geom_state->get_attrib(ta)) {
6548 CPT(
RenderAttrib) new_ta = ta->replace_texture(tex, new_tex);
6559 for (
size_t i = 0; i < num_children; ++i) {
6561 r_replace_texture(child, tex, new_tex);
6573 DCAST_INTO_R(gnode,
node,
nullptr);
6576 for (
int i = 0; i < num_geoms; i++) {
6582 geom_state->get_attrib(TextureAttrib::get_class_slot());
6583 if (attrib !=
nullptr) {
6587 if (texture_stage !=
nullptr) {
6589 return texture_stage;
6600 for (
int i = 0; i < num_children; i++) {
6602 CPT(
RenderState) next_state = state->compose(child->get_state());
6604 TextureStage *result = r_find_texture_stage(child, next_state, glob);
6605 if (result !=
nullptr) {
6618 NodePath::TextureStages &texture_stages)
const {
6621 DCAST_INTO_V(gnode,
node);
6624 for (
int i = 0; i < num_geoms; i++) {
6630 geom_state->get_attrib(TextureAttrib::get_class_slot());
6631 if (attrib !=
nullptr) {
6635 if (texture_stage !=
nullptr) {
6636 texture_stages.insert(texture_stage);
6646 for (
int i = 0; i < num_children; i++) {
6648 CPT(
RenderState) next_state = state->compose(child->get_state());
6649 r_find_all_texture_stages(child, next_state, texture_stages);
6660 node->get_attrib(TextureAttrib::get_class_slot());
6661 if (attrib !=
nullptr) {
6663 CPT(
RenderAttrib) new_attrib = ta->unify_texture_stages(stage);
6664 if (new_attrib != ta) {
6671 DCAST_INTO_V(gnode,
node);
6674 for (
int i = 0; i < num_geoms; i++) {
6679 state->get_attrib(TextureAttrib::get_class_slot());
6680 if (attrib !=
nullptr) {
6682 CPT(
RenderAttrib) new_attrib = ta->unify_texture_stages(stage);
6683 if (new_attrib != ta) {
6684 CPT(
RenderState) new_state = state->add_attrib(new_attrib);
6694 for (
int i = 0; i < num_children; i++) {
6696 r_unify_texture_stages(child, stage);
6708 DCAST_INTO_R(gnode,
node,
nullptr);
6711 for (
int i = 0; i < num_geoms; i++) {
6717 geom_state->get_attrib(MaterialAttrib::get_class_slot());
6718 if (attrib !=
nullptr) {
6722 if (material !=
nullptr) {
6723 if (glob.
matches(material->get_name())) {
6735 for (
int i = 0; i < num_children; i++) {
6737 CPT(
RenderState) next_state = state->compose(child->get_state());
6739 Material *result = r_find_material(child, next_state, glob);
6740 if (result !=
nullptr) {
6753 NodePath::Materials &materials)
const {
6756 DCAST_INTO_V(gnode,
node);
6759 for (
int i = 0; i < num_geoms; i++) {
6765 geom_state->get_attrib(MaterialAttrib::get_class_slot());
6766 if (attrib !=
nullptr) {
6770 if (material !=
nullptr) {
6771 materials.insert(material);
6781 for (
int i = 0; i < num_children; i++) {
6783 CPT(
RenderState) next_state = state->compose(child->get_state());
6784 r_find_all_materials(child, next_state, materials);
6798 if (node_state->get_attrib(ma)) {
6808 DCAST_INTO_V(gnode,
node);
6811 for (
int i = 0; i < num_geoms; i++) {
6816 if (geom_state->get_attrib(ma)) {
6828 for (
size_t i = 0; i < num_children; ++i) {
6830 r_replace_material(child, mat, new_attrib);
6848 if (root ==
nullptr || root ==
node()) {
6860 while (comp !=
nullptr) {
6862 path.push_back(
node);
6868 comp = comp->
get_next(pipeline_stage, current_thread);
6871 if (comp ==
nullptr) {
6879 for (
int i = path.size() - 1; i >= 0; --i) {
6893 if (
node.is_null()) {
6906 nassertd(!comp.is_null()) {
6907 while (p_list[pi++]) {}
6912 while (p_list[pi] !=
nullptr) {
6920 PandaNode::Paths::const_iterator it;
6921 for (it =
node->_paths.begin(); it !=
node->_paths.end(); ++it) {
6922 if ((*it)->get_next(pipeline_stage, current_thread) == comp) {
6929 if (it ==
node->_paths.end()) {
6935 node->_paths.insert(comp);