// TAKES: a polygon 'in', a clipped polygon 'out'
// RETURNS: number of vertices in polygon 'out'; clipped polygon 'out'
// MEMBERS: point on plane 'pos', normal of plane 'nor'
void plane3::clip(const array<vec3> &in, array<vec3> &out) const
{
out.alloc(in.size() + 1); // make room for max number of out verts
array<float> dist;
dist.alloc(in.size());
int numOut = 0;
for (int i = 0; i < dist.size(); ++i) {
dist[i] = dot(in[i] - pos, nor);
if (dist[i] <= 0.0f) { ++numOut; }
}
if (numOut == dist.size()) { // all verts are either behind, or on, plane
out.dealloc();
return;
}
int numIn = 0;
for (int i = 0, j = in.size() - 1; i < in.size(); j=i, ++i) {
if ((dist[i] < 0.0f) == (dist[j] >= 0.0f)) {
out[numIn++] = in[i] + (in[j] - in[i]) * (dist[i] / (dist[i] - dist[j]));
}
if (dist[i] >= 0.0f) {
out[numIn++] = in[i];
}
}
out.resize(numIn); // resize to actual size of output poly (numIn <= out.size())
}