Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

BRUSH.H File Reference

Go to the source code of this file.

Functions

int AddPlanept (float *f)
void Brush_AddToList (brush_t *b, brush_t *list)
brush_tBrush_Alloc ()
void Brush_Build (brush_t *b, bool bSnap=true, bool bMarkMap=true, bool bConvert=false)
void Brush_BuildWindings (brush_t *b, bool bSnap=true)
brush_tBrush_Clone (brush_t *b)
brush_tBrush_Create (vec3_t mins, vec3_t maxs, texdef_t *texdef)
void Brush_Draw (brush_t *b)
void Brush_DrawXY (brush_t *b, int nViewType)
void Brush_FitTexture (brush_t *b, int nHeight, int nWidth)
void Brush_Free (brush_t *b, bool bRemoveNode=true)
brush_tBrush_FullClone (brush_t *b)
const char * Brush_GetKeyValue (brush_t *b, const char *pKey)
winding_tBrush_MakeFaceWinding (brush_t *b, face_t *face)
void Brush_MakeSided (int sides)
void Brush_MakeSidedCone (int sides)
void Brush_MakeSidedSphere (int sides)
int Brush_MemorySize (brush_t *b)
void Brush_Move (brush_t *b, const vec3_t move, bool bSnap=true)
int Brush_MoveVertex (brush_t *b, vec3_t vertex, vec3_t delta, vec3_t end, bool bSnap=true)
const char * Brush_Name (brush_t *b)
brush_tBrush_Parse (void)
face_tBrush_Ray (vec3_t origin, vec3_t dir, brush_t *b, float *dist)
void Brush_RemoveEmptyFaces (brush_t *b)
void Brush_RemoveFromList (brush_t *b)
void Brush_ResetFaceOriginals (brush_t *b)
void Brush_Rotate (brush_t *b, vec3_t vAngle, vec3_t vOrigin, bool bBuild=true)
void Brush_SelectFaceForDragging (brush_t *b, face_t *f, qboolean shear)
void Brush_SetEpair (brush_t *b, const char *pKey, const char *pValue)
void Brush_SetTexture (brush_t *b, texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale=false, IPluginTexdef *pPlugTexdef=NULL)
void Brush_SideSelect (brush_t *b, vec3_t origin, vec3_t dir, qboolean shear)
void Brush_SnapToGrid (brush_t *pb)
void Brush_SplitBrushByFace (brush_t *in, face_t *f, brush_t **front, brush_t **back)
void Brush_Write (brush_t *b, CMemFile *pMemFile)
void Brush_Write (brush_t *b, FILE *f)
face_tFace_Alloc (void)
face_tFace_Clone (face_t *f)
void Face_Draw (face_t *face)
void Face_FitTexture (face_t *face, int nHeight, int nWidth)
void Face_Free (face_t *f)
void Face_MakePlane (face_t *f)
void Face_TextureVectors (face_t *f, float STfromXYZ[2][4])
void SetFaceTexdef (brush_t *b, face_t *f, texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale=false, IPluginTexdef *pPlugTexdef=NULL)
float SetShadeForPlane (plane_t *p)


Function Documentation

int AddPlanept float *  f  ) 
 

Definition at line 2987 of file Brush.cpp.

References QEGlobals_t::d_move_points, QEGlobals_t::d_num_move_points, g_qeglobals, and i.

Referenced by Brush_SelectFaceForDragging(), SelectFaceEdge(), and SelectVertex().

02988 {
02989     int     i;
02990 
02991     for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)
02992         if (g_qeglobals.d_move_points[i] == f)
02993             return 0;
02994     g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = f;
02995     return 1;
02996 }

void Brush_AddToList brush_t b,
brush_t list
 

Definition at line 2807 of file Brush.cpp.

References b, brush_t, DispatchRadiantMsg(), Error(), brush_s::next, Patch_Select(), brush_s::patchBrush, brush_s::pPatch, brush_s::prev, brush_s::pTerrain, RADIANT_SELECTION, selected_brushes, Terrain_Select(), and brush_s::terrainBrush.

Referenced by AddBrushForPatch(), AddBrushForTerrain(), AddProp(), AddRegionBrushes(), Brush_CopyList(), Brush_MakeSided(), Brush_MakeSidedCone(), Brush_MakeSidedSphere(), CPlugInManager::CommitBrushHandleToMap(), CXYWnd::Copy(), CopyAndSelect(), CopyToMap(), CreateEntityBrush(), CreateEntityFromName(), CreateSmartBrush(), CSG_MakeHollow(), CSG_Merge(), CSG_Subtract(), Map_ApplyRegion(), Map_RegionOff(), CXYWnd::NewBrushDrag(), CMainFrame::OnCreate(), CXYWnd::Paste(), CXYWnd::ProduceSplitLists(), QERApp_CreateBrush(), Select_AllOfType(), Select_Brush(), Select_Clone(), Select_CompleteTall(), Select_Inside(), Select_PartialTall(), Select_Ray(), Select_Touching(), SelectBrush(), Undo_AddBrush(), Undo_AddBrushList(), Undo_Redo(), and Undo_Undo().

02808 {
02809     if (b->next || b->prev)
02810         Error ("Brush_AddToList: allready linked");
02811     
02812     if (list == &selected_brushes || list == &active_brushes)
02813     {
02814         if (b->patchBrush && list == &selected_brushes)
02815         {
02816             Patch_Select(b->pPatch);
02817         }
02818         if (b->terrainBrush && list == &selected_brushes) {
02819             Terrain_Select(b->pTerrain);
02820         }
02821     }
02822     b->next = list->next;
02823     list->next->prev = b;
02824     list->next = b;
02825     b->prev = list;
02826     
02827     // TTimo messaging
02828     DispatchRadiantMsg( RADIANT_SELECTION );    
02829 }

Here is the call graph for this function:

brush_t* Brush_Alloc  ) 
 

Definition at line 46 of file Brush.cpp.

References b, brush_t, and qmalloc().

Referenced by Brush_Clone(), Brush_Create(), Brush_CreatePyramid(), Brush_FullClone(), Brush_MakeSided(), Brush_MakeSidedCone(), Brush_MakeSidedSphere(), Brush_Merge(), Brush_MergeList(), Brush_Parse(), and CPlugInManager::CreateBrushHandle().

00047 {
00048   brush_t *b = (brush_t*)qmalloc(sizeof(brush_t));
00049   return b;
00050 }

Here is the call graph for this function:

void Brush_Build brush_t b,
bool  bSnap = true,
bool  bMarkMap = true,
bool  bConvert = false
 

Definition at line 643 of file Brush.cpp.

References b, QEGlobals_t::bNeedConvert, Brush_BuildWindings(), brush_t, QEGlobals_t::d_select_mode, g_qeglobals, Group_AddToProperGroup(), QEGlobals_t::m_bBrushPrimitMode, Patch_BuildPoints(), sel_vertex, SetupVertexSelection(), Sys_MarkMapModified(), and Sys_Printf().

Referenced by AddBrushForPatch(), AddBrushForTerrain(), AddProp(), AddRegionBrushes(), Brush_FullClone(), Brush_MakeSided(), Brush_MakeSidedCone(), Brush_MakeSidedSphere(), Brush_Move(), Brush_RebuildBrush(), Brush_Resize(), Brush_Rotate(), Brush_SetTexture(), Brush_SnapToGrid(), Brush_SplitBrushByFace(), CPlugInManager::CommitBrushHandleToMap(), CPlugInManager::CommitEntityHandleToMap(), CXYWnd::Copy(), CopyAndSelect(), CopyBrush(), CopyToMap(), CreateEntityBrush(), CreateEntityFromName(), CreateSmartBrush(), Drag_Begin(), Entity_Create(), Entity_Parse(), FindReplaceTextures(), Map_BuildBrushData(), Map_ImportBuffer(), MoveSelection(), CXYWnd::NewBrushDrag(), CMainFrame::OnBrushFlipx(), CMainFrame::OnBrushFlipy(), CMainFrame::OnCreate(), CXYWnd::Paste(), QERApp_BuildBrush(), QERApp_BuildBrush2(), QERApp_CreateBrush(), QERApp_SetFaceInfo(), RotateTextures(), Select_ApplyMatrix(), Select_Clone(), Select_FitTexture(), Select_RotateTexture(), Select_Scale(), Select_ScaleTexture(), Select_SetTexture(), Select_ShiftTexture(), and Select_Ungroup().

00644 {
00645     bool        bLocalConvert;
00646 
00647 #ifdef _DEBUG
00648     if (!g_qeglobals.m_bBrushPrimitMode && bConvert)
00649         Sys_Printf("Warning : conversion from brush primitive to old brush format not implemented\n");
00650 #endif
00651 
00652     // if bConvert is set and g_qeglobals.bNeedConvert is not, that just means we need convert for this brush only
00653     if (bConvert && !g_qeglobals.bNeedConvert)
00654     {
00655         bLocalConvert = true;
00656         g_qeglobals.bNeedConvert = true;
00657     }
00658 
00659     /*
00660     ** build the windings and generate the bounding box
00661     */
00662     Brush_BuildWindings(b, bSnap);
00663 
00664     Patch_BuildPoints (b);
00665 
00666     /*
00667     ** move the points and edges if in select mode
00668     */
00669     if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge)
00670         SetupVertexSelection ();
00671 
00672     if (b->itemOwner == NULL)
00673       Group_AddToProperGroup(b);
00674 
00675     if (bMarkMap)
00676     {
00677         Sys_MarkMapModified();
00678     }
00679 
00680     if (bLocalConvert)
00681         g_qeglobals.bNeedConvert = false;
00682 }

Here is the call graph for this function:

void Brush_BuildWindings brush_t b,
bool  bSnap = true
 

Definition at line 3150 of file Brush.cpp.

References b, QEGlobals_t::bNeedConvert, brush_s::brush_faces, Brush_MakeFacePlanes(), Brush_MakeFaceWinding(), Brush_SnapPlanepts(), brush_t, face_s::d_texture, EmitBrushPrimitTextureCoordinates(), EmitTextureCoordinates(), Face_SetColor(), face_t, face_s::face_winding, FaceToBrushPrimitFace(), free(), g_qeglobals, i, j, QEGlobals_t::m_bBrushPrimitMode, brush_s::maxs, brush_s::mins, texdef_t::name, face_s::next, winding_t::numpoints, winding_t::points, face_s::texdef, Texture_ForName(), v, vec_t, and w.

Referenced by Brush_Build(), Brush_Merge(), and Brush_MergeList().

03151 {
03152     winding_t *w;
03153     face_t    *face;
03154     vec_t      v;
03155 
03156     if (bSnap)
03157         Brush_SnapPlanepts( b );
03158 
03159     // clear the mins/maxs bounds
03160     b->mins[0] = b->mins[1] = b->mins[2] = 99999;
03161     b->maxs[0] = b->maxs[1] = b->maxs[2] = -99999;
03162 
03163     Brush_MakeFacePlanes (b);
03164 
03165     face = b->brush_faces;
03166 
03167     float fCurveColor = 1.0;
03168 
03169     for ( ; face ; face=face->next)
03170     {
03171         int i, j;
03172         free(face->face_winding);
03173         w = face->face_winding = Brush_MakeFaceWinding (b, face);
03174         face->d_texture = Texture_ForName( face->texdef.name );
03175 
03176         if (!w)
03177             continue;
03178     
03179         for (i=0 ; i<w->numpoints ; i++)
03180         {
03181             // add to bounding box
03182             for (j=0 ; j<3 ; j++)
03183             {
03184                 v = w->points[i][j];
03185                 if (v > b->maxs[j])
03186                     b->maxs[j] = v;
03187                 if (v < b->mins[j])
03188                     b->mins[j] = v;
03189             }
03190         }
03191         // setup s and t vectors, and set color
03192         //if (!g_PrefsDlg.m_bGLLighting)
03193     //{
03194           Face_SetColor (b, face, fCurveColor);
03195     //}
03196 
03197         fCurveColor -= .10;
03198         if (fCurveColor <= 0)
03199             fCurveColor = 1.0;
03200 
03201         // computing ST coordinates for the windings
03202         if (g_qeglobals.m_bBrushPrimitMode)
03203         {
03204             if (g_qeglobals.bNeedConvert)
03205             {
03206                 // we have parsed old brushes format and need conversion
03207                 // convert old brush texture representation to new format
03208                 FaceToBrushPrimitFace(face);
03209 #ifdef _DEBUG
03210                 // use old texture coordinates code to check against
03211                 for (i=0 ; i<w->numpoints ; i++)
03212                     EmitTextureCoordinates( w->points[i], face->d_texture, face);
03213 #endif
03214             }
03215             // use new texture representation to compute texture coordinates
03216             // in debug mode we will check against old code and warn if there are differences
03217             EmitBrushPrimitTextureCoordinates(face,w);
03218         }
03219         else
03220         {
03221             for (i=0 ; i<w->numpoints ; i++)
03222                 EmitTextureCoordinates( w->points[i], face->d_texture, face);
03223         }
03224     }
03225 }

Here is the call graph for this function:

brush_t* Brush_Clone brush_t b  ) 
 

Definition at line 2619 of file Brush.cpp.

References b, Brush_Alloc(), brush_s::brush_faces, Brush_RemoveFromList(), brush_t, Entity_UnlinkBrush(), f, Face_Clone(), face_t, g_nBrushId, n, face_s::next, brush_s::numberId, brush_s::owner, p, Patch_Duplicate(), brush_s::patchBrush, brush_s::pPatch, terrainMesh_t::pSymbiot, patchMesh_t::pSymbiot, brush_s::pTerrain, Terrain_Duplicate(), and brush_s::terrainBrush.

Referenced by Brush_SplitBrushByFace(), CXYWnd::Copy(), CopyBrush(), CXYWnd::Paste(), and Select_Clone().

02620 {
02621     brush_t *n = NULL;
02622     face_t  *f, *nf;
02623 
02624     if (b->patchBrush)
02625     {
02626         patchMesh_t *p = Patch_Duplicate(b->pPatch);
02627         Brush_RemoveFromList(p->pSymbiot);
02628         Entity_UnlinkBrush(p->pSymbiot);
02629         n = p->pSymbiot;
02630     }
02631     else if (b->terrainBrush)
02632     {
02633         terrainMesh_t *p = Terrain_Duplicate(b->pTerrain);
02634         Brush_RemoveFromList(p->pSymbiot);
02635         Entity_UnlinkBrush(p->pSymbiot);
02636         n = p->pSymbiot;
02637     }
02638     else
02639     {
02640     n = Brush_Alloc();
02641       n->numberId = g_nBrushId++;
02642         n->owner = b->owner;
02643         for (f=b->brush_faces ; f ; f=f->next)
02644         {
02645             nf = Face_Clone( f );
02646             nf->next = n->brush_faces;
02647             n->brush_faces = nf;
02648         }
02649     }
02650 
02651     return n;
02652 }

Here is the call graph for this function:

brush_t* Brush_Create vec3_t  mins,
vec3_t  maxs,
texdef_t texdef
 

Definition at line 2210 of file Brush.cpp.

