47 PStatCollector CollisionPolygon::_volume_pcollector(
"Collision Volumes:CollisionPolygon");
48 PStatCollector CollisionPolygon::_test_pcollector(
"Collision Tests:CollisionPolygon");
57 _points(copy._points),
58 _to_2d_mat(copy._to_2d_mat)
81 int num_points = end - begin;
90 for (pi = begin; pi != end && all_ok; ++pi) {
96 for (pj = begin; pj != pi && all_ok; ++pj) {
108 bool got_normal =
false;
109 for (
int i = 2; i < num_points && !got_normal; i++) {
110 LPlane plane(begin[0], begin[1], begin[i]);
111 LVector3 normal = plane.get_normal();
112 PN_stdfloat normal_length = normal.length();
113 got_normal = IS_THRESHOLD_EQUAL(normal_length, 1.0f, 0.001f);
130 return (_points.size() >= 3);
139 if (_points.size() < 3) {
144 LPoint2 p0 = _points[0]._p;
145 LPoint2 p1 = _points[1]._p;
146 PN_stdfloat dx1 = p1[0] - p0[0];
147 PN_stdfloat dy1 = p1[1] - p0[1];
151 PN_stdfloat dx2 = p1[0] - p0[0];
152 PN_stdfloat dy2 = p1[1] - p0[1];
153 int asum = ((dx1 * dy2 - dx2 * dy1 >= 0.0f) ? 1 : 0);
155 for (
size_t i = 0; i < _points.size() - 1; i++) {
157 p1 = _points[(i+3) % _points.size()]._p;
163 int csum = ((dx1 * dy2 - dx2 * dy1 >= 0.0f) ? 1 : 0);
179 xform(
const LMatrix4 &mat) {
184 if (collide_cat.is_spam()) {
186 <<
"CollisionPolygon transformed by:\n";
187 mat.write(collide_cat.spam(
false), 2);
188 if (_points.empty()) {
189 collide_cat.spam(
false)
194 if (!_points.empty()) {
196 rederive_to_3d_mat(to_3d_mat);
198 epvector<LPoint3> verts;
199 verts.reserve(_points.size());
200 Points::const_iterator pi;
201 for (pi = _points.begin(); pi != _points.end(); ++pi) {
202 verts.push_back(to_3d((*pi)._p, to_3d_mat) * mat);
205 const LPoint3 *verts_begin = &verts[0];
206 const LPoint3 *verts_end = verts_begin + verts.size();
207 setup_points(verts_begin, verts_end);
210 CollisionSolid::xform(mat);
221 rederive_to_3d_mat(to_3d_mat);
223 LPoint2 median = _points[0]._p;
224 for (
int n = 1; n < (int)_points.size(); n++) {
225 median += _points[n]._p;
227 median /= _points.size();
229 return to_3d(median, to_3d_mat);
239 bool bounds_only)
const {
241 if (cpa ==
nullptr) {
244 return CollisionSolid::get_viz(trav, data, bounds_only);
247 if (collide_cat.is_debug()) {
249 <<
"drawing polygon with clip plane " << *cpa <<
"\n";
258 if (apply_clip_plane(new_points, cpa, data.get_net_transform(trav))) {
260 return CollisionSolid::get_viz(trav, data, bounds_only);
263 if (new_points.empty()) {
271 draw_polygon(viz_geom_node, bounds_viz_geom_node, new_points);
274 return bounds_viz_geom_node;
276 return viz_geom_node;
286 return _volume_pcollector;
295 return _test_pcollector;
301 void CollisionPolygon::
302 output(std::ostream &out)
const {
303 out <<
"cpolygon, (" << get_plane()
304 <<
"), " << _points.size() <<
" vertices";
310 void CollisionPolygon::
311 write(std::ostream &out,
int indent_level)
const {
312 indent(out, indent_level) << (*this) <<
"\n";
313 Points::const_iterator pi;
314 for (pi = _points.begin(); pi != _points.end(); ++pi) {
315 indent(out, indent_level + 2) << (*pi)._p <<
"\n";
319 rederive_to_3d_mat(to_3d_mat);
320 out <<
"In 3-d space:\n";
321 for (pi = _points.begin(); pi != _points.end(); ++pi) {
322 LVertex vert = to_3d((*pi)._p, to_3d_mat);
323 indent(out, indent_level + 2) << vert <<
"\n";
331 compute_internal_bounds()
const {
332 if (_points.empty()) {
337 rederive_to_3d_mat(to_3d_mat);
339 Points::const_iterator pi = _points.begin();
340 LPoint3 p = to_3d((*pi)._p, to_3d_mat);
345 for (++pi; pi != _points.end(); ++pi) {
346 p = to_3d((*pi)._p, to_3d_mat);
348 n.set(min(n[0], p[0]),
351 x.set(max(x[0], p[0]),
364 test_intersection_from_sphere(
const CollisionEntry &entry)
const {
365 if (_points.size() < 3) {
370 DCAST_INTO_R(sphere, entry.
get_from(),
nullptr);
375 const LMatrix4 &wrt_mat = wrt_space->get_mat();
377 LPoint3 orig_center = sphere->get_center() * wrt_mat;
378 LPoint3 from_center = orig_center;
379 bool moved_from_center =
false;
380 PN_stdfloat t = 1.0f;
381 LPoint3 contact_point(from_center);
382 PN_stdfloat actual_t = 1.0f;
384 LVector3 from_radius_v =
385 LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
386 PN_stdfloat from_radius_2 = from_radius_v.length_squared();
387 PN_stdfloat from_radius = csqrt(from_radius_2);
389 if (wrt_prev_space != wrt_space) {
393 LPoint3 b = from_center;
394 LPoint3 a = sphere->get_center() * wrt_prev_space->get_mat();
395 LVector3 delta = b - a;
399 PN_stdfloat dot = delta.dot(get_normal());
404 if (IS_NEARLY_ZERO(dot)) {
417 PN_stdfloat dist_to_p = dist_to_plane(a);
418 t = (dist_to_p / -dot);
422 actual_t = ((dist_to_p - from_radius) / -dot);
423 actual_t = min((PN_stdfloat)1.0, max((PN_stdfloat)0.0, actual_t));
424 contact_point = a + (actual_t * delta);
429 }
else if (t < 0.0f) {
431 moved_from_center =
true;
434 from_center = a + t * delta;
435 moved_from_center =
true;
442 if (!IS_THRESHOLD_EQUAL(normal.length_squared(), 1.0f, 0.001)) {
443 if (collide_cat.is_info()) {
446 <<
" has normal " << normal <<
" of length " << normal.length()
456 if (!get_plane().intersects_line(dist, from_center, -get_normal())) {
462 if (dist > from_radius || dist < -from_radius) {
467 LPoint2 p = to_2d(from_center - dist * get_normal());
468 PN_stdfloat edge_dist = 0.0f;
471 if (cpa !=
nullptr) {
474 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
476 edge_dist = dist_to_polygon(p, _points);
478 }
else if (new_points.empty()) {
484 edge_dist = dist_to_polygon(p, new_points);
489 edge_dist = dist_to_polygon(p, _points);
495 if (edge_dist > from_radius) {
505 PN_stdfloat max_dist = from_radius;
506 if (edge_dist >= 0.0f) {
507 PN_stdfloat max_dist_2 = max(from_radius_2 - edge_dist * edge_dist, (PN_stdfloat)0.0);
508 max_dist = csqrt(max_dist_2);
511 if (dist > max_dist || -dist > max_dist) {
516 if (collide_cat.is_debug()) {
523 PN_stdfloat into_depth = max_dist - dist;
524 if (moved_from_center) {
527 PN_stdfloat orig_dist;
528 get_plane().intersects_line(orig_dist, orig_center, -normal);
529 into_depth = max_dist - orig_dist;
532 new_entry->set_surface_normal(normal);
533 new_entry->set_surface_point(from_center - normal * dist);
534 new_entry->set_interior_point(from_center - normal * (dist + into_depth));
535 new_entry->set_contact_pos(contact_point);
536 new_entry->set_contact_normal(get_normal());
537 new_entry->set_t(actual_t);
548 if (_points.size() < 3) {
553 DCAST_INTO_R(line, entry.
get_from(),
nullptr);
555 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
557 LPoint3 from_origin = line->get_origin() * wrt_mat;
558 LVector3 from_direction = line->get_direction() * wrt_mat;
561 if (!get_plane().intersects_line(t, from_origin, from_direction)) {
566 LPoint3 plane_point = from_origin + t * from_direction;
567 LPoint2 p = to_2d(plane_point);
570 if (cpa !=
nullptr) {
573 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
575 if (!point_is_inside(p, _points)) {
580 if (new_points.size() < 3) {
583 if (!point_is_inside(p, new_points)) {
590 if (!point_is_inside(p, _points)) {
595 if (collide_cat.is_debug()) {
604 new_entry->set_surface_normal(normal);
605 new_entry->set_surface_point(plane_point);
616 if (_points.size() < 3) {
621 DCAST_INTO_R(ray, entry.
get_from(),
nullptr);
623 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
625 LPoint3 from_origin = ray->get_origin() * wrt_mat;
626 LVector3 from_direction = ray->get_direction() * wrt_mat;
629 if (!get_plane().intersects_line(t, from_origin, from_direction)) {
639 LPoint3 plane_point = from_origin + t * from_direction;
640 LPoint2 p = to_2d(plane_point);
643 if (cpa !=
nullptr) {
646 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
648 if (!point_is_inside(p, _points)) {
653 if (new_points.size() < 3) {
656 if (!point_is_inside(p, new_points)) {
663 if (!point_is_inside(p, _points)) {
668 if (collide_cat.is_debug()) {
677 new_entry->set_surface_normal(normal);
678 new_entry->set_surface_point(plane_point);
688 test_intersection_from_segment(
const CollisionEntry &entry)
const {
689 if (_points.size() < 3) {
694 DCAST_INTO_R(segment, entry.
get_from(),
nullptr);
696 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
698 LPoint3 from_a = segment->get_point_a() * wrt_mat;
699 LPoint3 from_b = segment->get_point_b() * wrt_mat;
700 LPoint3 from_direction = from_b - from_a;
703 if (!get_plane().intersects_line(t, from_a, from_direction)) {
708 if (t < 0.0f || t > 1.0f) {
714 LPoint3 plane_point = from_a + t * from_direction;
715 LPoint2 p = to_2d(plane_point);
718 if (cpa !=
nullptr) {
721 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
723 if (!point_is_inside(p, _points)) {
728 if (new_points.size() < 3) {
731 if (!point_is_inside(p, new_points)) {
738 if (!point_is_inside(p, _points)) {
743 if (collide_cat.is_debug()) {
752 new_entry->set_surface_normal(normal);
753 new_entry->set_surface_point(plane_point);
763 test_intersection_from_parabola(
const CollisionEntry &entry)
const {
764 if (_points.size() < 3) {
769 DCAST_INTO_R(parabola, entry.
get_from(),
nullptr);
771 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
775 local_p.xform(wrt_mat);
778 if (!get_plane().intersects_parabola(t1, t2, local_p)) {
784 if (t1 >= parabola->
get_t1() && t1 <= parabola->get_t2()) {
785 if (t2 >= parabola->
get_t1() && t2 <= parabola->get_t2()) {
794 }
else if (t2 >= parabola->
get_t1() && t2 <= parabola->get_t2()) {
803 LPoint3 plane_point = local_p.calc_point(t);
804 LPoint2 p = to_2d(plane_point);
807 if (cpa !=
nullptr) {
810 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
812 if (!point_is_inside(p, _points)) {
817 if (new_points.size() < 3) {
820 if (!point_is_inside(p, new_points)) {
827 if (!point_is_inside(p, _points)) {
832 if (collide_cat.is_debug()) {
841 new_entry->set_surface_normal(normal);
842 new_entry->set_surface_point(plane_point);
854 DCAST_INTO_R(box, entry.
get_from(),
nullptr);
858 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
859 LMatrix4 plane_mat = wrt_mat * _to_2d_mat;
861 LPoint3 from_center = box->get_center() * plane_mat;
862 LVector3 from_extents = box->get_dimensions() * 0.5f;
865 LVecBase3 box_x = plane_mat.get_row3(0) * from_extents[0];
866 LVecBase3 box_y = plane_mat.get_row3(1) * from_extents[1];
867 LVecBase3 box_z = plane_mat.get_row3(2) * from_extents[2];
870 if (cabs(from_center[1]) > cabs(box_x[1]) + cabs(box_y[1]) + cabs(box_z[1])) {
876 PN_stdfloat r1, center, r2;
878 r1 = cabs(box_x.dot(box_x)) + cabs(box_y.dot(box_x)) + cabs(box_z.dot(box_x));
879 project(box_x, center, r2);
880 if (cabs(from_center.dot(box_x) - center) > r1 + r2) {
884 r1 = cabs(box_x.dot(box_y)) + cabs(box_y.dot(box_y)) + cabs(box_z.dot(box_y));
885 project(box_y, center, r2);
886 if (cabs(from_center.dot(box_y) - center) > r1 + r2) {
890 r1 = cabs(box_x.dot(box_z)) + cabs(box_y.dot(box_z)) + cabs(box_z.dot(box_z));
891 project(box_z, center, r2);
892 if (cabs(from_center.dot(box_z) - center) > r1 + r2) {
898 Points::const_iterator pi;
899 for (pi = _points.begin(); pi != _points.end(); ++pi) {
900 const PointDef &pd = *pi;
903 axis.set(-box_x[1] * pd._v[1],
904 box_x[0] * pd._v[1] - box_x[2] * pd._v[0],
905 box_x[1] * pd._v[0]);
906 r1 = cabs(box_x.dot(axis)) + cabs(box_y.dot(axis)) + cabs(box_z.dot(axis));
907 project(axis, center, r2);
908 if (cabs(from_center.dot(axis) - center) > r1 + r2) {
912 axis.set(-box_y[1] * pd._v[1],
913 box_y[0] * pd._v[1] - box_y[2] * pd._v[0],
914 box_y[1] * pd._v[0]);
915 r1 = cabs(box_x.dot(axis)) + cabs(box_y.dot(axis)) + cabs(box_z.dot(axis));
916 project(axis, center, r2);
917 if (cabs(from_center.dot(axis) - center) > r1 + r2) {
921 axis.set(-box_z[1] * pd._v[1],
922 box_z[0] * pd._v[1] - box_z[2] * pd._v[0],
923 box_z[1] * pd._v[0]);
924 r1 = cabs(box_x.dot(axis)) + cabs(box_y.dot(axis)) + cabs(box_z.dot(axis));
925 project(axis, center, r2);
926 if (cabs(from_center.dot(axis) - center) > r1 + r2) {
931 if (collide_cat.is_debug()) {
939 new_entry->set_surface_normal(normal);
944 LPoint3 interior_point = box->get_center() * wrt_mat +
945 wrt_mat.get_row3(0) * from_extents[0] * ((box_x[1] > 0) - (box_x[1] < 0)) +
946 wrt_mat.get_row3(1) * from_extents[1] * ((box_y[1] > 0) - (box_y[1] < 0)) +
947 wrt_mat.get_row3(2) * from_extents[2] * ((box_z[1] > 0) - (box_z[1] < 0));
950 new_entry->set_surface_point(get_plane().project(interior_point));
951 new_entry->set_interior_point(interior_point);
960 void CollisionPolygon::
962 if (collide_cat.is_debug()) {
964 <<
"Recomputing viz for " << *
this <<
"\n";
966 nassertv(_viz_geom !=
nullptr && _bounds_viz_geom !=
nullptr);
967 draw_polygon(_viz_geom, _bounds_viz_geom, _points);
978 PN_stdfloat CollisionPolygon::
979 dist_to_line_segment(
const LPoint2 &p,
980 const LPoint2 &f,
const LPoint2 &t,
982 LVector2 v1 = (p - f);
983 PN_stdfloat d = (v1[0] * v[1] - v1[1] * v[0]);
989 LPoint2 q = p + LVector2(-v[1], v[0]) * d;
999 return (p - f).length();
1000 }
if (q[0] > t[0]) {
1001 return (p - t).length();
1008 return (p - f).length();
1009 }
if (q[1] > t[1]) {
1010 return (p - t).length();
1020 return (p - f).length();
1021 }
if (q[0] > t[0]) {
1022 return (p - t).length();
1029 return (p - f).length();
1030 }
if (q[1] < t[1]) {
1031 return (p - t).length();
1044 return (p - f).length();
1045 }
if (q[0] < t[0]) {
1046 return (p - t).length();
1053 return (p - f).length();
1054 }
if (q[1] > t[1]) {
1055 return (p - t).length();
1062 if (-v[0] > -v[1]) {
1065 return (p - f).length();
1066 }
if (q[0] < t[0]) {
1067 return (p - t).length();
1074 return (p - f).length();
1075 }
if (q[1] < t[1]) {
1076 return (p - t).length();
1090 void CollisionPolygon::
1091 compute_vectors(Points &points) {
1092 size_t num_points = points.size();
1093 for (
size_t i = 0; i < num_points; i++) {
1094 points[i]._v = points[(i + 1) % num_points]._p - points[i]._p;
1095 points[i]._v.normalize();
1103 void CollisionPolygon::
1106 if (points.size() < 3) {
1107 if (collide_cat.is_debug()) {
1109 <<
"(Degenerate poly, ignoring.)\n";
1115 rederive_to_3d_mat(to_3d_mat);
1122 Points::const_iterator pi;
1123 for (pi = points.begin(); pi != points.end(); ++pi) {
1124 vertex.add_data3(to_3d((*pi)._p, to_3d_mat));
1128 body->add_consecutive_vertices(0, points.size());
1129 body->close_primitive();
1132 border->add_consecutive_vertices(0, points.size());
1133 border->add_vertex(0);
1134 border->close_primitive();
1137 geom1->add_primitive(body);
1140 geom2->add_primitive(border);
1154 bool CollisionPolygon::
1161 for (
int i = 0; i < (int)points.size() - 1; i++) {
1162 if (is_right(p - points[i]._p, points[i+1]._p - points[i]._p)) {
1166 if (is_right(p - points[points.size() - 1]._p,
1167 points[0]._p - points[points.size() - 1]._p)) {
1179 PN_stdfloat CollisionPolygon::
1190 bool got_dist =
false;
1191 PN_stdfloat best_dist = -1.0f;
1193 size_t num_points = points.size();
1194 for (
size_t i = 0; i < num_points - 1; ++i) {
1195 PN_stdfloat d = dist_to_line_segment(p, points[i]._p, points[i + 1]._p,
1198 if (!got_dist || d < best_dist) {
1205 PN_stdfloat d = dist_to_line_segment(p, points[num_points - 1]._p, points[0]._p,
1206 points[num_points - 1]._v);
1208 if (!got_dist || d < best_dist) {
1221 void CollisionPolygon::
1222 project(
const LVector3 &axis, PN_stdfloat ¢er, PN_stdfloat &extent)
const {
1223 PN_stdfloat begin, end;
1225 Points::const_iterator pi;
1226 pi = _points.begin();
1228 const LPoint2 &point = (*pi)._p;
1229 begin = point[0] * axis[0] + point[1] * axis[2];
1232 for (; pi != _points.end(); ++pi) {
1233 const LPoint2 &point = (*pi)._p;
1235 PN_stdfloat t = point[0] * axis[0] + point[1] * axis[2];
1236 begin = min(begin, t);
1240 center = (end + begin) * 0.5f;
1241 extent = cabs((end - begin) * 0.5f);
1247 void CollisionPolygon::
1248 setup_points(
const LPoint3 *begin,
const LPoint3 *end) {
1249 int num_points = end - begin;
1250 nassertv(num_points >= 3);
1256 LVector3 normal = LVector3::zero();
1262 for (
int i = 0; i < num_points; i++) {
1263 const LPoint3 &p0 = begin[i];
1264 const LPoint3 &p1 = begin[(i + 1) % num_points];
1265 normal[0] += p0[1] * p1[2] - p0[2] * p1[1];
1266 normal[1] += p0[2] * p1[0] - p0[0] * p1[2];
1267 normal[2] += p0[0] * p1[1] - p0[1] * p1[0];
1270 if (normal.length_squared() == 0.0f) {
1279 collide_cat.error() <<
"Invalid points in CollisionPolygon:\n";
1281 for (pi = begin; pi != end; ++pi) {
1282 collide_cat.error(
false) <<
" " << (*pi) <<
"\n";
1284 collide_cat.error(
false)
1285 <<
" normal " << normal <<
" with length " << normal.length() <<
"\n";
1291 if (collide_cat.is_spam()) {
1293 <<
"CollisionPolygon defined with " << num_points <<
" vertices:\n";
1295 for (pi = begin; pi != end; ++pi) {
1296 collide_cat.spam(
false) <<
" " << (*pi) <<
"\n";
1301 set_plane(LPlane(normal, begin[0]));
1306 calc_to_3d_mat(to_3d_mat);
1309 _to_2d_mat.invert_from(to_3d_mat);
1314 for (pi = begin; pi != end; ++pi) {
1315 LPoint3 point = (*pi) * _to_2d_mat;
1316 _points.push_back(PointDef(point[0], point[2]));
1319 nassertv(_points.size() >= 3);
1337 compute_vectors(_points);
1344 LPoint3 CollisionPolygon::
1345 legacy_to_3d(
const LVecBase2 &point2d,
int axis)
const {
1346 nassertr(!point2d.is_nan(), LPoint3(0.0f, 0.0f, 0.0f));
1348 LVector3 normal = get_normal();
1349 PN_stdfloat D = get_plane()[3];
1351 nassertr(!normal.is_nan(), LPoint3(0.0f, 0.0f, 0.0f));
1352 nassertr(!cnan(D), LPoint3(0.0f, 0.0f, 0.0f));
1356 return LPoint3(-(normal[1]*point2d[0] + normal[2]*point2d[1] + D)/normal[0], point2d[0], point2d[1]);
1359 return LPoint3(point2d[0],
1360 -(normal[0]*point2d[0] + normal[2]*point2d[1] + D)/normal[1], point2d[1]);
1363 return LPoint3(point2d[0], point2d[1],
1364 -(normal[0]*point2d[0] + normal[1]*point2d[1] + D)/normal[2]);
1367 nassertr(
false, LPoint3(0.0f, 0.0f, 0.0f));
1368 return LPoint3(0.0f, 0.0f, 0.0f);
1379 bool CollisionPolygon::
1382 const LPlane &plane)
const {
1384 if (source_points.empty()) {
1390 if (!plane.intersects_plane(from3d, delta3d, get_plane())) {
1393 if (plane.dist_to_plane(get_plane().
get_point()) < 0.0) {
1396 new_points = source_points;
1404 LPoint2 from2d = to_2d(from3d);
1405 LVector2 delta2d = to_2d(delta3d);
1407 PN_stdfloat a = -delta2d[1];
1408 PN_stdfloat b = delta2d[0];
1409 PN_stdfloat c = from2d[0] * delta2d[1] - from2d[1] * delta2d[0];
1417 new_points.reserve(source_points.size() + 1);
1419 LPoint2 last_point = source_points.back()._p;
1420 bool last_is_in = !is_right(last_point - from2d, delta2d);
1421 bool all_in = last_is_in;
1422 Points::const_iterator pi;
1423 for (pi = source_points.begin(); pi != source_points.end(); ++pi) {
1424 const LPoint2 &this_point = (*pi)._p;
1425 bool this_is_in = !is_right(this_point - from2d, delta2d);
1429 bool crossed_over = (this_is_in != last_is_in);
1433 LVector2 d = this_point - last_point;
1434 PN_stdfloat denom = (a * d[0] + b * d[1]);
1436 PN_stdfloat t = -(a * last_point[0] + b * last_point[1] + c) / denom;
1437 LPoint2 p = last_point + t * d;
1439 new_points.push_back(PointDef(p[0], p[1]));
1440 last_is_in = this_is_in;
1446 new_points.push_back(PointDef(this_point[0], this_point[1]));
1451 last_point = this_point;
1464 bool CollisionPolygon::
1471 bool first_plane =
true;
1473 for (
int i = 0; i < num_planes; i++) {
1478 net_transform->invert_compose(plane_path.get_net_transform());
1480 LPlane plane = plane_node->
get_plane() * new_transform->get_mat();
1482 first_plane =
false;
1483 if (!clip_polygon(new_points, _points, plane)) {
1488 last_points.swap(new_points);
1489 if (!clip_polygon(new_points, last_points, plane)) {
1497 compute_vectors(new_points);
1511 for (
size_t i = 0; i < _points.size(); i++) {
1512 _points[i]._p.write_datagram(me);
1513 _points[i]._v.write_datagram(me);
1515 _to_2d_mat.write_datagram(me);
1523 void CollisionPolygon::
1525 CollisionPlane::fillin(scan, manager);
1528 for (
size_t i = 0; i < size; i++) {
1531 p.read_datagram(scan);
1532 v.read_datagram(scan);
1533 _points.push_back(PointDef(p, v));
1535 _to_2d_mat.read_datagram(scan);
1541 if (_points.size() >= 3) {
1543 rederive_to_3d_mat(to_3d_mat);
1545 epvector<LPoint3> verts;
1546 verts.reserve(_points.size());
1547 Points::const_iterator pi;
1548 for (pi = _points.begin(); pi != _points.end(); ++pi) {
1549 verts.push_back(to_3d((*pi)._p, to_3d_mat));
1552 const LPoint3 *verts_begin = &verts[0];
1553 const LPoint3 *verts_end = verts_begin + verts.size();
1554 setup_points(verts_begin, verts_end);
1570 me->fillin(scan, manager);