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 {
189 out <<
"box, (" << get_min() <<
") to (" << get_max() <<
")";
196 compute_internal_bounds()
const {
204 test_intersection_from_sphere(
const CollisionEntry &entry)
const {
207 DCAST_INTO_R(sphere, entry.
get_from(),
nullptr);
212 const LMatrix4 &wrt_mat = wrt_space->get_mat();
214 LPoint3 orig_center = sphere->get_center() * wrt_mat;
215 LPoint3 from_center = orig_center;
216 bool moved_from_center =
false;
217 PN_stdfloat t = 1.0f;
218 LPoint3 contact_point(from_center);
219 PN_stdfloat actual_t = 1.0f;
221 LVector3 from_radius_v =
222 LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
223 PN_stdfloat from_radius_2 = from_radius_v.length_squared();
224 PN_stdfloat from_radius = csqrt(from_radius_2);
227 PN_stdfloat max_dist = 0.0;
228 PN_stdfloat dist = 0.0;
233 for(ip = 0, intersect =
false; ip < 6 && !intersect; ip++) {
235 if (_points[ip].size() < 3) {
238 if (wrt_prev_space != wrt_space) {
242 LPoint3 b = from_center;
243 LPoint3 a = sphere->get_center() * wrt_prev_space->get_mat();
244 LVector3 delta = b - a;
248 PN_stdfloat dot = delta.dot(plane.get_normal());
253 if (IS_NEARLY_ZERO(dot)) {
266 PN_stdfloat dist_to_p = plane.dist_to_plane(a);
267 t = (dist_to_p / -dot);
271 actual_t = ((dist_to_p - from_radius) / -dot);
272 actual_t = min((PN_stdfloat)1.0, max((PN_stdfloat)0.0, actual_t));
273 contact_point = a + (actual_t * delta);
278 }
else if (t < 0.0f) {
280 moved_from_center =
true;
282 from_center = a + t * delta;
283 moved_from_center =
true;
303 if (!plane.intersects_line(dist, from_center, -(plane.get_normal()))) {
309 if (dist > from_radius || dist < -from_radius) {
314 LPoint2 p =
to_2d(from_center - dist * plane.get_normal(), ip);
315 PN_stdfloat edge_dist = 0.0f;
318 if (cpa !=
nullptr) {
324 }
else if (new_points.empty()) {
336 max_dist = from_radius;
346 if((edge_dist > 0) &&
347 ((edge_dist * edge_dist + dist * dist) > from_radius_2)) {
357 if (edge_dist >= 0.0f) {
358 PN_stdfloat max_dist_2 = max(from_radius_2 - edge_dist * edge_dist, (PN_stdfloat)0.0);
359 max_dist = csqrt(max_dist_2);
362 if (dist > max_dist) {
371 if (collide_cat.is_debug()) {
379 PN_stdfloat into_depth = max_dist - dist;
380 if (moved_from_center) {
383 PN_stdfloat orig_dist;
384 plane.intersects_line(orig_dist, orig_center, -normal);
385 into_depth = max_dist - orig_dist;
389 LPoint3 surface = from_center - normal * dist;
390 surface = surface.fmax(_min);
391 surface = surface.fmin(_max);
393 new_entry->set_surface_normal(normal);
394 new_entry->set_surface_point(surface);
395 new_entry->set_interior_point(surface - normal * into_depth);
396 new_entry->set_contact_pos(contact_point);
397 new_entry->set_contact_normal(plane.get_normal());
398 new_entry->set_t(actual_t);
409 DCAST_INTO_R(line, entry.
get_from(),
nullptr);
411 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
413 LPoint3 from_origin = line->get_origin() * wrt_mat;
414 LVector3 from_direction = line->get_direction() * wrt_mat;
417 if (!intersects_line(t1, t2, from_origin, from_direction)) {
422 if (collide_cat.is_debug()) {
429 LPoint3 point = from_origin + t1 * from_direction;
430 new_entry->set_surface_point(point);
436 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
437 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
438 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
441 new_entry->set_surface_normal(normal);
453 DCAST_INTO_R(ray, entry.
get_from(),
nullptr);
454 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
456 LPoint3 from_origin = ray->get_origin() * wrt_mat;
457 LVector3 from_direction = ray->get_direction() * wrt_mat;
460 if (!intersects_line(t1, t2, from_origin, from_direction) || (t1 < 0.0 && t2 < 0.0)) {
465 if (collide_cat.is_debug()) {
474 new_entry->set_interior_point(from_origin);
478 LPoint3 point = from_origin + t1 * from_direction;
479 new_entry->set_surface_point(point);
485 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
486 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
487 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
490 new_entry->set_surface_normal(normal);
500 test_intersection_from_segment(
const CollisionEntry &entry)
const {
502 DCAST_INTO_R(seg, entry.
get_from(),
nullptr);
503 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
505 LPoint3 from_origin = seg->get_point_a() * wrt_mat;
506 LPoint3 from_extent = seg->get_point_b() * wrt_mat;
507 LVector3 from_direction = from_extent - from_origin;
510 if (!intersects_line(t1, t2, from_origin, from_direction) ||
511 (t1 < 0.0 && t2 < 0.0) || (t1 > 1.0 && t2 > 1.0)) {
516 if (collide_cat.is_debug()) {
525 if (t1 < (1.0 - t2)) {
530 new_entry->set_interior_point(from_origin + std::min(std::max(t2, 0.0), 1.0) * from_direction);
532 LPoint3 point = from_origin + t1 * from_direction;
533 new_entry->set_surface_point(point);
539 IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]),
540 IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]),
541 IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2])
544 new_entry->set_surface_normal(normal);
554 test_intersection_from_capsule(
const CollisionEntry &entry)
const {
556 DCAST_INTO_R(capsule, entry.
get_from(),
nullptr);
558 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
560 LPoint3 from_a = capsule->get_point_a() * wrt_mat;
561 LPoint3 from_b = capsule->get_point_b() * wrt_mat;
562 LVector3 from_direction = from_b - from_a;
563 PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, capsule->get_radius())).length_squared();
564 PN_stdfloat radius = csqrt(radius_sq);
566 LPoint3 box_min = get_min();
567 LPoint3 box_max = get_max();
568 LVector3 dimensions = box_max - box_min;
577 if (!intersects_line(t1, t2, from_a, from_direction, radius)) {
581 if (t2 < 0.0 || t1 > 1.0) {
585 t1 = std::min(1.0, std::max(0.0, (t1 + t2) * 0.5));
586 LPoint3 point = from_a + from_direction * t1;
593 if ((point[0] < box_min[0] || point[0] > box_max[0]) +
594 (point[1] < box_min[1] || point[1] > box_max[1]) +
595 (point[2] < box_min[2] || point[2] > box_max[2]) > 1) {
597 static const struct {
615 PN_stdfloat best_dist_sq = FLT_MAX;
617 for (
int i = 0; i < 12; ++i) {
618 LPoint3 vertex = edges[i].point;
619 vertex.componentwise_mult(dimensions);
622 delta[edges[i].axis] = dimensions[edges[i].axis];
624 CollisionCapsule::calc_closest_segment_points(u1, u2, from_a, from_direction, vertex, delta);
625 PN_stdfloat dist_sq = ((from_a + from_direction * u1) - (vertex + delta * u2)).length_squared();
626 if (dist_sq < best_dist_sq) {
627 best_dist_sq = dist_sq;
631 if (best_dist_sq > radius_sq) {
637 if (collide_cat.is_debug()) {
645 LVector3 diff = point - _center;
646 diff[0] /= dimensions[0];
647 diff[1] /= dimensions[1];
648 diff[2] /= dimensions[2];
650 if (cabs(diff[0]) > cabs(diff[1])) {
651 if (cabs(diff[0]) > cabs(diff[2])) {
657 if (cabs(diff[1]) > cabs(diff[2])) {
664 normal[axis] = std::copysign(1, diff[axis]);
666 LPoint3 clamped = point.fmax(box_min).fmin(box_max);
667 LPoint3 surface_point = clamped;
668 surface_point[axis] = (diff[axis] >= 0.0f) ? box_max[axis] : box_min[axis];
671 LVector3 interior_vec;
672 if (clamped != point) {
675 interior_vec = point - surface_point;
676 if (!interior_vec.normalize()) {
677 interior_vec = normal;
681 interior_vec = normal;
683 new_entry->set_interior_point(point - interior_vec * radius);
684 new_entry->set_surface_point(surface_point);
689 new_entry->set_surface_normal(normal);
701 DCAST_INTO_R(box, entry.
get_from(),
nullptr);
703 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
705 LPoint3 diff = wrt_mat.xform_point_general(box->get_center()) - _center;
706 LVector3 from_extents = box->get_dimensions() * 0.5f;
707 LVector3 into_extents = get_dimensions() * 0.5f;
709 LVecBase3 box_x = wrt_mat.get_row3(0);
710 LVecBase3 box_y = wrt_mat.get_row3(1);
711 LVecBase3 box_z = wrt_mat.get_row3(2);
719 from_extents[0] *= l;
722 from_extents[1] *= l;
725 from_extents[2] *= l;
729 PN_stdfloat min_pen = 0;
734 r1 = into_extents[0];
735 r2 = cabs(box_x[0] * from_extents[0]) +
736 cabs(box_y[0] * from_extents[1]) +
737 cabs(box_z[0] * from_extents[2]);
738 pen = r1 + r2 - cabs(diff[0]);
744 r1 = into_extents[1];
745 r2 = cabs(box_x[1] * from_extents[0]) +
746 cabs(box_y[1] * from_extents[1]) +
747 cabs(box_z[1] * from_extents[2]);
748 pen = r1 + r2 - cabs(diff[1]);
757 r1 = into_extents[2];
758 r2 = cabs(box_x[2] * from_extents[0]) +
759 cabs(box_y[2] * from_extents[1]) +
760 cabs(box_z[2] * from_extents[2]);
761 pen = r1 + r2 - cabs(diff[2]);
771 r1 = cabs(box_x[0] * into_extents[0]) +
772 cabs(box_x[1] * into_extents[1]) +
773 cabs(box_x[2] * into_extents[2]);
774 r2 = from_extents[0];
775 pen = r1 + r2 - cabs(diff.dot(box_x));
783 r1 = cabs(box_y[0] * into_extents[0]) +
784 cabs(box_y[1] * into_extents[1]) +
785 cabs(box_y[2] * into_extents[2]);
786 r2 = from_extents[1];
787 pen = r1 + r2 - cabs(diff.dot(box_y));
795 r1 = cabs(box_z[0] * into_extents[0]) +
796 cabs(box_z[1] * into_extents[1]) +
797 cabs(box_z[2] * into_extents[2]);
798 r2 = from_extents[2];
799 pen = r1 + r2 - cabs(diff.dot(box_z));
808 r1 = into_extents[1] * cabs(box_x[2]) + into_extents[2] * cabs(box_x[1]);
809 r2 = from_extents[1] * cabs(box_z[0]) + from_extents[2] * cabs(box_y[0]);
810 if (cabs(diff[2] * box_x[1] - diff[1] * box_x[2]) > r1 + r2) {
814 r1 = into_extents[1] * cabs(box_y[2]) + into_extents[2] * cabs(box_y[1]);
815 r2 = from_extents[0] * cabs(box_z[0]) + from_extents[2] * cabs(box_x[0]);
816 if (cabs(diff[2] * box_y[1] - diff[1] * box_y[2]) > r1 + r2) {
820 r1 = into_extents[1] * cabs(box_z[2]) + into_extents[2] * cabs(box_z[1]);
821 r2 = from_extents[0] * cabs(box_y[0]) + from_extents[1] * cabs(box_x[0]);
822 if (cabs(diff[2] * box_z[1] - diff[1] * box_z[2]) > r1 + r2) {
826 r1 = into_extents[0] * cabs(box_x[2]) + into_extents[2] * cabs(box_x[0]);
827 r2 = from_extents[1] * cabs(box_z[1]) + from_extents[2] * cabs(box_y[1]);
828 if (cabs(diff[0] * box_x[2] - diff[2] * box_x[0]) > r1 + r2) {
832 r1 = into_extents[0] * cabs(box_y[2]) + into_extents[2] * cabs(box_y[0]);
833 r2 = from_extents[0] * cabs(box_z[1]) + from_extents[2] * cabs(box_x[1]);
834 if (cabs(diff[0] * box_y[2] - diff[2] * box_y[0]) > r1 + r2) {
838 r1 = into_extents[0] * cabs(box_z[2]) + into_extents[2] * cabs(box_z[0]);
839 r2 = from_extents[0] * cabs(box_y[1]) + from_extents[1] * cabs(box_x[1]);
840 if (cabs(diff[0] * box_z[2] - diff[2] * box_z[0]) > r1 + r2) {
844 r1 = into_extents[0] * cabs(box_x[1]) + into_extents[1] * cabs(box_x[0]);
845 r2 = from_extents[1] * cabs(box_z[2]) + from_extents[2] * cabs(box_y[2]);
846 if (cabs(diff[1] * box_x[0] - diff[0] * box_x[1]) > r1 + r2) {
850 r1 = into_extents[0] * cabs(box_y[1]) + into_extents[1] * cabs(box_y[0]);
851 r2 = from_extents[0] * cabs(box_z[2]) + from_extents[2] * cabs(box_x[2]);
852 if (cabs(diff[1] * box_y[0] - diff[0] * box_y[1]) > r1 + r2) {
856 r1 = into_extents[0] * cabs(box_z[1]) + into_extents[1] * cabs(box_z[0]);
857 r2 = from_extents[0] * cabs(box_y[2]) + from_extents[1] * cabs(box_x[2]);
858 if (cabs(diff[1] * box_z[0] - diff[0] * box_z[1]) > r1 + r2) {
862 if (collide_cat.is_debug()) {
872 min(max(diff[0], -into_extents[0]), into_extents[0]),
873 min(max(diff[1], -into_extents[1]), into_extents[1]),
874 min(max(diff[2], -into_extents[2]), into_extents[2]));
878 PN_stdfloat diff_axis = diff[axis];
879 int sign = (diff_axis >= 0) ? 1 : -1;
881 surface[axis] = into_extents[axis] * sign;
883 new_entry->set_surface_point(surface + _center);
886 new_entry->set_interior_point(surface + _center + normal * -min_pen);
891 new_entry->set_surface_normal(normal);
903 if (collide_cat.is_debug()) {
905 <<
"Recomputing viz for " << *
this <<
"\n";
912 vdata->unclean_set_num_rows(8);
916 vertex.set_data3(_min[0], _min[1], _min[2]);
917 vertex.set_data3(_min[0], _max[1], _min[2]);
918 vertex.set_data3(_max[0], _max[1], _min[2]);
919 vertex.set_data3(_max[0], _min[1], _min[2]);
921 vertex.set_data3(_min[0], _min[1], _max[2]);
922 vertex.set_data3(_min[0], _max[1], _max[2]);
923 vertex.set_data3(_max[0], _max[1], _max[2]);
924 vertex.set_data3(_max[0], _min[1], _max[2]);
930 tris->add_vertices(0, 1, 2);
931 tris->add_vertices(2, 3, 0);
934 tris->add_vertices(4, 7, 6);
935 tris->add_vertices(6, 5, 4);
938 tris->add_vertices(0, 4, 1);
939 tris->add_vertices(1, 4, 5);
941 tris->add_vertices(1, 5, 2);
942 tris->add_vertices(2, 5, 6);
944 tris->add_vertices(2, 6, 3);
945 tris->add_vertices(3, 6, 7);
947 tris->add_vertices(3, 7, 0);
948 tris->add_vertices(0, 7, 4);
951 geom->add_primitive(tris);
953 _viz_geom->add_geom(geom, get_solid_viz_state());
954 _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
966 intersects_line(
double &t1,
double &t2,
967 const LPoint3 &from,
const LVector3 &delta,
968 PN_stdfloat inflate_size)
const {
970 LPoint3 bmin = _min - LVector3(inflate_size);
971 LPoint3 bmax = _max + LVector3(inflate_size);
973 double tmin = -DBL_MAX;
974 double tmax = DBL_MAX;
976 for (
int i = 0; i < 3; ++i) {
977 PN_stdfloat d = delta[i];
978 if (!IS_NEARLY_ZERO(d)) {
979 double tmin2 = (bmin[i] - from[i]) / d;
980 double tmax2 = (bmax[i] - from[i]) / d;
982 std::swap(tmin2, tmax2);
984 tmin = std::max(tmin, tmin2);
985 tmax = std::min(tmax, tmax2);
991 }
else if (from[i] < bmin[i] || from[i] > bmax[i]) {
1016 bool first_plane =
true;
1018 for (
int i = 0; i < num_planes; i++) {
1023 net_transform->invert_compose(plane_path.get_net_transform());
1025 LPlane plane = plane_node->
get_plane() * new_transform->get_mat();
1027 first_plane =
false;
1028 if (!
clip_polygon(new_points, _points[plane_no], plane, plane_no)) {
1033 last_points.swap(new_points);
1034 if (!
clip_polygon(new_points, last_points, plane, plane_no)) {
1058 const LPlane &plane,
int plane_no)
const {
1060 if (source_points.empty()) {
1066 if (!plane.intersects_plane(from3d, delta3d,
get_plane(plane_no))) {
1072 new_points = source_points;
1080 LPoint2 from2d =
to_2d(from3d,plane_no);
1081 LVector2 delta2d =
to_2d(delta3d,plane_no);
1083 PN_stdfloat a = -delta2d[1];
1084 PN_stdfloat b = delta2d[0];
1085 PN_stdfloat c = from2d[0] * delta2d[1] - from2d[1] * delta2d[0];
1093 new_points.reserve(source_points.size() + 1);
1095 LPoint2 last_point = source_points.back()._p;
1096 bool last_is_in = !is_right(last_point - from2d, delta2d);
1097 bool all_in = last_is_in;
1098 Points::const_iterator pi;
1099 for (pi = source_points.begin(); pi != source_points.end(); ++pi) {
1100 const LPoint2 &this_point = (*pi)._p;
1101 bool this_is_in = !is_right(this_point - from2d, delta2d);
1105 bool crossed_over = (this_is_in != last_is_in);
1109 LVector2 d = this_point - last_point;
1110 PN_stdfloat denom = (a * d[0] + b * d[1]);
1112 PN_stdfloat t = -(a * last_point[0] + b * last_point[1] + c) / denom;
1113 LPoint2 p = last_point + t * d;
1115 new_points.push_back(
PointDef(p[0], p[1]));
1116 last_is_in = this_is_in;
1122 new_points.push_back(
PointDef(this_point[0], this_point[1]));
1127 last_point = this_point;
1150 bool got_dist =
false;
1151 PN_stdfloat best_dist = -1.0f;
1153 size_t num_points = points.size();
1154 for (
size_t i = 0; i < num_points - 1; ++i) {
1155 PN_stdfloat d = dist_to_line_segment(p, points[i]._p, points[i + 1]._p,
1158 if (!got_dist || d < best_dist) {
1165 PN_stdfloat d = dist_to_line_segment(p, points[num_points - 1]._p, points[0]._p,
1166 points[num_points - 1]._v);
1168 if (!got_dist || d < best_dist) {
1185 PN_stdfloat CollisionBox::
1186 dist_to_line_segment(
const LPoint2 &p,
1187 const LPoint2 &f,
const LPoint2 &t,
1188 const LVector2 &v) {
1189 LVector2 v1 = (p - f);
1190 PN_stdfloat d = (v1[0] * v[1] - v1[1] * v[0]);
1196 LPoint2 q = p + LVector2(-v[1], v[0]) * d;
1206 return (p - f).length();
1207 }
if (q[0] > t[0]) {
1208 return (p - t).length();
1215 return (p - f).length();
1216 }
if (q[1] > t[1]) {
1217 return (p - t).length();
1227 return (p - f).length();
1228 }
if (q[0] > t[0]) {
1229 return (p - t).length();
1236 return (p - f).length();
1237 }
if (q[1] < t[1]) {
1238 return (p - t).length();
1251 return (p - f).length();
1252 }
if (q[0] < t[0]) {
1253 return (p - t).length();
1260 return (p - f).length();
1261 }
if (q[1] > t[1]) {
1262 return (p - t).length();
1269 if (-v[0] > -v[1]) {
1272 return (p - f).length();
1273 }
if (q[0] < t[0]) {
1274 return (p - t).length();
1281 return (p - f).length();
1282 }
if (q[1] < t[1]) {
1283 return (p - t).length();
1302 for (
int i = 0; i < (int)points.size() - 1; i++) {
1303 if (is_right(p - points[i]._p, points[i+1]._p - points[i]._p)) {
1307 if (is_right(p - points[points.size() - 1]._p,
1308 points[0]._p - points[points.size() - 1]._p)) {
1321 size_t num_points = points.size();
1322 for (
size_t i = 0; i < num_points; i++) {
1323 points[i]._v = points[(i + 1) % num_points]._p - points[i]._p;
1324 points[i]._v.normalize();
1343 _center.write_datagram(me);
1344 _min.write_datagram(me);
1345 _max.write_datagram(me);
1346 for(
int i=0; i < 8; i++) {
1347 _vertex[i].write_datagram(me);
1353 for(
int i=0; i < 6; i++) {
1354 _planes[i].write_datagram(me);
1356 for(
int i=0; i < 6; i++) {
1357 _to_2d_mat[i].write_datagram(me);
1359 for(
int i=0; i < 6; i++) {
1361 for (
size_t j = 0; j < _points[i].size(); j++) {
1362 _points[i][j]._p.write_datagram(me);
1363 _points[i][j]._v.write_datagram(me);
1378 me->fillin(scan, manager);
1389 CollisionSolid::fillin(scan, manager);
1390 _center.read_datagram(scan);
1391 _min.read_datagram(scan);
1392 _max.read_datagram(scan);
1393 for(
int i=0; i < 8; i++) {
1394 _vertex[i].read_datagram(scan);
1400 for(
int i=0; i < 6; i++) {
1401 _planes[i].read_datagram(scan);
1403 for(
int i=0; i < 6; i++) {
1404 _to_2d_mat[i].read_datagram(scan);
1406 for(
int i=0; i < 6; i++) {
1408 for (
size_t j = 0; j < size; j++) {
1411 p.read_datagram(scan);
1412 v.read_datagram(scan);
1413 _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.