References b, Brush_Alloc(), brush_s::brush_faces, brush_t, texdef_t::contents, Error(), f, Face_Alloc(), face_t, texdef_t::flags, g_qeglobals, i, j, QEGlobals_t::m_bBrushPrimitMode, face_s::next, face_s::planepts, texdef_t::rotate, texdef_t::scale, texdef_t::shift, Sys_Printf(), face_s::texdef, vec3_t, and VectorCopy.

Referenced by AddBrushForPatch(), AddBrushForTerrain(), AddProp(), AddRegionBrushes(), Brush_CreatePyramid(), Brush_Resize(), CPlugInManager::CommitEntityHandleToMap(), CreateEntityBrush(), CreateEntityFromName(), CreateSmartBrush(), Entity_Create(), Entity_Parse(), CXYWnd::NewBrushDrag(), CMainFrame::OnCreate(), and QERApp_CreateBrush().

02211 {
02212     int     i, j;
02213     vec3_t  pts[4][2];
02214     face_t  *f;
02215     brush_t *b;
02216 
02217     // brush primitive mode : convert texdef to brushprimit_texdef ?
02218     // most of the time texdef is empty
02219     if (g_qeglobals.m_bBrushPrimitMode)
02220     {
02221         // check texdef is empty .. if there are cases it's not we need to write some conversion code
02222         if (texdef->shift[0]!=0 || texdef->shift[1]!=0 || texdef->scale[0]!=0 || texdef->scale[1]!=0 || texdef->rotate!=0)
02223             Sys_Printf("Warning : non-zero texdef detected in Brush_Create .. need brush primitive conversion\n");
02224     }
02225 
02226     for (i=0 ; i<3 ; i++)
02227     {
02228         if (maxs[i] < mins[i])
02229             Error ("Brush_InitSolid: backwards");
02230     }
02231 
02232     b = Brush_Alloc();
02233     
02234     pts[0][0][0] = mins[0];
02235     pts[0][0][1] = mins[1];
02236     
02237     pts[1][0][0] = mins[0];
02238     pts[1][0][1] = maxs[1];
02239     
02240     pts[2][0][0] = maxs[0];
02241     pts[2][0][1] = maxs[1];
02242     
02243     pts[3][0][0] = maxs[0];
02244     pts[3][0][1] = mins[1];
02245     
02246     for (i=0 ; i<4 ; i++)
02247     {
02248         pts[i][0][2] = mins[2];
02249         pts[i][1][0] = pts[i][0][0];
02250         pts[i][1][1] = pts[i][0][1];
02251         pts[i][1][2] = maxs[2];
02252     }
02253 
02254     for (i=0 ; i<4 ; i++)
02255     {
02256         f = Face_Alloc();
02257         f->texdef = *texdef;
02258         f->texdef.flags &= ~SURF_KEEP;
02259         f->texdef.contents &= ~CONTENTS_KEEP;
02260         f->next = b->brush_faces;
02261         b->brush_faces = f;
02262         j = (i+1)%4;
02263 
02264         VectorCopy (pts[j][1], f->planepts[0]);
02265         VectorCopy (pts[i][1], f->planepts[1]);
02266         VectorCopy (pts[i][0], f->planepts[2]);
02267     }
02268     
02269     f = Face_Alloc();
02270     f->texdef = *texdef;
02271     f->texdef.flags &= ~SURF_KEEP;
02272     f->texdef.contents &= ~CONTENTS_KEEP;
02273     f->next = b->brush_faces;
02274     b->brush_faces = f;
02275 
02276     VectorCopy (pts[0][1], f->planepts[0]);
02277     VectorCopy (pts[1][1], f->planepts[1]);
02278     VectorCopy (pts[2][1], f->planepts[2]);
02279 
02280     f = Face_Alloc();
02281     f->texdef = *texdef;
02282     f->texdef.flags &= ~SURF_KEEP;
02283     f->texdef.contents &= ~CONTENTS_KEEP;
02284     f->next = b->brush_faces;
02285     b->brush_faces = f;
02286 
02287     VectorCopy (pts[2][0], f->planepts[0]);
02288     VectorCopy (pts[1][0], f->planepts[1]);
02289     VectorCopy (pts[0][0], f->planepts[2]);
02290 
02291     return b;
02292 }

Here is the call graph for this function:

void Brush_Draw brush_t b  ) 
 

Definition at line 3920 of file Brush.cpp.

References b, qtexture_s::bFromShader, brush_s::bModelFailed, Brush_DrawFacingAngle(), brush_s::brush_faces, brush_t, CCamWnd::Camera(), IPluginEntity::CamRender(), cd_texture, face_s::d_color, QEGlobals_t::d_savedinfo, face_s::d_texture, camera_t::draw_mode, DrawLight(), entity_s::eclass, SavedInfo_t::exclude, face_t, face_s::face_winding, eclass_s::fixedsize, texdef_t::flags, qtexture_s::fTrans, g_pParentWnd, g_PrefsDlg, g_qeglobals, CMainFrame::GetCamera(), brush_s::hiddenBrush, i, CPrefsDlg::m_bGLLighting, CPrefsDlg::m_bNewLightDraw, texdef_t::name, face_s::next, plane_t::normal, eclass_s::nShowFlags, winding_t::numpoints, order, brush_s::owner, PaintedModel(), Patch_DrawCam(), brush_s::patchBrush, face_s::plane, winding_t::points, brush_s::pPatch, entity_s::pPlugEnt, brush_s::pTerrain, qglBegin, qglBindTexture, qglColor3fv, qglColor4f, qglDisable, qglEnable, qglEnd, qglNormal3fv, qglTexCoord2fv, qglVertex3fv, qtexture_t, strstr(), Terrain_DrawCam(), brush_s::terrainBrush, face_s::texdef, qtexture_s::texture_number, and w.

Referenced by CCamWnd::Cam_Draw().

03921 {
03922     face_t          *face;
03923     int             i, order;
03924     qtexture_t      *prev = 0;
03925     winding_t *w;
03926 
03927     if ( b->owner && ( b->owner->eclass->nShowFlags & ECLASS_PLUGINENTITY ) )
03928     {
03929         b->owner->pPlugEnt->CamRender();
03930         return;
03931     }
03932     
03933     // (TTimo) NOTE: added by build 173, I check after pPlugEnt so it doesn't interfere ?
03934     if (b->hiddenBrush)
03935     {
03936         return;
03937     }
03938 
03939     if (b->patchBrush)
03940     {
03941         //Patch_DrawCam(b->nPatchID);
03942         Patch_DrawCam(b->pPatch);
03943         //if (!g_bPatchShowBounds)
03944         return;
03945     }
03946     
03947     if (b->terrainBrush)
03948     {
03949         Terrain_DrawCam(b->pTerrain);
03950         return;
03951     }
03952 
03953     int nDrawMode = g_pParentWnd->GetCamera()->Camera().draw_mode;
03954     
03955     if (b->owner->eclass->fixedsize)
03956     {
03957         
03958         if (!(g_qeglobals.d_savedinfo.exclude & EXCLUDE_ANGLES) && (b->owner->eclass->nShowFlags & ECLASS_ANGLE))
03959         {
03960             Brush_DrawFacingAngle(b, b->owner);
03961         }
03962         
03963         if (g_PrefsDlg.m_bNewLightDraw && (b->owner->eclass->nShowFlags & ECLASS_LIGHT))
03964         {
03965             DrawLight(b);
03966             return;
03967         }
03968         if (nDrawMode == cd_texture || nDrawMode == cd_light)
03969             qglDisable (GL_TEXTURE_2D);
03970         
03971         // if we are wireframing models
03972         bool bp = (b->bModelFailed) ? false : PaintedModel(b, true);
03973         
03974         if (nDrawMode == cd_texture || nDrawMode == cd_light)
03975             qglEnable (GL_TEXTURE_2D);
03976         
03977         if (bp)
03978             return;
03979     }
03980     
03981     // guarantee the texture will be set first
03982     prev = NULL;
03983     for (face = b->brush_faces,order = 0 ; face ; face=face->next, order++)
03984     {
03985         w = face->face_winding;
03986         if (!w)
03987         {
03988             continue;       // freed face
03989         }
03990         
03991         if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK)
03992         {
03993             if (strstr(face->texdef.name, "caulk"))
03994             {
03995                 continue;
03996             }
03997         }
03998         
03999 #if 0
04000         if (b->alphaBrush)
04001         {
04002             if (!(face->texdef.flags & SURF_ALPHA))
04003                 continue;
04004             //--qglPushAttrib(GL_ALL_ATTRIB_BITS);
04005             qglDisable(GL_CULL_FACE);
04006             //--qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
04007             //--qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
04008             //--qglDisable(GL_DEPTH_TEST);
04009             //--qglBlendFunc (GL_SRC_ALPHA, GL_DST_ALPHA);
04010             //--qglEnable (GL_BLEND);
04011         }
04012 #endif
04013         
04014         if ((nDrawMode == cd_texture || nDrawMode == cd_light) && face->d_texture != prev)
04015         {
04016             // set the texture for this face
04017             prev = face->d_texture;
04018             qglBindTexture( GL_TEXTURE_2D, face->d_texture->texture_number );
04019         }
04020         
04021         
04022         
04023         if (!b->patchBrush)
04024         {
04025             if (face->texdef.flags & SURF_TRANS33) 
04026                 qglColor4f ( face->d_color[0], face->d_color[1], face->d_color[2], 0.33 );
04027             else if ( face->texdef.flags & SURF_TRANS66) 
04028                 qglColor4f ( face->d_color[0], face->d_color[1], face->d_color[2], 0.66 );
04029             else
04030                 qglColor3fv( face->d_color );
04031         }
04032         else
04033         {
04034             qglColor4f ( face->d_color[0], face->d_color[1], face->d_color[2], 0.13 );
04035         }
04036         
04037         // shader drawing stuff
04038         if (face->d_texture->bFromShader)
04039         {
04040             // setup shader drawing
04041             qglColor4f ( face->d_color[0], face->d_color[1], face->d_color[2], face->d_texture->fTrans );
04042             
04043         }
04044         
04045         // draw the polygon
04046         
04047         //if (nDrawMode == cd_light)
04048         //{
04049         if (g_PrefsDlg.m_bGLLighting)
04050         {
04051             qglNormal3fv(face->plane.normal);
04052         }
04053         //}
04054         
04055         qglBegin(GL_POLYGON);
04056         //if (nDrawMode == cd_light)
04057         
04058         for (i=0 ; i<w->numpoints ; i++)
04059         {
04060             if (nDrawMode == cd_texture || nDrawMode == cd_light)
04061                 qglTexCoord2fv( &w->points[i][3] );
04062             qglVertex3fv(w->points[i]);
04063         }
04064         qglEnd();
04065     }
04066     
04067 #if 0
04068     if (b->alphaBrush)
04069     {
04070         //--qglPopAttrib();
04071         qglEnable(GL_CULL_FACE);
04072         //--qglDisable (GL_BLEND);
04073         //--qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
04074     }
04075 #endif
04076     
04077     if (b->owner->eclass->fixedsize && (nDrawMode == cd_texture || nDrawMode == cd_light))
04078         qglEnable (GL_TEXTURE_2D);
04079     
04080     qglBindTexture( GL_TEXTURE_2D, 0 );
04081 }

Here is the call graph for this function:

void Brush_DrawXY brush_t b,
int  nViewType
 

Definition at line 4097 of file Brush.cpp.

References b, brush_s::brush_faces, brush_t, DrawBrushEntityName(), entity_s::eclass, face_t, face_s::face_winding, eclass_s::fixedsize, g_PrefsDlg, brush_s::hiddenBrush, i, CPrefsDlg::m_bNewLightDraw, brush_s::maxs, brush_s::mins, face_s::next, plane_t::normal, eclass_s::nShowFlags, winding_t::numpoints, order, brush_s::owner, PaintedModel(), Patch_DrawXY(), brush_s::patchBrush, face_s::plane, winding_t::points, brush_s::pPatch, brush_s::pTerrain, qglBegin, qglEnd, qglPolygonMode, qglVertex3fv, Terrain_DrawXY(), brush_s::terrainBrush, vec3_t, VectorCopy, and w.

Referenced by CXYWnd::XY_Draw().

04098 {
04099     face_t *face;
04100     int     order;
04101     winding_t *w;
04102     int        i;
04103 
04104     if (b->hiddenBrush)
04105     {
04106         return;
04107     }
04108 
04109     if (b->patchBrush)
04110     {
04111         //Patch_DrawXY(b->nPatchID);
04112         Patch_DrawXY(b->pPatch);
04113         if (!g_bPatchShowBounds)
04114             return;
04115     }
04116 
04117     if (b->terrainBrush)
04118     {
04119         Terrain_DrawXY(b->pTerrain, b->owner);
04120     }
04121                      
04122 
04123     if (b->owner->eclass->fixedsize)
04124     {
04125         if (g_PrefsDlg.m_bNewLightDraw && (b->owner->eclass->nShowFlags & ECLASS_LIGHT))
04126         {
04127             vec3_t vCorners[4];
04128             float fMid = b->mins[2] + (b->maxs[2] - b->mins[2]) / 2;
04129 
04130             vCorners[0][0] = b->mins[0];
04131             vCorners[0][1] = b->mins[1];
04132             vCorners[0][2] = fMid;
04133 
04134             vCorners[1][0] = b->mins[0];
04135             vCorners[1][1] = b->maxs[1];
04136             vCorners[1][2] = fMid;
04137 
04138             vCorners[2][0] = b->maxs[0];
04139             vCorners[2][1] = b->maxs[1];
04140             vCorners[2][2] = fMid;
04141 
04142             vCorners[3][0] = b->maxs[0];
04143             vCorners[3][1] = b->mins[1];
04144             vCorners[3][2] = fMid;
04145 
04146             vec3_t vTop, vBottom;
04147 
04148             vTop[0] = b->mins[0] + ((b->maxs[0] - b->mins[0]) / 2);
04149             vTop[1] = b->mins[1] + ((b->maxs[1] - b->mins[1]) / 2);
04150             vTop[2] = b->maxs[2];
04151 
04152             VectorCopy(vTop, vBottom);
04153             vBottom[2] = b->mins[2];
04154 
04155             qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
04156             qglBegin(GL_TRIANGLE_FAN);
04157             qglVertex3fv(vTop);
04158             qglVertex3fv(vCorners[0]);
04159             qglVertex3fv(vCorners[1]);
04160             qglVertex3fv(vCorners[2]);
04161             qglVertex3fv(vCorners[3]);
04162             qglVertex3fv(vCorners[0]);
04163             qglEnd();
04164             qglBegin(GL_TRIANGLE_FAN);
04165             qglVertex3fv(vBottom);
04166             qglVertex3fv(vCorners[0]);
04167             qglVertex3fv(vCorners[3]);
04168             qglVertex3fv(vCorners[2]);
04169             qglVertex3fv(vCorners[1]);
04170             qglVertex3fv(vCorners[0]);
04171             qglEnd();
04172             DrawBrushEntityName (b);
04173             return;
04174         }
04175         else if (b->owner->eclass->nShowFlags & ECLASS_MISCMODEL)
04176         {
04177             if (PaintedModel(b, false))
04178             return;
04179         }
04180     }
04181 
04182     for (face = b->brush_faces,order = 0 ; face ; face=face->next, order++)
04183     {
04184         // only draw polygons facing in a direction we care about
04185     if (nViewType == XY)
04186     {
04187           if (face->plane.normal[2] <= 0)
04188               continue;
04189     }
04190     else
04191     {
04192       if (nViewType == XZ)
04193       {
04194         if (face->plane.normal[1] <= 0)
04195           continue;
04196       }
04197       else 
04198       {
04199         if (face->plane.normal[0] <= 0)
04200           continue;
04201       }
04202     }
04203 
04204         w = face->face_winding;
04205         if (!w)
04206             continue;
04207 
04208     //if (b->alphaBrush && !(face->texdef.flags & SURF_ALPHA))
04209     //  continue;
04210 
04211         // draw the polygon
04212         qglBegin(GL_LINE_LOOP);
04213     for (i=0 ; i<w->numpoints ; i++)
04214           qglVertex3fv(w->points[i]);
04215         qglEnd();
04216     }
04217 
04218     DrawBrushEntityName (b);
04219 
04220 }

