cbspbrush_t * CompileCBspbrushClass( hobj_t *brush, hmanager_t *planehm, hmanager_t *texdefhm ) { int i; cbspbrush_t *bb; hobj_search_iterator_t surfiter; hobj_t *surface; hobj_t *plane; hobj_t *texdef; hpair_t *pair; InitClassSearchIterator( &surfiter, brush, "surface" ); for ( i = 0; ( surface = SearchGetNextClass( &surfiter ) ); i++ ) { } bb = NewBrush( i ); bb->surfacenum = i; pair = FindHPair( brush, "content" ); if ( !pair ) Error( "missing 'contents' in brush '%s'.\n", brush->name ); HPairCastToInt_safe( &bb->contents, pair ); InitClassSearchIterator( &surfiter, brush, "surface" ); for ( i = 0; ( surface = SearchGetNextClass( &surfiter ) ); i++ ) { // contents pair = FindHPair( surface, "content" ); if ( !pair ) Error( "missing 'content' in surface '%s'.\n", surface->name ); HPairCastToInt( &bb->surfaces[i].contents, pair ); // clsref plane pair = FindHPair( surface, "plane" ); if ( !pair ) Error( "missing 'plane' in surface '%s'.\n", surface->name ); plane = HManagerSearchClassName( planehm, pair->value ); bb->surfaces[i].pl = GetClassExtra( plane ); // clsref texdef pair = FindHPair( surface, "texdef" ); if ( !texdefhm || !pair ) { bb->surfaces[i].td = NULL; } else { texdef = HManagerSearchClassName( texdefhm, pair->value ); bb->surfaces[i].td = GetClassExtra( texdef ); } bb->original = brush; SetClassExtra( brush, bb ); } return bb; }
bool DEntity::LoadFromPrt( char *filename ){ CPortals portals; strcpy( portals.fn, filename ); portals.Load(); if ( portals.node_count == 0 ) { return false; } ClearBrushes(); ClearEPairs(); bool build = false; for ( unsigned int i = 0; i < portals.node_count; i++ ) { build = false; DBrush* brush = NewBrush(); for ( unsigned int j = 0; j < portals.node[i].portal_count; j++ ) { for ( unsigned int k = 0; k < portals.node[i].portal[j].point_count - 2; k++ ) { vec3_t v1{}, v2{}, normal{}, n{}; VectorSubtract( portals.node[i].portal[j].point[k + 2].p, portals.node[i].portal[j].point[k + 1].p, v1 ); VectorSubtract( portals.node[i].portal[j].point[k].p, portals.node[i].portal[j].point[k + 1].p, v2 ); CrossProduct( v1, v2, n ); VectorNormalize( n, v2 ); if ( k == 0 ) { VectorCopy( v2, normal ); } else { VectorSubtract( v2, normal, v1 ); if ( VectorLength( v1 ) > 0.01 ) { build = true; break; } } } if ( !build ) { brush->AddFace( portals.node[i].portal[j].point[2].p, portals.node[i].portal[j].point[1].p, portals.node[i].portal[j].point[0].p, "textures/common/caulk", false ); } else{ brush->AddFace( portals.node[i].portal[j].point[0].p, portals.node[i].portal[j].point[1].p, portals.node[i].portal[j].point[2].p, "textures/common/caulk", false ); } } if ( build ) { brush->BuildInRadiant( false, NULL ); } } return true; }
void CChartPointsSerie::Draw(CDC *pDC) { if (!m_bIsVisible) return; CBrush NewBrush(m_ObjectColor); CBrush* pOldBrush; if (pDC->GetSafeHdc()) { pDC->SetBkMode(TRANSPARENT); //To have lines limited in the drawing rectangle : pDC->IntersectClipRect(m_ObjectRect); pOldBrush = pDC->SelectObject(&NewBrush); //Draw all points that haven't been drawn yet for (m_iLastDrawnPoint;m_iLastDrawnPoint<(int)m_vPoints.size();m_iLastDrawnPoint++) { CPoint ScreenPoint; ValueToScreen(m_vPoints[m_iLastDrawnPoint].X,m_vPoints[m_iLastDrawnPoint].Y,ScreenPoint); CRect PointRect; PointRect.SetRect(ScreenPoint.x-m_iXPointSize/2,ScreenPoint.y-m_iYPointSize/2,ScreenPoint.x+m_iXPointSize/2,ScreenPoint.y+m_iYPointSize/2); switch(m_iPointType) { case ptEllipse: pDC->Ellipse(PointRect); break; case ptRectangle: pDC->Rectangle(PointRect); break; case ptTriangle: { CPoint TrPoints[3]; TrPoints[0].x = PointRect.left; TrPoints[0].y = PointRect.bottom; TrPoints[1].x = PointRect.right; TrPoints[1].y = PointRect.bottom; TrPoints[2].x = PointRect.left + (int)fabs((PointRect.left-PointRect.right)/2.0); TrPoints[2].y = PointRect.top; pDC->Polygon(TrPoints,3); } break; } } pDC->SelectClipRgn(NULL); pDC->SelectObject(pOldBrush); } }
int CChartPointsSerie::DrawLegend(CDC *pDC, CPoint UpperLeft, int BitmapWidth) const { if (m_strSerieName== _T("")) return 0; //Draw Text int TextHeigh = pDC->GetTextExtent(m_strSerieName.c_str()).cy; pDC->ExtTextOut(UpperLeft.x+BitmapWidth+6,UpperLeft.y,ETO_CLIPPED,NULL,m_strSerieName.c_str(),NULL); CRect PointRect; if (TextHeigh > m_iYPointSize) { int Offset = (TextHeigh - m_iYPointSize)/2; PointRect.SetRect(UpperLeft.x+4,UpperLeft.y+Offset,UpperLeft.x+m_iXPointSize+4,UpperLeft.y+Offset+m_iYPointSize); } else PointRect.SetRect(UpperLeft.x+4,UpperLeft.y,UpperLeft.x+m_iXPointSize+4,UpperLeft.y+m_iYPointSize); CBrush NewBrush(m_ObjectColor); CBrush* pOldBrush = pDC->SelectObject(&NewBrush); switch(m_iPointType) { case ptEllipse: pDC->Ellipse(PointRect); break; case ptRectangle: pDC->Rectangle(PointRect); break; case ptTriangle: { CPoint TrPoints[3]; TrPoints[0].x = PointRect.left; TrPoints[0].y = PointRect.bottom; TrPoints[1].x = PointRect.right; TrPoints[1].y = PointRect.bottom; TrPoints[2].x = PointRect.left + (int)fabs((PointRect.left-PointRect.right)/2.0); TrPoints[2].y = PointRect.top; pDC->Polygon(TrPoints,3); } break; } pDC->SelectObject(pOldBrush); if (TextHeigh>m_iYPointSize) return TextHeigh; else return m_iYPointSize; }
bool DEntity::LoadFromEntity( entity_t* ent, bool bLoadPatches ) { ClearPatches(); ClearBrushes(); ClearEPairs(); QER_Entity = ent; epair_t* epl = *g_EntityTable.m_pfnGetEntityKeyValList( QER_Entity ); LoadEPairList( epl ); bool keep = FALSE; int i; for ( i = 0; brushEntityList[i]; i++ ) { if ( !stricmp( brushEntityList[i], m_Classname ) ) { keep = TRUE; break; } } if ( !keep ) { return FALSE; } int count = g_FuncTable.m_pfnAllocateEntityBrushHandles( QER_Entity ); for ( i = 0; i < count; i++ ) { brush_t *brush = (brush_t*)g_FuncTable.m_pfnGetEntityBrushHandle( i ); if ( brush == NULL ) { DoMessageBox( "GTKRadiant returned a NULL pointer, NOT a good sign", "WARNING!!!", MB_OK ); continue; } if ( brush->pPatch ) { if ( bLoadPatches ) { DPatch* loadPatch = NewPatch(); loadPatch->LoadFromBrush_t( brush ); } } else { DBrush* loadBrush = NewBrush( i ); loadBrush->LoadFromBrush_t( brush, TRUE ); } } g_FuncTable.m_pfnReleaseEntityBrushHandles(); return TRUE; }
void CMagneticView::SolidRect(CDC* pDC, LPCRECT lpRect, COLORREF Colour) { CPen NewPen(PS_SOLID,1,Colour); CPen* pOldPen = pDC->SelectObject(&NewPen); CBrush NewBrush(Colour); CBrush* pOldBrush = pDC->SelectObject(&NewBrush); pDC->Rectangle(lpRect); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); }
////////////////////////////////////////////////////////////////////////////// // CLogoMdi message handlers BOOL CLogoMdi::OnEraseBkgnd(CDC* pDC) { // This is where the real work is done printing the logo in the corner.. RECT rect,m_rDataBox; GetClientRect(&rect); CopyRect(&m_rDataBox,&rect); if (bgImage==NULL){ CBrush NewBrush(GetSysColor(COLOR_DESKTOP)) ; pDC->SetBrushOrg(0,0) ; CBrush* pOldBrush = (CBrush*)pDC->SelectObject(&NewBrush); pDC->PatBlt(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top ,PATCOPY); pDC->SelectObject(pOldBrush); } else { bgImage->Tile(pDC->GetSafeHdc(),&rect); } TEXTMETRIC tm; pDC->GetTextMetrics(&tm); CFont* oldFont = pDC->SelectObject(&m_LogoFont); CSize sz = pDC->GetTextExtent(sLogoString, sLogoString.GetLength()); // GetTextExtent calculates the size of the displayed logo // which depends on the device context.... // Calculate the box size by subtracting the text width and height from the // window size. Also subtract 20% of the average character size to keep the // logo from printing into the borders... m_rDataBox.left = m_rDataBox.right - sz.cx - tm.tmAveCharWidth/2; m_rDataBox.top = m_rDataBox.bottom - sz.cy - tm.tmHeight/5; pDC->SetBkMode(TRANSPARENT); // shift logo box right, and print black... COLORREF oldColor = pDC->SetTextColor(RGB(0,0,0)); pDC->DrawText(sLogoString, sLogoString.GetLength(), &m_rDataBox, DT_VCENTER | DT_SINGLELINE | DT_CENTER); // shift logo box left and print white m_rDataBox.left -= 3*tm.tmAveCharWidth/5; pDC->SetTextColor(RGB(255,255,255)); pDC->DrawText(sLogoString, sLogoString.GetLength(), &m_rDataBox, DT_VCENTER | DT_SINGLELINE | DT_CENTER); // Restore original location and print in the button face color m_rDataBox.left += tm.tmAveCharWidth/5; pDC->SetTextColor(GetSysColor(COLOR_BTNFACE)); pDC->DrawText(sLogoString, sLogoString.GetLength(), &m_rDataBox, DT_VCENTER | DT_SINGLELINE | DT_CENTER); // restore the original properties and release resources... pDC->SelectObject(oldFont); pDC->SetTextColor(oldColor); return TRUE; }
void CChartPointsSerie::DrawLegend(CDC *pDC, const CRect& rectBitmap) const { if (m_strSerieName== _T("")) return; CRect PointRect(0,0,m_iXPointSize,m_iYPointSize); if ( (rectBitmap.Height()>m_iYPointSize) && (rectBitmap.Width()>m_iXPointSize) ) { int XOffset = rectBitmap.left + rectBitmap.Width()/2 - m_iXPointSize/2; int YOffset = rectBitmap.top + rectBitmap.Height()/2 - m_iYPointSize/2; PointRect.OffsetRect(XOffset,YOffset); } else PointRect = rectBitmap; CBrush NewBrush(m_SerieColor); CBrush* pOldBrush = pDC->SelectObject(&NewBrush); switch(m_iPointType) { case ptEllipse: pDC->Ellipse(PointRect); break; case ptRectangle: pDC->Rectangle(PointRect); break; case ptTriangle: { CPoint TrPoints[3]; TrPoints[0].x = PointRect.left; TrPoints[0].y = PointRect.bottom; TrPoints[1].x = PointRect.right; TrPoints[1].y = PointRect.bottom; TrPoints[2].x = PointRect.left + (int)fabs((PointRect.left-PointRect.right)/2.0); TrPoints[2].y = PointRect.top; pDC->Polygon(TrPoints,3); } break; } pDC->SelectObject(pOldBrush); DeleteObject(NewBrush); }
DBrush* DEntity::GetBrushForID( int ID ){ DBrush* buildBrush = NULL; for ( std::list<DBrush *>::const_iterator chkBrush = brushList.begin(); chkBrush != brushList.end(); chkBrush++ ) { if ( ( *chkBrush )->m_nBrushID == ID ) { buildBrush = ( *chkBrush ); break; } } if ( !buildBrush ) { buildBrush = NewBrush( ID ); } return buildBrush; }
/* ==================== CopyBrush ==================== */ cbspbrush_t * CopyBrush( cbspbrush_t *in ) { int i; int size; cbspbrush_t *b; size = (int)&(((cbspbrush_t *)0)->surfaces[in->surfacenum]); b = NewBrush( in->surfacenum ); memcpy( b, in, size ); for ( i = 0; i < in->surfacenum; i++ ) { if ( in->surfaces[i].p ) b->surfaces[i].p = CopyPolygon( in->surfaces[i].p ); } return b; }
void DEntity::LoadSelectedBrushes(){ ClearBrushes(); ClearEPairs(); int count = g_FuncTable.m_pfnAllocateSelectedBrushHandles(); for ( int i = 0; i < count; i++ ) { brush_t *brush = (brush_t*)g_FuncTable.m_pfnGetSelectedBrushHandle( i ); if ( brush->pPatch ) { continue; } DBrush* loadBrush = NewBrush( i ); loadBrush->LoadFromBrush_t( brush, TRUE ); } g_FuncTable.m_pfnReleaseSelectedBrushHandles(); }
void CChartPointsSerie::Draw(CDC *pDC) { if (!m_bIsVisible) return; if (!pDC->GetSafeHdc()) return; CBrush NewBrush(m_SerieColor); CPen BorderPen(PS_SOLID, 1, m_colBorder); CBrush ShadowBrush(m_ShadowColor); CPen ShadowPen(PS_SOLID, 1, m_ShadowColor); CPen* pOldPen = pDC->SelectObject(&BorderPen); CBrush* pOldBrush = pDC->SelectObject(&NewBrush); pDC->SetBkMode(TRANSPARENT); //To have lines limited in the drawing rectangle : pDC->IntersectClipRect(m_PlottingRect); //Draw all points that haven't been drawn yet for (m_uLastDrawnPoint;m_uLastDrawnPoint<(int)GetPointsCount();m_uLastDrawnPoint++) { SChartXYPoint Point = GetPoint(m_uLastDrawnPoint); CPoint ScreenPoint; ValueToScreen(Point.X, Point.Y, ScreenPoint); CRect PointRect; PointRect.SetRect(ScreenPoint.x-m_iXPointSize/2,ScreenPoint.y-m_iYPointSize/2,ScreenPoint.x+m_iXPointSize/2,ScreenPoint.y+m_iYPointSize/2); CRect ShadowRect = PointRect + CSize(m_iShadowDepth,m_iShadowDepth); switch(m_iPointType) { case ptEllipse: if (m_bShadow) { pOldPen = pDC->SelectObject(&ShadowPen); pDC->SelectObject(&ShadowBrush); pDC->Ellipse(ShadowRect); pDC->SelectObject(&NewBrush); pDC->SelectObject(&BorderPen); } pDC->Ellipse(PointRect); break; case ptRectangle: if (m_bShadow) { pOldPen = pDC->SelectObject(&ShadowPen); pDC->SelectObject(&ShadowBrush); pDC->Rectangle(ShadowRect); pDC->SelectObject(&NewBrush); pDC->SelectObject(&BorderPen); } pDC->Rectangle(PointRect); break; case ptTriangle: { CPoint TrPoints[3]; TrPoints[0].x = PointRect.left; TrPoints[0].y = PointRect.bottom; TrPoints[1].x = PointRect.right; TrPoints[1].y = PointRect.bottom; TrPoints[2].x = PointRect.left + (int)fabs((PointRect.left-PointRect.right)/2.0); TrPoints[2].y = PointRect.top; if (m_bShadow) { CPoint ShadowPoints[3]; for (int i=0;i<3;i++) { ShadowPoints[i] = TrPoints[i] + CSize(m_iShadowDepth,m_iShadowDepth); } pOldPen = pDC->SelectObject(&ShadowPen); pDC->SelectObject(&ShadowBrush); pDC->Polygon(ShadowPoints,3); pDC->SelectObject(&NewBrush); pDC->SelectObject(&BorderPen); } pDC->Polygon(TrPoints,3); } break; } } pDC->SelectClipRgn(NULL); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); DeleteObject(BorderPen); DeleteObject(NewBrush); DeleteObject(ShadowBrush); DeleteObject(ShadowPen); }
void CChartPointsSerie::DrawAll(CDC *pDC) { if (!m_bIsVisible) return; CBrush NewBrush(m_ObjectColor); CBrush ShadowBrush(m_ShadowColor); CPen ShadowPen(PS_SOLID,1,m_ShadowColor); CPen* pOldPen; CBrush* pOldBrush; int iFirst=0, iLast=0; GetVisiblePoints(iFirst,iLast); if (pDC->GetSafeHdc()) { pDC->SetBkMode(TRANSPARENT); //To have lines limited in the drawing rectangle : pDC->IntersectClipRect(m_ObjectRect); pOldBrush = pDC->SelectObject(&NewBrush); for (m_iLastDrawnPoint=iFirst;m_iLastDrawnPoint<=iLast;m_iLastDrawnPoint++) { CPoint ScreenPoint; ValueToScreen(m_vPoints[m_iLastDrawnPoint].X,m_vPoints[m_iLastDrawnPoint].Y,ScreenPoint); CRect PointRect; PointRect.SetRect(ScreenPoint.x-m_iXPointSize/2,ScreenPoint.y-m_iYPointSize/2,ScreenPoint.x+m_iXPointSize/2,ScreenPoint.y+m_iYPointSize/2); CRect ShadowRect = PointRect + CSize(m_iShadowDepth,m_iShadowDepth); switch(m_iPointType) { case ptEllipse: if (m_bShadow) { pOldPen = pDC->SelectObject(&ShadowPen); pDC->SelectObject(&ShadowBrush); pDC->Ellipse(ShadowRect); pDC->SelectObject(&NewBrush); pDC->SelectObject(pOldPen); } pDC->Ellipse(PointRect); break; case ptRectangle: if (m_bShadow) { pOldPen = pDC->SelectObject(&ShadowPen); pDC->SelectObject(&ShadowBrush); pDC->Rectangle(ShadowRect); pDC->SelectObject(&NewBrush); pDC->SelectObject(pOldPen); } pDC->Rectangle(PointRect); break; case ptTriangle: { CPoint TrPoints[3]; TrPoints[0].x = PointRect.left; TrPoints[0].y = PointRect.bottom; TrPoints[1].x = PointRect.right; TrPoints[1].y = PointRect.bottom; TrPoints[2].x = PointRect.left + (int)fabs((PointRect.left-PointRect.right)/2.0); TrPoints[2].y = PointRect.top; if (m_bShadow) { CPoint ShadowPoints[3]; for (int i=0;i<3;i++) { ShadowPoints[i] = TrPoints[i] + CSize(m_iShadowDepth,m_iShadowDepth); } pOldPen = pDC->SelectObject(&ShadowPen); pDC->SelectObject(&ShadowBrush); pDC->Polygon(ShadowPoints,3); pDC->SelectObject(&NewBrush); pDC->SelectObject(pOldPen); } pDC->Polygon(TrPoints,3); } break; } } pDC->SelectClipRgn(NULL); pDC->SelectObject(pOldBrush); DeleteObject(NewBrush); } }
void CChartGradient::DrawGradient(CDC* pDC, const CRect& GradientRect, COLORREF Color1, COLORREF Color2, EGradientType GradientType) { #if _MFC_VER > 0x0600 if ( (GradientType == gtHorizontal) || (GradientType == gtVertical) ) { TRIVERTEX vertex[2] ; vertex[0].x = GradientRect.left; vertex[0].y = GradientRect.top; vertex[0].Red = ((COLOR16)GetRValue(Color1))<<8; vertex[0].Green = ((COLOR16)GetGValue(Color1))<<8; vertex[0].Blue = ((COLOR16)GetBValue(Color1))<<8; vertex[0].Alpha = 0x0000; vertex[1].x = GradientRect.right; vertex[1].y = GradientRect.bottom; vertex[1].Red = ((COLOR16)GetRValue(Color2))<<8; vertex[1].Green = ((COLOR16)GetGValue(Color2))<<8; vertex[1].Blue = ((COLOR16)GetBValue(Color2))<<8; vertex[1].Alpha = 0x0000; GRADIENT_RECT gRect; gRect.UpperLeft = 0; gRect.LowerRight = 1; if (GradientType == gtHorizontal) pDC->GradientFill(vertex,2,&gRect,1,GRADIENT_FILL_RECT_H); else pDC->GradientFill(vertex,2,&gRect,1,GRADIENT_FILL_RECT_V); } else { for (int i=0;i<2; i++) { TRIVERTEX vertex[2] ; if (GradientType == gtHorizontalDouble) { vertex[0].x = GradientRect.left + (GradientRect.Width()/2) * i; vertex[0].y = GradientRect.top; } else { vertex[0].x = GradientRect.left; vertex[0].y = GradientRect.top + (GradientRect.Height()/2) * i; } if (i==0) { vertex[0].Red = ((COLOR16)GetRValue(Color1))<<8; vertex[0].Green = ((COLOR16)GetGValue(Color1))<<8; vertex[0].Blue = ((COLOR16)GetBValue(Color1))<<8; } else { vertex[0].Red = ((COLOR16)GetRValue(Color2))<<8; vertex[0].Green = ((COLOR16)GetGValue(Color2))<<8; vertex[0].Blue = ((COLOR16)GetBValue(Color2))<<8; } vertex[0].Alpha = 0x0000; if (GradientType == gtHorizontalDouble) { vertex[1].x = GradientRect.left + (GradientRect.Width()/2) * (i+1); vertex[1].y = GradientRect.bottom; } else { vertex[1].x = GradientRect.right; vertex[1].y = GradientRect.top + (GradientRect.Height()/2) * (i+1); } if (i==0) { vertex[1].Red = ((COLOR16)GetRValue(Color2))<<8; vertex[1].Green = ((COLOR16)GetGValue(Color2))<<8; vertex[1].Blue = ((COLOR16)GetBValue(Color2))<<8; } else { vertex[1].Red = ((COLOR16)GetRValue(Color1))<<8; vertex[1].Green = ((COLOR16)GetGValue(Color1))<<8; vertex[1].Blue = ((COLOR16)GetBValue(Color1))<<8; } vertex[1].Alpha = 0x0000; GRADIENT_RECT gRect; gRect.UpperLeft = 0; gRect.LowerRight = 1; if (GradientType == gtHorizontalDouble) pDC->GradientFill(vertex,2,&gRect,1,GRADIENT_FILL_RECT_H); else pDC->GradientFill(vertex,2,&gRect,1,GRADIENT_FILL_RECT_V); } } #else CBrush NewBrush(Color1); pDC->FillRect(GradientRect,&NewBrush); DeleteObject(NewBrush); #endif }
void CSG_SplitBrush_new( cbspbrush_t *in, cplane_t *plane, cbspbrush_t **front, cbspbrush_t **back ) { int i; int exact; polygon_t *splitpoly; cbspbrush_t *b, *f; *front = *back = NULL; // // split plane part of brush ? // exact = CSG_IsExactOnPlane( in, plane ); if ( exact == BRUSH_BACK_ON ) { *back = CopyBrush( in ); return; } if ( exact == BRUSH_FRONT_ON ) { *front = CopyBrush( in ); return; } // // real check // splitpoly = BasePolygonForPlane( plane->norm, plane->dist ); for ( i = 0; i < in->surfacenum; i++ ) { ClipPolygonInPlace( &splitpoly, in->surfaces[i].pl->norm, in->surfaces[i].pl->dist ); if ( !splitpoly ) break; } if ( !splitpoly ) { // no splitpoly => brush is not split by plane // determine on which side of plane is the complete brush int check = -1; for ( i = 0; i < in->surfacenum; i++ ) { if ( !in->surfaces[i].p ) continue; check = CheckPolygonWithPlane( in->surfaces[i].p, plane->norm, plane->dist ); if ( check == POLY_BACK ) break; else if ( check == POLY_FRONT ) break; else if ( check == POLY_ON ) continue; printf( "?" ); } if ( check == POLY_BACK ) { *back = CopyBrush( in ); return; } else if ( check == POLY_FRONT ) { *front = CopyBrush( in ); return; } else { printf( "can't get planeside of brush.\n" ); *front = NULL; *back = NULL; return; } } // // split input brush // f = NewBrush( in->surfacenum + 2 ); b = NewBrush( in->surfacenum + 2 ); f->surfacenum = b->surfacenum = 0; f->original = in->original; b->original = in->original; f->contents = in->contents; b->contents = in->contents; for( i = 0; i < in->surfacenum; i++ ) { polygon_t *fpoly, *bpoly; SplitPolygon( in->surfaces[i].p, plane->norm, plane->dist, &fpoly, &bpoly ); if ( fpoly ) { // add polygon to front brush and copy the rest if ( f->surfacenum == in->surfacenum + 2 ) Error( "reached max surfs\n" ); memcpy( &f->surfaces[f->surfacenum], &in->surfaces[i], sizeof( csurface_t ) ); f->surfaces[f->surfacenum].p = fpoly; f->surfacenum++; } if ( bpoly ) { // add polygon to back brush and copy the rest if ( b->surfacenum == in->surfacenum + 2 ) Error( "reached max surfs\n" ); memcpy( &b->surfaces[b->surfacenum], &in->surfaces[i], sizeof( csurface_t ) ); b->surfaces[b->surfacenum].p = bpoly; b->surfacenum++; } } // // add split plane to front and back brush // // the backside brush gets the plane if ( f->surfacenum == in->surfacenum + 2 ) Error( "reached max surfs\n" ); b->surfaces[b->surfacenum].pl = plane; b->surfaces[b->surfacenum].td = NULL; b->surfaces[b->surfacenum].state = SURFACE_STATE_BYSPLIT; b->surfaces[b->surfacenum].contents = 0; b->surfaces[b->surfacenum].p = splitpoly; b->surfacenum++; // the frontside brush gets the flipplane if ( b->surfacenum == in->surfacenum + 2 ) Error( "reached max surfs\n" ); f->surfaces[f->surfacenum].pl = plane->flipplane; f->surfaces[f->surfacenum].td = NULL; f->surfaces[f->surfacenum].state = SURFACE_STATE_BYSPLIT; f->surfaces[f->surfacenum].contents = 0; f->surfaces[f->surfacenum].p = PolygonFlip( splitpoly ); f->surfacenum++; if ( b->surfacenum < 4 ) { printf( "no back %d\n", b->surfacenum ); FreeBrush( b ); b = NULL; } if ( f->surfacenum < 4 ) { printf( "no front %d\n", f->surfacenum ); FreeBrush( f ); f = NULL; } if ( b ) CalcBrushBounds( b ); if ( f ) CalcBrushBounds( f ); *back = b; *front = f; }