43 PStatCollector CollisionBox::_volume_pcollector(
"Collision Volumes:CollisionBox");
44 PStatCollector CollisionBox::_test_pcollector(
"Collision Tests:CollisionBox");
47 const int CollisionBox::plane_def[6][4] = {
69 for(
int plane = 0; plane < 6; plane++) {
71 array[0] =
get_point(plane_def[plane][0]);
72 array[1] =
get_point(plane_def[plane][1]);
73 array[2] =
get_point(plane_def[plane][2]);
74 array[3] =
get_point(plane_def[plane][3]);
83 setup_points(
const LPoint3 *begin,
const LPoint3 *end,
int plane) {
84 int num_points = end - begin;
85 nassertv(num_points >= 3);
87 _points[plane].clear();
95 _to_2d_mat[plane].invert_from(to_3d_mat);
100 for (pi = begin; pi != end; ++pi) {
101 LPoint3 point = (*pi) * _to_2d_mat[plane];
102 _points[plane].push_back(
PointDef(point[0], point[2]));
105 nassertv(_points[plane].size() >= 3);
131 return entry.
get_into()->test_intersection_from_box(entry);
138 xform(
const LMatrix4 &mat) {
141 _center = _center * mat;
142 for(
int v = 0; v < 8; v++) {
143 _vertex[v] = _vertex[v] * mat;
145 for(
int p = 0; p < 6 ; p++) {
148 _x = _vertex[0].get_x() - _center.get_x();
149 _y = _vertex[0].get_y() - _center.get_y();
150 _z = _vertex[0].get_z() - _center.get_z();
151 _radius = sqrt(_x * _x + _y * _y + _z * _z);
154 mark_internal_bounds_stale();
173 return _volume_pcollector;
182 return _test_pcollector;
189 output(std::ostream &out)
const {
190 out <<
"box, (" << get_min() <<
") to (" << get_max() <<
")";
197 compute_internal_bounds()
const {
205 test_intersection_from_sphere(
const CollisionEntry &entry)
const {
208 DCAST_INTO_R(sphere, entry.
get_from(),
nullptr);
213 const LMatrix4 &wrt_mat = wrt_space->get_mat();
215 LPoint3 orig_center = sphere->get_center() * wrt_mat;
216 LPoint3 from_center = orig_center;
217 bool moved_from_center =
false;
218 PN_stdfloat t = 1.0f;
219 LPoint3 contact_point(from_center);
220 PN_stdfloat actual_t = 1.0f;
222 LVector3 from_radius_v =
223 LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
224 PN_stdfloat from_radius_2 = from_radius_v.length_squared();
225 PN_stdfloat from_radius = csqrt(from_radius_2);
228 PN_stdfloat max_dist = 0.0;
229 PN_stdfloat dist = 0.0;
234 for(ip = 0, intersect =
false; ip < 6 && !intersect; ip++) {
236 if (_points[ip].size() < 3) {
239 if (wrt_prev_space != wrt_space) {
243 LPoint3 b = from_center;
244 LPoint3 a = sphere->get_center() * wrt_prev_space->get_mat();
245 LVector3 delta = b - a;
249 PN_stdfloat dot = delta.dot(plane.get_normal());
254 if (IS_NEARLY_ZERO(dot)) {
267 PN_stdfloat dist_to_p = plane.dist_to_plane(a);
268 t = (dist_to_p / -dot);
272 actual_t = ((dist_to_p - from_radius) / -dot);
273 actual_t = min((PN_stdfloat)1.0, max((PN_stdfloat)0.0, actual_t));
274 contact_point = a + (actual_t * delta);
279 }
else if (t < 0.0f) {
281 moved_from_center =
true;
283 from_center = a + t * delta;
284 moved_from_center =
true;
304 if (!plane.intersects_line(dist, from_center, -(plane.get_normal()))) {
310 if (dist > from_radius || dist < -from_radius) {
315 LPoint2 p =
to_2d(from_center - dist * plane.get_normal(), ip);
316 PN_stdfloat edge_dist = 0.0f;
319 if (cpa !=
nullptr) {
325 }
else if (new_points.empty()) {
337 max_dist = from_radius;
347 if((edge_dist > 0) &&
348 ((edge_dist * edge_dist + dist * dist) > from_radius_2)) {
358 if (edge_dist >= 0.0f) {
359 PN_stdfloat max_dist_2 = max(from_radius_2 - edge_dist * edge_dist, (PN_stdfloat)0.0);
360 max_dist = csqrt(max_dist_2);
363 if (dist > max_dist) {
372 if (collide_cat.is_debug()) {
380 PN_stdfloat into_depth = max_dist - dist;
381 if (moved_from_center) {
384 PN_stdfloat orig_dist;
385 plane.intersects_line(orig_dist, orig_center, -normal);
386 into_depth = max_dist - orig_dist;
390 LPoint3 surface = from_center - normal * dist;
391 surface = surface.fmax(_min);
392 surface = surface.fmin(_max);
394 new_entry->set_surface_normal(normal);
395 new_entry->set_surface_point(surface);
396 new_entry->set_interior_point(surface - normal * into_depth);
397 new_entry->set_contact_pos(contact_point);
398 new_entry->set_contact_normal(plane.get_normal());
399 new_entry->set_t(actual_t);
410 DCAST_INTO_R(line, entry.
get_from(),
nullptr);
412 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
414 LPoint3 from_origin = line->get_origin() * wrt_mat;
415 LVector3 from_direction = line->get_direction() * wrt_mat;
418 if (!intersects_line(t1, t2, from_origin, from_direction)) {
423 if (collide_cat.is_debug()) {
430 LPoint3 point = from_origin + t1 * from_direction;
431 new_entry->set_surface_point(point);
437 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
438 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
439 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
442 new_entry->set_surface_normal(normal);
454 DCAST_INTO_R(ray, entry.
get_from(),
nullptr);
455 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
457 LPoint3 from_origin = ray->get_origin() * wrt_mat;
458 LVector3 from_direction = ray->get_direction() * wrt_mat;
461 if (!intersects_line(t1, t2, from_origin, from_direction) || (t1 < 0.0 && t2 < 0.0)) {
466 if (collide_cat.is_debug()) {
475 new_entry->set_interior_point(from_origin);
479 LPoint3 point = from_origin + t1 * from_direction;
480 new_entry->set_surface_point(point);
486 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
487 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
488 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
491 new_entry->set_surface_normal(normal);
501 test_intersection_from_segment(
const CollisionEntry &entry)
const {
503 DCAST_INTO_R(seg, entry.
get_from(),
nullptr);
504 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
506 LPoint3 from_origin = seg->get_point_a() * wrt_mat;
507 LPoint3 from_extent = seg->get_point_b() * wrt_mat;
508 LVector3 from_direction = from_extent - from_origin;
511 if (!intersects_line(t1, t2, from_origin, from_direction) ||
512 (t1 < 0.0 && t2 < 0.0) || (t1 > 1.0 && t2 > 1.0)) {
517 if (collide_cat.is_debug()) {
526 if (t1 < (1.0 - t2)) {
531 new_entry->set_interior_point(from_origin + std::min(std::max(t2, 0.0), 1.0) * from_direction);
533 LPoint3 point = from_origin + t1 * from_direction;
534 new_entry->set_surface_point(point);
540 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
541 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
542 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
545 new_entry->set_surface_normal(normal);
555 test_intersection_from_capsule(
const CollisionEntry &entry)
const {
557 DCAST_INTO_R(capsule, entry.
get_from(),
nullptr);
559 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
561 LPoint3 from_a = capsule->get_point_a() * wrt_mat;
562 LPoint3 from_b = capsule->get_point_b() * wrt_mat;
563 LVector3 from_direction = from_b - from_a;
564 PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, capsule->get_radius())).length_squared();
565 PN_stdfloat radius = csqrt(radius_sq);
567 LPoint3 box_min = get_min();
568 LPoint3 box_max = get_max();
569 LVector3 dimensions = box_max - box_min;
578 if (!intersects_line(t1, t2, from_a, from_direction, radius)) {
582 if (t2 < 0.0 || t1 > 1.0) {
586 t1 = std::min(1.0, std::max(0.0, (t1 + t2) * 0.5));
587 LPoint3 point = from_a + from_direction * t1;
594 if ((point[0] < box_min[0] || point[0] > box_max[0]) +
595 (point[1] < box_min[1] || point[1] > box_max[1]) +
596 (point[2] < box_min[2] || point[2] > box_max[2]) > 1) {
598 static const struct {
616 PN_stdfloat best_dist_sq = FLT_MAX;
618 for (
int i = 0; i < 12; ++i) {
619 LPoint3 vertex = edges[i].point;
620 vertex.componentwise_mult(dimensions);
623 delta[edges[i].axis] = dimensions[edges[i].axis];
625 CollisionCapsule::calc_closest_segment_points(u1, u2, from_a, from_direction, vertex, delta);
626 PN_stdfloat dist_sq = ((from_a + from_direction * u1) - (vertex + delta * u2)).length_squared();
627 if (dist_sq < best_dist_sq) {
628 best_dist_sq = dist_sq;
632 if (best_dist_sq > radius_sq) {
638 if (collide_cat.is_debug()) {
646 LVector3 diff = point - _center;
647 diff[0] /= dimensions[0];
648 diff[1] /= dimensions[1];
649 diff[2] /= dimensions[2];
651 if (cabs(diff[0]) > cabs(diff[1])) {
652 if (cabs(diff[0]) > cabs(diff[2])) {
658 if (cabs(diff[1]) > cabs(diff[2])) {
665 normal[axis] = std::copysign(1, diff[axis]);
667 LPoint3 clamped = point.fmax(box_min).fmin(box_max);
668 LPoint3 surface_point = clamped;
669 surface_point[axis] = (diff[axis] >= 0.0f) ? box_max[axis] : box_min[axis];
672 LVector3 interior_vec;
673 if (clamped != point) {
676 interior_vec = point - surface_point;
677 if (!interior_vec.normalize()) {
678 interior_vec = normal;
682 interior_vec = normal;
684 new_entry->set_interior_point(point - interior_vec * radius);
685 new_entry->set_surface_point(surface_point);
690 new_entry->set_surface_normal(normal);
702 DCAST_INTO_R(box, entry.
get_from(),
nullptr);
704 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
706 LPoint3 diff = wrt_mat.xform_point_general(box->get_center()) - _center;
707 LVector3 from_extents = box->get_dimensions() * 0.5f;
708 LVector3 into_extents = get_dimensions() * 0.5f;
710 LVecBase3 box_x = wrt_mat.get_row3(0);
711 LVecBase3 box_y = wrt_mat.get_row3(1);
712 LVecBase3 box_z = wrt_mat.get_row3(2);
720 from_extents[0] *= l;
723 from_extents[1] *= l;
726 from_extents[2] *= l;
730 PN_stdfloat min_pen = 0;
735 r1 = into_extents[0];
736 r2 = cabs(box_x[0] * from_extents[0]) +
737 cabs(box_y[0] * from_extents[1]) +
738 cabs(box_z[0] * from_extents[2]);
739 pen = r1 + r2 - cabs(diff[0]);
745 r1 = into_extents[1];
746 r2 = cabs(box_x[1] * from_extents[0]) +
747 cabs(box_y[1] * from_extents[1]) +
748 cabs(box_z[1] * from_extents[2]);
749 pen = r1 + r2 - cabs(diff[1]);
758 r1 = into_extents[2];
759 r2 = cabs(box_x[2] * from_extents[0]) +
760 cabs(box_y[2] * from_extents[1]) +
761 cabs(box_z[2] * from_extents[2]);
762 pen = r1 + r2 - cabs(diff[2]);
772 r1 = cabs(box_x[0] * into_extents[0]) +
773 cabs(box_x[1] * into_extents[1]) +
774 cabs(box_x[2] * into_extents[2]);
775 r2 = from_extents[0];
776 pen = r1 + r2 - cabs(diff.dot(box_x));
784 r1 = cabs(box_y[0] * into_extents[0]) +
785 cabs(box_y[1] * into_extents[1]) +
786 cabs(box_y[2] * into_extents[2]);
787 r2 = from_extents[1];
788 pen = r1 + r2 - cabs(diff.dot(box_y));
796 r1 = cabs(box_z[0] * into_extents[0]) +
797 cabs(box_z[1] * into_extents[1]) +
798 cabs(box_z[2] * into_extents[2]);
799 r2 = from_extents[2];
800 pen = r1 + r2 - cabs(diff.dot(box_z));
809 r1 = into_extents[1] * cabs(box_x[2]) + into_extents[2] * cabs(box_x[1]);
810 r2 = from_extents[1] * cabs(box_z[0]) + from_extents[2] * cabs(box_y[0]);
811 if (cabs(diff[2] * box_x[1] - diff[1] * box_x[2]) > r1 + r2) {
815 r1 = into_extents[1] * cabs(box_y[2]) + into_extents[2] * cabs(box_y[1]);
816 r2 = from_extents[0] * cabs(box_z[0]) + from_extents[2] * cabs(box_x[0]);
817 if (cabs(diff[2] * box_y[1] - diff[1] * box_y[2]) > r1 + r2) {
821 r1 = into_extents[1] * cabs(box_z[2]) + into_extents[2] * cabs(box_z[1]);
822 r2 = from_extents[0] * cabs(box_y[0]) + from_extents[1] * cabs(box_x[0]);
823 if (cabs(diff[2] * box_z[1] - diff[1] * box_z[2]) > r1 + r2) {
827 r1 = into_extents[0] * cabs(box_x[2]) + into_extents[2] * cabs(box_x[0]);
828 r2 = from_extents[1] * cabs(box_z[1]) + from_extents[2] * cabs(box_y[1]);
829 if (cabs(diff[0] * box_x[2] - diff[2] * box_x[0]) > r1 + r2) {
833 r1 = into_extents[0] * cabs(box_y[2]) + into_extents[2] * cabs(box_y[0]);
834 r2 = from_extents[0] * cabs(box_z[1]) + from_extents[2] * cabs(box_x[1]);
835 if (cabs(diff[0] * box_y[2] - diff[2] * box_y[0]) > r1 + r2) {
839 r1 = into_extents[0] * cabs(box_z[2]) + into_extents[2] * cabs(box_z[0]);
840 r2 = from_extents[0] * cabs(box_y[1]) + from_extents[1] * cabs(box_x[1]);
841 if (cabs(diff[0] * box_z[2] - diff[2] * box_z[0]) > r1 + r2) {
845 r1 = into_extents[0] * cabs(box_x[1]) + into_extents[1] * cabs(box_x[0]);
846 r2 = from_extents[1] * cabs(box_z[2]) + from_extents[2] * cabs(box_y[2]);
847 if (cabs(diff[1] * box_x[0] - diff[0] * box_x[1]) > r1 + r2) {
851 r1 = into_extents[0] * cabs(box_y[1]) + into_extents[1] * cabs(box_y[0]);
852 r2 = from_extents[0] * cabs(box_z[2]) + from_extents[2] * cabs(box_x[2]);
853 if (cabs(diff[1] * box_y[0] - diff[0] * box_y[1]) > r1 + r2) {
857 r1 = into_extents[0] * cabs(box_z[1]) + into_extents[1] * cabs(box_z[0]);
858 r2 = from_extents[0] * cabs(box_y[2]) + from_extents[1] * cabs(box_x[2]);
859 if (cabs(diff[1] * box_z[0] - diff[0] * box_z[1]) > r1 + r2) {
863 if (collide_cat.is_debug()) {
873 min(max(diff[0], -into_extents[0]), into_extents[0]),
874 min(max(diff[1], -into_extents[1]), into_extents[1]),
875 min(max(diff[2], -into_extents[2]), into_extents[2]));
879 PN_stdfloat diff_axis = diff[axis];
880 int sign = (diff_axis >= 0) ? 1 : -1;
882 surface[axis] = into_extents[axis] * sign;
884 new_entry->set_surface_point(surface + _center);
887 new_entry->set_interior_point(surface + _center + normal * -min_pen);
892 new_entry->set_surface_normal(normal);
904 if (collide_cat.is_debug()) {
906 <<
"Recomputing viz for " << *
this <<
"\n";
913 vdata->unclean_set_num_rows(8);
917 vertex.set_data3(_min[0], _min[1], _min[2]);
918 vertex.set_data3(_min[0], _max[1], _min[2]);
919 vertex.set_data3(_max[0], _max[1], _min[2]);
920 vertex.set_data3(_max[0], _min[1], _min[2]);
922 vertex.set_data3(_min[0], _min[1], _max[2]);
923 vertex.set_data3(_min[0], _max[1], _max[2]);
924 vertex.set_data3(_max[0], _max[1], _max[2]);
925 vertex.set_data3(_max[0], _min[1], _max[2]);
931 tris->add_vertices(0, 1, 2);
932 tris->add_vertices(2, 3, 0);
935 tris->add_vertices(4, 7, 6);
936 tris->add_vertices(6, 5, 4);
939 tris->add_vertices(0, 4, 1);
940 tris->add_vertices(1, 4, 5);
942 tris->add_vertices(1, 5, 2);
943 tris->add_vertices(2, 5, 6);
945 tris->add_vertices(2, 6, 3);
946 tris->add_vertices(3, 6, 7);
948 tris->add_vertices(3, 7, 0);
949 tris->add_vertices(0, 7, 4);
954 lines->add_vertices(0, 1);
955 lines->add_vertices(1, 2);
956 lines->add_vertices(0, 3);
957 lines->add_vertices(2, 3);
960 lines->add_vertices(4, 5);
961 lines->add_vertices(5, 6);
962 lines->add_vertices(4, 7);
963 lines->add_vertices(6, 7);
966 lines->add_vertices(0, 4);
967 lines->add_vertices(1, 5);
968 lines->add_vertices(2, 6);
969 lines->add_vertices(3, 7);
972 geom1->add_primitive(tris);
975 geom2->add_primitive(lines);
977 _viz_geom->add_geom(geom1, get_solid_viz_state());
978 _viz_geom->add_geom(geom2, get_wireframe_viz_state());
980 _bounds_viz_geom->add_geom(geom1, get_solid_bounds_viz_state());
981 _bounds_viz_geom->add_geom(geom2, get_wireframe_viz_state());
993 intersects_line(
double &t1,
double &t2,
994 const LPoint3 &from,
const LVector3 &delta,
995 PN_stdfloat inflate_size)
const {
997 LPoint3 bmin = _min - LVector3(inflate_size);
998 LPoint3 bmax = _max + LVector3(inflate_size);
1000 double tmin = -DBL_MAX;
1001 double tmax = DBL_MAX;
1003 for (
int i = 0; i < 3; ++i) {
1004 PN_stdfloat d = delta[i];
1005 if (!IS_NEARLY_ZERO(d)) {
1006 double tmin2 = (bmin[i] - from[i]) / d;
1007 double tmax2 = (bmax[i] - from[i]) / d;
1008 if (tmin2 > tmax2) {
1009 std::swap(tmin2, tmax2);
1011 tmin = std::max(tmin, tmin2);
1012 tmax = std::min(tmax, tmax2);
1018 }
else if (from[i] < bmin[i] || from[i] > bmax[i]) {
1043 bool first_plane =
true;
1045 for (
int i = 0; i < num_planes; i++) {
1050 net_transform->invert_compose(plane_path.get_net_transform());
1052 LPlane plane = plane_node->
get_plane() * new_transform->get_mat();
1054 first_plane =
false;
1055 if (!
clip_polygon(new_points, _points[plane_no], plane, plane_no)) {
1060 last_points.swap(new_points);
1061 if (!
clip_polygon(new_points, last_points, plane, plane_no)) {
1085 const LPlane &plane,
int plane_no)
const {
1087 if (source_points.empty()) {
1093 if (!plane.intersects_plane(from3d, delta3d,
get_plane(plane_no))) {
1099 new_points = source_points;
1107 LPoint2 from2d =
to_2d(from3d,plane_no);
1108 LVector2 delta2d =
to_2d(delta3d,plane_no);
1110 PN_stdfloat a = -delta2d[1];
1111 PN_stdfloat b = delta2d[0];
1112 PN_stdfloat c = from2d[0] * delta2d[1] - from2d[1] * delta2d[0];
1120 new_points.reserve(source_points.size() + 1);
1122 LPoint2 last_point = source_points.back()._p;
1123 bool last_is_in = !is_right(last_point - from2d, delta2d);
1124 bool all_in = last_is_in;
1125 Points::const_iterator pi;
1126 for (pi = source_points.begin(); pi != source_points.end(); ++pi) {
1127 const LPoint2 &this_point = (*pi)._p;
1128 bool this_is_in = !is_right(this_point - from2d, delta2d);
1132 bool crossed_over = (this_is_in != last_is_in);
1136 LVector2 d = this_point - last_point;
1137 PN_stdfloat denom = (a * d[0] + b * d[1]);
1139 PN_stdfloat t = -(a * last_point[0] + b * last_point[1] + c) / denom;
1140 LPoint2 p = last_point + t * d;
1142 new_points.push_back(
PointDef(p[0], p[1]));
1143 last_is_in = this_is_in;
1149 new_points.push_back(
PointDef(this_point[0], this_point[1]));
1154 last_point = this_point;
1177 bool got_dist =
false;
1178 PN_stdfloat best_dist = -1.0f;
1180 size_t num_points = points.size();
1181 for (
size_t i = 0; i < num_points - 1; ++i) {
1182 PN_stdfloat d = dist_to_line_segment(p, points[i]._p, points[i + 1]._p,
1185 if (!got_dist || d < best_dist) {
1192 PN_stdfloat d = dist_to_line_segment(p, points[num_points - 1]._p, points[0]._p,
1193 points[num_points - 1]._v);
1195 if (!got_dist || d < best_dist) {
1212 PN_stdfloat CollisionBox::
1213 dist_to_line_segment(
const LPoint2 &p,
1214 const LPoint2 &f,
const LPoint2 &t,
1215 const LVector2 &v) {
1216 LVector2 v1 = (p - f);
1217 PN_stdfloat d = (v1[0] * v[1] - v1[1] * v[0]);
1223 LPoint2 q = p + LVector2(-v[1], v[0]) * d;
1233 return (p - f).length();
1234 }
if (q[0] > t[0]) {
1235 return (p - t).length();
1242 return (p - f).length();
1243 }
if (q[1] > t[1]) {
1244 return (p - t).length();
1254 return (p - f).length();
1255 }
if (q[0] > t[0]) {
1256 return (p - t).length();
1263 return (p - f).length();
1264 }
if (q[1] < t[1]) {
1265 return (p - t).length();
1278 return (p - f).length();
1279 }
if (q[0] < t[0]) {
1280 return (p - t).length();
1287 return (p - f).length();
1288 }
if (q[1] > t[1]) {
1289 return (p - t).length();
1296 if (-v[0] > -v[1]) {
1299 return (p - f).length();
1300 }
if (q[0] < t[0]) {
1301 return (p - t).length();
1308 return (p - f).length();
1309 }
if (q[1] < t[1]) {
1310 return (p - t).length();
1329 for (
int i = 0; i < (int)points.size() - 1; i++) {
1330 if (is_right(p - points[i]._p, points[i+1]._p - points[i]._p)) {
1334 if (is_right(p - points[points.size() - 1]._p,
1335 points[0]._p - points[points.size() - 1]._p)) {
1348 size_t num_points = points.size();
1349 for (
size_t i = 0; i < num_points; i++) {
1350 points[i]._v = points[(i + 1) % num_points]._p - points[i]._p;
1351 points[i]._v.normalize();
1370 _center.write_datagram(me);
1371 _min.write_datagram(me);
1372 _max.write_datagram(me);
1373 for(
int i=0; i < 8; i++) {
1374 _vertex[i].write_datagram(me);
1380 for(
int i=0; i < 6; i++) {
1381 _planes[i].write_datagram(me);
1383 for(
int i=0; i < 6; i++) {
1384 _to_2d_mat[i].write_datagram(me);
1386 for(
int i=0; i < 6; i++) {
1388 for (
size_t j = 0; j < _points[i].size(); j++) {
1389 _points[i][j]._p.write_datagram(me);
1390 _points[i][j]._v.write_datagram(me);
1405 me->fillin(scan, manager);
1416 CollisionSolid::fillin(scan, manager);
1417 _center.read_datagram(scan);
1418 _min.read_datagram(scan);
1419 _max.read_datagram(scan);
1420 for(
int i=0; i < 8; i++) {
1421 _vertex[i].read_datagram(scan);
1427 for(
int i=0; i < 6; i++) {
1428 _planes[i].read_datagram(scan);
1430 for(
int i=0; i < 6; i++) {
1431 _to_2d_mat[i].read_datagram(scan);
1433 for(
int i=0; i < 6; i++) {
1435 for (
size_t j = 0; j < size; j++) {
1438 p.read_datagram(scan);
1439 v.read_datagram(scan);
1440 _points[i].push_back(PointDef(p, v));
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
This defines a bounding sphere, consisting of a center and a radius.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
This functions similarly to a LightAttrib.
get_on_plane
Returns the nth plane enabled by the attribute, sorted in render order.
get_num_on_planes
Returns the number of planes that are enabled by the attribute.
A cuboid collision volume or object.
static void register_with_read_factory()
Factory method to generate a CollisionBox object.
PN_stdfloat dist_to_polygon(const LPoint2 &p, const Points &points) const
Returns the linear distance from the 2-d point to the nearest part of the polygon defined by the poin...
void setup_points(const LPoint3 *begin, const LPoint3 *end, int plane)
Computes the plane and 2d projection of points that make up this side.
bool apply_clip_plane(Points &new_points, const ClipPlaneAttrib *cpa, const TransformState *net_transform, int plane_no) const
Clips the polygon by all of the clip planes named in the clip plane attribute and fills new_points up...
bool clip_polygon(Points &new_points, const Points &source_points, const LPlane &plane, int plane_no) const
Clips the source_points of the polygon by the indicated clipping plane, and modifies new_points to re...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
void calc_to_3d_mat(LMatrix4 &to_3d_mat, int plane) const
Fills the indicated matrix with the appropriate rotation transform to move points from the 2-d plane ...
static void compute_vectors(Points &points)
Now that the _p members of the given points array have been computed, go back and compute all of the ...
void setup_box()
Compute parameters for each of the box's sides.
LPlane get_plane(int n) const
Returns the nth face of the rectangular solid.
bool point_is_inside(const LPoint2 &p, const Points &points) const
Returns true if the indicated point is within the polygon's 2-d space, false otherwise.
virtual PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
LPoint2 to_2d(const LVecBase3 &point3d, int plane) const
Assuming the indicated point in 3-d space lies within the polygon's plane, returns the corresponding ...
LPoint3 get_point(int n) const
Returns the nth vertex of the OBB.
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...
LPlane set_plane(int n) const
Creates the nth face of the rectangular solid.
This implements a solid consisting of a cylinder with hemispherical endcaps, also known as a capsule ...
Defines a single collision event.
get_into
Returns the CollisionSolid pointer for the particular solid was collided into.
get_from_node_path
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
get_into_node_path
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
get_from
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
An infinite line, similar to a CollisionRay, except that it extends in both directions.
An infinite ray, with a specific origin and direction.
A finite line segment, with two specific endpoints but no thickness.
The abstract base class for all things that can collide with other things in the world,...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
bool has_effective_normal() const
Returns true if a special normal was set by set_effective_normal(), false otherwise.
const LVector3 & get_effective_normal() const
Returns the normal that was set by set_effective_normal().
get_respect_effective_normal
See set_respect_effective_normal().
A spherical collision volume or object.
A class to retrieve the individual data elements previously stored in a Datagram.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Defines a series of disconnected line segments.
Defines a series of disconnected triangles.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
A container for geometry primitives.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
PandaNode * node() const
Returns the referenced node of the path.
A lightweight class that represents a single element that may be timed and/or counted via stats.
A node that contains a plane.
const LPlane & get_plane() const
Returns the plane represented by the PlaneNode.
int get_clip_effect() const
Returns the clip_effect bits for this clip plane.
TypeHandle is the identifier used to differentiate C++ class types.
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT(CollisionEntry) CollisionBox
First Dispatch point for box as a FROM object.
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.
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.
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.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.