Here is the call graph for this function:

void Brush_FitTexture brush_t b,
int  nHeight,
int  nWidth
 

Definition at line 4585 of file Brush.cpp.

References b, brush_s::brush_faces, brush_t, Face_FitTexture(), face_t, and face_s::next.

Referenced by Select_FitTexture().

04586 {
04587     face_t *face;
04588 
04589     for (face = b->brush_faces ; face ; face=face->next)
04590   {
04591     Face_FitTexture( face, nHeight, nWidth );
04592   }
04593 }

Here is the call graph for this function:

void Brush_Free brush_t b,
bool  bRemoveNode = true
 

Definition at line 2510 of file Brush.cpp.

References b, brush_s::brush_faces, Brush_RemoveFromList(), brush_t, Entity_UnlinkBrush(), epair_t, brush_s::epairs, f, Face_Free(), face_t, free(), Group_RemoveBrush(), epair_s::key, brush_s::next, epair_s::next, face_s::next, next, brush_s::onext, Patch_Delete(), brush_s::patchBrush, brush_s::pPatch, brush_s::pTerrain, Terrain_Delete(), brush_s::terrainBrush, and epair_s::value.

Referenced by AddProp(), Brush_MakeConvexBrushes(), Brush_MakeSided(), Brush_MakeSidedCone(), Brush_MakeSidedSphere(), Brush_MergeListPairs(), Brush_SplitBrushByFace(), Brush_Subtract(), CleanList(), CPlugInManager::Cleanup(), CreateEntityFromName(), CSG_MakeHollow(), CSG_Merge(), CSG_Subtract(), Entity_Free(), Entity_Parse(), Map_BuildBrushData(), Map_Free(), CXYWnd::NewBrushDrag(), CMainFrame::OnDestroy(), QERApp_DeletePatch(), RemoveRegionBrushes(), Select_Delete(), Undo_Clear(), Undo_ClearRedo(), and Undo_FreeFirstUndo().

02511 {
02512     face_t  *f, *next;
02513     epair_t *ep, *enext;
02514 
02515     // remove from group
02516     if (bRemoveNode)
02517         Group_RemoveBrush(b);
02518 
02519     // free the patch if it's there
02520     if (b->patchBrush)
02521     {
02522         Patch_Delete(b->pPatch);
02523     }
02524 
02525     if( b->terrainBrush )
02526     {
02527         Terrain_Delete( b->pTerrain );
02528     }
02529 
02530     // free faces
02531     for (f=b->brush_faces ; f ; f=next)
02532     {
02533         next = f->next;
02534         Face_Free( f );
02535     }
02536 
02537     //Timo : free brush epairs
02538     for (ep = b->epairs ; ep ; ep=enext )
02539     {
02540         enext = ep->next;
02541         free (ep->key);
02542         free (ep->value);
02543         free (ep);
02544     }
02545 
02546     // unlink from active/selected list
02547     if (b->next)
02548         Brush_RemoveFromList (b);
02549 
02550     // unlink from entity list
02551     if (b->onext)
02552         Entity_UnlinkBrush (b);
02553 
02554     free (b);
02555 }

Here is the call graph for this function:

brush_t* Brush_FullClone brush_t b  ) 
 

Definition at line 2663 of file Brush.cpp.

References b, Brush_Alloc(), Brush_Build(), brush_s::brush_faces, Brush_RemoveFromList(), brush_t, face_s::d_texture, EmitBrushPrimitTextureCoordinates(), EmitTextureCoordinates(), Entity_UnlinkBrush(), f, f2(), Face_FullClone(), Face_SetColor(), face_t, face_s::face_winding, g_nBrushId, g_qeglobals, j, QEGlobals_t::m_bBrushPrimitMode, brush_s::maxs, brush_s::mins, n, face_s::next, brush_s::numberId, winding_t::numpoints, face_s::original, brush_s::owner, p, Patch_Duplicate(), brush_s::patchBrush, winding_t::points, brush_s::pPatch, terrainMesh_t::pSymbiot, patchMesh_t::pSymbiot, brush_s::pTerrain, Terrain_Duplicate(), brush_s::terrainBrush, and VectorCopy.

Referenced by Undo_AddBrush(), and Undo_AddBrushList().

02664 {
02665     brush_t *n = NULL;
02666     face_t *f, *nf, *f2, *nf2;
02667     int j;
02668 
02669     if (b->patchBrush)
02670     {
02671         patchMesh_t *p = Patch_Duplicate(b->pPatch);
02672         Brush_RemoveFromList(p->pSymbiot);
02673         Entity_UnlinkBrush(p->pSymbiot);
02674         n = p->pSymbiot;
02675         n->owner = b->owner;
02676         Brush_Build(n);
02677     }
02678     else if (b->terrainBrush)
02679     {
02680         terrainMesh_t *p = Terrain_Duplicate(b->pTerrain);
02681         Brush_RemoveFromList(p->pSymbiot);
02682         Entity_UnlinkBrush(p->pSymbiot);
02683         n = p->pSymbiot;
02684         n->owner = b->owner;
02685         Brush_Build(n);
02686     }
02687     else
02688     {
02689     n = Brush_Alloc();
02690     n->numberId = g_nBrushId++;
02691         n->owner = b->owner;
02692         VectorCopy(b->mins, n->mins);
02693         VectorCopy(b->maxs, n->maxs);
02694         //
02695         for (f = b->brush_faces; f; f = f->next)
02696         {
02697             if (f->original) continue;
02698             nf = Face_FullClone(f);
02699             nf->next = n->brush_faces;
02700             n->brush_faces = nf;
02701             //copy all faces that have the original set to this face
02702             for (f2 = b->brush_faces; f2; f2 = f2->next)
02703             {
02704                 if (f2->original == f)
02705                 {
02706                     nf2 = Face_FullClone(f2);
02707                     nf2->next = n->brush_faces;
02708                     n->brush_faces = nf2;
02709                     //set original
02710                     nf2->original = nf;
02711                 }
02712             }
02713         }
02714         for (nf = n->brush_faces; nf; nf = nf->next)
02715         {
02716             Face_SetColor(n, nf, 1.0);
02717             if (nf->face_winding)
02718       {
02719         if (g_qeglobals.m_bBrushPrimitMode)
02720                 EmitBrushPrimitTextureCoordinates(nf,nf->face_winding);
02721         else
02722         {
02723                   for (j = 0; j < nf->face_winding->numpoints; j++)
02724                     EmitTextureCoordinates(nf->face_winding->points[j], nf->d_texture, nf);
02725         }
02726       }
02727         }
02728   }
02729     return n;
02730 }

Here is the call graph for this function:

const char* Brush_GetKeyValue brush_t b,
const char *  pKey
 

Definition at line 1902 of file Brush.cpp.

References b, brush_t, brush_s::epairs, g_qeglobals, QEGlobals_t::m_bBrushPrimitMode, Patch_GetKeyValue(), brush_s::patchBrush, brush_s::pPatch, brush_s::pTerrain, Sys_Printf(), Terrain_GetKeyValue(), brush_s::terrainBrush, and ValueForKey().

Referenced by Group_AddToItem(), and Group_AddToProperGroup().

01903 {
01904     if (g_qeglobals.m_bBrushPrimitMode)
01905     {
01906     if (b->patchBrush)
01907     {
01908       return Patch_GetKeyValue(b->pPatch, pKey);
01909     }
01910     else if (b->terrainBrush)
01911     {
01912       return Terrain_GetKeyValue(b->pTerrain, pKey);
01913     }
01914     else
01915     {
01916           return ValueForKey(b->epairs, pKey);
01917     }
01918     }
01919     else
01920     {
01921         Sys_Printf("Can only set brush/patch key/values in Brush primitive mode\n");
01922     }
01923   return "";
01924 }

Here is the call graph for this function:

winding_t* Brush_MakeFaceWinding brush_t b,
face_t face
 

Definition at line 564 of file Brush.cpp.

References b, brush_s::brush_faces, brush_t, plane_t::dist, DotProduct, fabs(), face_t, free(), face_s::next, plane_t::normal, face_s::plane, printf(), qboolean, vec3_origin, VectorSubtract, w, Winding_BaseForPlane(), and Winding_Clip().

Referenced by Brush_BuildWindings(), Brush_SelectFaceForDragging(), MakeFace(), SelectFaceEdge(), and SelectVertex().

00565 {
00566     winding_t   *w;
00567     face_t      *clip;
00568     plane_t         plane;
00569     qboolean        past;
00570 
00571     // get a poly that covers an effectively infinite area
00572     w = Winding_BaseForPlane (&face->plane);
00573 
00574     // chop the poly by all of the other faces
00575     past = false;
00576     for (clip = b->brush_faces ; clip && w ; clip=clip->next)
00577     {
00578         if (clip == face)
00579         {
00580             past = true;
00581             continue;
00582         }
00583         if (DotProduct (face->plane.normal, clip->plane.normal) > 0.999
00584             && fabs(face->plane.dist - clip->plane.dist) < 0.01 )
00585         {   // identical plane, use the later one
00586             if (past)
00587             {
00588                 free (w);
00589                 return NULL;
00590             }
00591             continue;
00592         }
00593 
00594         // flip the plane, because we want to keep the back side
00595         VectorSubtract (vec3_origin,clip->plane.normal, plane.normal);
00596         plane.dist = -clip->plane.dist;
00597         
00598         w = Winding_Clip (w, &plane, false);
00599         if (!w)
00600             return w;
00601     }
00602     
00603     if (w->numpoints < 3)
00604     {
00605         free(w);
00606         w = NULL;
00607     }
00608 
00609     if (!w)
00610         printf ("unused plane\n");
00611 
00612     return w;
00613 }

Here is the call graph for this function:

void Brush_MakeSided int  sides  ) 
 

Definition at line 2382 of file Brush.cpp.

References CMainFrame::ActiveXY(), b, Brush_AddToList(), Brush_Alloc(), Brush_Build(), brush_s::brush_faces, Brush_Free(), brush_t, cos(), QEGlobals_t::d_texturewin, Entity_LinkBrush(), f, Face_Alloc(), face_t, floor(), g_pParentWnd, g_qeglobals, CXYWnd::GetViewType(), i, MAX_POINTS_ON_WINDING, brush_s::maxs, brush_s::mins, face_s::next, brush_s::next, face_s::planepts, QE_SingleBrush(), selected_brushes, sin(), sv, Sys_Printf(), Sys_Status(), Sys_UpdateWindows(), face_s::texdef, texturewin_t::texdef, vec3_t, VectorCopy, W_ALL, width, world_entity, XY, XZ, and YZ.

Referenced by CMainFrame::OnBrush3sided(), CMainFrame::OnBrush4sided(), CMainFrame::OnBrush5sided(), CMainFrame::OnBrush6sided(), CMainFrame::OnBrush7sided(), CMainFrame::OnBrush8sided(), CMainFrame::OnBrush9sided(), and SidesDlgProc().

