+ if(dynarr_size(back_polys)) {
+ if(!(node->back = build_tree(back_polys, dynarr_size(back_polys)))) {
+ goto fail;
+ }
+ }
+
+ free(clipped);
+ free(clipped_neg);
+
+ /* we no longer need the original polygon array */
+ dynarr_free(polyarr);
+
+ return node;
+
+fail:
+ free(clipped);
+ free(clipped_neg);
+
+ for(i=0; i<dynarr_size(front_polys); i++) {
+ free(front_polys[i].verts);
+ }
+ dynarr_free(front_polys);
+
+ for(i=0; i<dynarr_size(back_polys); i++) {
+ free(back_polys[i].verts);
+ }
+ dynarr_free(back_polys);
+
+ return 0;
+}
+
+#undef DRAW_NGONS
+
+#ifndef DRAW_NGONS
+static void debug_draw_poly(struct g3d_vertex *varr, int vcount)
+{
+ int i, nfaces = vcount - 2;
+ int vbuf_size = nfaces * 3;
+ struct g3d_vertex *vbuf = alloca(vbuf_size * sizeof *vbuf);
+ struct g3d_vertex *vptr = varr + 1;
+
+ for(i=0; i<nfaces; i++) {
+ vbuf[i * 3] = varr[0];
+ vbuf[i * 3 + 1] = *vptr++;
+ vbuf[i * 3 + 2] = *vptr;
+ }
+
+ g3d_draw_indexed(G3D_TRIANGLES, vbuf, vbuf_size, 0, 0);
+}
+#endif
+
+static void draw_bsp_tree(struct bspnode *n, const vec3_t *vdir)
+{
+ float dot;
+ struct bsppoly *p;
+
+ if(!n) return;
+
+ p = &n->poly;
+
+ dot = vdir->x * p->plane.nx + vdir->y * p->plane.ny + vdir->z * p->plane.nz;
+ if(dot >= 0.0f) {
+ draw_bsp_tree(n->front, vdir);
+#ifdef DRAW_NGONS
+ g3d_draw_indexed(p->vcount, p->verts, p->vcount, 0, 0);
+#else
+ debug_draw_poly(p->verts, p->vcount);
+#endif
+ draw_bsp_tree(n->back, vdir);
+ } else {
+ draw_bsp_tree(n->back, vdir);
+#ifdef DRAW_NGONS
+ g3d_draw_indexed(p->vcount, p->verts, p->vcount, 0, 0);
+#else
+ debug_draw_poly(p->verts, p->vcount);
+#endif
+ draw_bsp_tree(n->front, vdir);
+ }