+#define SVBSP_CLIP_EPSILON (1.0f / 1024.0f)
+
+#define SVBSP_DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
+
+typedef struct svbsp_polygon_s
+{
+ float points[MAX_SVBSP_POLYGONPOINTS][3];
+ //unsigned char splitflags[MAX_SVBSP_POLYGONPOINTS];
+ int facesplitflag;
+ int numpoints;
+}
+svbsp_polygon_t;
+
+static void SVBSP_PlaneFromPoints(float *plane4f, const float *p1, const float *p2, const float *p3)
+{
+ float ilength;
+ // calculate unnormalized plane
+ plane4f[0] = (p1[1] - p2[1]) * (p3[2] - p2[2]) - (p1[2] - p2[2]) * (p3[1] - p2[1]);
+ plane4f[1] = (p1[2] - p2[2]) * (p3[0] - p2[0]) - (p1[0] - p2[0]) * (p3[2] - p2[2]);
+ plane4f[2] = (p1[0] - p2[0]) * (p3[1] - p2[1]) - (p1[1] - p2[1]) * (p3[0] - p2[0]);
+ plane4f[3] = SVBSP_DotProduct(plane4f, p1);
+ // normalize the plane normal and adjust distance accordingly
+ ilength = (float)sqrt(SVBSP_DotProduct(plane4f, plane4f));
+ if (ilength)
+ ilength = 1.0f / ilength;
+ plane4f[0] *= ilength;
+ plane4f[1] *= ilength;
+ plane4f[2] *= ilength;
+ plane4f[3] *= ilength;
+}
+
+static void SVBSP_DividePolygon(const svbsp_polygon_t *poly, const float *plane, svbsp_polygon_t *front, svbsp_polygon_t *back, const float *dists, const int *sides)
+{
+ int i, j, count = poly->numpoints, frontcount = 0, backcount = 0;
+ float frac, ifrac, c[3], pdist, ndist;
+ const float *nextpoint;
+ const float *points = poly->points[0];
+ float *outfront = front->points[0];
+ float *outback = back->points[0];
+ for(i = 0;i < count;i++, points += 3)
+ {
+ j = i + 1;
+ if (j >= count)
+ j = 0;
+ if (!(sides[i] & 2))
+ {
+ outfront[frontcount*3+0] = points[0];
+ outfront[frontcount*3+1] = points[1];
+ outfront[frontcount*3+2] = points[2];
+ frontcount++;
+ }
+ if (!(sides[i] & 1))
+ {
+ outback[backcount*3+0] = points[0];
+ outback[backcount*3+1] = points[1];
+ outback[backcount*3+2] = points[2];
+ backcount++;
+ }
+ if ((sides[i] | sides[j]) == 3)
+ {
+ // don't allow splits if remaining points would overflow point buffer
+ if (frontcount + (count - i) > MAX_SVBSP_POLYGONPOINTS - 1)
+ continue;
+ if (backcount + (count - i) > MAX_SVBSP_POLYGONPOINTS - 1)
+ continue;
+ nextpoint = poly->points[j];
+ pdist = dists[i];
+ ndist = dists[j];
+ frac = pdist / (pdist - ndist);
+ ifrac = 1.0f - frac;
+ c[0] = points[0] * ifrac + frac * nextpoint[0];
+ c[1] = points[1] * ifrac + frac * nextpoint[1];
+ c[2] = points[2] * ifrac + frac * nextpoint[2];
+ outfront[frontcount*3+0] = c[0];
+ outfront[frontcount*3+1] = c[1];
+ outfront[frontcount*3+2] = c[2];
+ frontcount++;
+ outback[backcount*3+0] = c[0];
+ outback[backcount*3+1] = c[1];
+ outback[backcount*3+2] = c[2];
+ backcount++;
+ }
+ }
+ front->numpoints = frontcount;
+ back->numpoints = backcount;
+}