02383 {
02384     int     i, axis;
02385     vec3_t  mins, maxs;
02386     brush_t *b;
02387     texdef_t    *texdef;
02388     face_t  *f;
02389     vec3_t  mid;
02390     float   width;
02391     float   sv, cv;
02392 
02393     if (sides < 3)
02394     {
02395         Sys_Status ("Bad sides number", 0);
02396         return;
02397     }
02398 
02399     if (sides >= MAX_POINTS_ON_WINDING-4)
02400     {
02401         Sys_Printf("too many sides.\n");
02402         return;
02403     }
02404 
02405     if (!QE_SingleBrush ())
02406     {
02407         Sys_Status ("Must have a single brush selected", 0 );
02408         return;
02409     }
02410 
02411     b = selected_brushes.next;
02412     VectorCopy (b->mins, mins);
02413     VectorCopy (b->maxs, maxs);
02414     texdef = &g_qeglobals.d_texturewin.texdef;
02415 
02416     Brush_Free (b);
02417 
02418     if (g_pParentWnd->ActiveXY())
02419     {
02420         switch(g_pParentWnd->ActiveXY()->GetViewType())
02421         {
02422             case XY: axis = 2; break;
02423             case XZ: axis = 1; break;
02424             case YZ: axis = 0; break;
02425         }
02426     }
02427     else
02428     {
02429         axis = 2;
02430     }
02431 
02432     // find center of brush
02433     width = 8;
02434     for (i = 0; i < 3; i++)
02435     {
02436         mid[i] = (maxs[i] + mins[i]) * 0.5;
02437         if (i == axis) continue;
02438         if ((maxs[i] - mins[i]) * 0.5 > width)
02439             width = (maxs[i] - mins[i]) * 0.5;
02440     }
02441 
02442     b = Brush_Alloc();
02443         
02444     // create top face
02445     f = Face_Alloc();
02446     f->texdef = *texdef;
02447     f->next = b->brush_faces;
02448     b->brush_faces = f;
02449 
02450     f->planepts[2][(axis+1)%3] = mins[(axis+1)%3]; f->planepts[2][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[2][axis] = maxs[axis];
02451     f->planepts[1][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[1][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[1][axis] = maxs[axis];
02452     f->planepts[0][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[0][(axis+2)%3] = maxs[(axis+2)%3]; f->planepts[0][axis] = maxs[axis];
02453 
02454     // create bottom face
02455     f = Face_Alloc();
02456     f->texdef = *texdef;
02457     f->next = b->brush_faces;
02458     b->brush_faces = f;
02459 
02460     f->planepts[0][(axis+1)%3] = mins[(axis+1)%3]; f->planepts[0][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[0][axis] = mins[axis];
02461     f->planepts[1][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[1][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[1][axis] = mins[axis];
02462     f->planepts[2][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[2][(axis+2)%3] = maxs[(axis+2)%3]; f->planepts[2][axis] = mins[axis];
02463 
02464     for (i=0 ; i<sides ; i++)
02465     {
02466         f = Face_Alloc();
02467         f->texdef = *texdef;
02468         f->next = b->brush_faces;
02469         b->brush_faces = f;
02470 
02471         sv = sin (i*3.14159265*2/sides);
02472         cv = cos (i*3.14159265*2/sides);
02473 
02474         f->planepts[0][(axis+1)%3] = floor(mid[(axis+1)%3]+width*cv+0.5);
02475         f->planepts[0][(axis+2)%3] = floor(mid[(axis+2)%3]+width*sv+0.5);
02476         f->planepts[0][axis] = mins[axis];
02477 
02478         f->planepts[1][(axis+1)%3] = f->planepts[0][(axis+1)%3];
02479         f->planepts[1][(axis+2)%3] = f->planepts[0][(axis+2)%3];
02480         f->planepts[1][axis] = maxs[axis];
02481 
02482         f->planepts[2][(axis+1)%3] = floor(f->planepts[0][(axis+1)%3] - width*sv + 0.5);
02483         f->planepts[2][(axis+2)%3] = floor(f->planepts[0][(axis+2)%3] + width*cv + 0.5);
02484         f->planepts[2][axis] = maxs[axis];
02485     }
02486 
02487     Brush_AddToList (b, &selected_brushes);
02488 
02489     Entity_LinkBrush (world_entity, b);
02490 
02491     Brush_Build( b );
02492 
02493     Sys_UpdateWindows (W_ALL);
02494 }

Here is the call graph for this function:

void Brush_MakeSidedCone int  sides  ) 
 

Definition at line 4290 of file Brush.cpp.

References b, Brush_AddToList(), Brush_Alloc(), Brush_Build(), brush_s::brush_faces, Brush_Free(), brush_t, cos(), QEGlobals_t::d_texturewin, Entity_LinkBrush(), f, Face_Alloc(), face_t, floor(), g_qeglobals, i, brush_s::maxs, brush_s::mins, face_s::next, brush_s::next, face_s::planepts, QE_SingleBrush(), selected_brushes, sin(), sv, Sys_Status(), Sys_UpdateWindows(), face_s::texdef, texturewin_t::texdef, vec3_t, VectorCopy, W_ALL, width, and world_entity.

Referenced by SidesDlgProc().

04291 {
04292     int     i;
04293     vec3_t  mins, maxs;
04294     brush_t *b;
04295     texdef_t    *texdef;
04296     face_t  *f;
04297     vec3_t  mid;
04298     float   width;
04299     float   sv, cv;
04300 
04301     if (sides < 3)
04302     {
04303         Sys_Status ("Bad sides number", 0);
04304         return;
04305     }
04306 
04307     if (!QE_SingleBrush ())
04308     {
04309         Sys_Status ("Must have a single brush selected", 0 );
04310         return;
04311     }
04312 
04313     b = selected_brushes.next;
04314     VectorCopy (b->mins, mins);
04315     VectorCopy (b->maxs, maxs);
04316     texdef = &g_qeglobals.d_texturewin.texdef;
04317 
04318     Brush_Free (b);
04319 
04320     // find center of brush
04321     width = 8;
04322     for (i=0 ; i<2 ; i++)
04323     {
04324         mid[i] = (maxs[i] + mins[i])*0.5;
04325         if (maxs[i] - mins[i] > width)
04326             width = maxs[i] - mins[i];
04327     }
04328     width /= 2;
04329 
04330     b = Brush_Alloc();
04331 
04332     // create bottom face
04333     f = Face_Alloc();
04334     f->texdef = *texdef;
04335     f->next = b->brush_faces;
04336     b->brush_faces = f;
04337 
04338     f->planepts[0][0] = mins[0];f->planepts[0][1] = mins[1];f->planepts[0][2] = mins[2];
04339     f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = mins[2];
04340     f->planepts[2][0] = maxs[0];f->planepts[2][1] = maxs[1];f->planepts[2][2] = mins[2];
04341 
04342     for (i=0 ; i<sides ; i++)
04343     {
04344         f = Face_Alloc();
04345         f->texdef = *texdef;
04346         f->next = b->brush_faces;
04347         b->brush_faces = f;
04348 
04349         sv = sin (i*3.14159265*2/sides);
04350         cv = cos (i*3.14159265*2/sides);
04351 
04352 
04353         f->planepts[0][0] = floor(mid[0]+width*cv+0.5);
04354         f->planepts[0][1] = floor(mid[1]+width*sv+0.5);
04355         f->planepts[0][2] = mins[2];
04356 
04357         f->planepts[1][0] = mid[0];
04358         f->planepts[1][1] = mid[1];
04359         f->planepts[1][2] = maxs[2];
04360 
04361         f->planepts[2][0] = floor(f->planepts[0][0] - width * sv + 0.5);
04362         f->planepts[2][1] = floor(f->planepts[0][1] + width * cv + 0.5);
04363         f->planepts[2][2] = maxs[2];
04364 
04365     }
04366 
04367     Brush_AddToList (b, &selected_brushes);
04368 
04369     Entity_LinkBrush (world_entity, b);
04370 
04371     Brush_Build( b );
04372 
04373     Sys_UpdateWindows (W_ALL);
04374 }

Here is the call graph for this function:

void Brush_MakeSidedSphere int  sides  ) 
 

Definition at line 4384 of file Brush.cpp.

References b, Brush_AddToList(), Brush_Alloc(), Brush_Build(), brush_s::brush_faces, Brush_Free(), brush_t, QEGlobals_t::d_texturewin, Entity_LinkBrush(), f, Face_Alloc(), face_t, g_qeglobals, i, j, k, brush_s::maxs, brush_s::mins, face_s::next, brush_s::next, p, face_s::planepts, Q_PI, QE_SingleBrush(), selected_brushes, Sys_Status(), Sys_UpdateWindows(), t, face_s::texdef, texturewin_t::texdef, vec3_t, VectorAdd, VectorCopy, VectorPolar(), W_ALL, and world_entity.

Referenced by SidesDlgProc().

04385 {
04386     int     i,j;
04387     vec3_t  mins, maxs;
04388     brush_t *b;
04389     texdef_t    *texdef;
04390     face_t  *f;
04391     vec3_t  mid;
04392 
04393     if (sides < 4)
04394     {
04395         Sys_Status ("Bad sides number", 0);
04396         return;
04397     }
04398 
04399     if (!QE_SingleBrush ())
04400     {
04401         Sys_Status ("Must have a single brush selected", 0 );
04402         return;
04403     }
04404 
04405     b = selected_brushes.next;
04406     VectorCopy (b->mins, mins);
04407     VectorCopy (b->maxs, maxs);
04408     texdef = &g_qeglobals.d_texturewin.texdef;
04409 
04410     Brush_Free (b);
04411 
04412     // find center of brush
04413     float radius = 8;
04414     for (i=0 ; i<2 ; i++)
04415     {
04416         mid[i] = (maxs[i] + mins[i])*0.5;
04417         if (maxs[i] - mins[i] > radius)
04418             radius = maxs[i] - mins[i];
04419     }
04420     radius /= 2;
04421 
04422     b = Brush_Alloc();
04423 
04424     float dt = float(2 * Q_PI / sides);
04425     float dp = float(Q_PI / sides);
04426   float t,p;
04427     for(i=0; i <= sides-1; i++)
04428   {
04429         for(j=0;j <= sides-2; j++)
04430         {
04431             t = i * dt;
04432             p = float(j * dp - Q_PI / 2);
04433 
04434       f = Face_Alloc();
04435         f->texdef = *texdef;
04436         f->next = b->brush_faces;
04437         b->brush_faces = f;
04438 
04439       VectorPolar(f->planepts[0], radius, t, p);
04440       VectorPolar(f->planepts[1], radius, t, p + dp);
04441       VectorPolar(f->planepts[2], radius, t + dt, p + dp);
04442 
04443       for (int k = 0; k < 3; k++)
04444         VectorAdd(f->planepts[k], mid, f->planepts[k]);
04445         }
04446   }
04447 
04448   p = float((sides - 1) * dp - Q_PI / 2);
04449     for(i = 0; i <= sides-1; i++)
04450     {
04451         t = i * dt;
04452 
04453     f = Face_Alloc();
04454       f->texdef = *texdef;
04455       f->next = b->brush_faces;
04456       b->brush_faces = f;
04457 
04458     VectorPolar(f->planepts[0], radius, t, p);
04459     VectorPolar(f->planepts[1], radius, t + dt, p + dp);
04460     VectorPolar(f->planepts[2], radius, t + dt, p);
04461 
04462     for (int k = 0; k < 3; k++)
04463       VectorAdd(f->planepts[k], mid, f->planepts[k]);
04464     }
04465 
04466     Brush_AddToList (b, &selected_brushes);
04467 
04468     Entity_LinkBrush (world_entity, b);
04469 
04470     Brush_Build( b );
04471 
04472     Sys_UpdateWindows (W_ALL);
04473 }

Here is the call graph for this function:

int Brush_MemorySize brush_t b  ) 
 

Definition at line 2580 of file Brush.cpp.

References b, brush_s::brush_faces, brush_t, epair_t, brush_s::epairs, f, Face_MemorySize(), face_t, epair_s::key, epair_s::next, face_s::next, Patch_MemorySize(), brush_s::patchBrush, brush_s::pPatch, brush_s::pTerrain, Terrain_MemorySize(), brush_s::terrainBrush, and epair_s::value.

Referenced by Undo_AddBrush(), Undo_AddBrushList(), Undo_Clear(), Undo_FreeFirstUndo(), Undo_Redo(), and Undo_Undo().

02581 {
02582     face_t  *f;
02583     epair_t *ep;
02584     int size = 0;
02585 
02586     //
02587     if (b->patchBrush)
02588     {
02589         size += Patch_MemorySize(b->pPatch);
02590     }
02591     if (b->terrainBrush)
02592     {
02593         size += Terrain_MemorySize(b->pTerrain);
02594     }
02595     //
02596     for (f = b->brush_faces; f; f = f->next)
02597     {
02598         size += Face_MemorySize(f);
02599     }
02600     //
02601     for (ep = b->epairs; ep; ep = ep->next )
02602     {
02603         size += _msize(ep->key);
02604         size += _msize(ep->value);
02605         size += _msize(ep);
02606     }
02607     size += _msize(b);
02608     return size;
02609 }

Here is the call graph for this function:

void Brush_Move brush_t b,
const vec3_t  move,
bool  bSnap = true
 

Definition at line 4227 of file Brush.cpp.

References b, Brush_Build(), brush_s::brush_faces, brush_t, entity_s::eclass, f, Face_MoveTexture(), face_t, eclass_s::fixedsize, g_PrefsDlg, i, CPrefsDlg::m_bTextureLock, move(), face_s::next, entity_s::origin, brush_s::owner, Patch_Move(), brush_s::patchBrush, face_s::planepts, brush_s::pPatch, brush_s::pTerrain, Terrain_Move(), brush_s::terrainBrush, vec3_t, VectorAdd, and VectorCopy.

Referenced by Brush_Center(), MoveHold(), Select_Clone(), and Select_Move().

04228 {
04229   int i;
04230   face_t *f;
04231 
04232   for (f=b->brush_faces ; f ; f=f->next)
04233   {
04234     vec3_t vTemp;
04235     VectorCopy(move, vTemp);
04236 
04237     if (g_PrefsDlg.m_bTextureLock)
04238       Face_MoveTexture(f, vTemp);
04239     
04240     for (i=0 ; i<3 ; i++)
04241       VectorAdd (f->planepts[i], move, f->planepts[i]);
04242   }
04243   Brush_Build( b, bSnap );
04244 
04245 
04246   if (b->patchBrush)
04247   {
04248     //Patch_Move(b->nPatchID, move);
04249     Patch_Move(b->pPatch, move);
04250   }
04251 
04252   if (b->terrainBrush)
04253   {
04254     Terrain_Move(b->pTerrain, move);
04255   }
04256 
04257 
04258   // PGM - keep the origin vector up to date on fixed size entities.
04259   if(b->owner->eclass->fixedsize)
04260   {
04261     VectorAdd(b->owner->origin, move, b->owner->origin);
04262       //VectorAdd(b->maxs, b->mins, b->owner->origin);
04263       //VectorScale(b->owner->origin, 0.5, b->owner->origin);
04264   }
04265 }

Here is the call graph for this function:

int Brush_MoveVertex brush_t b,
vec3_t  vertex,
vec3_t  delta,
vec3_t  end,
bool  bSnap = true
 

Definition at line 1320 of file Brush.cpp.

References b, brush_t, face_t, g_qeglobals, VectorCopy, and w.

Referenced by MoveSelection().

01321 {
01322     face_t *f, *face, *newface, *lastface, *nextface;
01323     face_t *movefaces[MAX_MOVE_FACES];
01324     int movefacepoints[MAX_MOVE_FACES];
01325     winding_t *w, tmpw;
01326     vec3_t start, mid;
01327     plane_t plane;
01328     int i, j, k, nummovefaces, result, done;
01329     float dot, front, back, frac, smallestfrac;
01330 
01331     result = true;
01332     //
01333     tmpw.numpoints = 3;
01334     tmpw.maxpoints = 3;
01335     VectorCopy(vertex, start);
01336     VectorAdd(vertex, delta, end);
01337     //snap or not?
01338     if (bSnap)
01339         for (i = 0; i < 3; i++)
01340             end[i] = floor(end[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
01341     //
01342     VectorCopy(end, mid);
01343     //if the start and end are the same
01344     if (Point_Equal(start, end, 0.3)) return false;
01345     //the end point may not be the same as another vertex
01346     for (face = b->brush_faces; face; face = face->next)
01347     {
01348         w = face->face_winding;
01349         if (!w) continue;
01350         for (i = 0; i < w->numpoints; i++)
01351         {
01352             if (Point_Equal(w->points[i], end, 0.3))
01353             {
01354                 VectorCopy(vertex, end);
01355                 return false;
01356             }
01357         }
01358     }
01359     //
01360     done = false;
01361     while(!done)
01362     {
01363         //chop off triangles from all brush faces that use the to be moved vertex
01364         //store pointers to these chopped off triangles in movefaces[]
01365         nummovefaces = 0;
01366         for (face = b->brush_faces; face; face = face->next)
01367         {
01368             w = face->face_winding;
01369             if (!w) continue;
01370             for (i = 0; i < w->numpoints; i++)
01371             {
01372                 if (Point_Equal(w->points[i], start, 0.2))
01373                 {
01374                     if (face->face_winding->numpoints <= 3)
01375                     {
01376                         movefacepoints[nummovefaces] = i;
01377                         movefaces[nummovefaces++] = face;
01378                         break;
01379                     }
01380                     dot = DotProduct(end, face->plane.normal) - face->plane.dist;
01381                     //if the end point is in front of the face plane
01382                     if (dot > 0.1)
01383                     {
01384                         //fanout triangle subdivision
01385                         for (k = i; k < i + w->numpoints-3; k++)
01386                         {
01387                             VectorCopy(w->points[i], tmpw.points[0]);
01388                             VectorCopy(w->points[(k+1) % w->numpoints], tmpw.points[1]);
01389                             VectorCopy(w->points[(k+2) % w->numpoints], tmpw.points[2]);
01390                             //
01391                             newface = Face_Clone(face);
01392                             //get the original
01393                             for (f = face; f->original; f = f->original) ;
01394                             newface->original = f;
01395                             //store the new winding
01396                             if (newface->face_winding) Winding_Free(newface->face_winding);
01397                             newface->face_winding = Winding_Clone(&tmpw);
01398                             //get the texture
01399                             newface->d_texture = Texture_ForName( newface->texdef.name );
01400                             //add the face to the brush
01401                             newface->next = b->brush_faces;
01402                             b->brush_faces = newface;
01403                             //add this new triangle to the move faces
01404                             movefacepoints[nummovefaces] = 0;
01405                             movefaces[nummovefaces++] = newface;
01406                         }
01407                         //give the original face a new winding
01408                         VectorCopy(w->points[(i-2+w->numpoints) % w->numpoints], tmpw.points[0]);
01409                         VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[1]);
01410                         VectorCopy(w->points[i], tmpw.points[2]);
01411                         Winding_Free(face->face_winding);
01412                         face->face_winding = Winding_Clone(&tmpw);
01413                         //add the original face to the move faces
01414                         movefacepoints[nummovefaces] = 2;
01415                         movefaces[nummovefaces++] = face;
01416                     }
01417                     else
01418                     {
01419                         //chop a triangle off the face
01420                         VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[0]);
01421                         VectorCopy(w->points[i], tmpw.points[1]);
01422                         VectorCopy(w->points[(i+1) % w->numpoints], tmpw.points[2]);
01423                         //remove the point from the face winding
01424                         Winding_RemovePoint(w, i);
01425                         //get texture crap right
01426                         Face_SetColor(b, face, 1.0);
01427                         for (j = 0; j < w->numpoints; j++)
01428                             EmitTextureCoordinates(w->points[j], face->d_texture, face);
01429                         //make a triangle face
01430                         newface = Face_Clone(face);
01431                         //get the original
01432                         for (f = face; f->original; f = f->original) ;
01433                         newface->original = f;
01434                         //store the new winding
01435                         if (newface->face_winding) Winding_Free(newface->face_winding);
01436                         newface->face_winding = Winding_Clone(&tmpw);
01437                         //get the texture
01438                         newface->d_texture = Texture_ForName( newface->texdef.name );
01439                         //add the face to the brush
01440                         newface->next = b->brush_faces;
01441                         b->brush_faces = newface;
01442                         //
01443                         movefacepoints[nummovefaces] = 1;
01444                         movefaces[nummovefaces++] = newface;
01445                     }
01446                     break;
01447                 }
01448             }
01449         }
01450         //now movefaces contains pointers to triangle faces that
01451         //contain the to be moved vertex
01452         //
01453         done = true;
01454         VectorCopy(end, mid);
01455         smallestfrac = 1;
01456         for (face = b->brush_faces; face; face = face->next)
01457         {
01458             //check if there is a move face that has this face as the original
01459             for (i = 0; i < nummovefaces; i++)
01460             {
01461                 if (movefaces[i]->original == face) break;
01462             }
01463             if (i >= nummovefaces) continue;
01464             //check if the original is not a move face itself
01465             for (j = 0; j < nummovefaces; j++)
01466             {
01467                 if (face == movefaces[j]) break;
01468             }
01469             //if the original is not a move face itself
01470             if (j >= nummovefaces)
01471             {
01472                 memcpy(&plane, &movefaces[i]->original->plane, sizeof(plane_t));
01473             }
01474             else
01475             {
01476                 k = movefacepoints[j];
01477                 w = movefaces[j]->face_winding;
01478                 VectorCopy(w->points[(k+1)%w->numpoints], tmpw.points[0]);
01479                 VectorCopy(w->points[(k+2)%w->numpoints], tmpw.points[1]);
01480                 //
01481                 k = movefacepoints[i];
01482                 w = movefaces[i]->face_winding;
01483                 VectorCopy(w->points[(k+1)%w->numpoints], tmpw.points[2]);
01484                 if (!Plane_FromPoints(tmpw.points[0], tmpw.points[1], tmpw.points[2], &plane))
01485                 {
01486                     VectorCopy(w->points[(k+2)%w->numpoints], tmpw.points[2]);
01487                     if (!Plane_FromPoints(tmpw.points[0], tmpw.points[1], tmpw.points[2], &plane))
01488                         //this should never happen otherwise the face merge did a crappy job a previous pass
01489                         continue;
01490                 }
01491             }
01492             //now we've got the plane to check agains
01493             front = DotProduct(start, plane.normal) - plane.dist;
01494             back = DotProduct(end, plane.normal) - plane.dist;
01495             //if the whole move is at one side of the plane
01496             if (front < 0.01 && back < 0.01) continue;
01497             if (front > -0.01 && back > -0.01) continue;
01498             //if there's no movement orthogonal to this plane at all
01499             if (fabs(front-back) < 0.001) continue;
01500             //ok first only move till the plane is hit
01501             frac = front/(front-back);
01502             if (frac < smallestfrac)
01503             {
01504                 mid[0] = start[0] + (end[0] - start[0]) * frac;
01505                 mid[1] = start[1] + (end[1] - start[1]) * frac;
01506                 mid[2] = start[2] + (end[2] - start[2]) * frac;
01507                 smallestfrac = frac;
01508             }
01509             //
01510             done = false;
01511         }
01512 
01513         //move the vertex
01514         for (i = 0; i < nummovefaces; i++)
01515         {
01516             //move vertex to end position
01517             VectorCopy(mid, movefaces[i]->face_winding->points[movefacepoints[i]]);
01518             //create new face plane
01519             for (j = 0; j < 3; j++)
01520             {
01521                 VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
01522             }
01523             Face_MakePlane(movefaces[i]);
01524             if (VectorLength(movefaces[i]->plane.normal) < 0.1)
01525                 result = false;
01526         }
01527         //if the brush is no longer convex
01528         if (!result || !Brush_Convex(b))
01529         {
01530             for (i = 0; i < nummovefaces; i++)
01531             {
01532                 //move the vertex back to the initial position
01533                 VectorCopy(start, movefaces[i]->face_winding->points[movefacepoints[i]]);
01534                 //create new face plane
01535                 for (j = 0; j < 3; j++)
01536                 {
01537                     VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
01538                 }
01539                 Face_MakePlane(movefaces[i]);
01540             }
01541             result = false;
01542             VectorCopy(start, end);
01543             done = true;
01544         }
01545         else
01546         {
01547             VectorCopy(mid, start);
01548         }
01549         //get texture crap right
01550         for (i = 0; i < nummovefaces; i++)
01551         {
01552             Face_SetColor(b, movefaces[i], 1.0);
01553             for (j = 0; j < movefaces[i]->face_winding->numpoints; j++)
01554                 EmitTextureCoordinates(movefaces[i]->face_winding->points[j], movefaces[i]->d_texture, movefaces[i]);
01555         }
01556 
01557         //now try to merge faces with their original faces
01558         lastface = NULL;
01559         for (face = b->brush_faces; face; face = nextface)
01560         {
01561             nextface = face->next;
01562             if (!face->original)
01563             {
01564                 lastface = face;
01565                 continue;
01566             }
01567             if (!Plane_Equal(&face->plane, &face->original->plane, false))
01568             {
01569                 lastface = face;
01570                 continue;
01571             }
01572             w = Winding_TryMerge(face->face_winding, face->original->face_winding, face->plane.normal, true);
01573             if (!w)
01574             {
01575                 lastface = face;
01576                 continue;
01577             }
01578             Winding_Free(face->original->face_winding);
01579             face->original->face_winding = w;
01580             //get texture crap right
01581             Face_SetColor(b, face->original, 1.0);
01582             for (j = 0; j < face->original->face_winding->numpoints; j++)
01583                 EmitTextureCoordinates(face->original->face_winding->points[j], face->original->d_texture, face->original);
01584             //remove the face that was merged with the original
01585             if (lastface) lastface->next = face->next;
01586             else b->brush_faces = face->next;
01587             Face_Free(face);
01588         }
01589     }
01590     return result;
01591 }

const char* Brush_Name brush_t b  ) 
 

Definition at line 34 of file Brush.cpp.

References b, Brush_SetEpair(), brush_t, g_nBrushId, g_qeglobals, QEGlobals_t::m_bBrushPrimitMode, brush_s::numberId, and sprintf().

00035 {
00036   static char cBuff[1024];
00037     b->numberId = g_nBrushId++;
00038     if (g_qeglobals.m_bBrushPrimitMode)
00039   {
00040     sprintf(cBuff, "Brush %i", b->numberId);
00041     Brush_SetEpair(b, "Name", cBuff);
00042   }
00043   return cBuff;
00044 }

Here is the call graph for this function:

brush_t* Brush_Parse void   ) 
 

Definition at line 1666 of file Brush.cpp.

References atof(), atoi, b, QEGlobals_t::bNeedConvert, QEGlobals_t::bOldBrushes, QEGlobals_t::bPrimitBrushes, Brush_Alloc(), brush_s::brush_faces, brush_t, BrushPrimit_Parse(), QEGlobals_t::bSurfacePropertiesPlugin, qtexture_s::contents, texdef_t::contents, QEGlobals_t::d_parsed_brushes, face_s::d_texture, f, Face_Alloc(), face_t, qtexture_s::flags, texdef_t::flags, free(), g_qeglobals, GETPLUGINTEXDEF, GetToken(), i, j, QEGlobals_t::m_bBrushPrimitMode, texdef_t::name, face_s::next, Patch_Parse(), face_s::planepts, texdef_t::rotate, texdef_t::scale, texdef_t::SetName(), texdef_t::shift, strcmp(), Sys_Printf(), Terrain_Parse(), face_s::texdef, Texture_ForName(), TokenAvailable(), qtexture_s::value, texdef_t::value, and Warning().

Referenced by Entity_Parse().

01667 {
01668     brush_t     *b;
01669     face_t      *f;
01670     int         i,j;
01671     
01672     g_qeglobals.d_parsed_brushes++;
01673     b = Brush_Alloc();
01674 
01675     do
01676     {
01677         if (!GetToken (true))
01678             break;
01679         if (!strcmp (token, "}") )
01680             break;
01681         
01682         // handle "Brush" primitive
01683         if (strcmpi(token, "brushDef") == 0)
01684         {
01685             // Timo parsing new brush format
01686             g_qeglobals.bPrimitBrushes=true;
01687             // check the map is not mixing the two kinds of brushes
01688             if (g_qeglobals.m_bBrushPrimitMode)
01689             {
01690                 if (g_qeglobals.bOldBrushes)
01691                     Sys_Printf("Warning : old brushes and brush primitive in the same file are not allowed ( Brush_Parse )\n");
01692             }
01693             //++Timo write new brush primitive -> old conversion code for Q3->Q2 conversions ?
01694             else
01695                 Sys_Printf("Warning : conversion code from brush primitive not done ( Brush_Parse )\n");
01696             
01697             BrushPrimit_Parse(b);
01698             if (b == NULL)
01699             {
01700                 Warning ("parsing brush primitive");
01701                 return NULL;
01702             }
01703             else
01704             {
01705                 continue;
01706             }
01707         }
01708         if ( strcmpi( token, "terrainDef" ) == 0 )
01709         {
01710             free (b);
01711 
01712             b = Terrain_Parse();
01713             if (b == NULL)
01714             {
01715                 Warning ("parsing terrain/brush");
01716                 return NULL;
01717             }
01718             else
01719             {
01720                 continue;
01721             }
01722         }
01723         if (strcmpi(token, "patchDef2") == 0 || strcmpi(token, "patchDef3") == 0)
01724         {
01725             free (b);
01726             
01727             // double string compare but will go away soon
01728             b = Patch_Parse(strcmpi(token, "patchDef2") == 0);
01729             if (b == NULL)
01730             {
01731                 Warning ("parsing patch/brush");
01732                 return NULL;
01733             }
01734             else
01735             {
01736                 continue;
01737             }
01738             // handle inline patch
01739         }
01740         else
01741         {
01742             // Timo parsing old brush format
01743             g_qeglobals.bOldBrushes=true;
01744             if (g_qeglobals.m_bBrushPrimitMode)
01745             {
01746                 // check the map is not mixing the two kinds of brushes
01747                 if (g_qeglobals.bPrimitBrushes)
01748                     Sys_Printf("Warning : old brushes and brush primitive in the same file are not allowed ( Brush_Parse )\n");
01749                 // set the "need" conversion flag
01750                 g_qeglobals.bNeedConvert=true;
01751             }
01752             
01753             f = Face_Alloc();
01754             
01755             // add the brush to the end of the chain, so
01756             // loading and saving a map doesn't reverse the order
01757             
01758             f->next = NULL;
01759             if (!b->brush_faces)
01760             {
01761                 b->brush_faces = f;
01762             }
01763             else
01764             {
01765                 face_t *scan;
01766                 for (scan=b->brush_faces ; scan->next ; scan=scan->next)
01767                     ;
01768                 scan->next = f;
01769             }
01770             
01771             // read the three point plane definition
01772             for (i=0 ; i<3 ; i++)
01773             {
01774                 if (i != 0)
01775                     GetToken (true);
01776                 if (strcmp (token, "(") )
01777                 {
01778                     Warning ("parsing brush");
01779                     return NULL;
01780                 }
01781                 
01782                 for (j=0 ; j<3 ; j++)
01783                 {
01784                     GetToken (false);
01785                     f->planepts[i][j] = atof(token);
01786                 }
01787                 
01788                 GetToken (false);
01789                 if (strcmp (token, ")") )
01790                 {
01791                     Warning ("parsing brush");
01792                     return NULL;
01793                 }
01794             }
01795         }
01796 
01797         // Timo
01798         // if we have a surface plugin, we'll call the plugin parsing
01799         if (g_qeglobals.bSurfacePropertiesPlugin)
01800         {
01801             GETPLUGINTEXDEF(f)->ParseTexdef();
01802         }
01803         else
01804         {
01805             
01806             // read the texturedef
01807             GetToken (false);
01808             f->texdef.SetName(token);
01809             if (token[0] == '(')
01810             {
01811                 int i = 32;
01812             }
01813             GetToken (false);
01814             f->texdef.shift[0] = atoi(token);
01815             GetToken (false);
01816             f->texdef.shift[1] = atoi(token);
01817             GetToken (false);
01818             f->texdef.rotate = atoi(token); 
01819             GetToken (false);
01820             f->texdef.scale[0] = atof(token);
01821             GetToken (false);
01822             f->texdef.scale[1] = atof(token);
01823                         
01824             // the flags and value field aren't necessarily present
01825             f->d_texture = Texture_ForName( f->texdef.name );
01826             f->texdef.flags = f->d_texture->flags;
01827             f->texdef.value = f->d_texture->value;
01828             f->texdef.contents = f->d_texture->contents;
01829             
01830             if (TokenAvailable ())
01831             {
01832                 GetToken (false);
01833                 f->texdef.contents = atoi(token);
01834                 GetToken (false);
01835                 f->texdef.flags = atoi(token);
01836                 GetToken (false);
01837                 f->texdef.value = atoi(token);
01838             }
01839             
01840         }
01841     } while (1);
01842     
01843     return b;
01844 }

Here is the call graph for this function:

face_t* Brush_Ray vec3_t  origin,
vec3_t  dir,
brush_t b,
float *  dist
 

Definition at line 2741 of file Brush.cpp.

References b, brush_s::brush_faces, brush_t, plane_t::dist, DotProduct, f, face_t, i, face_s::next, plane_t::normal, p2, face_s::plane, vec3_t, VectorCopy, and VectorSubtract.

Referenced by CCamWnd::Cam_ChangeFloor(), Test_Ray(), and Z_Draw().

02742 {
02743     face_t  *f, *firstface;
02744     vec3_t  p1, p2;
02745     float   frac, d1, d2;
02746     int     i;
02747 
02748     VectorCopy (origin, p1);
02749     for (i=0 ; i<3 ; i++)
02750         p2[i] = p1[i] + dir[i]*16384;
02751 
02752     for (f=b->brush_faces ; f ; f=f->next)
02753     {
02754         d1 = DotProduct (p1, f->plane.normal) - f->plane.dist;
02755         d2 = DotProduct (p2, f->plane.normal) - f->plane.dist;
02756         if (d1 >= 0 && d2 >= 0)
02757         {
02758             *dist = 0;
02759             return NULL;    // ray is on front side of face
02760         }
02761         if (d1 <=0 && d2 <= 0)
02762             continue;
02763     // clip the ray to the plane
02764         frac = d1 / (d1 - d2);
02765         if (d1 > 0)
02766         {
02767             firstface = f;
02768             for (i=0 ; i<3 ; i++)
02769                 p1[i] = p1[i] + frac *(p2[i] - p1[i]);
02770         }
02771         else
02772         {
02773             for (i=0 ; i<3 ; i++)
02774                 p2[i] = p1[i] + frac *(p2[i] - p1[i]);
02775         }
02776     }
02777 
02778     // find distance p1 is along dir
02779     VectorSubtract (p1, origin, p1);
02780     d1 = DotProduct (p1, dir);
02781 
02782     *dist = d1;
02783 
02784     return firstface;
02785 }

void Brush_RemoveEmptyFaces brush_t b  ) 
 

Definition at line 3234 of file Brush.cpp.

References b, brush_s::brush_faces, brush_t, f, Face_Free(), face_t, face_s::face_winding, face_s::next, and next.

Referenced by Brush_SplitBrushByFace().

03235 {
03236     face_t  *f, *next;
03237 
03238     f = b->brush_faces;
03239     b->brush_faces = NULL;
03240 
03241     for ( ; f ; f=next)
03242     {
03243         next = f->next;
03244         if (!f->face_winding)
03245             Face_Free (f);
03246         else
03247         {
03248             f->next = b->brush_faces;
03249             b->brush_faces = f;
03250         }
03251 
03252     }
03253 }

Here is the call graph for this function:

void Brush_RemoveFromList brush_t b  ) 
 

Definition at line 2831 of file Brush.cpp.

References b, brush_t, Error(), brush_s::next, Patch_Deselect(), brush_s::patchBrush, brush_s::pPatch, brush_s::prev, brush_s::pTerrain, Terrain_Deselect(), and brush_s::terrainBrush.

Referenced by Brush_Clone(), Brush_CopyList(), Brush_Free(), Brush_FullClone(), Brush_Resize(), CSG_Merge(), CSG_Subtract(), Map_ApplyRegion(), Map_RegionOff(), CXYWnd::ProduceSplitLists(), Select_AllOfType(), Select_Brush(), Select_Clone(), Select_CompleteTall(), Select_Inside(), Select_PartialTall(), Select_Ray(), Select_Touching(), SelectBrush(), Undo_Redo(), and Undo_Undo().

02832 {
02833     if (!b->next || !b->prev)
02834         Error ("Brush_RemoveFromList: not linked");
02835     
02836     if (b->patchBrush)
02837     {
02838         Patch_Deselect(b->pPatch);
02839         //Patch_Deselect(b->nPatchID);
02840     }
02841     if (b->terrainBrush)
02842     {
02843         Terrain_Deselect(b->pTerrain);
02844     }
02845 
02846     b->next->prev = b->prev;
02847     b->prev->next = b->next;
02848     b->next = b->prev = NULL;
02849 }

Here is the call graph for this function:

void Brush_ResetFaceOriginals brush_t b  ) 
 

