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);
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)) {
445 <<
" has normal " << normal <<
" of length " << normal.length()
454 if (!get_plane().intersects_line(dist, from_center, -get_normal())) {
460 if (dist > from_radius || dist < -from_radius) {
465 LPoint2 p = to_2d(from_center - dist * get_normal());
466 PN_stdfloat edge_dist = 0.0f;
469 if (cpa !=
nullptr) {
472 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
474 edge_dist = dist_to_polygon(p, _points);
476 }
else if (new_points.empty()) {
482 edge_dist = dist_to_polygon(p, new_points);
487 edge_dist = dist_to_polygon(p, _points);
493 if (edge_dist > from_radius) {
503 PN_stdfloat max_dist = from_radius;
504 if (edge_dist >= 0.0f) {
505 PN_stdfloat max_dist_2 = max(from_radius_2 - edge_dist * edge_dist, (PN_stdfloat)0.0);
506 max_dist = csqrt(max_dist_2);
509 if (dist > max_dist) {
514 if (collide_cat.is_debug()) {
521 PN_stdfloat into_depth = max_dist - dist;
522 if (moved_from_center) {
525 PN_stdfloat orig_dist;
526 get_plane().intersects_line(orig_dist, orig_center, -normal);
527 into_depth = max_dist - orig_dist;
530 new_entry->set_surface_normal(normal);
531 new_entry->set_surface_point(from_center - normal * dist);
532 new_entry->set_interior_point(from_center - normal * (dist + into_depth));
533 new_entry->set_contact_pos(contact_point);
534 new_entry->set_contact_normal(get_normal());
535 new_entry->set_t(actual_t);
546 if (_points.size() < 3) {
551 DCAST_INTO_R(line, entry.
get_from(),
nullptr);
553 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
555 LPoint3 from_origin = line->get_origin() * wrt_mat;
556 LVector3 from_direction = line->get_direction() * wrt_mat;
559 if (!get_plane().intersects_line(t, from_origin, from_direction)) {
564 LPoint3 plane_point = from_origin + t * from_direction;
565 LPoint2 p = to_2d(plane_point);
568 if (cpa !=
nullptr) {
571 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
573 if (!point_is_inside(p, _points)) {
578 if (new_points.size() < 3) {
581 if (!point_is_inside(p, new_points)) {
588 if (!point_is_inside(p, _points)) {
593 if (collide_cat.is_debug()) {
602 new_entry->set_surface_normal(normal);
603 new_entry->set_surface_point(plane_point);
614 if (_points.size() < 3) {
619 DCAST_INTO_R(ray, entry.
get_from(),
nullptr);
621 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
623 LPoint3 from_origin = ray->get_origin() * wrt_mat;
624 LVector3 from_direction = ray->get_direction() * wrt_mat;
627 if (!get_plane().intersects_line(t, from_origin, from_direction)) {
637 LPoint3 plane_point = from_origin + t * from_direction;
638 LPoint2 p = to_2d(plane_point);
641 if (cpa !=
nullptr) {
644 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
646 if (!point_is_inside(p, _points)) {
651 if (new_points.size() < 3) {
654 if (!point_is_inside(p, new_points)) {
661 if (!point_is_inside(p, _points)) {
666 if (collide_cat.is_debug()) {
675 new_entry->set_surface_normal(normal);
676 new_entry->set_surface_point(plane_point);
686 test_intersection_from_segment(
const CollisionEntry &entry)
const {
687 if (_points.size() < 3) {
692 DCAST_INTO_R(segment, entry.
get_from(),
nullptr);
694 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
696 LPoint3 from_a = segment->get_point_a() * wrt_mat;
697 LPoint3 from_b = segment->get_point_b() * wrt_mat;
698 LPoint3 from_direction = from_b - from_a;
701 if (!get_plane().intersects_line(t, from_a, from_direction)) {
706 if (t < 0.0f || t > 1.0f) {
712 LPoint3 plane_point = from_a + t * from_direction;
713 LPoint2 p = to_2d(plane_point);
716 if (cpa !=
nullptr) {
719 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
721 if (!point_is_inside(p, _points)) {
726 if (new_points.size() < 3) {
729 if (!point_is_inside(p, new_points)) {
736 if (!point_is_inside(p, _points)) {
741 if (collide_cat.is_debug()) {
750 new_entry->set_surface_normal(normal);
751 new_entry->set_surface_point(plane_point);
761 test_intersection_from_parabola(
const CollisionEntry &entry)
const {
762 if (_points.size() < 3) {
767 DCAST_INTO_R(parabola, entry.
get_from(),
nullptr);
769 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
773 local_p.xform(wrt_mat);
776 if (!get_plane().intersects_parabola(t1, t2, local_p)) {
782 if (t1 >= parabola->
get_t1() && t1 <= parabola->get_t2()) {
783 if (t2 >= parabola->
get_t1() && t2 <= parabola->get_t2()) {
792 }
else if (t2 >= parabola->
get_t1() && t2 <= parabola->get_t2()) {
801 LPoint3 plane_point = local_p.calc_point(t);
802 LPoint2 p = to_2d(plane_point);
805 if (cpa !=
nullptr) {
808 if (apply_clip_plane(new_points, cpa, entry.
get_into_node_path().get_net_transform())) {
810 if (!point_is_inside(p, _points)) {
815 if (new_points.size() < 3) {
818 if (!point_is_inside(p, new_points)) {
825 if (!point_is_inside(p, _points)) {
830 if (collide_cat.is_debug()) {
839 new_entry->set_surface_normal(normal);
840 new_entry->set_surface_point(plane_point);
852 DCAST_INTO_R(box, entry.
get_from(),
nullptr);
856 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
857 LMatrix4 plane_mat = wrt_mat * _to_2d_mat;
859 LPoint3 from_center = box->get_center() * plane_mat;
860 LVector3 from_extents = box->get_dimensions() * 0.5f;
863 LVecBase3 box_x = plane_mat.get_row3(0) * from_extents[0];
864 LVecBase3 box_y = plane_mat.get_row3(1) * from_extents[1];
865 LVecBase3 box_z = plane_mat.get_row3(2) * from_extents[2];
868 if (cabs(from_center[1]) > cabs(box_x[1]) + cabs(box_y[1]) + cabs(box_z[1])) {
874 PN_stdfloat r1, center, r2;
876 r1 = cabs(box_x.dot(box_x)) + cabs(box_y.dot(box_x)) + cabs(box_z.dot(box_x));
877 project(box_x, center, r2);
878 if (cabs(from_center.dot(box_x) - center) > r1 + r2) {
882 r1 = cabs(box_x.dot(box_y)) + cabs(box_y.dot(box_y)) + cabs(box_z.dot(box_y));
883 project(box_y, center, r2);
884 if (cabs(from_center.dot(box_y) - center) > r1 + r2) {
888 r1 = cabs(box_x.dot(box_z)) + cabs(box_y.dot(box_z)) + cabs(box_z.dot(box_z));
889 project(box_z, center, r2);
890 if (cabs(from_center.dot(box_z) - center) > r1 + r2) {
896 Points::const_iterator pi;
897 for (pi = _points.begin(); pi != _points.end(); ++pi) {
898 const PointDef &pd = *pi;
901 axis.set(-box_x[1] * pd._v[1],
902 box_x[0] * pd._v[1] - box_x[2] * pd._v[0],
903 box_x[1] * pd._v[0]);
904 r1 = cabs(box_x.dot(axis)) + cabs(box_y.dot(axis)) + cabs(box_z.dot(axis));
905 project(axis, center, r2);
906 if (cabs(from_center.dot(axis) - center) > r1 + r2) {
910 axis.set(-box_y[1] * pd._v[1],
911 box_y[0] * pd._v[1] - box_y[2] * pd._v[0],
912 box_y[1] * pd._v[0]);
913 r1 = cabs(box_x.dot(axis)) + cabs(box_y.dot(axis)) + cabs(box_z.dot(axis));
914 project(axis, center, r2);
915 if (cabs(from_center.dot(axis) - center) > r1 + r2) {
919 axis.set(-box_z[1] * pd._v[1],
920 box_z[0] * pd._v[1] - box_z[2] * pd._v[0],
921 box_z[1] * pd._v[0]);
922 r1 = cabs(box_x.dot(axis)) + cabs(box_y.dot(axis)) + cabs(box_z.dot(axis));
923 project(axis, center, r2);
924 if (cabs(from_center.dot(axis) - center) > r1 + r2) {
929 if (collide_cat.is_debug()) {
937 new_entry->set_surface_normal(normal);
942 LPoint3 interior_point = box->get_center() * wrt_mat +
943 wrt_mat.get_row3(0) * from_extents[0] * ((box_x[1] > 0) - (box_x[1] < 0)) +
944 wrt_mat.get_row3(1) * from_extents[1] * ((box_y[1] > 0) - (box_y[1] < 0)) +
945 wrt_mat.get_row3(2) * from_extents[2] * ((box_z[1] > 0) - (box_z[1] < 0));
948 new_entry->set_surface_point(get_plane().project(interior_point));
949 new_entry->set_interior_point(interior_point);
958 void CollisionPolygon::
960 if (collide_cat.is_debug()) {
962 <<
"Recomputing viz for " << *
this <<
"\n";
964 nassertv(_viz_geom !=
nullptr && _bounds_viz_geom !=
nullptr);
965 draw_polygon(_viz_geom, _bounds_viz_geom, _points);
976 PN_stdfloat CollisionPolygon::
977 dist_to_line_segment(
const LPoint2 &p,
978 const LPoint2 &f,
const LPoint2 &t,
980 LVector2 v1 = (p - f);
981 PN_stdfloat d = (v1[0] * v[1] - v1[1] * v[0]);
987 LPoint2 q = p + LVector2(-v[1], v[0]) * d;
997 return (p - f).length();
999 return (p - t).length();
1006 return (p - f).length();
1007 }
if (q[1] > t[1]) {
1008 return (p - t).length();
1018 return (p - f).length();
1019 }
if (q[0] > t[0]) {
1020 return (p - t).length();
1027 return (p - f).length();
1028 }
if (q[1] < t[1]) {
1029 return (p - t).length();
1042 return (p - f).length();
1043 }
if (q[0] < t[0]) {
1044 return (p - t).length();
1051 return (p - f).length();
1052 }
if (q[1] > t[1]) {
1053 return (p - t).length();
1060 if (-v[0] > -v[1]) {
1063 return (p - f).length();
1064 }
if (q[0] < t[0]) {
1065 return (p - t).length();
1072 return (p - f).length();
1073 }
if (q[1] < t[1]) {
1074 return (p - t).length();
1088 void CollisionPolygon::
1089 compute_vectors(Points &points) {
1090 size_t num_points = points.size();
1091 for (
size_t i = 0; i < num_points; i++) {
1092 points[i]._v = points[(i + 1) % num_points]._p - points[i]._p;
1093 points[i]._v.normalize();
1101 void CollisionPolygon::
1104 if (points.size() < 3) {
1105 if (collide_cat.is_debug()) {
1107 <<
"(Degenerate poly, ignoring.)\n";
1113 rederive_to_3d_mat(to_3d_mat);
1120 Points::const_iterator pi;
1121 for (pi = points.begin(); pi != points.end(); ++pi) {
1122 vertex.add_data3(to_3d((*pi)._p, to_3d_mat));
1126 body->add_consecutive_vertices(0, points.size());
1127 body->close_primitive();
1130 border->add_consecutive_vertices(0, points.size());
1131 border->add_vertex(0);
1132 border->close_primitive();
1135 geom1->add_primitive(body);
1138 geom2->add_primitive(border);
1152 bool CollisionPolygon::
1159 for (
int i = 0; i < (int)points.size() - 1; i++) {
1160 if (is_right(p - points[i]._p, points[i+1]._p - points[i]._p)) {
1164 if (is_right(p - points[points.size() - 1]._p,
1165 points[0]._p - points[points.size() - 1]._p)) {
1177 PN_stdfloat CollisionPolygon::
1188 bool got_dist =
false;
1189 PN_stdfloat best_dist = -1.0f;
1191 size_t num_points = points.size();
1192 for (
size_t i = 0; i < num_points - 1; ++i) {
1193 PN_stdfloat d = dist_to_line_segment(p, points[i]._p, points[i + 1]._p,
1196 if (!got_dist || d < best_dist) {
1203 PN_stdfloat d = dist_to_line_segment(p, points[num_points - 1]._p, points[0]._p,
1204 points[num_points - 1]._v);
1206 if (!got_dist || d < best_dist) {
1219 void CollisionPolygon::
1220 project(
const LVector3 &axis, PN_stdfloat ¢er, PN_stdfloat &extent)
const {
1221 PN_stdfloat begin, end;
1223 Points::const_iterator pi;
1224 pi = _points.begin();
1226 const LPoint2 &point = (*pi)._p;
1227 begin = point[0] * axis[0] + point[1] * axis[2];
1230 for (; pi != _points.end(); ++pi) {
1231 const LPoint2 &point = (*pi)._p;
1233 PN_stdfloat t = point[0] * axis[0] + point[1] * axis[2];
1234 begin = min(begin, t);
1238 center = (end + begin) * 0.5f;
1239 extent = cabs((end - begin) * 0.5f);
1245 void CollisionPolygon::
1246 setup_points(
const LPoint3 *begin,
const LPoint3 *end) {
1247 int num_points = end - begin;
1248 nassertv(num_points >= 3);
1254 LVector3 normal = LVector3::zero();
1260 for (
int i = 0; i < num_points; i++) {
1261 const LPoint3 &p0 = begin[i];
1262 const LPoint3 &p1 = begin[(i + 1) % num_points];
1263 normal[0] += p0[1] * p1[2] - p0[2] * p1[1];
1264 normal[1] += p0[2] * p1[0] - p0[0] * p1[2];
1265 normal[2] += p0[0] * p1[1] - p0[1] * p1[0];
1268 if (normal.length_squared() == 0.0f) {
1277 collide_cat.error() <<
"Invalid points in CollisionPolygon:\n";
1279 for (pi = begin; pi != end; ++pi) {
1280 collide_cat.error(
false) <<
" " << (*pi) <<
"\n";
1282 collide_cat.error(
false)
1283 <<
" normal " << normal <<
" with length " << normal.length() <<
"\n";
1289 if (collide_cat.is_spam()) {
1291 <<
"CollisionPolygon defined with " << num_points <<
" vertices:\n";
1293 for (pi = begin; pi != end; ++pi) {
1294 collide_cat.spam(
false) <<
" " << (*pi) <<
"\n";
1299 set_plane(LPlane(normal, begin[0]));
1304 calc_to_3d_mat(to_3d_mat);
1307 _to_2d_mat.invert_from(to_3d_mat);
1312 for (pi = begin; pi != end; ++pi) {
1313 LPoint3 point = (*pi) * _to_2d_mat;
1314 _points.push_back(PointDef(point[0], point[2]));
1317 nassertv(_points.size() >= 3);
1335 compute_vectors(_points);
1342 LPoint3 CollisionPolygon::
1343 legacy_to_3d(
const LVecBase2 &point2d,
int axis)
const {
1344 nassertr(!point2d.is_nan(), LPoint3(0.0f, 0.0f, 0.0f));
1346 LVector3 normal = get_normal();
1347 PN_stdfloat D = get_plane()[3];
1349 nassertr(!normal.is_nan(), LPoint3(0.0f, 0.0f, 0.0f));
1350 nassertr(!cnan(D), LPoint3(0.0f, 0.0f, 0.0f));
1354 return LPoint3(-(normal[1]*point2d[0] + normal[2]*point2d[1] + D)/normal[0], point2d[0], point2d[1]);
1357 return LPoint3(point2d[0],
1358 -(normal[0]*point2d[0] + normal[2]*point2d[1] + D)/normal[1], point2d[1]);
1361 return LPoint3(point2d[0], point2d[1],
1362 -(normal[0]*point2d[0] + normal[1]*point2d[1] + D)/normal[2]);
1365 nassertr(
false, LPoint3(0.0f, 0.0f, 0.0f));
1366 return LPoint3(0.0f, 0.0f, 0.0f);
1377 bool CollisionPolygon::
1380 const LPlane &plane)
const {
1382 if (source_points.empty()) {
1388 if (!plane.intersects_plane(from3d, delta3d, get_plane())) {
1391 if (plane.dist_to_plane(get_plane().
get_point()) < 0.0) {
1394 new_points = source_points;
1402 LPoint2 from2d = to_2d(from3d);
1403 LVector2 delta2d = to_2d(delta3d);
1405 PN_stdfloat a = -delta2d[1];
1406 PN_stdfloat b = delta2d[0];
1407 PN_stdfloat c = from2d[0] * delta2d[1] - from2d[1] * delta2d[0];
1415 new_points.reserve(source_points.size() + 1);
1417 LPoint2 last_point = source_points.back()._p;
1418 bool last_is_in = !is_right(last_point - from2d, delta2d);
1419 bool all_in = last_is_in;
1420 Points::const_iterator pi;
1421 for (pi = source_points.begin(); pi != source_points.end(); ++pi) {
1422 const LPoint2 &this_point = (*pi)._p;
1423 bool this_is_in = !is_right(this_point - from2d, delta2d);
1427 bool crossed_over = (this_is_in != last_is_in);
1431 LVector2 d = this_point - last_point;
1432 PN_stdfloat denom = (a * d[0] + b * d[1]);
1434 PN_stdfloat t = -(a * last_point[0] + b * last_point[1] + c) / denom;
1435 LPoint2 p = last_point + t * d;
1437 new_points.push_back(PointDef(p[0], p[1]));
1438 last_is_in = this_is_in;
1444 new_points.push_back(PointDef(this_point[0], this_point[1]));
1449 last_point = this_point;
1462 bool CollisionPolygon::
1469 bool first_plane =
true;
1471 for (
int i = 0; i < num_planes; i++) {
1476 net_transform->invert_compose(plane_path.get_net_transform());
1478 LPlane plane = plane_node->
get_plane() * new_transform->get_mat();
1480 first_plane =
false;
1481 if (!clip_polygon(new_points, _points, plane)) {
1486 last_points.swap(new_points);
1487 if (!clip_polygon(new_points, last_points, plane)) {
1495 compute_vectors(new_points);
1509 for (
size_t i = 0; i < _points.size(); i++) {
1510 _points[i]._p.write_datagram(me);
1511 _points[i]._v.write_datagram(me);
1513 _to_2d_mat.write_datagram(me);
1521 void CollisionPolygon::
1523 CollisionPlane::fillin(scan, manager);
1526 for (
size_t i = 0; i < size; i++) {
1529 p.read_datagram(scan);
1530 v.read_datagram(scan);
1531 _points.push_back(PointDef(p, v));
1533 _to_2d_mat.read_datagram(scan);
1539 if (_points.size() >= 3) {
1541 rederive_to_3d_mat(to_3d_mat);
1543 epvector<LPoint3> verts;
1544 verts.reserve(_points.size());
1545 Points::const_iterator pi;
1546 for (pi = _points.begin(); pi != _points.end(); ++pi) {
1547 verts.push_back(to_3d((*pi)._p, to_3d_mat));
1550 const LPoint3 *verts_begin = &verts[0];
1551 const LPoint3 *verts_end = verts_begin + verts.size();
1552 setup_points(verts_begin, verts_end);
1568 me->fillin(scan, manager);