Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. #define BEHIND -1
  2. #define COINCIDING 0
  3. #define IN_FRONT 1
  4. #define EPSILON 1.0e-3f
  5.  
  6. // TAKES: a signed distance 'dist' to the plane
  7. // RETURNS: integer indicating side of input distance
  8. int plane3::classify(const float dist) const
  9. {
  10.     if (dist < -EPSILON)    { return BEHIND; }
  11.     if (dist > EPSILON)     { return IN_FRONT; }
  12.     return COINCIDING;
  13. }
  14.  
  15. // TAKES: a polygon 'in', a clipped polygon 'out'
  16. // RETURNS: number of vertices in polygon 'out'; clipped polygon 'out'
  17. // MEMBERS: point on plane 'pos', normal of plane 'nor'
  18. void plane3::clip(const array<vec3> &in, array<vec3> &out) const
  19. {
  20.     out.alloc(in.size() + 1); // make room for max number of out verts
  21.     array<float> dist;
  22.     array<int> side;
  23.     dist.alloc(in.size());
  24.     side.alloc(in.size());
  25.     int numOut = 0;
  26.     for (int i = 0; i < in.size(); ++i) {
  27.         dist[i] = dot(in[i] - pos, nor);
  28.         side[i] = classify(dist[i]);
  29.         if (side[i] <= COINCIDING) { ++numOut; }
  30.     }
  31.     if (numOut == in.size()) { // all verts are either behind, or on, plane
  32.         out.dealloc();
  33.         return;
  34.     }
  35.     int numIn = 0;
  36.     for (int i = 0, j = in.size() - 1; i < in.size(); j=i, ++i) {
  37.         if ((side[i] < COINCIDING) == (side[j] >= COINCIDING)) {
  38.             out[numIn++] = in[i] + (in[j] - in[i]) * (dist[i] / (dist[i] - dist[j]));
  39.         }
  40.         if (side[i] >= COINCIDING) {
  41.             out[numIn++] = in[i];
  42.         }
  43.     }
  44.     out.resize(numIn); // resize to actual size of output poly (numIn <= out.size())
  45. }