Definition at line 1647 of file Brush.cpp.

References b, brush_s::brush_faces, brush_t, face_t, face_s::next, and face_s::original.

Referenced by MoveSelection().

01648 {
01649     face_t *face;
01650 
01651     for (face = b->brush_faces; face; face = face->next)
01652     {
01653         face->original = NULL;
01654     }
01655 }

void Brush_Rotate brush_t b,
vec3_t  vAngle,
vec3_t  vOrigin,
bool  bBuild = true
 

Definition at line 3270 of file Brush.cpp.

References b, Brush_Build(), brush_s::brush_faces, brush_t, f, face_t, i, face_s::next, face_s::planepts, and VectorRotate().

Referenced by CPlugInManager::CommitEntityHandleToMap(), Entity_Parse(), and TrackMD3Angles().

03271 {
03272     for (face_t* f=b->brush_faces ; f ; f=f->next)
03273     {
03274         for (int i=0 ; i<3 ; i++)
03275         {
03276             VectorRotate(f->planepts[i], vAngle, vOrigin, f->planepts[i]);
03277         }
03278     }
03279     if (bBuild)
03280     {
03281         Brush_Build(b, false, false);
03282     }
03283 }

Here is the call graph for this function:

void Brush_SelectFaceForDragging brush_t b,
face_t f,
qboolean  shear
 

