43 PStatCollector CollisionTraverser::_collisions_pcollector(
"App:Collisions");
45 PStatCollector CollisionTraverser::_cnode_volume_pcollector(
"Collision Volumes:CollisionNode");
46 PStatCollector CollisionTraverser::_gnode_volume_pcollector(
"Collision Volumes:GeomNode");
47 PStatCollector CollisionTraverser::_geom_volume_pcollector(
"Collision Volumes:Geom");
52 class SortByColliderSort {
59 inline bool operator () (
int a,
int b)
const {
60 const CollisionTraverser::OrderedColliderDef &ocd_a = _trav._ordered_colliders[a];
61 const CollisionTraverser::OrderedColliderDef &ocd_b = _trav._ordered_colliders[b];
62 return ((
const CollisionNode *)ocd_a._node_path.node())->get_collider_sort() < ((
const CollisionNode *)ocd_b._node_path.node())->get_collider_sort();
72 CollisionTraverser(
const std::string &name) :
74 _this_pcollector(_collisions_pcollector, name)
76 _respect_prev_transform = respect_prev_transform;
77 #ifdef DO_COLLISION_RECORDING 86 ~CollisionTraverser() {
87 #ifdef DO_COLLISION_RECORDING 103 nassertv(_ordered_colliders.size() == _colliders.size());
105 nassertv(handler !=
nullptr);
107 Colliders::iterator ci = _colliders.find(collider);
108 if (ci != _colliders.end()) {
110 if ((*ci).second != handler) {
113 (*ci).second = handler;
116 Handlers::iterator hi = _handlers.find(old_handler);
117 nassertv(hi != _handlers.end());
119 nassertv((*hi).second >= 0);
120 if ((*hi).second == 0) {
124 hi = _handlers.find(handler);
125 if (hi == _handlers.end()) {
126 _handlers.insert(Handlers::value_type(handler, 1));
134 _colliders.insert(Colliders::value_type(collider, handler));
135 OrderedColliderDef ocdef;
136 ocdef._node_path = collider;
137 ocdef._in_graph =
true;
138 _ordered_colliders.push_back(ocdef);
140 Handlers::iterator hi = _handlers.find(handler);
141 if (hi == _handlers.end()) {
142 _handlers.insert(Handlers::value_type(handler, 1));
148 nassertv(_ordered_colliders.size() == _colliders.size());
159 nassertr(_ordered_colliders.size() == _colliders.size(),
false);
161 Colliders::iterator ci = _colliders.find(collider);
162 if (ci == _colliders.end()) {
170 Handlers::iterator hi = _handlers.find(handler);
171 nassertr(hi != _handlers.end(),
false);
173 nassertr((*hi).second >= 0,
false);
174 if ((*hi).second == 0) {
178 _colliders.erase(ci);
180 OrderedColliders::iterator oci;
181 oci = _ordered_colliders.begin();
182 while (oci != _ordered_colliders.end() &&
183 (*oci)._node_path != collider) {
187 nassertr(oci != _ordered_colliders.end(),
false);
188 _ordered_colliders.erase(oci);
190 nassertr(_ordered_colliders.size() == _colliders.size(),
false);
200 Colliders::const_iterator ci = _colliders.find(collider);
201 return (ci != _colliders.end());
208 int CollisionTraverser::
209 get_num_colliders()
const {
210 nassertr(_ordered_colliders.size() == _colliders.size(), 0);
211 return _ordered_colliders.size();
220 nassertr(_ordered_colliders.size() == _colliders.size(),
NodePath());
221 nassertr(n >= 0 && n < (
int)_ordered_colliders.size(),
NodePath());
222 return _ordered_colliders[n]._node_path;
232 Colliders::const_iterator ci = _colliders.find(collider);
233 if (ci != _colliders.end()) {
246 _ordered_colliders.clear();
253 void CollisionTraverser::
257 #ifdef DO_COLLISION_RECORDING 258 if (has_recorder()) {
259 get_recorder()->begin_traversal();
261 #endif // DO_COLLISION_RECORDING 263 Handlers::iterator hi;
264 for (hi = _handlers.begin(); hi != _handlers.end(); ++hi) {
265 if ((*hi).first->wants_all_potential_collidees()) {
266 (*hi).first->set_root(root);
268 (*hi).first->begin_group();
271 bool traversal_done =
false;
273 !allow_collider_multiple) {
276 LevelStatesSingle level_states;
277 prepare_colliders_single(level_states, root);
279 if (level_states.size() == 1 || !allow_collider_multiple) {
280 traversal_done =
true;
284 for (
size_t pass = 0; pass < level_states.size(); ++pass) {
286 PStatTimer pass_timer(get_pass_collector(pass));
288 r_traverse_single(level_states[pass], pass);
293 if (!traversal_done &&
296 LevelStatesDouble level_states;
297 prepare_colliders_double(level_states, root);
299 if (level_states.size() == 1) {
300 traversal_done =
true;
302 for (
size_t pass = 0; pass < level_states.size(); ++pass) {
304 PStatTimer pass_timer(get_pass_collector(pass));
306 r_traverse_double(level_states[pass], pass);
311 if (!traversal_done) {
313 LevelStatesQuad level_states;
314 prepare_colliders_quad(level_states, root);
316 traversal_done =
true;
318 for (
size_t pass = 0; pass < level_states.size(); ++pass) {
320 PStatTimer pass_timer(get_pass_collector(pass));
322 r_traverse_quad(level_states[pass], pass);
326 hi = _handlers.begin();
327 while (hi != _handlers.end()) {
328 if (!(*hi).first->end_group()) {
330 hi = remove_handler(hi);
336 #ifdef DO_COLLISION_RECORDING 337 if (has_recorder()) {
338 get_recorder()->end_traversal();
340 #endif // DO_COLLISION_RECORDING 342 CollisionLevelStateBase::_node_volume_pcollector.flush_level();
343 _cnode_volume_pcollector.flush_level();
344 _gnode_volume_pcollector.flush_level();
345 _geom_volume_pcollector.flush_level();
354 #ifdef DO_COLLISION_RECORDING 371 void CollisionTraverser::
372 set_recorder(CollisionRecorder *recorder) {
373 if (recorder != _recorder) {
375 if (_recorder !=
nullptr) {
376 nassertv(_recorder->_trav ==
this);
377 _recorder->_trav =
nullptr;
380 _recorder = recorder;
383 if (_recorder !=
nullptr) {
384 nassertv(_recorder->_trav !=
this);
385 if (_recorder->_trav !=
nullptr) {
386 _recorder->_trav->clear_recorder();
388 nassertv(_recorder->_trav ==
nullptr);
389 _recorder->_trav =
this;
400 CollisionVisualizer *CollisionTraverser::
401 show_collisions(
const NodePath &root) {
403 CollisionVisualizer *viz =
new CollisionVisualizer(
"show_collisions");
412 void CollisionTraverser::
414 if (!_collision_visualizer_np.is_empty()) {
415 _collision_visualizer_np.remove_node();
420 #endif // DO_COLLISION_RECORDING 425 void CollisionTraverser::
426 output(std::ostream &out)
const {
427 out <<
"CollisionTraverser, " << _colliders.size()
428 <<
" colliders and " << _handlers.size() <<
" handlers.\n";
434 void CollisionTraverser::
435 write(std::ostream &out,
int indent_level)
const {
437 <<
"CollisionTraverser, " << _colliders.size()
438 <<
" colliders and " << _handlers.size() <<
" handlers:\n";
440 OrderedColliders::const_iterator oci;
441 for (oci = _ordered_colliders.begin();
442 oci != _ordered_colliders.end();
444 NodePath cnode_path = (*oci)._node_path;
445 bool in_graph = (*oci)._in_graph;
447 Colliders::const_iterator ci;
448 ci = _colliders.find(cnode_path);
449 nassertv(ci != _colliders.end());
452 nassertv(handler !=
nullptr);
454 indent(out, indent_level + 2)
457 out <<
" handled by " << handler->get_type() <<
"\n";
465 int num_solids = cnode->get_num_solids();
466 for (
int i = 0; i < num_solids; ++i) {
467 cnode->get_solid(i)->write(out, indent_level + 4);
480 void CollisionTraverser::
483 int num_colliders = _colliders.size();
491 level_state.reserve(min(num_colliders, max_colliders));
495 int *indirect = (
int *)alloca(
sizeof(
int) * num_colliders);
497 for (i = 0; i < num_colliders; ++i) {
500 std::sort(indirect, indirect + num_colliders, SortByColliderSort(*
this));
502 int num_remaining_colliders = num_colliders;
503 for (i = 0; i < num_colliders; ++i) {
504 OrderedColliderDef &ocd = _ordered_colliders[indirect[i]];
505 NodePath cnode_path = ocd._node_path;
511 <<
"Collider " << cnode_path
512 <<
" is not in scene graph. Ignoring.\n";
513 ocd._in_graph =
false;
517 ocd._in_graph =
true;
522 def._node_path = cnode_path;
524 int num_solids = cnode->get_num_solids();
525 for (
int s = 0; s < num_solids; ++s) {
527 def._collider = collider;
528 level_state.prepare_collider(def, root);
530 if (level_state.get_num_colliders() == max_colliders) {
532 level_states.push_back(level_state);
534 level_state.reserve(min(num_remaining_colliders, max_colliders));
539 --num_remaining_colliders;
540 nassertv(num_remaining_colliders >= 0);
543 if (level_state.get_num_colliders() != 0) {
544 level_states.push_back(level_state);
546 nassertv(num_remaining_colliders == 0);
552 void CollisionTraverser::
564 DCAST_INTO_V(cnode, node);
567 if (node_bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
568 DCAST_INTO_V(node_gbv, node_bv);
572 entry._into_node = cnode;
574 if (_respect_prev_transform) {
575 entry._flags |= CollisionEntry::F_respect_prev_transform;
578 int num_colliders = level_state.get_num_colliders();
579 for (
int c = 0; c < num_colliders; ++c) {
581 entry._from_node = level_state.get_collider_node(c);
583 if ((entry._from_node->get_from_collide_mask() &
588 entry._from_node_path = level_state.get_collider_node_path(c);
589 entry._from = level_state.get_collider(c);
591 compare_collider_to_node(
602 if (collide_cat.is_spam()) {
604 <<
"Reached " << *node <<
"\n";
609 DCAST_INTO_V(gnode, node);
612 if (node_bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
613 DCAST_INTO_V(node_gbv, node_bv);
617 entry._into_node = gnode;
619 if (_respect_prev_transform) {
620 entry._flags |= CollisionEntry::F_respect_prev_transform;
623 int num_colliders = level_state.get_num_colliders();
624 for (
int c = 0; c < num_colliders; ++c) {
626 entry._from_node = level_state.get_collider_node(c);
628 if ((entry._from_node->get_from_collide_mask() &
633 entry._from_node_path = level_state.get_collider_node_path(c);
634 entry._from = level_state.get_collider(c);
636 compare_collider_to_geom_node(
650 if (index >= 0 && index < node->get_num_children()) {
652 r_traverse_single(next_state, pass);
661 int index = DCAST(
LODNode, node)->get_lowest_switch();
664 for (
int i = 0; i < num_children; ++i) {
668 ~
GeomNode::get_default_collide_mask());
670 r_traverse_single(next_state, pass);
677 for (
int i = 0; i < num_children; ++i) {
679 r_traverse_single(next_state, pass);
691 void CollisionTraverser::
694 int num_colliders = _colliders.size();
702 level_state.
reserve(min(num_colliders, max_colliders));
706 int *indirect = (
int *)alloca(
sizeof(
int) * num_colliders);
708 for (i = 0; i < num_colliders; ++i) {
711 std::sort(indirect, indirect + num_colliders, SortByColliderSort(*
this));
713 int num_remaining_colliders = num_colliders;
714 for (i = 0; i < num_colliders; ++i) {
715 OrderedColliderDef &ocd = _ordered_colliders[indirect[i]];
716 NodePath cnode_path = ocd._node_path;
722 <<
"Collider " << cnode_path
723 <<
" is not in scene graph. Ignoring.\n";
724 ocd._in_graph =
false;
728 ocd._in_graph =
true;
733 def._node_path = cnode_path;
735 int num_solids = cnode->get_num_solids();
736 for (
int s = 0; s < num_solids; ++s) {
738 def._collider = collider;
741 if (level_state.get_num_colliders() == max_colliders) {
743 level_states.push_back(level_state);
745 level_state.
reserve(min(num_remaining_colliders, max_colliders));
750 --num_remaining_colliders;
751 nassertv(num_remaining_colliders >= 0);
754 if (level_state.get_num_colliders() != 0) {
755 level_states.push_back(level_state);
757 nassertv(num_remaining_colliders == 0);
763 void CollisionTraverser::
775 DCAST_INTO_V(cnode, node);
778 if (node_bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
779 DCAST_INTO_V(node_gbv, node_bv);
783 entry._into_node = cnode;
785 if (_respect_prev_transform) {
786 entry._flags |= CollisionEntry::F_respect_prev_transform;
789 int num_colliders = level_state.get_num_colliders();
790 for (
int c = 0; c < num_colliders; ++c) {
792 entry._from_node = level_state.get_collider_node(c);
794 if ((entry._from_node->get_from_collide_mask() &
799 entry._from_node_path = level_state.get_collider_node_path(c);
800 entry._from = level_state.get_collider(c);
802 compare_collider_to_node(
813 if (collide_cat.is_spam()) {
815 <<
"Reached " << *node <<
"\n";
820 DCAST_INTO_V(gnode, node);
823 if (node_bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
824 DCAST_INTO_V(node_gbv, node_bv);
828 entry._into_node = gnode;
830 if (_respect_prev_transform) {
831 entry._flags |= CollisionEntry::F_respect_prev_transform;
834 int num_colliders = level_state.get_num_colliders();
835 for (
int c = 0; c < num_colliders; ++c) {
837 entry._from_node = level_state.get_collider_node(c);
839 if ((entry._from_node->get_from_collide_mask() &
844 entry._from_node_path = level_state.get_collider_node_path(c);
845 entry._from = level_state.get_collider(c);
847 compare_collider_to_geom_node(
861 if (index >= 0 && index < node->get_num_children()) {
863 r_traverse_double(next_state, pass);
872 int index = DCAST(
LODNode, node)->get_lowest_switch();
875 for (
int i = 0; i < num_children; ++i) {
879 ~
GeomNode::get_default_collide_mask());
881 r_traverse_double(next_state, pass);
888 for (
int i = 0; i < num_children; ++i) {
890 r_traverse_double(next_state, pass);
902 void CollisionTraverser::
905 int num_colliders = _colliders.size();
913 level_state.
reserve(min(num_colliders, max_colliders));
917 int *indirect = (
int *)alloca(
sizeof(
int) * num_colliders);
919 for (i = 0; i < num_colliders; ++i) {
922 std::sort(indirect, indirect + num_colliders, SortByColliderSort(*
this));
924 int num_remaining_colliders = num_colliders;
925 for (i = 0; i < num_colliders; ++i) {
926 OrderedColliderDef &ocd = _ordered_colliders[indirect[i]];
927 NodePath cnode_path = ocd._node_path;
933 <<
"Collider " << cnode_path
934 <<
" is not in scene graph. Ignoring.\n";
935 ocd._in_graph =
false;
939 ocd._in_graph =
true;
944 def._node_path = cnode_path;
946 int num_solids = cnode->get_num_solids();
947 for (
int s = 0; s < num_solids; ++s) {
949 def._collider = collider;
952 if (level_state.get_num_colliders() == max_colliders) {
954 level_states.push_back(level_state);
956 level_state.
reserve(min(num_remaining_colliders, max_colliders));
961 --num_remaining_colliders;
962 nassertv(num_remaining_colliders >= 0);
965 if (level_state.get_num_colliders() != 0) {
966 level_states.push_back(level_state);
968 nassertv(num_remaining_colliders == 0);
974 void CollisionTraverser::
986 DCAST_INTO_V(cnode, node);
989 if (node_bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
990 DCAST_INTO_V(node_gbv, node_bv);
994 entry._into_node = cnode;
996 if (_respect_prev_transform) {
997 entry._flags |= CollisionEntry::F_respect_prev_transform;
1000 int num_colliders = level_state.get_num_colliders();
1001 for (
int c = 0; c < num_colliders; ++c) {
1003 entry._from_node = level_state.get_collider_node(c);
1005 if ((entry._from_node->get_from_collide_mask() &
1010 entry._from_node_path = level_state.get_collider_node_path(c);
1011 entry._from = level_state.get_collider(c);
1013 compare_collider_to_node(
1024 if (collide_cat.is_spam()) {
1026 <<
"Reached " << *node <<
"\n";
1031 DCAST_INTO_V(gnode, node);
1034 if (node_bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
1035 DCAST_INTO_V(node_gbv, node_bv);
1039 entry._into_node = gnode;
1041 if (_respect_prev_transform) {
1042 entry._flags |= CollisionEntry::F_respect_prev_transform;
1045 int num_colliders = level_state.get_num_colliders();
1046 for (
int c = 0; c < num_colliders; ++c) {
1048 entry._from_node = level_state.get_collider_node(c);
1050 if ((entry._from_node->get_from_collide_mask() &
1055 entry._from_node_path = level_state.get_collider_node_path(c);
1056 entry._from = level_state.get_collider(c);
1058 compare_collider_to_geom_node(
1072 if (index >= 0 && index < node->get_num_children()) {
1074 r_traverse_quad(next_state, pass);
1083 int index = DCAST(
LODNode, node)->get_lowest_switch();
1086 for (
int i = 0; i < num_children; ++i) {
1090 ~
GeomNode::get_default_collide_mask());
1092 r_traverse_quad(next_state, pass);
1099 for (
int i = 0; i < num_children; ++i) {
1101 r_traverse_quad(next_state, pass);
1109 void CollisionTraverser::
1114 bool within_node_bounds =
true;
1115 if (from_parent_gbv !=
nullptr &&
1116 into_node_gbv !=
nullptr) {
1117 within_node_bounds = (into_node_gbv->
contains(from_parent_gbv) != 0);
1118 _cnode_volume_pcollector.add_level(1);
1121 if (within_node_bounds) {
1125 DCAST_INTO_V(cnode, entry._into_node);
1127 int num_solids = cnode->get_num_solids();
1128 if (collide_cat.is_spam()) {
1130 <<
"Colliding against CollisionNode " << entry._into_node
1131 <<
" which has " << num_solids <<
" collision solids.\n";
1138 if (num_solids == 1) {
1139 entry._into = cnode->_solids[0].get_read_pointer(current_thread);
1140 Colliders::const_iterator ci;
1142 nassertv(ci != _colliders.end());
1143 entry.test_intersection((*ci).second,
this);
1145 CollisionNode::Solids::const_iterator si;
1146 for (si = cnode->_solids.begin(); si != cnode->_solids.end(); ++si) {
1147 entry._into = (*si).get_read_pointer(current_thread);
1155 if (solid_bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
1159 compare_collider_to_solid(entry, from_node_gbv, solid_gbv);
1168 void CollisionTraverser::
1173 bool within_node_bounds =
true;
1174 if (from_parent_gbv !=
nullptr &&
1175 into_node_gbv !=
nullptr) {
1176 within_node_bounds = (into_node_gbv->
contains(from_parent_gbv) != 0);
1177 _gnode_volume_pcollector.add_level(1);
1180 if (within_node_bounds) {
1182 DCAST_INTO_V(gnode, entry._into_node);
1184 for (
int s = 0; s < num_geoms; ++s) {
1185 entry._into =
nullptr;
1186 const Geom *geom = DCAST(
Geom, gnode->get_geom(s));
1187 if (geom !=
nullptr) {
1190 if (num_geoms > 1 &&
1191 geom_bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
1197 DCAST_INTO_V(geom_gbv, geom_bv);
1200 compare_collider_to_geom(entry, geom, from_node_gbv, geom_gbv);
1209 void CollisionTraverser::
1213 bool within_solid_bounds =
true;
1214 if (from_node_gbv !=
nullptr &&
1215 solid_gbv !=
nullptr) {
1216 within_solid_bounds = (solid_gbv->
contains(from_node_gbv) != 0);
1221 if (collide_cat.is_spam()) {
1222 collide_cat.spam(
false)
1223 <<
"Comparing to solid: " << *from_node_gbv
1224 <<
" to " << *solid_gbv <<
", within_solid_bounds = " 1225 << within_solid_bounds <<
"\n";
1229 if (within_solid_bounds) {
1230 Colliders::const_iterator ci;
1232 nassertv(ci != _colliders.end());
1233 entry.test_intersection((*ci).second,
this);
1240 void CollisionTraverser::
1244 bool within_geom_bounds =
true;
1245 if (from_node_gbv !=
nullptr &&
1246 geom_gbv !=
nullptr) {
1247 within_geom_bounds = (geom_gbv->
contains(from_node_gbv) != 0);
1248 _geom_volume_pcollector.add_level(1);
1250 if (within_geom_bounds) {
1251 Colliders::const_iterator ci;
1253 nassertv(ci != _colliders.end());
1257 CPT(
GeomVertexData) data = geom->get_animated_vertex_data(
true, current_thread);
1260 int num_primitives = geom->get_num_primitives();
1261 for (
int i = 0; i < num_primitives; ++i) {
1264 nassertv(tris->is_of_type(GeomTriangles::get_class_type()));
1266 if (tris->is_indexed()) {
1269 while (!index.is_at_end()) {
1273 v[0] = vertex.get_data3();
1274 vertex.set_row_unsafe(index.get_data1i());
1275 v[1] = vertex.get_data3();
1276 vertex.set_row_unsafe(index.get_data1i());
1277 v[2] = vertex.get_data3();
1282 bool within_solid_bounds =
true;
1283 if (from_node_gbv !=
nullptr) {
1285 sphere->
around(v, v + 3);
1286 within_solid_bounds = (sphere->contains(from_node_gbv) != 0);
1288 CollisionGeom::_volume_pcollector.add_level(1);
1291 if (within_solid_bounds) {
1293 entry._into = cgeom;
1294 entry.test_intersection((*ci).second,
this);
1302 for (
int i = 0; i < num_vertices; i += 3) {
1305 v[0] = vertex.get_data3();
1306 v[1] = vertex.get_data3();
1307 v[2] = vertex.get_data3();
1312 bool within_solid_bounds =
true;
1313 if (from_node_gbv !=
nullptr) {
1315 sphere->
around(v, v + 3);
1316 within_solid_bounds = (sphere->contains(from_node_gbv) != 0);
1318 CollisionGeom::_volume_pcollector.add_level(1);
1321 if (within_solid_bounds) {
1323 entry._into = cgeom;
1324 entry.test_intersection((*ci).second,
this);
1343 CollisionTraverser::Handlers::iterator CollisionTraverser::
1344 remove_handler(CollisionTraverser::Handlers::iterator hi) {
1345 nassertr(hi != _handlers.end(), hi);
1348 Handlers::iterator hnext = hi;
1350 _handlers.erase(hi);
1354 Colliders::iterator ci;
1355 ci = _colliders.begin();
1356 while (ci != _colliders.end()) {
1357 if ((*ci).second == handler) {
1361 Colliders::iterator cnext = ci;
1363 _colliders.erase(ci);
1367 OrderedColliders::iterator oci;
1368 oci = _ordered_colliders.begin();
1369 while (oci != _ordered_colliders.end() &&
1370 (*oci)._node_path != node_path) {
1373 nassertr(oci != _ordered_colliders.end(), hi);
1374 _ordered_colliders.erase(oci);
1376 nassertr(_ordered_colliders.size() == _colliders.size(), hi);
1391 get_pass_collector(
int pass) {
1392 nassertr(pass >= 0, _this_pcollector);
1393 while ((
int)_pass_collectors.size() <= pass) {
1394 std::ostringstream name;
1395 name <<
"pass" << (_pass_collectors.size() + 1);
1397 _pass_collectors.push_back(col);
1399 _solid_collide_collectors.push_back(sc_col);
1402 return _pass_collectors[pass];
virtual int get_visible_child() const
Returns the index number of the currently visible child of this node.
A basic node of the scene graph or data graph.
get_from_node_path
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
The abstract interface to a number of classes that decide what to do when a collision is detected.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int contains(const GeometricBoundingVolume *vol) const
Returns the appropriate set of IntersectionFlags to indicate the amount of intersection with the indi...
NodePath get_node_path() const
Returns the NodePath representing the node instance we have traversed to.
bool is_empty() const
Returns true if the NodePath contains no nodes.
PandaNode * get_child(size_t n) const
Returns the nth child of the node.
This is the state information the CollisionTraverser retains for each level during traversal.
The abstract base class for all things that can collide with other things in the world,...
This defines a bounding sphere, consisting of a center and a radius.
bool has_collider(int n) const
Returns true if the nth collider in the LevelState is still part of the level.
void set_include_mask(CollideMask include_mask)
Specifies the mask that is applied to the into CollideMask of nodes in the scene graph before testing...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_num_vertices
Returns the number of indices used by all the primitives in this object.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_collider(const NodePath &collider, CollisionHandler *handler)
Adds a new CollisionNode, representing an object that will be tested for collisions into other object...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_first_vertex() const
Returns the first vertex number referenced by the primitive.
void clear_colliders()
Completely empties the set of collision nodes and their associated handlers.
This is our own Panda specialization on the default STL vector.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
A lightweight class that represents a single element that may be timed and/or counted via stats.
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
get_current_thread
Returns a pointer to the currently-executing Thread object.
A base class for all things which can have a name.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static bool verify_points(const LPoint3 &a, const LPoint3 &b, const LPoint3 &c)
Verifies that the indicated set of points will define a valid CollisionPolygon: that is,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool any_in_bounds()
Checks the bounding volume of the current node against each of our colliders.
NodePath attach_new_node(PandaNode *node, int sort=0, Thread *current_thread=Thread::get_current_thread()) const
Attaches a new node, with or without existing parents, to the scene graph below the referenced node o...
size_t get_num_children() const
Returns the number of children of the node.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
virtual bool is_collision_node() const
A simple downcast check.
Defines a single collision event.
const GeometricBoundingVolume * get_local_bound(int n) const
Returns the bounding volume of the indicated collider, transformed into the current node's transform ...
get_into_collide_mask
Returns the current "into" CollideMask.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
void prepare_collider(const ColliderDef &def, const NodePath &root)
Adds the indicated Collider to the set of Colliders in the current level state.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_children
Returns an object that can be used to walk through the list of children of the node.
A special CollisionPolygon created just for the purpose of detecting collision against geometry.
const GeometricBoundingVolume * get_parent_bound(int n) const
Returns the bounding volume of the indicated collider, transformed into the previous node's transform...
void reserve(int num_colliders)
Indicates an intention to add the indicated number of colliders to the level state.
get_collider
Returns the nth CollisionNode that has been added to the traverser via add_collider().
virtual bool is_lod_node() const
A simple downcast check.
bool has_collider(const NodePath &collider) const
Returns true if the indicated node is current in the set of nodes that will be tested each frame for ...
static void flush_level()
Flushes the PStatCollectors used during traversal.
bool is_same_graph(const NodePath &other, Thread *current_thread=Thread::get_current_thread()) const
Returns true if the node represented by this NodePath is parented within the same graph as that of th...
get_primitive_type
Returns the fundamental primitive type that is common to all GeomPrimitives added within the Geom.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CollisionHandler * get_handler(const NodePath &collider) const
Returns the handler that is currently assigned to serve the indicated collision node,...
PandaNode * node() const
Returns the referenced node of the path.
get_into
Returns the CollisionSolid pointer for the particular solid was collided into.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_num_geoms
Returns the number of geoms in the node.
static void flush_level()
Flushes the PStatCollectors used during traversal.
A thread; that is, a lightweight process.
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
static void flush_level()
Flushes the PStatCollectors used during traversal.
A node in the scene graph that can hold any number of CollisionSolids.
virtual bool has_single_child_visibility() const
Should be overridden by derived classes to return true if this kind of node has the special property ...
bool remove_collider(const NodePath &collider)
Removes the collider (and its associated handler) from the set of CollisionNodes that will be tested ...
void set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
This class manages the traversal through the scene graph to detect collisions.
get_child
Returns the nth child node of this node.
TypeHandle is the identifier used to differentiate C++ class types.
static void flush_level()
Flushes the PStatCollectors used during traversal.
virtual bool is_geom_node() const
A simple downcast check.
bool apply_transform()
Applies the inverse transform from the current node, if any, onto all the colliders in the level stat...
bool around(const GeometricBoundingVolume **first, const GeometricBoundingVolume **last)
Resets the volume to enclose only the volumes indicated.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node that holds Geom objects, renderable pieces of geometry.
get_into_collide_mask
Returns the "into" collide mask for this node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PandaNode * node() const
Returns the PandaNode pointer of the node we have traversed to.
static void flush_level()
Flushes the PStatCollectors used during traversal.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static int get_max_colliders()
Returns the maximum number of colliders that may be added to the CollisionLevelStateBase at any one t...