/* ============== CSG_SplitBrushByFace The incoming brush is NOT freed. The incoming face is NOT left referenced. ============== */ void CSG_SplitBrushByFace (brush_t *in, face_t *f, brush_t **front, brush_t **back) { brush_t *b; face_t *nf; vec3_t temp; b = Brush_Clone (in); nf = Face_Clone (f); nf->texdef = b->brush_faces->texdef; nf->next = b->brush_faces; b->brush_faces = nf; Brush_Build( b ); Brush_RemoveEmptyFaces ( b ); if ( !b->brush_faces ) { // completely clipped away Brush_Free (b); *back = NULL; } else { Entity_LinkBrush (in->owner, b); *back = b; } b = Brush_Clone (in); nf = Face_Clone (f); // swap the plane winding VectorCopy (nf->planepts[0], temp); VectorCopy (nf->planepts[1], nf->planepts[0]); VectorCopy (temp, nf->planepts[1]); nf->texdef = b->brush_faces->texdef; nf->next = b->brush_faces; b->brush_faces = nf; Brush_Build( b ); Brush_RemoveEmptyFaces ( b ); if ( !b->brush_faces ) { // completely clipped away Brush_Free (b); *front = NULL; } else { Entity_LinkBrush (in->owner, b); *front = b; } }
/* Does NOT add the new brush to any lists */ brush_t *Brush_Clone (brush_t *b) { brush_t *n; face_t *f, *nf; n = qmalloc(sizeof(brush_t)); n->owner = b->owner; for (f=b->brush_faces ; f ; f=f->next) { nf = Face_Clone( f ); nf->next = n->brush_faces; n->brush_faces = nf; } return n; }
/* =================== DrawPatch =================== */ void DrawPatch (face_t *cf, float ctrl[3][3][5]) { int i, j; float u, v; vec5_t verts[CBLOCK_SUBDIVISIONS+1][CBLOCK_SUBDIVISIONS+1]; if (curveFile) { fprintf (curveFile, "PATCH {\n"); fprintf (curveFile, "textures/%s\n", cf->texdef.name); Write3DMatrix (curveFile, 3, 3, 5, (float *)ctrl); fprintf (curveFile, "}\n"); return; } for (i = 0 ; i <= CBLOCK_SUBDIVISIONS ; i++) { for (j = 0 ; j <= CBLOCK_SUBDIVISIONS ; j++) { u = (float)i / CBLOCK_SUBDIVISIONS; v = (float)j / CBLOCK_SUBDIVISIONS; SamplePatch (ctrl, u, v, verts[i][j]); } } if ( bevelBrush ) { face_t *f; vec3_t v0, v1, v2; vec3_t d1, d2, cross; for (i = 0 ; i < CBLOCK_SUBDIVISIONS ; i++) { for (j = 0 ; j < CBLOCK_SUBDIVISIONS ; j++) { VectorCopy( verts[i][j], v0 ); VectorCopy( verts[i][j+1], v1 ); VectorCopy( verts[i+1][j], v2 ); VectorSubtract( v0, v1, d1 ); VectorSubtract( v2, v1, d2 ); CrossProduct( d1, d2, cross ); if ( VectorLength( cross ) == 0 ) { continue; // degenerate } f = Face_Clone( bevelBrush->brush_faces ); f->texdef.flags |= SURF_CURVE_FAKE; VectorCopy( v0, f->planepts[0] ); VectorCopy( v1, f->planepts[1] ); VectorCopy( v2, f->planepts[2] ); Brush_MakeFacePlane( f ); f->next = bevelBrush->brush_faces; bevelBrush->brush_faces = f; } } return; } qglBindTexture (GL_TEXTURE_2D, cf->d_texture->texture_number); float fColor[3]; SetColor(cf, fColor); for (i = 0 ; i < CBLOCK_SUBDIVISIONS ; i++) { qglBegin (GL_QUAD_STRIP); for (j = 0 ; j <= CBLOCK_SUBDIVISIONS ; j++) { qglTexCoord2fv( verts[i+1][j] + 3 ); qglVertex3fv( verts[i+1][j] ); qglTexCoord2fv( verts[i][j] + 3 ); qglVertex3fv( verts[i][j] ); DecColor(fColor); } qglEnd (); } }
/* =============== DrawRuledSurface =============== */ void DrawRuledSurface (face_t *cf, float ctrl[2][3][5] ) { int j, k, l; vec5_t curve[2][CBLOCK_SUBDIVISIONS+1]; //float u; float *v; if (curveFile) { fprintf (curveFile, "RULED {\n"); fprintf (curveFile, "textures/%s\n", cf->texdef.name); Write3DMatrix (curveFile, 2, 3, 5, (float *)ctrl); fprintf (curveFile, "}\n"); return; } for (j = 0 ; j < 2 ; j++) { for (l = 0 ; l < 5 ; l++) { float a, b, c; float qA, qB, qC; float f; int k; a = ctrl[j][0][l]; b = ctrl[j][1][l]; c = ctrl[j][2][l]; qA = a - 2 * b + c; qB = 2 * b - 2 * a; qC = a; for (k = 0 ; k <= CBLOCK_SUBDIVISIONS ; k++) { f = (float)k / CBLOCK_SUBDIVISIONS; curve[j][k][l] = qA*f*f + qB*f + qC; } } } if ( bevelBrush ) { face_t *f; for (k = 0 ; k < CBLOCK_SUBDIVISIONS ; k++) { f = Face_Clone( bevelBrush->brush_faces ); f->texdef.flags |= SURF_CURVE_FAKE; f->next = bevelBrush->brush_faces; bevelBrush->brush_faces = f; VectorCopy( curve[0][k], f->planepts[0] ); VectorCopy( curve[1][k], f->planepts[1] ); VectorCopy( curve[0][k+1], f->planepts[2] ); Brush_MakeFacePlane( f ); } return; } qglBindTexture (GL_TEXTURE_2D, cf->d_texture->texture_number); float fColor[3]; SetColor(cf, fColor); qglBegin (GL_QUAD_STRIP); for (k = 0 ; k <= CBLOCK_SUBDIVISIONS ; k++) { v = curve[0][k]; qglTexCoord2fv( v + 3 ); qglVertex3fv( v ); v = curve[1][k]; qglTexCoord2fv( v + 3 ); qglVertex3fv( v ); } qglEnd (); }