Definition at line 3006 of file Brush.cpp.

References AddPlanept(), b, brush_s::brush_faces, Brush_MakeFaceWinding(), brush_t, c, d, plane_t::dist, DotProduct, entity_s::eclass, f, f2(), fabs(), face_t, eclass_s::fixedsize, free(), i, face_s::next, brush_s::next, plane_t::normal, winding_t::numpoints, ON_EPSILON, brush_s::owner, face_s::plane, face_s::planepts, winding_t::points, selected_brushes, VectorCopy, and w.

Referenced by Brush_SideSelect(), and Drag_Setup().

03007 {
03008     int     i;
03009     face_t  *f2;
03010     winding_t   *w;
03011     float   d;
03012     brush_t *b2;
03013     int     c;
03014 
03015     if (b->owner->eclass->fixedsize)
03016         return;
03017 
03018     c = 0;
03019     for (i=0 ; i<3 ; i++)
03020         c += AddPlanept (f->planepts[i]);
03021     if (c == 0)
03022         return;     // allready completely added
03023 
03024     // select all points on this plane in all brushes the selection
03025     for (b2=selected_brushes.next ; b2 != &selected_brushes ; b2 = b2->next)
03026     {
03027         if (b2 == b)
03028             continue;
03029         for (f2=b2->brush_faces ; f2 ; f2=f2->next)
03030         {
03031             for (i=0 ; i<3 ; i++)
03032                 if (fabs(DotProduct(f2->planepts[i], f->plane.normal)
03033                 -f->plane.dist) > ON_EPSILON)
03034                     break;
03035             if (i==3)
03036             {   // move this face as well
03037                 Brush_SelectFaceForDragging (b2, f2, shear);
03038                 break;
03039             }
03040         }
03041     }
03042 
03043 
03044     // if shearing, take all the planes adjacent to 
03045     // selected faces and rotate their points so the
03046     // edge clipped by a selcted face has two of the points
03047     if (!shear)
03048         return;
03049 
03050     for (f2=b->brush_faces ; f2 ; f2=f2->next)
03051     {
03052         if (f2 == f)
03053             continue;
03054         w = Brush_MakeFaceWinding (b, f2);
03055         if (!w)
03056             continue;
03057 
03058         // any points on f will become new control points
03059         for (i=0 ; i<w->numpoints ; i++)
03060         {
03061             d = DotProduct (w->points[i], f->plane.normal) 
03062                 - f->plane.dist;
03063             if (d > -ON_EPSILON && d < ON_EPSILON)
03064                 break;
03065         }
03066 
03067         //
03068         // if none of the points were on the plane,
03069         // leave it alone
03070         //
03071         if (i != w->numpoints)
03072         {
03073             if (i == 0)
03074             {   // see if the first clockwise point was the
03075                 // last point on the winding
03076                 d = DotProduct (w->points[w->numpoints-1]
03077                     , f->plane.normal) - f->plane.dist;
03078                 if (d > -ON_EPSILON && d < ON_EPSILON)
03079                     i = w->numpoints - 1;
03080             }
03081 
03082             AddPlanept (f2->planepts[0]);
03083 
03084             VectorCopy (w->points[i], f2->planepts[0]);
03085             if (++i == w->numpoints)
03086                 i = 0;
03087             
03088             // see if the next point is also on the plane
03089             d = DotProduct (w->points[i]
03090                 , f->plane.normal) - f->plane.dist;
03091             if (d > -ON_EPSILON && d < ON_EPSILON)
03092                 AddPlanept (f2->planepts[1]);
03093 
03094             VectorCopy (w->points[i], f2->planepts[1]);
03095             if (++i == w->numpoints)
03096                 i = 0;
03097 
03098             // the third point is never on the plane
03099 
03100             VectorCopy (w->points[i], f2->planepts[2]);
03101         }
03102 
03103         free(w);
03104     }
03105 }

Here is the call graph for this function:

void Brush_SetEpair brush_t b,
const char *  pKey,
const char *  pValue
 

Definition at line 1874 of file Brush.cpp.

References b, brush_t, brush_s::epairs, g_qeglobals, QEGlobals_t::m_bBrushPrimitMode, Patch_SetEpair(), brush_s::patchBrush, brush_s::pPatch, brush_s::pTerrain, SetKeyValue(), Sys_Printf(), Terrain_SetEpair(), and brush_s::terrainBrush.

Referenced by Brush_Name(), Select_AddToGroup(), and Select_Name().

01875 {
01876     if (g_qeglobals.m_bBrushPrimitMode)
01877     {
01878     if (b->patchBrush)
01879     {
01880       Patch_SetEpair(b->pPatch, pKey, pValue);
01881     }
01882     else if (b->terrainBrush)
01883     {
01884       Terrain_SetEpair(b->pTerrain, pKey, pValue);
01885     }
01886     else
01887     {
01888           SetKeyValue(b->epairs, pKey, pValue);
01889     }
01890     }
01891     else
01892     {
01893         Sys_Printf("Can only set key/values in Brush primitive mode\n");
01894     }
01895 }

Here is the call graph for this function:

void Brush_SetTexture brush_t b,
texdef_t texdef,
brushprimit_texdef_t brushprimit_texdef,
bool  bFitScale = false,
IPluginTexdef pPlugTexdef = NULL
 

Definition at line 2938 of file Brush.cpp.

References b, bFitScale, Brush_Build(), brush_s::brush_faces, brush_t, brushprimit_texdef, brushprimit_texdef_t, f, face_t, face_s::next, Patch_SetTexture(), brush_s::patchBrush, brush_s::pPatch, brush_s::pTerrain, SetFaceTexdef(), Terrain_SetTexture(), and brush_s::terrainBrush.

Referenced by Drag_Begin(), and Select_SetTexture().

02939 {
02940     for (face_t* f = b->brush_faces ; f ; f = f->next) 
02941     {
02942         SetFaceTexdef (b, f, texdef, brushprimit_texdef, bFitScale, pTexdef);
02943     }
02944     Brush_Build( b );
02945     if (b->patchBrush)
02946     {
02947         //++timo clean
02948 //      Sys_Printf("WARNING: Brush_SetTexture needs surface plugin code for patches\n");
02949         Patch_SetTexture(b->pPatch, texdef, pTexdef );
02950     }
02951     if (b->terrainBrush)
02952     {
02953         Terrain_SetTexture(b->pTerrain, texdef);
02954     }
02955 
02956 }

Here is the call graph for this function:

void Brush_SideSelect brush_t b,
vec3_t  origin,
vec3_t  dir,
qboolean  shear
 

Definition at line 3115 of file Brush.cpp.

References b, brush_s::brush_faces, Brush_SelectFaceForDragging(), brush_t, ClipLineToFace(), f, f2(), face_t, face_s::next, p2, vec3_t, VectorCompare(), VectorCopy, and VectorMA.

Referenced by Drag_Setup().

03117 {
03118     face_t  *f, *f2;
03119     vec3_t  p1, p2;
03120 
03121   //if (b->patchBrush)
03122   //  return;
03123     //Patch_SideSelect(b->nPatchID, origin, dir);
03124     for (f=b->brush_faces ; f ; f=f->next)
03125     {
03126         VectorCopy (origin, p1);
03127         VectorMA (origin, 16384, dir, p2);
03128 
03129         for (f2=b->brush_faces ; f2 ; f2=f2->next)
03130         {
03131             if (f2 == f)
03132                 continue;
03133             ClipLineToFace (p1, p2, f2);
03134         }
03135 
03136         if (f2)
03137             continue;
03138 
03139         if (VectorCompare (p1, origin))
03140             continue;
03141         if (ClipLineToFace (p1, p2, f))
03142             continue;
03143 
03144         Brush_SelectFaceForDragging (b, f, shear);
03145     }
03146 
03147     
03148 }

Here is the call graph for this function:

void Brush_SnapToGrid brush_t pb  ) 
 

Definition at line 3255 of file Brush.cpp.

References Brush_Build(), brush_s::brush_faces, brush_t, QEGlobals_t::d_gridsize, f, face_t, floor(), g_qeglobals, i, j, face_s::next, and face_s::planepts.

Referenced by Select_SnapToGrid().

