43PStatCollector CollisionBox::_volume_pcollector(
"Collision Volumes:CollisionBox");
44PStatCollector CollisionBox::_test_pcollector(
"Collision Tests:CollisionBox");
47const 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]);
83setup_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);
138xform(
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;
189output(std::ostream &out)
const {
190 out <<
"box, (" << get_min() <<
") to (" << get_max() <<
")";
197compute_internal_bounds()
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;
233 bool fully_inside =
true;
235 for(ip = 0, intersect =
false; ip < 6 && !intersect; ip++) {
237 if (_points[ip].size() < 3) {
238 fully_inside =
false;
241 if (wrt_prev_space != wrt_space) {
245 LPoint3 b = from_center;
246 LPoint3 a = sphere->get_center() * wrt_prev_space->get_mat();
247 LVector3 delta = b - a;
251 PN_stdfloat dot = delta.dot(plane.get_normal());
253 fully_inside =
false;
257 if (IS_NEARLY_ZERO(dot)) {
270 PN_stdfloat dist_to_p = plane.dist_to_plane(a);
271 t = (dist_to_p / -dot);
275 actual_t = ((dist_to_p - from_radius) / -dot);
276 actual_t = min((PN_stdfloat)1.0, max((PN_stdfloat)0.0, actual_t));
277 contact_point = a + (actual_t * delta);
282 }
else if (t < 0.0f) {
284 moved_from_center =
true;
286 from_center = a + t * delta;
287 moved_from_center =
true;
307 if (!plane.intersects_line(dist, from_center, -(plane.get_normal()))) {
310 fully_inside =
false;
314 if (dist > from_radius) {
318 if (dist < -from_radius) {
322 fully_inside =
false;
324 LPoint2 p =
to_2d(from_center - dist * plane.get_normal(), ip);
325 PN_stdfloat edge_dist = 0.0f;
328 if (cpa !=
nullptr) {
334 }
else if (new_points.empty()) {
346 max_dist = from_radius;
356 if((edge_dist > 0) &&
357 ((edge_dist * edge_dist + dist * dist) > from_radius_2)) {
367 if (edge_dist >= 0.0f) {
368 PN_stdfloat max_dist_2 = max(from_radius_2 - edge_dist * edge_dist, (PN_stdfloat)0.0);
369 max_dist = csqrt(max_dist_2);
372 if (dist > max_dist) {
378 if (!fully_inside && !intersect) {
382 if (collide_cat.is_debug()) {
390 PN_stdfloat into_depth = max_dist - dist;
391 if (moved_from_center) {
394 PN_stdfloat orig_dist;
395 plane.intersects_line(orig_dist, orig_center, -normal);
396 into_depth = max_dist - orig_dist;
400 LPoint3 surface = from_center - normal * dist;
401 surface = surface.fmax(_min);
402 surface = surface.fmin(_max);
404 new_entry->set_surface_normal(normal);
405 new_entry->set_surface_point(surface);
406 new_entry->set_interior_point(surface - normal * into_depth);
407 new_entry->set_contact_pos(contact_point);
408 new_entry->set_contact_normal(plane.get_normal());
409 new_entry->set_t(actual_t);
420 DCAST_INTO_R(line, entry.
get_from(),
nullptr);
422 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
424 LPoint3 from_origin = line->get_origin() * wrt_mat;
425 LVector3 from_direction = line->get_direction() * wrt_mat;
428 if (!intersects_line(t1, t2, from_origin, from_direction)) {
433 if (collide_cat.is_debug()) {
440 LPoint3 point = from_origin + t1 * from_direction;
441 new_entry->set_surface_point(point);
447 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
448 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
449 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
452 new_entry->set_surface_normal(normal);
464 DCAST_INTO_R(ray, entry.
get_from(),
nullptr);
465 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
467 LPoint3 from_origin = ray->get_origin() * wrt_mat;
468 LVector3 from_direction = ray->get_direction() * wrt_mat;
471 if (!intersects_line(t1, t2, from_origin, from_direction) || (t1 < 0.0 && t2 < 0.0)) {
476 if (collide_cat.is_debug()) {
485 new_entry->set_interior_point(from_origin);
489 LPoint3 point = from_origin + t1 * from_direction;
490 new_entry->set_surface_point(point);
496 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
497 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
498 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
501 new_entry->set_surface_normal(normal);
511test_intersection_from_segment(
const CollisionEntry &entry)
const {
513 DCAST_INTO_R(seg, entry.
get_from(),
nullptr);
514 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
516 LPoint3 from_origin = seg->get_point_a() * wrt_mat;
517 LPoint3 from_extent = seg->get_point_b() * wrt_mat;
518 LVector3 from_direction = from_extent - from_origin;
521 if (!intersects_line(t1, t2, from_origin, from_direction) ||
522 (t1 < 0.0 && t2 < 0.0) || (t1 > 1.0 && t2 > 1.0)) {
527 if (collide_cat.is_debug()) {
536 if (t1 < (1.0 - t2)) {
541 new_entry->set_interior_point(from_origin + std::min(std::max(t2, 0.0), 1.0) * from_direction);
543 LPoint3 point = from_origin + t1 * from_direction;
544 new_entry->set_surface_point(point);
550 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
551 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
552 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
555 new_entry->set_surface_normal(normal);
565test_intersection_from_capsule(
const CollisionEntry &entry)
const {
567 DCAST_INTO_R(capsule, entry.
get_from(),
nullptr);
569 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
571 LPoint3 from_a = capsule->get_point_a() * wrt_mat;
572 LPoint3 from_b = capsule->get_point_b() * wrt_mat;
573 LVector3 from_direction = from_b - from_a;
574 PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, capsule->get_radius())).length_squared();
575 PN_stdfloat radius = csqrt(radius_sq);
577 LPoint3 box_min = get_min();
578 LPoint3 box_max = get_max();
579 LVector3 dimensions = box_max - box_min;
588 if (!intersects_line(t1, t2, from_a, from_direction, radius)) {
592 if (t2 < 0.0 || t1 > 1.0) {
596 t1 = std::min(1.0, std::max(0.0, (t1 + t2) * 0.5));
597 LPoint3 point = from_a + from_direction * t1;
604 if ((point[0] < box_min[0] || point[0] > box_max[0]) +
605 (point[1] < box_min[1] || point[1] > box_max[1]) +
606 (point[2] < box_min[2] || point[2] > box_max[2]) > 1) {
608 static const struct {
626 PN_stdfloat best_dist_sq = FLT_MAX;
628 for (
int i = 0; i < 12; ++i) {
629 LPoint3 vertex = edges[i].point;
630 vertex.componentwise_mult(dimensions);
633 delta[edges[i].axis] = dimensions[edges[i].axis];
635 CollisionCapsule::calc_closest_segment_points(u1, u2, from_a, from_direction, vertex, delta);
636 PN_stdfloat dist_sq = ((from_a + from_direction * u1) - (vertex + delta * u2)).length_squared();
637 if (dist_sq < best_dist_sq) {
638 best_dist_sq = dist_sq;
642 if (best_dist_sq > radius_sq) {
648 if (collide_cat.is_debug()) {
656 LVector3 diff = point - _center;
657 diff[0] /= dimensions[0];
658 diff[1] /= dimensions[1];
659 diff[2] /= dimensions[2];
661 if (cabs(diff[0]) > cabs(diff[1])) {
662 if (cabs(diff[0]) > cabs(diff[2])) {
668 if (cabs(diff[1]) > cabs(diff[2])) {
675 normal[axis] = std::copysign(1, diff[axis]);
677 LPoint3 clamped = point.fmax(box_min).fmin(box_max);
678 LPoint3 surface_point = clamped;
679 surface_point[axis] = (diff[axis] >= 0.0f) ? box_max[axis] : box_min[axis];
682 LVector3 interior_vec;
683 if (clamped != point) {
686 interior_vec = point - surface_point;
687 if (!interior_vec.normalize()) {
688 interior_vec = normal;
692 interior_vec = normal;
694 new_entry->set_interior_point(point - interior_vec * radius);
695 new_entry->set_surface_point(surface_point);
700 new_entry->set_surface_normal(normal);
712 DCAST_INTO_R(box, entry.
get_from(),
nullptr);
714 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
716 LPoint3 diff = wrt_mat.xform_point_general(box->get_center()) - _center;
717 LVector3 from_extents = box->get_dimensions() * 0.5f;
718 LVector3 into_extents = get_dimensions() * 0.5f;
720 LVecBase3 box_x = wrt_mat.get_row3(0);
721 LVecBase3 box_y = wrt_mat.get_row3(1);
722 LVecBase3 box_z = wrt_mat.get_row3(2);
730 from_extents[0] *= l;
733 from_extents[1] *= l;
736 from_extents[2] *= l;
740 PN_stdfloat min_pen = 0;
745 r1 = into_extents[0];
746 r2 = cabs(box_x[0] * from_extents[0]) +
747 cabs(box_y[0] * from_extents[1]) +
748 cabs(box_z[0] * from_extents[2]);
749 pen = r1 + r2 - cabs(diff[0]);
755 r1 = into_extents[1];
756 r2 = cabs(box_x[1] * from_extents[0]) +
757 cabs(box_y[1] * from_extents[1]) +
758 cabs(box_z[1] * from_extents[2]);
759 pen = r1 + r2 - cabs(diff[1]);
768 r1 = into_extents[2];
769 r2 = cabs(box_x[2] * from_extents[0]) +
770 cabs(box_y[2] * from_extents[1]) +
771 cabs(box_z[2] * from_extents[2]);
772 pen = r1 + r2 - cabs(diff[2]);
782 r1 = cabs(box_x[0] * into_extents[0]) +
783 cabs(box_x[1] * into_extents[1]) +
784 cabs(box_x[2] * into_extents[2]);
785 r2 = from_extents[0];
786 pen = r1 + r2 - cabs(diff.dot(box_x));
794 r1 = cabs(box_y[0] * into_extents[0]) +
795 cabs(box_y[1] * into_extents[1]) +
796 cabs(box_y[2] * into_extents[2]);
797 r2 = from_extents[1];
798 pen = r1 + r2 - cabs(diff.dot(box_y));
806 r1 = cabs(box_z[0] * into_extents[0]) +
807 cabs(box_z[1] * into_extents[1]) +
808 cabs(box_z[2] * into_extents[2]);
809 r2 = from_extents[2];
810 pen = r1 + r2 - cabs(diff.dot(box_z));
819 r1 = into_extents[1] * cabs(box_x[2]) + into_extents[2] * cabs(box_x[1]);
820 r2 = from_extents[1] * cabs(box_z[0]) + from_extents[2] * cabs(box_y[0]);
821 if (cabs(diff[2] * box_x[1] - diff[1] * box_x[2]) > r1 + r2) {
825 r1 = into_extents[1] * cabs(box_y[2]) + into_extents[2] * cabs(box_y[1]);
826 r2 = from_extents[0] * cabs(box_z[0]) + from_extents[2] * cabs(box_x[0]);
827 if (cabs(diff[2] * box_y[1] - diff[1] * box_y[2]) > r1 + r2) {
831 r1 = into_extents[1] * cabs(box_z[2]) + into_extents[2] * cabs(box_z[1]);
832 r2 = from_extents[0] * cabs(box_y[0]) + from_extents[1] * cabs(box_x[0]);
833 if (cabs(diff[2] * box_z[1] - diff[1] * box_z[2]) > r1 + r2) {
837 r1 = into_extents[0] * cabs(box_x[2]) + into_extents[2] * cabs(box_x[0]);
838 r2 = from_extents[1] * cabs(box_z[1]) + from_extents[2] * cabs(box_y[1]);
839 if (cabs(diff[0] * box_x[2] - diff[2] * box_x[0]) > r1 + r2) {
843 r1 = into_extents[0] * cabs(box_y[2]) + into_extents[2] * cabs(box_y[0]);
844 r2 = from_extents[0] * cabs(box_z[1]) + from_extents[2] * cabs(box_x[1]);
845 if (cabs(diff[0] * box_y[2] - diff[2] * box_y[0]) > r1 + r2) {
849 r1 = into_extents[0] * cabs(box_z[2]) + into_extents[2] * cabs(box_z[0]);
850 r2 = from_extents[0] * cabs(box_y[1]) + from_extents[1] * cabs(box_x[1]);
851 if (cabs(diff[0] * box_z[2] - diff[2] * box_z[0]) > r1 + r2) {
855 r1 = into_extents[0] * cabs(box_x[1]) + into_extents[1] * cabs(box_x[0]);
856 r2 = from_extents[1] * cabs(box_z[2]) + from_extents[2] * cabs(box_y[2]);
857 if (cabs(diff[1] * box_x[0] - diff[0] * box_x[1]) > r1 + r2) {
861 r1 = into_extents[0] * cabs(box_y[1]) + into_extents[1] * cabs(box_y[0]);
862 r2 = from_extents[0] * cabs(box_z[2]) + from_extents[2] * cabs(box_x[2]);
863 if (cabs(diff[1] * box_y[0] - diff[0] * box_y[1]) > r1 + r2) {
867 r1 = into_extents[0] * cabs(box_z[1]) + into_extents[1] * cabs(box_z[0]);
868 r2 = from_extents[0] * cabs(box_y[2]) + from_extents[1] * cabs(box_x[2]);
869 if (cabs(diff[1] * box_z[0] - diff[0] * box_z[1]) > r1 + r2) {
873 if (collide_cat.is_debug()) {
883 min(max(diff[0], -into_extents[0]), into_extents[0]),
884 min(max(diff[1], -into_extents[1]), into_extents[1]),
885 min(max(diff[2], -into_extents[2]), into_extents[2]));
889 PN_stdfloat diff_axis = diff[axis];
890 int sign = (diff_axis >= 0) ? 1 : -1;
892 surface[axis] = into_extents[axis] * sign;
894 new_entry->set_surface_point(surface + _center);
897 new_entry->set_interior_point(surface + _center + normal * -min_pen);
902 new_entry->set_surface_normal(normal);
914 if (collide_cat.is_debug()) {
916 <<
"Recomputing viz for " << *
this <<
"\n";
923 vdata->unclean_set_num_rows(8);
927 vertex.set_data3(_min[0], _min[1], _min[2]);
928 vertex.set_data3(_min[0], _max[1], _min[2]);
929 vertex.set_data3(_max[0], _max[1], _min[2]);
930 vertex.set_data3(_max[0], _min[1], _min[2]);
932 vertex.set_data3(_min[0], _min[1], _max[2]);
933 vertex.set_data3(_min[0], _max[1], _max[2]);
934 vertex.set_data3(_max[0], _max[1], _max[2]);
935 vertex.set_data3(_max[0], _min[1], _max[2]);
941 tris->add_vertices(0, 1, 2);
942 tris->add_vertices(2, 3, 0);
945 tris->add_vertices(4, 7, 6);
946 tris->add_vertices(6, 5, 4);
949 tris->add_vertices(0, 4, 1);
950 tris->add_vertices(1, 4, 5);
952 tris->add_vertices(1, 5, 2);
953 tris->add_vertices(2, 5, 6);
955 tris->add_vertices(2, 6, 3);
956 tris->add_vertices(3, 6, 7);
958 tris->add_vertices(3, 7, 0);
959 tris->add_vertices(0, 7, 4);
964 lines->add_vertices(0, 1);
965 lines->add_vertices(1, 2);
966 lines->add_vertices(0, 3);
967 lines->add_vertices(2, 3);
970 lines->add_vertices(4, 5);
971 lines->add_vertices(5, 6);
972 lines->add_vertices(4, 7);
973 lines->add_vertices(6, 7);
976 lines->add_vertices(0, 4);
977 lines->add_vertices(1, 5);
978 lines->add_vertices(2, 6);
979 lines->add_vertices(3, 7);
982 geom1->add_primitive(tris);
985 geom2->add_primitive(lines);
987 _viz_geom->add_geom(geom1, get_solid_viz_state());
988 _viz_geom->add_geom(geom2, get_wireframe_viz_state());
990 _bounds_viz_geom->add_geom(geom1, get_solid_bounds_viz_state());
991 _bounds_viz_geom->add_geom(geom2, get_wireframe_viz_state());
1003intersects_line(
double &t1,
double &t2,
1004 const LPoint3 &from,
const LVector3 &delta,
1005 PN_stdfloat inflate_size)
const {
1007 LPoint3 bmin = _min - LVector3(inflate_size);
1008 LPoint3 bmax = _max + LVector3(inflate_size);
1010 double tmin = -DBL_MAX;
1011 double tmax = DBL_MAX;
1013 for (
int i = 0; i < 3; ++i) {
1014 PN_stdfloat d = delta[i];
1015 if (!IS_NEARLY_ZERO(d)) {
1016 double tmin2 = (bmin[i] - from[i]) / d;
1017 double tmax2 = (bmax[i] - from[i]) / d;
1018 if (tmin2 > tmax2) {
1019 std::swap(tmin2, tmax2);
1021 tmin = std::max(tmin, tmin2);
1022 tmax = std::min(tmax, tmax2);
1028 }
else if (from[i] < bmin[i] || from[i] > bmax[i]) {
1053 bool first_plane =
true;
1055 for (
int i = 0; i < num_planes; i++) {
1060 net_transform->invert_compose(plane_path.get_net_transform());
1062 LPlane plane = plane_node->
get_plane() * new_transform->get_mat();
1064 first_plane =
false;
1065 if (!
clip_polygon(new_points, _points[plane_no], plane, plane_no)) {
1070 last_points.swap(new_points);
1071 if (!
clip_polygon(new_points, last_points, plane, plane_no)) {
1095 const LPlane &plane,
int plane_no)
const {
1097 if (source_points.empty()) {
1103 if (!plane.intersects_plane(from3d, delta3d,
get_plane(plane_no))) {
1109 new_points = source_points;
1117 LPoint2 from2d =
to_2d(from3d,plane_no);
1118 LVector2 delta2d =
to_2d(delta3d,plane_no);
1120 PN_stdfloat a = -delta2d[1];
1121 PN_stdfloat b = delta2d[0];
1122 PN_stdfloat c = from2d[0] * delta2d[1] - from2d[1] * delta2d[0];
1130 new_points.reserve(source_points.size() + 1);
1132 LPoint2 last_point = source_points.back()._p;
1133 bool last_is_in = !is_right(last_point - from2d, delta2d);
1134 bool all_in = last_is_in;
1135 Points::const_iterator pi;
1136 for (pi = source_points.begin(); pi != source_points.end(); ++pi) {
1137 const LPoint2 &this_point = (*pi)._p;
1138 bool this_is_in = !is_right(this_point - from2d, delta2d);
1142 bool crossed_over = (this_is_in != last_is_in);
1146 LVector2 d = this_point - last_point;
1147 PN_stdfloat denom = (a * d[0] + b * d[1]);
1149 PN_stdfloat t = -(a * last_point[0] + b * last_point[1] + c) / denom;
1150 LPoint2 p = last_point + t * d;
1152 new_points.push_back(
PointDef(p[0], p[1]));
1153 last_is_in = this_is_in;
1159 new_points.push_back(
PointDef(this_point[0], this_point[1]));
1164 last_point = this_point;
1187 bool got_dist =
false;
1188 PN_stdfloat best_dist = -1.0f;
1190 size_t num_points = points.size();
1191 for (
size_t i = 0; i < num_points - 1; ++i) {
1192 PN_stdfloat d = dist_to_line_segment(p, points[i]._p, points[i + 1]._p,
1195 if (!got_dist || d < best_dist) {
1202 PN_stdfloat d = dist_to_line_segment(p, points[num_points - 1]._p, points[0]._p,
1203 points[num_points - 1]._v);
1205 if (!got_dist || d < best_dist) {
1222PN_stdfloat CollisionBox::
1223dist_to_line_segment(
const LPoint2 &p,
1224 const LPoint2 &f,
const LPoint2 &t,
1225 const LVector2 &v) {
1226 LVector2 v1 = (p - f);
1227 PN_stdfloat d = (v1[0] * v[1] - v1[1] * v[0]);
1233 LPoint2 q = p + LVector2(-v[1], v[0]) * d;
1243 return (p - f).length();
1244 }
if (q[0] > t[0]) {
1245 return (p - t).length();
1252 return (p - f).length();
1253 }
if (q[1] > t[1]) {
1254 return (p - t).length();
1264 return (p - f).length();
1265 }
if (q[0] > t[0]) {
1266 return (p - t).length();
1273 return (p - f).length();
1274 }
if (q[1] < t[1]) {
1275 return (p - t).length();
1288 return (p - f).length();
1289 }
if (q[0] < t[0]) {
1290 return (p - t).length();
1297 return (p - f).length();
1298 }
if (q[1] > t[1]) {
1299 return (p - t).length();
1306 if (-v[0] > -v[1]) {
1309 return (p - f).length();
1310 }
if (q[0] < t[0]) {
1311 return (p - t).length();
1318 return (p - f).length();
1319 }
if (q[1] < t[1]) {
1320 return (p - t).length();
1339 for (
int i = 0; i < (int)points.size() - 1; i++) {
1340 if (is_right(p - points[i]._p, points[i+1]._p - points[i]._p)) {
1344 if (is_right(p - points[points.size() - 1]._p,
1345 points[0]._p - points[points.size() - 1]._p)) {
1358 size_t num_points = points.size();
1359 for (
size_t i = 0; i < num_points; i++) {
1360 points[i]._v = points[(i + 1) % num_points]._p - points[i]._p;
1361 points[i]._v.normalize();
1380 _center.write_datagram(me);
1381 _min.write_datagram(me);
1382 _max.write_datagram(me);
1383 for(
int i=0; i < 8; i++) {
1384 _vertex[i].write_datagram(me);
1390 for(
int i=0; i < 6; i++) {
1391 _planes[i].write_datagram(me);
1393 for(
int i=0; i < 6; i++) {
1394 _to_2d_mat[i].write_datagram(me);
1396 for(
int i=0; i < 6; i++) {
1398 for (
size_t j = 0; j < _points[i].size(); j++) {
1399 _points[i][j]._p.write_datagram(me);
1400 _points[i][j]._v.write_datagram(me);
1415 me->fillin(scan, manager);
1426 CollisionSolid::fillin(scan, manager);
1427 _center.read_datagram(scan);
1428 _min.read_datagram(scan);
1429 _max.read_datagram(scan);
1430 for(
int i=0; i < 8; i++) {
1431 _vertex[i].read_datagram(scan);
1437 for(
int i=0; i < 6; i++) {
1438 _planes[i].read_datagram(scan);
1440 for(
int i=0; i < 6; i++) {
1441 _to_2d_mat[i].read_datagram(scan);
1443 for(
int i=0; i < 6; i++) {
1445 for (
size_t j = 0; j < size; j++) {
1448 p.read_datagram(scan);
1449 v.read_datagram(scan);
1450 _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.
get_clip_effect
Returns the clip_effect bits for this clip plane.
get_plane
Returns the plane represented by the PlaneNode.
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.