42 PStatCollector CollisionBox::_volume_pcollector(
"Collision Volumes:CollisionBox");
43 PStatCollector CollisionBox::_test_pcollector(
"Collision Tests:CollisionBox");
46 const int CollisionBox::plane_def[6][4] = {
68 for(
int plane = 0; plane < 6; plane++) {
70 array[0] =
get_point(plane_def[plane][0]);
71 array[1] =
get_point(plane_def[plane][1]);
72 array[2] =
get_point(plane_def[plane][2]);
73 array[3] =
get_point(plane_def[plane][3]);
82 setup_points(
const LPoint3 *begin,
const LPoint3 *end,
int plane) {
83 int num_points = end - begin;
84 nassertv(num_points >= 3);
86 _points[plane].clear();
94 _to_2d_mat[plane].invert_from(to_3d_mat);
99 for (pi = begin; pi != end; ++pi) {
100 LPoint3 point = (*pi) * _to_2d_mat[plane];
101 _points[plane].push_back(
PointDef(point[0], point[2]));
104 nassertv(_points[plane].size() >= 3);
130 return entry.
get_into()->test_intersection_from_box(entry);
137 xform(
const LMatrix4 &mat) {
140 _center = _center * mat;
141 for(
int v = 0; v < 8; v++) {
142 _vertex[v] = _vertex[v] * mat;
144 for(
int p = 0; p < 6 ; p++) {
147 _x = _vertex[0].get_x() - _center.get_x();
148 _y = _vertex[0].get_y() - _center.get_y();
149 _z = _vertex[0].get_z() - _center.get_z();
150 _radius = sqrt(_x * _x + _y * _y + _z * _z);
153 mark_internal_bounds_stale();
172 return _volume_pcollector;
181 return _test_pcollector;
188 output(std::ostream &out)
const {
195 compute_internal_bounds()
const {
203 test_intersection_from_sphere(
const CollisionEntry &entry)
const {
206 DCAST_INTO_R(sphere, entry.
get_from(),
nullptr);
211 const LMatrix4 &wrt_mat = wrt_space->get_mat();
213 LPoint3 orig_center = sphere->get_center() * wrt_mat;
214 LPoint3 from_center = orig_center;
215 bool moved_from_center =
false;
216 PN_stdfloat t = 1.0f;
217 LPoint3 contact_point(from_center);
218 PN_stdfloat actual_t = 1.0f;
220 LVector3 from_radius_v =
221 LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
222 PN_stdfloat from_radius_2 = from_radius_v.length_squared();
223 PN_stdfloat from_radius = csqrt(from_radius_2);
226 PN_stdfloat max_dist = 0.0;
227 PN_stdfloat dist = 0.0;
232 for(ip = 0, intersect =
false; ip < 6 && !intersect; ip++) {
234 if (_points[ip].size() < 3) {
237 if (wrt_prev_space != wrt_space) {
241 LPoint3 b = from_center;
242 LPoint3 a = sphere->get_center() * wrt_prev_space->get_mat();
243 LVector3 delta = b - a;
247 PN_stdfloat dot = delta.dot(plane.get_normal());
252 if (IS_NEARLY_ZERO(dot)) {
265 PN_stdfloat dist_to_p = plane.dist_to_plane(a);
266 t = (dist_to_p / -dot);
270 actual_t = ((dist_to_p - from_radius) / -dot);
271 actual_t = min((PN_stdfloat)1.0, max((PN_stdfloat)0.0, actual_t));
272 contact_point = a + (actual_t * delta);
277 }
else if (t < 0.0f) {
279 moved_from_center =
true;
281 from_center = a + t * delta;
282 moved_from_center =
true;
302 if (!plane.intersects_line(dist, from_center, -(plane.get_normal()))) {
308 if (dist > from_radius || dist < -from_radius) {
313 LPoint2 p =
to_2d(from_center - dist * plane.get_normal(), ip);
314 PN_stdfloat edge_dist = 0.0f;
317 if (cpa !=
nullptr) {
323 }
else if (new_points.empty()) {
335 max_dist = from_radius;
345 if((edge_dist > 0) &&
346 ((edge_dist * edge_dist + dist * dist) > from_radius_2)) {
356 if (edge_dist >= 0.0f) {
357 PN_stdfloat max_dist_2 = max(from_radius_2 - edge_dist * edge_dist, (PN_stdfloat)0.0);
358 max_dist = csqrt(max_dist_2);
361 if (dist > max_dist) {
370 if (collide_cat.is_debug()) {
378 PN_stdfloat into_depth = max_dist - dist;
379 if (moved_from_center) {
382 PN_stdfloat orig_dist;
383 plane.intersects_line(orig_dist, orig_center, -normal);
384 into_depth = max_dist - orig_dist;
388 LPoint3 surface = from_center - normal * dist;
389 surface = surface.fmax(_min);
390 surface = surface.fmin(_max);
392 new_entry->set_surface_normal(normal);
393 new_entry->set_surface_point(surface);
394 new_entry->set_interior_point(surface - normal * into_depth);
395 new_entry->set_contact_pos(contact_point);
396 new_entry->set_contact_normal(plane.get_normal());
397 new_entry->set_t(actual_t);
408 DCAST_INTO_R(line, entry.
get_from(),
nullptr);
410 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
412 LPoint3 from_origin = line->get_origin() * wrt_mat;
413 LVector3 from_direction = line->get_direction() * wrt_mat;
416 if (!intersects_line(t1, t2, from_origin, from_direction)) {
421 if (collide_cat.is_debug()) {
428 LPoint3 point = from_origin + t1 * from_direction;
429 new_entry->set_surface_point(point);
435 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
436 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
437 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
440 new_entry->set_surface_normal(normal);
452 DCAST_INTO_R(ray, entry.
get_from(),
nullptr);
453 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
455 LPoint3 from_origin = ray->get_origin() * wrt_mat;
456 LVector3 from_direction = ray->get_direction() * wrt_mat;
459 if (!intersects_line(t1, t2, from_origin, from_direction) || (t1 < 0.0 && t2 < 0.0)) {
464 if (collide_cat.is_debug()) {
473 new_entry->set_interior_point(from_origin);
477 LPoint3 point = from_origin + t1 * from_direction;
478 new_entry->set_surface_point(point);
484 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
485 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
486 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
489 new_entry->set_surface_normal(normal);
499 test_intersection_from_segment(
const CollisionEntry &entry)
const {
501 DCAST_INTO_R(seg, entry.
get_from(),
nullptr);
502 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
504 LPoint3 from_origin = seg->get_point_a() * wrt_mat;
505 LPoint3 from_extent = seg->get_point_b() * wrt_mat;
506 LVector3 from_direction = from_extent - from_origin;
509 if (!intersects_line(t1, t2, from_origin, from_direction) ||
510 (t1 < 0.0 && t2 < 0.0) || (t1 > 1.0 && t2 > 1.0)) {
515 if (collide_cat.is_debug()) {
524 if (t1 < (1.0 - t2)) {
529 new_entry->set_interior_point(from_origin + std::min(std::max(t2, 0.0), 1.0) * from_direction);
531 LPoint3 point = from_origin + t1 * from_direction;
532 new_entry->set_surface_point(point);
538 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
539 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
540 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
543 new_entry->set_surface_normal(normal);
553 test_intersection_from_capsule(
const CollisionEntry &entry)
const {
555 DCAST_INTO_R(capsule, entry.
get_from(),
nullptr);
557 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
559 LPoint3 from_a = capsule->get_point_a() * wrt_mat;
560 LPoint3 from_b = capsule->get_point_b() * wrt_mat;
561 LVector3 from_direction = from_b - from_a;
562 PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, capsule->get_radius())).length_squared();
563 PN_stdfloat radius = csqrt(radius_sq);
565 LPoint3 box_min = get_min();
566 LPoint3 box_max = get_max();
567 LVector3 dimensions = box_max - box_min;
576 if (!intersects_line(t1, t2, from_a, from_direction, radius)) {
580 if (t2 < 0.0 || t1 > 1.0) {
584 t1 = std::min(1.0, std::max(0.0, (t1 + t2) * 0.5));
585 LPoint3 point = from_a + from_direction * t1;
592 if ((point[0] < box_min[0] || point[0] > box_max[0]) +
593 (point[1] < box_min[1] || point[1] > box_max[1]) +
594 (point[2] < box_min[2] || point[2] > box_max[2]) > 1) {
596 static const struct {
614 PN_stdfloat best_dist_sq = FLT_MAX;
616 for (
int i = 0; i < 12; ++i) {
617 LPoint3 vertex = edges[i].point;
618 vertex.componentwise_mult(dimensions);
621 delta[edges[i].axis] = dimensions[edges[i].axis];
623 CollisionCapsule::calc_closest_segment_points(u1, u2, from_a, from_direction, vertex, delta);
624 PN_stdfloat dist_sq = ((from_a + from_direction * u1) - (vertex + delta * u2)).length_squared();
625 if (dist_sq < best_dist_sq) {
626 best_dist_sq = dist_sq;
630 if (best_dist_sq > radius_sq) {
636 if (collide_cat.is_debug()) {
644 LVector3 diff = point - _center;
645 diff[0] /= dimensions[0];
646 diff[1] /= dimensions[1];
647 diff[2] /= dimensions[2];
649 if (cabs(diff[0]) > cabs(diff[1])) {
650 if (cabs(diff[0]) > cabs(diff[2])) {
656 if (cabs(diff[1]) > cabs(diff[2])) {
663 normal[axis] = std::copysign(1, diff[axis]);
665 LPoint3 clamped = point.fmax(box_min).fmin(box_max);
666 LPoint3 surface_point = clamped;
667 surface_point[axis] = (diff[axis] >= 0.0f) ? box_max[axis] : box_min[axis];
670 LVector3 interior_vec;
671 if (clamped != point) {
674 interior_vec = point - surface_point;
675 if (!interior_vec.normalize()) {
676 interior_vec = normal;
680 interior_vec = normal;
682 new_entry->set_interior_point(point - interior_vec * radius);
683 new_entry->set_surface_point(surface_point);
688 new_entry->set_surface_normal(normal);
700 DCAST_INTO_R(box, entry.
get_from(),
nullptr);
702 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
704 LPoint3 diff = wrt_mat.xform_point_general(box->get_center()) - _center;
705 LVector3 from_extents = box->get_dimensions() * 0.5f;
706 LVector3 into_extents = get_dimensions() * 0.5f;
708 LVecBase3 box_x = wrt_mat.get_row3(0);
709 LVecBase3 box_y = wrt_mat.get_row3(1);
710 LVecBase3 box_z = wrt_mat.get_row3(2);
718 from_extents[0] *= l;
721 from_extents[1] *= l;
724 from_extents[2] *= l;
728 PN_stdfloat min_pen = 0;
733 r1 = into_extents[0];
734 r2 = cabs(box_x[0] * from_extents[0]) +
735 cabs(box_y[0] * from_extents[1]) +
736 cabs(box_z[0] * from_extents[2]);
737 pen = r1 + r2 - cabs(diff[0]);
743 r1 = into_extents[1];
744 r2 = cabs(box_x[1] * from_extents[0]) +
745 cabs(box_y[1] * from_extents[1]) +
746 cabs(box_z[1] * from_extents[2]);
747 pen = r1 + r2 - cabs(diff[1]);
756 r1 = into_extents[2];
757 r2 = cabs(box_x[2] * from_extents[0]) +
758 cabs(box_y[2] * from_extents[1]) +
759 cabs(box_z[2] * from_extents[2]);
760 pen = r1 + r2 - cabs(diff[2]);
770 r1 = cabs(box_x[0] * into_extents[0]) +
771 cabs(box_x[1] * into_extents[1]) +
772 cabs(box_x[2] * into_extents[2]);
773 r2 = from_extents[0];
774 pen = r1 + r2 - cabs(diff.dot(box_x));
782 r1 = cabs(box_y[0] * into_extents[0]) +
783 cabs(box_y[1] * into_extents[1]) +
784 cabs(box_y[2] * into_extents[2]);
785 r2 = from_extents[1];
786 pen = r1 + r2 - cabs(diff.dot(box_y));
794 r1 = cabs(box_z[0] * into_extents[0]) +
795 cabs(box_z[1] * into_extents[1]) +
796 cabs(box_z[2] * into_extents[2]);
797 r2 = from_extents[2];
798 pen = r1 + r2 - cabs(diff.dot(box_z));
807 r1 = into_extents[1] * cabs(box_x[2]) + into_extents[2] * cabs(box_x[1]);
808 r2 = from_extents[1] * cabs(box_z[0]) + from_extents[2] * cabs(box_y[0]);
809 if (cabs(diff[2] * box_x[1] - diff[1] * box_x[2]) > r1 + r2) {
813 r1 = into_extents[1] * cabs(box_y[2]) + into_extents[2] * cabs(box_y[1]);
814 r2 = from_extents[0] * cabs(box_z[0]) + from_extents[2] * cabs(box_x[0]);
815 if (cabs(diff[2] * box_y[1] - diff[1] * box_y[2]) > r1 + r2) {
819 r1 = into_extents[1] * cabs(box_z[2]) + into_extents[2] * cabs(box_z[1]);
820 r2 = from_extents[0] * cabs(box_y[0]) + from_extents[1] * cabs(box_x[0]);
821 if (cabs(diff[2] * box_z[1] - diff[1] * box_z[2]) > r1 + r2) {
825 r1 = into_extents[0] * cabs(box_x[2]) + into_extents[2] * cabs(box_x[0]);
826 r2 = from_extents[1] * cabs(box_z[1]) + from_extents[2] * cabs(box_y[1]);
827 if (cabs(diff[0] * box_x[2] - diff[2] * box_x[0]) > r1 + r2) {
831 r1 = into_extents[0] * cabs(box_y[2]) + into_extents[2] * cabs(box_y[0]);
832 r2 = from_extents[0] * cabs(box_z[1]) + from_extents[2] * cabs(box_x[1]);
833 if (cabs(diff[0] * box_y[2] - diff[2] * box_y[0]) > r1 + r2) {
837 r1 = into_extents[0] * cabs(box_z[2]) + into_extents[2] * cabs(box_z[0]);
838 r2 = from_extents[0] * cabs(box_y[1]) + from_extents[1] * cabs(box_x[1]);
839 if (cabs(diff[0] * box_z[2] - diff[2] * box_z[0]) > r1 + r2) {
843 r1 = into_extents[0] * cabs(box_x[1]) + into_extents[1] * cabs(box_x[0]);
844 r2 = from_extents[1] * cabs(box_z[2]) + from_extents[2] * cabs(box_y[2]);
845 if (cabs(diff[1] * box_x[0] - diff[0] * box_x[1]) > r1 + r2) {
849 r1 = into_extents[0] * cabs(box_y[1]) + into_extents[1] * cabs(box_y[0]);
850 r2 = from_extents[0] * cabs(box_z[2]) + from_extents[2] * cabs(box_x[2]);
851 if (cabs(diff[1] * box_y[0] - diff[0] * box_y[1]) > r1 + r2) {
855 r1 = into_extents[0] * cabs(box_z[1]) + into_extents[1] * cabs(box_z[0]);
856 r2 = from_extents[0] * cabs(box_y[2]) + from_extents[1] * cabs(box_x[2]);
857 if (cabs(diff[1] * box_z[0] - diff[0] * box_z[1]) > r1 + r2) {
861 if (collide_cat.is_debug()) {
871 min(max(diff[0], -into_extents[0]), into_extents[0]),
872 min(max(diff[1], -into_extents[1]), into_extents[1]),
873 min(max(diff[2], -into_extents[2]), into_extents[2]));
877 PN_stdfloat diff_axis = diff[axis];
878 int sign = (diff_axis >= 0) ? 1 : -1;
880 surface[axis] = into_extents[axis] * sign;
882 new_entry->set_surface_point(surface + _center);
885 new_entry->set_interior_point(surface + _center + normal * -min_pen);
890 new_entry->set_surface_normal(normal);
902 if (collide_cat.is_debug()) {
904 <<
"Recomputing viz for " << *
this <<
"\n";
911 vdata->unclean_set_num_rows(8);
915 vertex.set_data3(_min[0], _min[1], _min[2]);
916 vertex.set_data3(_min[0], _max[1], _min[2]);
917 vertex.set_data3(_max[0], _max[1], _min[2]);
918 vertex.set_data3(_max[0], _min[1], _min[2]);
920 vertex.set_data3(_min[0], _min[1], _max[2]);
921 vertex.set_data3(_min[0], _max[1], _max[2]);
922 vertex.set_data3(_max[0], _max[1], _max[2]);
923 vertex.set_data3(_max[0], _min[1], _max[2]);
929 tris->add_vertices(0, 1, 2);
930 tris->add_vertices(2, 3, 0);
933 tris->add_vertices(4, 7, 6);
934 tris->add_vertices(6, 5, 4);
937 tris->add_vertices(0, 4, 1);
938 tris->add_vertices(1, 4, 5);
940 tris->add_vertices(1, 5, 2);
941 tris->add_vertices(2, 5, 6);
943 tris->add_vertices(2, 6, 3);
944 tris->add_vertices(3, 6, 7);
946 tris->add_vertices(3, 7, 0);
947 tris->add_vertices(0, 7, 4);
950 geom->add_primitive(tris);
952 _viz_geom->add_geom(geom, get_solid_viz_state());
953 _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
965 intersects_line(
double &t1,
double &t2,
966 const LPoint3 &from,
const LVector3 &delta,
967 PN_stdfloat inflate_size)
const {
969 LPoint3 bmin = _min - LVector3(inflate_size);
970 LPoint3 bmax = _max + LVector3(inflate_size);
972 double tmin = -DBL_MAX;
973 double tmax = DBL_MAX;
975 for (
int i = 0; i < 3; ++i) {
976 PN_stdfloat d = delta[i];
977 if (!IS_NEARLY_ZERO(d)) {
978 double tmin2 = (bmin[i] - from[i]) / d;
979 double tmax2 = (bmax[i] - from[i]) / d;
981 std::swap(tmin2, tmax2);
983 tmin = std::max(tmin, tmin2);
984 tmax = std::min(tmax, tmax2);
990 }
else if (from[i] < bmin[i] || from[i] > bmax[i]) {
1015 bool first_plane =
true;
1017 for (
int i = 0; i < num_planes; i++) {
1022 net_transform->invert_compose(plane_path.get_net_transform());
1024 LPlane plane = plane_node->
get_plane() * new_transform->get_mat();
1026 first_plane =
false;
1027 if (!
clip_polygon(new_points, _points[plane_no], plane, plane_no)) {
1032 last_points.swap(new_points);
1033 if (!
clip_polygon(new_points, last_points, plane, plane_no)) {
1057 const LPlane &plane,
int plane_no)
const {
1059 if (source_points.empty()) {
1065 if (!plane.intersects_plane(from3d, delta3d,
get_plane(plane_no))) {
1071 new_points = source_points;
1079 LPoint2 from2d =
to_2d(from3d,plane_no);
1080 LVector2 delta2d =
to_2d(delta3d,plane_no);
1082 PN_stdfloat a = -delta2d[1];
1083 PN_stdfloat b = delta2d[0];
1084 PN_stdfloat c = from2d[0] * delta2d[1] - from2d[1] * delta2d[0];
1092 new_points.reserve(source_points.size() + 1);
1094 LPoint2 last_point = source_points.back()._p;
1095 bool last_is_in = !is_right(last_point - from2d, delta2d);
1096 bool all_in = last_is_in;
1097 Points::const_iterator pi;
1098 for (pi = source_points.begin(); pi != source_points.end(); ++pi) {
1099 const LPoint2 &this_point = (*pi)._p;
1100 bool this_is_in = !is_right(this_point - from2d, delta2d);
1104 bool crossed_over = (this_is_in != last_is_in);
1108 LVector2 d = this_point - last_point;
1109 PN_stdfloat denom = (a * d[0] + b * d[1]);
1111 PN_stdfloat t = -(a * last_point[0] + b * last_point[1] + c) / denom;
1112 LPoint2 p = last_point + t * d;
1114 new_points.push_back(
PointDef(p[0], p[1]));
1115 last_is_in = this_is_in;
1121 new_points.push_back(
PointDef(this_point[0], this_point[1]));
1126 last_point = this_point;
1149 bool got_dist =
false;
1150 PN_stdfloat best_dist = -1.0f;
1152 size_t num_points = points.size();
1153 for (
size_t i = 0; i < num_points - 1; ++i) {
1154 PN_stdfloat d = dist_to_line_segment(p, points[i]._p, points[i + 1]._p,
1157 if (!got_dist || d < best_dist) {
1164 PN_stdfloat d = dist_to_line_segment(p, points[num_points - 1]._p, points[0]._p,
1165 points[num_points - 1]._v);
1167 if (!got_dist || d < best_dist) {
1184 PN_stdfloat CollisionBox::
1185 dist_to_line_segment(
const LPoint2 &p,
1186 const LPoint2 &f,
const LPoint2 &t,
1187 const LVector2 &v) {
1188 LVector2 v1 = (p - f);
1189 PN_stdfloat d = (v1[0] * v[1] - v1[1] * v[0]);
1195 LPoint2 q = p + LVector2(-v[1], v[0]) * d;
1205 return (p - f).length();
1206 }
if (q[0] > t[0]) {
1207 return (p - t).length();
1214 return (p - f).length();
1215 }
if (q[1] > t[1]) {
1216 return (p - t).length();
1226 return (p - f).length();
1227 }
if (q[0] > t[0]) {
1228 return (p - t).length();
1235 return (p - f).length();
1236 }
if (q[1] < t[1]) {
1237 return (p - t).length();
1250 return (p - f).length();
1251 }
if (q[0] < t[0]) {
1252 return (p - t).length();
1259 return (p - f).length();
1260 }
if (q[1] > t[1]) {
1261 return (p - t).length();
1268 if (-v[0] > -v[1]) {
1271 return (p - f).length();
1272 }
if (q[0] < t[0]) {
1273 return (p - t).length();
1280 return (p - f).length();
1281 }
if (q[1] < t[1]) {
1282 return (p - t).length();
1301 for (
int i = 0; i < (int)points.size() - 1; i++) {
1302 if (is_right(p - points[i]._p, points[i+1]._p - points[i]._p)) {
1306 if (is_right(p - points[points.size() - 1]._p,
1307 points[0]._p - points[points.size() - 1]._p)) {
1320 size_t num_points = points.size();
1321 for (
size_t i = 0; i < num_points; i++) {
1322 points[i]._v = points[(i + 1) % num_points]._p - points[i]._p;
1323 points[i]._v.normalize();
1342 _center.write_datagram(me);
1343 _min.write_datagram(me);
1344 _max.write_datagram(me);
1345 for(
int i=0; i < 8; i++) {
1346 _vertex[i].write_datagram(me);
1352 for(
int i=0; i < 6; i++) {
1353 _planes[i].write_datagram(me);
1355 for(
int i=0; i < 6; i++) {
1356 _to_2d_mat[i].write_datagram(me);
1358 for(
int i=0; i < 6; i++) {
1360 for (
size_t j = 0; j < _points[i].size(); j++) {
1361 _points[i][j]._p.write_datagram(me);
1362 _points[i][j]._v.write_datagram(me);
1377 me->fillin(scan, manager);
1388 CollisionSolid::fillin(scan, manager);
1389 _center.read_datagram(scan);
1390 _min.read_datagram(scan);
1391 _max.read_datagram(scan);
1392 for(
int i=0; i < 8; i++) {
1393 _vertex[i].read_datagram(scan);
1399 for(
int i=0; i < 6; i++) {
1400 _planes[i].read_datagram(scan);
1402 for(
int i=0; i < 6; i++) {
1403 _to_2d_mat[i].read_datagram(scan);
1405 for(
int i=0; i < 6; i++) {
1407 for (
size_t j = 0; j < size; j++) {
1410 p.read_datagram(scan);
1411 v.read_datagram(scan);
1412 _points[i].push_back(PointDef(p, v));
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 ...
const LVector3 & get_effective_normal() const
Returns the normal that was set by set_effective_normal().
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
get_from_node_path
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
void setup_box()
Compute parameters for each of the box's sides.
An infinite ray, with a specific origin and direction.
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.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
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...
The abstract base class for all things that can collide with other things in the world,...
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.
This defines a bounding sphere, consisting of a center and a radius.
A cuboid collision volume or object.
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This functions similarly to a LightAttrib.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
A spherical collision volume or object.
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 ...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_into_node_path
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
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 ...
get_respect_effective_normal
See set_respect_effective_normal().
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
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.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
A finite line segment, with two specific endpoints but no thickness.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void register_with_read_factory()
Factory method to generate a CollisionBox object.
void setup_points(const LPoint3 *begin, const LPoint3 *end, int plane)
Computes the plane and 2d projection of points that make up this side.
const LPlane & get_plane() const
Returns the plane represented by the PlaneNode.
get_num_on_planes
Returns the number of planes that are enabled by the attribute.
Defines a single collision event.
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...
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...
This implements a solid consisting of a cylinder with hemispherical endcaps, also known as a capsule ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
PT(CollisionEntry) CollisionBox
First Dispatch point for box as a FROM object.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
LPlane set_plane(int n) const
Creates the nth face of the rectangular solid.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LPlane get_plane(int n) const
Returns the nth face of the rectangular solid.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An infinite line, similar to a CollisionRay, except that it extends in both directions.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
PandaNode * node() const
Returns the referenced node of the path.
get_into
Returns the CollisionSolid pointer for the particular solid was collided into.
get_on_plane
Returns the nth plane enabled by the attribute, sorted in render order.
get_from
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines a series of disconnected triangles.
LPoint3 get_point(int n) const
Returns the nth vertex of the OBB.
bool has_effective_normal() const
Returns true if a special normal was set by set_effective_normal(), false otherwise.
A class to retrieve the individual data elements previously stored in a Datagram.
TypeHandle is the identifier used to differentiate C++ class types.
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
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...
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 contains a plane.
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 PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
int get_clip_effect() const
Returns the clip_effect bits for this clip plane.