03256 {
03257     for (face_t *f = pb->brush_faces ; f; f = f->next)
03258     {
03259         for (int i = 0 ;i < 3 ;i++)
03260         {
03261             for (int j = 0 ;j < 3 ; j++)
03262             {
03263                 f->planepts[i][j] = floor (f->planepts[i][j] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
03264             }
03265         }
03266     }
03267     Brush_Build(pb);
03268 }

Here is the call graph for this function:

void Brush_SplitBrushByFace brush_t in,
face_t f,
brush_t **  front,
brush_t **  back
 

Definition at line 692 of file Brush.cpp.

References b, Brush_Build(), Brush_Clone(), brush_s::brush_faces, Brush_Free(), Brush_RemoveEmptyFaces(), brush_t, Entity_LinkBrush(), f, Face_Clone(), face_t, in, face_s::next, brush_s::owner, face_s::planepts, face_s::texdef, vec3_t, and VectorCopy.

Referenced by Brush_MakeConvexBrushes(), Brush_Subtract(), CSG_MakeHollow(), CXYWnd::ProduceSplitLists(), and CXYWnd::ProduceSplits().

00693 {
00694     brush_t *b;
00695     face_t  *nf;
00696     vec3_t  temp;
00697 
00698     b = Brush_Clone (in);
00699     nf = Face_Clone (f);
00700 
00701     nf->texdef = b->brush_faces->texdef;
00702     nf->next = b->brush_faces;
00703     b->brush_faces = nf;
00704 
00705     Brush_Build( b );
00706     Brush_RemoveEmptyFaces ( b );
00707     if ( !b->brush_faces )
00708     {   // completely clipped away
00709         Brush_Free (b);
00710         *back = NULL;
00711     }
00712     else
00713     {
00714         Entity_LinkBrush (in->owner, b);
00715         *back = b;
00716     }
00717 
00718     b = Brush_Clone (in);
00719     nf = Face_Clone (f);
00720     // swap the plane winding
00721     VectorCopy (nf->planepts[0], temp);
00722     VectorCopy (nf->planepts[1], nf->planepts[0]);
00723     VectorCopy (temp, nf->planepts[1]);
00724 
00725     nf->texdef = b->brush_faces->texdef;
00726     nf->next = b->brush_faces;
00727     b->brush_faces = nf;
00728 
00729     Brush_Build( b );
00730     Brush_RemoveEmptyFaces ( b );
00731     if ( !b->brush_faces )
00732     {   // completely clipped away
00733         Brush_Free (b);
00734         *front = NULL;
00735     }
00736     else
00737     {
00738         Entity_LinkBrush (in->owner, b);
00739         *front = b;
00740     }
00741 }

Here is the call graph for this function:

void Brush_Write brush_t b,
CMemFile *  pMemFile
 

Definition at line 2077 of file Brush.cpp.

References b, brush_s::brush_faces, brush_t, face_s::brushprimit_texdef, QEGlobals_t::bSurfacePropertiesPlugin, texdef_t::contents, brushprimit_texdef_s::coords, epair_t, brush_s::epairs, face_t, texdef_t::flags, g_pMemFile, g_qeglobals, GETPLUGINTEXDEF, i, j, epair_s::key, QEGlobals_t::m_bBrushPrimitMode, MemFile_fprintf(), texdef_t::name, face_s::next, epair_s::next, Patch_Write(), brush_s::patchBrush, face_s::pData, face_s::planepts, pname, brush_s::pPatch, brush_s::pTerrain, QERApp_MapPrintf_MEMFILE(), texdef_t::rotate, texdef_t::scale, texdef_t::shift, strlen(), Sys_Printf(), Terrain_Write(), brush_s::terrainBrush, face_s::texdef, texdef_t::value, and epair_s::value.

Referenced by Entity_Write(), and Entity_WriteSelected().

02078 {
02079     epair_t *ep;
02080     face_t  *fa;
02081     char *pname;
02082     int     i;
02083     
02084     if (b->patchBrush)
02085     {
02086         Patch_Write(b->pPatch, pMemFile);
02087         return;
02088     }
02089     if (b->terrainBrush)
02090     {
02091         Terrain_Write(b->pTerrain, pMemFile);
02092         return;
02093     }
02094     //++timo NOTE: it's not very difficult to add since the surface properties plugin
02095     // writes throught a printf-style function prototype
02096     if (g_qeglobals.bSurfacePropertiesPlugin)
02097     {
02098         Sys_Printf("WARNING: Brush_Write to a CMemFile and Surface Properties plugin not done\n");
02099     }
02100     if (g_qeglobals.m_bBrushPrimitMode)
02101     {
02102         // brush primitive format
02103         MemFile_fprintf (pMemFile, "{\nBrushDef\n{\n");
02104         // brush epairs
02105         if (b->epairs)
02106             for( ep = b->epairs ; ep ; ep=ep->next )
02107                 MemFile_fprintf (pMemFile, "\"%s\" \"%s\"\n", ep->key, ep->value );
02108         for (fa=b->brush_faces ; fa ; fa=fa->next)
02109         {
02110             // save planepts
02111             for (i=0 ; i<3 ; i++)
02112             {
02113                 MemFile_fprintf(pMemFile, "( ");
02114                 for (int j = 0; j < 3; j++)
02115                     if (fa->planepts[i][j] == static_cast<int>(fa->planepts[i][j]))
02116                         MemFile_fprintf(pMemFile, "%i ", static_cast<int>(fa->planepts[i][j]));
02117                     else
02118                         MemFile_fprintf(pMemFile, "%f ", fa->planepts[i][j]);
02119                 MemFile_fprintf(pMemFile, ") ");
02120             }
02121             // save texture coordinates
02122             MemFile_fprintf(pMemFile,"( ( ");
02123             for (i=0 ; i<3 ; i++)
02124                 if (fa->brushprimit_texdef.coords[0][i] == static_cast<int>(fa->brushprimit_texdef.coords[0][i]))
02125                     MemFile_fprintf(pMemFile,"%i ",static_cast<int>(fa->brushprimit_texdef.coords[0][i]));
02126                 else
02127                     MemFile_fprintf(pMemFile,"%f ",fa->brushprimit_texdef.coords[0][i]);
02128             MemFile_fprintf(pMemFile,") ( ");
02129             for (i=0 ; i<3 ; i++)
02130                 if (fa->brushprimit_texdef.coords[1][i] == static_cast<int>(fa->brushprimit_texdef.coords[1][i]))
02131                     MemFile_fprintf(pMemFile,"%i ",static_cast<int>(fa->brushprimit_texdef.coords[1][i]));
02132                 else
02133                     MemFile_fprintf(pMemFile,"%f ",fa->brushprimit_texdef.coords[1][i]);
02134             MemFile_fprintf(pMemFile,") ) ");
02135             // save texture attribs
02136       char *pName = strlen(fa->texdef.name) > 0 ? fa->texdef.name : "unnamed";
02137             MemFile_fprintf(pMemFile, "%s ", pName);
02138             MemFile_fprintf(pMemFile, "%i %i %i\n", fa->texdef.contents, fa->texdef.flags, fa->texdef.value);
02139         }
02140         MemFile_fprintf (pMemFile, "}\n}\n");
02141     }
02142     else
02143     {
02144         // old brushes format
02145         // also handle surface properties plugin
02146         MemFile_fprintf (pMemFile, "{\n");
02147         for (fa=b->brush_faces ; fa ; fa=fa->next)
02148         {
02149             for (i=0 ; i<3 ; i++)
02150             {
02151                 MemFile_fprintf(pMemFile, "( ");
02152                 for (int j = 0; j < 3; j++)
02153                 {
02154                     if (fa->planepts[i][j] == static_cast<int>(fa->planepts[i][j]))
02155                         MemFile_fprintf(pMemFile, "%i ", static_cast<int>(fa->planepts[i][j]));
02156                     else
02157                         MemFile_fprintf(pMemFile, "%f ", fa->planepts[i][j]);
02158                 }
02159                 MemFile_fprintf(pMemFile, ") ");
02160             }
02161             
02162             if (g_qeglobals.bSurfacePropertiesPlugin)
02163             {
02164                 g_pMemFile = pMemFile;
02165 #ifdef _DEBUG
02166                 if (!fa->pData)
02167                     Sys_Printf("ERROR: unexpected IPluginTexdef* is NULL in Brush_Write\n");
02168                 else
02169 #endif
02170                 GETPLUGINTEXDEF(fa)->WriteTexdef( QERApp_MapPrintf_MEMFILE );
02171             }
02172             else
02173             {
02174                 pname = fa->texdef.name;
02175                 if (pname[0] == 0)
02176                     pname = "unnamed";
02177                 
02178                 MemFile_fprintf (pMemFile, "%s %i %i %i ", pname,
02179                     (int)fa->texdef.shift[0], (int)fa->texdef.shift[1],
02180                     (int)fa->texdef.rotate);
02181                 
02182                 if (fa->texdef.scale[0] == (int)fa->texdef.scale[0])
02183                     MemFile_fprintf (pMemFile, "%i ", (int)fa->texdef.scale[0]);
02184                 else
02185                     MemFile_fprintf (pMemFile, "%f ", (float)fa->texdef.scale[0]);
02186                 if (fa->texdef.scale[1] == (int)fa->texdef.scale[1])
02187                     MemFile_fprintf (pMemFile, "%i", (int)fa->texdef.scale[1]);
02188                 else
02189                     MemFile_fprintf (pMemFile, "%f", (float)fa->texdef.scale[1]);
02190                 
02191                 MemFile_fprintf (pMemFile, " %i %i %i", fa->texdef.contents, fa->texdef.flags, fa->texdef.value);
02192             }
02193             MemFile_fprintf (pMemFile, "\n");
02194         }
02195         MemFile_fprintf (pMemFile, "}\n");
02196     }
02197     
02198     
02199 }

Here is the call graph for this function:

void Brush_Write brush_t b,
FILE f
 

Definition at line 1932 of file Brush.cpp.

References b, brush_s::brush_faces, brush_t, face_s::brushprimit_texdef, QEGlobals_t::bSurfacePropertiesPlugin, texdef_t::contents, brushprimit_texdef_s::coords, epair_t, brush_s::epairs, f, face_t, texdef_t::flags, fprintf(), g_File, g_qeglobals, GETPLUGINTEXDEF, i, j, epair_s::key, QEGlobals_t::m_bBrushPrimitMode, texdef_t::name, face_s::next, epair_s::next, Patch_Write(), brush_s::patchBrush, face_s::pData, face_s::planepts, pname, brush_s::pPatch, brush_s::pTerrain, QERApp_MapPrintf_FILE(), texdef_t::rotate, texdef_t::scale, texdef_t::shift, strlen(), Sys_Printf(), Terrain_Write(), face_s::texdef, texdef_t::value, and epair_s::value.

01933 {
01934     epair_t *ep;
01935     face_t  *fa;
01936     char    *pname;
01937     int     i;
01938     
01939     if (b->patchBrush)
01940     {
01941         Patch_Write(b->pPatch, f);
01942         return;
01943     }
01944     if ( b->pTerrain )
01945     {
01946         Terrain_Write(b->pTerrain, f);
01947         return;
01948     }
01949     if (g_qeglobals.m_bBrushPrimitMode)
01950     {
01951         // save brush primitive format
01952         fprintf (f, "{\nbrushDef\n{\n");
01953         // brush epairs
01954         if (b->epairs)
01955             for (ep = b->epairs ; ep ; ep=ep->next)
01956                 fprintf (f, "\"%s\" \"%s\"\n", ep->key, ep->value);
01957         for (fa=b->brush_faces ; fa ; fa=fa->next)
01958         {
01959             // save planepts
01960             for (i=0 ; i<3 ; i++)
01961             {
01962                 fprintf(f, "( ");
01963                 for (int j = 0; j < 3; j++)
01964                     if (fa->planepts[i][j] == static_cast<int>(fa->planepts[i][j]))
01965                         fprintf(f, "%i ", static_cast<int>(fa->planepts[i][j]));
01966                     else
01967                         fprintf(f, "%f ", fa->planepts[i][j]);
01968                 fprintf(f, ") ");
01969             }
01970             // save texture coordinates
01971             fprintf(f,"( ( ");
01972             for (i=0 ; i<3 ; i++)
01973                 if (fa->brushprimit_texdef.coords[0][i] == static_cast<int>(fa->brushprimit_texdef.coords[0][i]))
01974                     fprintf(f,"%i ",static_cast<int>(fa->brushprimit_texdef.coords[0][i]));
01975                 else
01976                     fprintf(f,"%f ",fa->brushprimit_texdef.coords[0][i]);
01977             fprintf(f,") ( ");
01978             for (i=0 ; i<3 ; i++)
01979                 if (fa->brushprimit_texdef.coords[1][i] == static_cast<int>(fa->brushprimit_texdef.coords[1][i]))
01980                     fprintf(f,"%i ",static_cast<int>(fa->brushprimit_texdef.coords[1][i]));
01981                 else
01982                     fprintf(f,"%f ",fa->brushprimit_texdef.coords[1][i]);
01983             fprintf(f,") ) ");
01984             // save texture attribs
01985             //++timo surface properties plugin not implemented for brush primitives
01986             if (g_qeglobals.bSurfacePropertiesPlugin)
01987                 Sys_Printf("WARNING: surface properties plugin not supported with brush primitives (yet)\n");
01988 
01989       char *pName = strlen(fa->texdef.name) > 0 ? fa->texdef.name : "unnamed";
01990             fprintf(f, "%s ", pName );
01991             fprintf(f, "%i %i %i\n", fa->texdef.contents, fa->texdef.flags, fa->texdef.value);
01992         }
01993         fprintf (f, "}\n}\n");
01994     }
01995     else
01996     {
01997         fprintf (f, "{\n");
01998         for (fa=b->brush_faces ; fa ; fa=fa->next)
01999         {
02000             for (i=0 ; i<3 ; i++)
02001             {
02002                 fprintf(f, "( ");
02003                 for (int j = 0; j < 3; j++)
02004                 {
02005                     if (fa->planepts[i][j] == static_cast<int>(fa->planepts[i][j]))
02006                         fprintf(f, "%i ", static_cast<int>(fa->planepts[i][j]));
02007                     else
02008                         fprintf(f, "%f ", fa->planepts[i][j]);
02009                 }
02010                 fprintf(f, ") ");
02011             }
02012             
02013             if (g_qeglobals.bSurfacePropertiesPlugin)
02014             {
02015                 g_File = f;
02016 #ifdef _DEBUG
02017                 if (!fa->pData)
02018                     Sys_Printf("ERROR: unexpected IPluginTexdef* is NULL in Brush_Write\n");
02019                 else
02020 #endif
02021                 GETPLUGINTEXDEF(fa)->WriteTexdef( QERApp_MapPrintf_FILE );
02022             }
02023             else
02024             {
02025                 pname = fa->texdef.name;
02026                 if (pname[0] == 0)
02027                     pname = "unnamed";
02028                 
02029                 fprintf (f, "%s %i %i %i ", pname,
02030                     (int)fa->texdef.shift[0], (int)fa->texdef.shift[1],
02031                     (int)fa->texdef.rotate);
02032                 
02033                 if (fa->texdef.scale[0] == (int)fa->texdef.scale[0])
02034                     fprintf (f, "%i ", (int)fa->texdef.scale[0]);
02035                 else
02036                     fprintf (f, "%f ", (float)fa->texdef.scale[0]);
02037                 if (fa->texdef.scale[1] == (int)fa->texdef.scale[1])
02038                     fprintf (f, "%i", (int)fa->texdef.scale[1]);
02039                 else
02040                     fprintf (f, "%f", (float)fa->texdef.scale[1]);
02041                 
02042                 fprintf (f, " %i %i %i", fa->texdef.contents, fa->texdef.flags, fa->texdef.value);
02043             }
02044             fprintf (f, "\n");
02045         }
02046         fprintf (f, "}\n");
02047     }
02048 }

Here is the call graph for this function:

face_t* Face_Alloc void   ) 
 

Definition at line 169 of file Brush.cpp.

00170 {
00171     face_t *f = (face_t*)qmalloc( sizeof( *f ) );
00172     
00173     if (g_qeglobals.bSurfacePropertiesPlugin)
00174         f->pData = static_cast<void *>( g_SurfaceTable.m_pfnTexdefAlloc( f ) );
00175 
00176     return f;
00177 }

face_t* Face_Clone face_t f  ) 
 

Definition at line 216 of file Brush.cpp.

References f, Face_Alloc(), face_t, memcpy(), n, face_s::planepts, and face_s::texdef.

Referenced by Brush_Clone(), and Brush_SplitBrushByFace().

00217 {
00218     face_t  *n;
00219 
00220     n = Face_Alloc();
00221     n->texdef = f->texdef;
00222 
00223     memcpy (n->planepts, f->planepts, sizeof(n->planepts));
00224 
00225     // all other fields are derived, and will be set by Brush_Build
00226     return n;
00227 }

Here is the call graph for this function:

void Face_Draw face_t face  ) 
 

Definition at line 4085 of file Brush.cpp.

References f, face_t, face_s::face_winding, i, winding_t::numpoints, winding_t::points, qglBegin, qglEnd, and qglVertex3fv.

Referenced by CCamWnd::Cam_Draw().

04086 {
04087     int i;
04088 
04089     if ( f->face_winding == 0 )
04090         return;
04091     qglBegin( GL_POLYGON );
04092     for ( i = 0 ; i < f->face_winding->numpoints; i++)
04093         qglVertex3fv( f->face_winding->points[i] );
04094     qglEnd();
04095 }

void Face_FitTexture face_t face,
int  nHeight,
int  nWidth
 

Definition at line 4475 of file Brush.cpp.

References AddPointToBounds(), ClearBounds(), cos(), face_s::d_texture, DotProduct, face_t, face_s::face_winding, qtexture_s::height, height, i, winding_t::numpoints, face_s::plane, winding_t::points, texdef_t::rotate, s, texdef_t::scale, texdef_t::shift, sin(), t, face_s::texdef, TextureAxisFromPlane(), vec3_t, vecs, w, qtexture_s::width, and width.

Referenced by Brush_FitTexture(), and Select_FitTexture().

04476 {
04477   winding_t *w;
04478   vec3_t   mins,maxs;
04479   int i;
04480   float width, height, temp;
04481   float rot_width, rot_height;
04482   float cosv,sinv,ang;
04483   float min_t, min_s, max_t, max_s;
04484   float s,t;
04485     vec3_t  vecs[2];
04486   vec3_t   coords[4];
04487     texdef_t    *td;
04488 
04489   if (nHeight < 1)
04490   {
04491     nHeight = 1;
04492   }
04493   if (nWidth < 1)
04494   {
04495     nWidth = 1;
04496   }
04497 
04498   ClearBounds (mins, maxs);
04499 
04500     td = &face->texdef;
04501     w = face->face_winding;
04502     if (!w)
04503     {
04504     return;
04505     }
04506   for (i=0 ; i<w->numpoints ; i++)
04507   {
04508     AddPointToBounds( w->points[i], mins, maxs );
04509   }
04510    // 
04511    // get the current angle
04512    //
04513     ang = td->rotate / 180 * Q_PI;
04514     sinv = sin(ang);
04515     cosv = cos(ang);
04516 
04517     // get natural texture axis
04518     TextureAxisFromPlane(&face->plane, vecs[0], vecs[1]);
04519 
04520   min_s = DotProduct( mins, vecs[0] );
04521   min_t = DotProduct( mins, vecs[1] );
04522   max_s = DotProduct( maxs, vecs[0] );
04523   max_t = DotProduct( maxs, vecs[1] );
04524   width = max_s - min_s;
04525   height = max_t - min_t;
04526   coords[0][0] = min_s;
04527   coords[0][1] = min_t;
04528   coords[1][0] = max_s;
04529   coords[1][1] = min_t;
04530   coords[2][0] = min_s;
04531   coords[2][1] = max_t;
04532   coords[3][0] = max_s;
04533   coords[3][1] = max_t;
04534   min_s = min_t = 99999;
04535   max_s = max_t = -99999;
04536   for (i=0; i<4; i++)
04537   {
04538     s = cosv * coords[i][0] - sinv * coords[i][1];
04539       t = sinv * coords[i][0] + cosv * coords[i][1];
04540     if (i&1)
04541     {
04542       if (s > max_s) 
04543       {
04544         max_s = s;
04545       }
04546     }
04547     else
04548     {
04549       if (s < min_s) 
04550       {
04551         min_s = s;
04552       }
04553       if (i<2)
04554       {
04555         if (t < min_t) 
04556         {
04557           min_t = t;
04558         }
04559       }
04560       else
04561       {
04562         if (t > max_t) 
04563         {
04564           max_t = t;
04565         }
04566       }
04567     }
04568   }
04569   rot_width =  (max_s - min_s);
04570   rot_height = (max_t - min_t);
04571   td->scale[0] = -(rot_width/((float)(face->d_texture->width*nWidth)));
04572   td->scale[1] = -(rot_height/((float)(face->d_texture->height*nHeight)));
04573 
04574   td->shift[0] = min_s/td->scale[0];
04575   temp = (int)(td->shift[0] / (face->d_texture->width*nWidth));
04576   temp = (temp+1)*face->d_texture->width*nWidth;
04577   td->shift[0] = (int)(temp - td->shift[0])%(face->d_texture->width*nWidth);
04578 
04579   td->shift[1] = min_t/td->scale[1];
04580   temp = (int)(td->shift[1] / (face->d_texture->height*nHeight));
04581   temp = (temp+1)*(face->d_texture->height*nHeight);
04582   td->shift[1] = (int)(temp - td->shift[1])%(face->d_texture->height*nHeight);
04583 }

Here is the call graph for this function:

void Face_Free face_t f  ) 
 

Definition at line 184 of file Brush.cpp.

References assert, QEGlobals_t::bSurfacePropertiesPlugin, f, face_t, face_s::face_winding, free(), g_qeglobals, GETPLUGINTEXDEF, face_s::pData, Sys_Printf(), face_s::texdef, and texdef_t::~texdef_t().

Referenced by Brush_Free(), Brush_RebuildBrush(), Brush_RemoveEmptyFaces(), Brush_Resize(), and QERApp_DeleteFace().

00185 {
00186     assert( f != 0 );
00187 
00188     if ( f->face_winding )
00189     {
00190         free( f->face_winding );
00191         f->face_winding = 0;
00192     }
00193 
00194     if (g_qeglobals.bSurfacePropertiesPlugin)
00195     {
00196 #ifdef _DEBUG
00197         if ( !f->pData )
00198         {
00199             Sys_Printf("WARNING: unexpected IPluginTexdef is NULL in Face_Free\n");
00200         }
00201         else
00202 #endif
00203         GETPLUGINTEXDEF(f)->DecRef();
00204     }
00205 
00206     f->texdef.~texdef_t();;
00207 
00208     free( f );
00209 }

Here is the call graph for this function:

void Face_MakePlane face_t f  ) 
 

Definition at line 432 of file Brush.cpp.

References CrossProduct(), plane_t::dist, DotProduct, f, face_t, j, plane_t::normal, face_s::plane, face_s::planepts, printf(), vec3_origin, vec3_t, VectorCompare(), and VectorNormalize().

Referenced by Brush_MakeFacePlanes().

00433 {
00434     int     j;
00435     vec3_t  t1, t2, t3;
00436 
00437     // convert to a vector / dist plane
00438     for (j=0 ; j<3 ; j++)
00439     {
00440         t1[j] = f->planepts[0][j] - f->planepts[1][j];
00441         t2[j] = f->planepts[2][j] - f->planepts[1][j];
00442         t3[j] = f->planepts[1][j];
00443     }
00444     
00445     CrossProduct(t1,t2, f->plane.normal);
00446     if (VectorCompare (f->plane.normal, vec3_origin))
00447         printf ("WARNING: brush plane with no normal\n");
00448     VectorNormalize (f->plane.normal);
00449     f->plane.dist = DotProduct (t3, f->plane.normal);
00450 }

Here is the call graph for this function:

void Face_TextureVectors face_t f,
float  STfromXYZ[2][4]
 

Definition at line 345 of file Brush.cpp.

References QEGlobals_t::bNeedConvert, cos(), face_s::d_texture, f, face_t, g_PrefsDlg, g_qeglobals, qtexture_s::height, i, j, QEGlobals_t::m_bBrushPrimitMode, CPrefsDlg::m_bHiColorTextures, memset(), face_s::plane, q, qtexture_t, texdef_t::rotate, texdef_t::scale, texdef_t::shift, sin(), sv, Sys_Printf(), face_s::texdef, TextureAxisFromPlane(), tv(), vec3_t, and qtexture_s::width.

Referenced by EmitTextureCoordinates().

00346 {
00347     vec3_t      pvecs[2];
00348     int         sv, tv;
00349     float       ang, sinv, cosv;
00350     float       ns, nt;
00351     int         i,j;
00352     qtexture_t *q;
00353     texdef_t    *td;
00354 
00355 #ifdef _DEBUG
00356     //++timo when playing with patches, this sometimes get called and the Warning is displayed
00357     // find some way out ..
00358     if (g_qeglobals.m_bBrushPrimitMode && !g_qeglobals.bNeedConvert)
00359         Sys_Printf("Warning : illegal call of Face_TextureVectors in brush primitive mode\n");
00360 #endif
00361 
00362     td = &f->texdef;
00363     q = f->d_texture;
00364 
00365     memset (STfromXYZ, 0, 8*sizeof(float));
00366 
00367     if (!td->scale[0])
00368         td->scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
00369     if (!td->scale[1])
00370         td->scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
00371 
00372     // get natural texture axis
00373     TextureAxisFromPlane(&f->plane, pvecs[0], pvecs[1]);
00374 
00375     // rotate axis
00376     if (td->rotate == 0)
00377         { sinv = 0 ; cosv = 1; }
00378     else if (td->rotate == 90)
00379         { sinv = 1 ; cosv = 0; }
00380     else if (td->rotate == 180)
00381         { sinv = 0 ; cosv = -1; }
00382     else if (td->rotate == 270)
00383         { sinv = -1 ; cosv = 0; }
00384     else
00385     {   
00386         ang = td->rotate / 180 * Q_PI;
00387         sinv = sin(ang);
00388         cosv = cos(ang);
00389     }
00390 
00391     if (pvecs[0][0])
00392         sv = 0;
00393     else if (pvecs[0][1])
00394         sv = 1;
00395     else
00396         sv = 2;
00397                 
00398     if (pvecs[1][0])
00399         tv = 0;
00400     else if (pvecs[1][1])
00401         tv = 1;
00402     else
00403         tv = 2;
00404                     
00405     for (i=0 ; i<2 ; i++) {
00406         ns = cosv * pvecs[i][sv] - sinv * pvecs[i][tv];
00407         nt = sinv * pvecs[i][sv] +  cosv * pvecs[i][tv];
00408         STfromXYZ[i][sv] = ns;
00409         STfromXYZ[i][tv] = nt;
00410     }
00411 
00412     // scale
00413     for (i=0 ; i<2 ; i++)
00414         for (j=0 ; j<3 ; j++)
00415             STfromXYZ[i][j] = STfromXYZ[i][j] / td->scale[i];
00416 
00417     // shift
00418     STfromXYZ[0][3] = td->shift[0];
00419     STfromXYZ[1][3] = td->shift[1];
00420 
00421     for (j=0 ; j<4 ; j++) {
00422         STfromXYZ[0][j] /= q->width;
00423         STfromXYZ[1][j] /= q->height;
00424     }
00425 }

Here is the call graph for this function:

void SetFaceTexdef brush_t b,
face_t f,
texdef_t texdef,
brushprimit_texdef_t brushprimit_texdef,
bool  bFitScale = false,
IPluginTexdef pPlugTexdef = NULL
 

Definition at line 2867 of file Brush.cpp.

References AbsoluteToLocal(), b, brush_s::brush_faces, brush_t, face_s::brushprimit_texdef, brushprimit_texdef, brushprimit_texdef_t, QEGlobals_t::bSurfacePropertiesPlugin, ComputeAbsolute(), texdef_t::contents, ConvertTexMatWithQTexture(), f, face_t, texdef_t::flags, g_qeglobals, g_SurfaceTable, GETPLUGINTEXDEF, IPluginTexdef::Hook(), QEGlobals_t::m_bBrushPrimitMode, _QERPlugSurfaceTable::m_pfnTexdefAlloc, texdef_t::name, face_s::next, NULL, p2, face_s::pData, face_s::plane, pPlugTexdef, texdef_t::scale, Sys_Printf(), face_s::texdef, Texture_ForName(), vec3_t, VectorAdd, VectorNormalize(), VectorScale, and VectorSubtract.

Referenced by Brush_SetTexture(), Drag_Begin(), and Select_SetTexture().

02867                                                                                                                                                    {
02868     int     oldFlags;
02869     int     oldContents;
02870     face_t  *tf;
02871 
02872     oldFlags = f->texdef.flags;
02873     oldContents = f->texdef.contents;
02874     if (g_qeglobals.m_bBrushPrimitMode)
02875     {
02876         f->texdef = *texdef;
02877         ConvertTexMatWithQTexture( brushprimit_texdef, NULL, &f->brushprimit_texdef, Texture_ForName( f->texdef.name ) );
02878     }
02879     else
02880         if (bFitScale)
02881         {
02882             f->texdef = *texdef;
02883             // fit the scaling of the texture on the actual plane
02884             vec3_t p1,p2,p3; // absolute coordinates
02885             // compute absolute coordinates
02886             ComputeAbsolute(f,p1,p2,p3);
02887             // compute the scale
02888             vec3_t vx,vy;
02889             VectorSubtract(p2,p1,vx);
02890             VectorNormalize(vx);
02891             VectorSubtract(p3,p1,vy);
02892             VectorNormalize(vy);
02893             // assign scale
02894             VectorScale(vx,texdef->scale[0],vx);
02895             VectorScale(vy,texdef->scale[1],vy);
02896             VectorAdd(p1,vx,p2);
02897             VectorAdd(p1,vy,p3);
02898             // compute back shift scale rot
02899             AbsoluteToLocal(f->plane,f,p1,p2,p3);
02900         }
02901         else
02902             f->texdef = *texdef;
02903     f->texdef.flags = (f->texdef.flags & ~SURF_KEEP) | (oldFlags & SURF_KEEP);
02904     f->texdef.contents = (f->texdef.contents & ~CONTENTS_KEEP) | (oldContents & CONTENTS_KEEP);
02905 
02906     // surface plugin
02907     if (g_qeglobals.bSurfacePropertiesPlugin)
02908     {
02909 #ifdef _DEBUG
02910         if (!f->pData)
02911             Sys_Printf("ERROR: unexpected IPluginTexdef* is NULL in SetFaceTexdef\n");
02912         else
02913 #endif
02914             GETPLUGINTEXDEF(f)->DecRef();
02915         IPluginTexdef *pTexdef = NULL;
02916         if ( pPlugTexdef )
02917         {
02918             pTexdef = pPlugTexdef->Copy();
02919             pTexdef->Hook( f );
02920         }
02921         else
02922             pTexdef = g_SurfaceTable.m_pfnTexdefAlloc( f );
02923         f->pData = pTexdef;
02924     }
02925 
02926     // if this is a curve face, set all other curve faces to the same texdef
02927     if (f->texdef.flags & SURF_CURVE) 
02928     {
02929         for (tf = b->brush_faces ; tf ; tf = tf->next) 
02930         {
02931             if (tf->texdef.flags & SURF_CURVE) 
02932                 tf->texdef = f->texdef;
02933         }
02934     }
02935 }

Here is the call graph for this function:

float SetShadeForPlane plane_t p  ) 
 

Definition at line 135 of file Brush.cpp.

References f, fabs(), i, lightaxis, plane_t::normal, and p.

Referenced by Face_SetColor().

00136 {
00137     int     i;
00138     float   f;
00139 
00140     // axial plane
00141     for (i=0 ; i<3 ; i++)
00142         if (fabs(p->normal[i]) > 0.9)
00143         {
00144             f = lightaxis[i];
00145             return f;
00146         }
00147 
00148     // between two axial planes
00149     for (i=0 ; i<3 ; i++)
00150         if (fabs(p->normal[i]) < 0.1)
00151         {
00152             f = (lightaxis[(i+1)%3] + lightaxis[(i+2)%3])/2;
00153             return f;
00154         }
00155 
00156     // other
00157     f= (lightaxis[0] + lightaxis[1] + lightaxis[2]) / 3;
00158     return f;
00159 }

Here is the call graph for this function:


Generated on Thu Aug 25 17:27:04 2005 for Quake III Arena by  doxygen 1.3.9.1