/* ============ Select_Brush ============ */ void Select_Brush( brush_s* brush, bool bComplete, bool bStatus ) { brush_s* b; entity_s* e; g_ptrSelectedFaces.RemoveAll(); g_ptrSelectedFaceBrushes.RemoveAll(); //selected_face = NULL; if ( g_qeglobals.d_select_count < 2 ) g_qeglobals.d_select_order[g_qeglobals.d_select_count] = brush; g_qeglobals.d_select_count++; //if (brush->patchBrush) // Patch_Select(brush->nPatchID); e = brush->owner; if ( e ) { // select complete entity on first click if ( e != world_entity && bComplete == true ) { for ( b = selected_brushes.next ; b != &selected_brushes ; b = b->next ) if ( b->owner == e ) goto singleselect; for ( b = e->brushes.onext ; b != &e->brushes ; b = b->onext ) { Brush_RemoveFromList( b ); Brush_AddToList( b, &selected_brushes ); } } else { singleselect: Brush_RemoveFromList( brush ); Brush_AddToList( brush, &selected_brushes ); UpdateSurfaceDialog(); UpdatePatchInspector(); } if ( e->eclass ) { UpdateEntitySel( brush->owner->eclass ); } } if ( bStatus ) { edVec3_c vMin, vMax, vSize; Select_GetBounds( vMin, vMax ); vSize = vMax - vMin; CString strStatus; strStatus.Format( "Selection X:: %.1f Y:: %.1f Z:: %.1f", vSize[0], vSize[1], vSize[2] ); g_pParentWnd->SetStatusText( 2, strStatus ); } }
/* ============= Undo_AddBrush ============= */ void Undo_AddBrush(brush_t *pBrush) { if (!g_lastundo) { Sys_Status("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Status("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //if the brush is already in the undo if (Undo_BrushInUndo(g_lastundo, pBrush)) return; //clone the brush brush_t* pClone = Brush_FullClone(pBrush); //save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; if (pBrush->owner && !(pBrush->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN)) { Undo_AddEntity(pBrush->owner); } //save the old undo ID for previous undos pClone->undoId = pBrush->undoId; Brush_AddToList (pClone, &g_lastundo->brushlist); // g_undoMemorySize += Brush_MemorySize(pClone); }
/* ============= Undo_AddBrush ============= */ void Undo_AddBrush(brush_t *pBrush) { // spog - disable undo if undo levels = 0 if (g_PrefsDlg.m_nUndoLevels == 0) { #ifdef DBG_UNDO Sys_Printf("Undo_AddBrush: undo is disabled.\n"); #endif return; } if (!g_lastundo) { Sys_Printf("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Printf("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //if the brush is already in the undo if (Undo_BrushInUndo(g_lastundo, pBrush)) return; //clone the brush brush_t* pClone = Brush_FullClone(pBrush); //save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; //save the old undo ID for previous undos pClone->undoId = pBrush->undoId; Brush_AddToList (pClone, &g_lastundo->brushlist); // g_undoMemorySize += Brush_MemorySize(pClone); }
void Select_Inside( void ) { brush_s* b, *next; int i; edVec3_c mins, maxs; if ( !QE_SingleBrush() ) return; clearSelection(); mins = selected_brushes.next->getMins(); maxs = selected_brushes.next->getMaxs(); Select_Delete(); for ( b = active_brushes.next ; b != &active_brushes ; b = next ) { next = b->next; if ( FilterBrush( b ) ) continue; for ( i = 0 ; i < 3 ; i++ ) if ( b->getMaxs()[i] > maxs[i] || b->getMins()[i] < mins[i] ) break; if ( i == 3 ) { Brush_RemoveFromList( b ); Brush_AddToList( b, &selected_brushes ); } } Sys_UpdateWindows( W_ALL ); }
/* ======================================================================================================================= Map_RegionOff Other filtering options may still be on ======================================================================================================================= */ void Map_RegionOff(void) { brush_t *b, *next; int i; region_active = false; for (i = 0; i < 3; i++) { region_maxs[i] = MAX_WORLD_COORD; // 4096; region_mins[i] = MIN_WORLD_COORD; // -4096; } for (b = filtered_brushes.next; b != &filtered_brushes; b = next) { next = b->next; if (Map_IsBrushFiltered(b)) { continue; // still filtered } Brush_RemoveFromList(b); if (active_brushes.next == NULL || active_brushes.prev == NULL) { active_brushes.next = &active_brushes; active_brushes.prev = &active_brushes; } Brush_AddToList(b, &active_brushes); } Sys_UpdateWindows(W_ALL); }
/* Turn the currently selected entity back into normal brushes */ void Select_Ungroup (void) { entity_t *e; brush_t *b; e = selected_brushes.next->owner; if (!e || e == world_entity || e->eclass->fixedsize) { Sys_Status ("Not a grouped entity.", 0); return; } for (b=e->brushes.onext ; b != &e->brushes ; b=e->brushes.onext) { Brush_RemoveFromList (b); Brush_AddToList (b, &active_brushes); Entity_UnlinkBrush (b); Entity_LinkBrush (world_entity, b); Brush_Build( b ); b->owner = world_entity; } Entity_Free (e); Sys_UpdateWindows (W_ALL); }
/* =========== Map_RegionOff Other filtering options may still be on =========== */ void Map_RegionOff( void ){ brush_t *b, *next; int i; region_active = false; for ( i = 0 ; i < 3 ; i++ ) { region_maxs[i] = g_MaxWorldCoord - 64; region_mins[i] = g_MinWorldCoord + 64; } for ( b = filtered_brushes.next ; b != &filtered_brushes ; b = next ) { next = b->next; if ( Map_IsBrushFiltered( b ) ) { continue; // still filtered } Brush_RemoveFromList( b ); if ( active_brushes.next == NULL || active_brushes.prev == NULL ) { active_brushes.next = &active_brushes; active_brushes.prev = &active_brushes; } Brush_AddToList( b, &active_brushes ); b->bFiltered = FilterBrush( b ); } Sys_UpdateWindows( W_ALL ); }
/* ============= CSG_MakeHollow ============= */ void CSG_MakeHollow (void) { brush_t *b, *front, *back, *next; face_t *f; face_t split; vec3_t move; int i; for (b = selected_brushes.next ; b != &selected_brushes ; b=next) { next = b->next; if (b->owner->eclass->fixedsize || b->hiddenBrush) continue; for (f = b->brush_faces ; f ; f=f->next) { split = *f; VectorScale (f->plane.normal, g_qeglobals.d_gridsize, move); for (i=0 ; i<3 ; i++) VectorSubtract (split.planepts[i], move, split.planepts[i]); CSG_SplitBrushByFace (b, &split, &front, &back); if (back) Brush_Free (back); if (front) Brush_AddToList (front, &selected_brushes); } Brush_Free (b); } Sys_UpdateWindows (W_ALL); }
void Select_Inside (void) { brush_t *b, *next; int i; vec3_t mins, maxs; if (!QE_SingleBrush ()) return; g_qeglobals.d_select_mode = sel_brush; Math_VectorCopy (selected_brushes.next->mins, mins); Math_VectorCopy (selected_brushes.next->maxs, maxs); Select_Delete (); for (b=active_brushes.next ; b != &active_brushes ; b=next) { next = b->next; for (i=0 ; i<3 ; i++) if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i]) break; if (i == 3) { Brush_RemoveFromList (b); Brush_AddToList (b, &selected_brushes); } } Sys_UpdateWindows (W_ALL); }
/* ============ Select_Ray If the origin is inside a brush, that brush will be ignored. ============ */ void Select_Ray (vec3_t origin, vec3_t dir, int flags) { trace_t t; t = Test_Ray (origin, dir, flags); if (!t.brush) return; if (flags == SF_SINGLEFACE) { selected_face = t.face; selected_face_brush = t.brush; Sys_UpdateWindows (W_ALL); g_qeglobals.d_select_mode = sel_brush; Texture_SetTexture (&t.face->texdef); UpdateSurfaceDialog(); return; } // move the brush to the other list g_qeglobals.d_select_mode = sel_brush; if (t.selected) { Brush_RemoveFromList (t.brush); Brush_AddToList (t.brush, &active_brushes); } else { Select_Brush (t.brush, !(GetKeyState(VK_MENU) & 0x8000)); } Sys_UpdateWindows (W_ALL); }
void Select_Touching (void) { brush_t *b, *next; int i; vec3_t mins, maxs; if (!QE_SingleBrush ()) return; g_qeglobals.d_select_mode = sel_brush; VectorCopy (selected_brushes.next->mins, mins); VectorCopy (selected_brushes.next->maxs, maxs); for (b=active_brushes.next ; b != &active_brushes ; b=next) { next = b->next; if (FilterBrush (b)) continue; for (i=0 ; i<3 ; i++) if (b->mins[i] > maxs[i]+1 || b->maxs[i] < mins[i]-1) break; if (i == 3) { Brush_RemoveFromList (b); Brush_AddToList (b, &selected_brushes); } } Sys_UpdateWindows (W_ALL); }
void Select_PartialTall( void ) { brush_s* b, *next; //int i; edVec3_c mins, maxs; if ( !QE_SingleBrush() ) return; clearSelection(); mins = selected_brushes.next->getMins(); maxs = selected_brushes.next->getMaxs(); Select_Delete(); int nDim1 = ( g_pParentWnd->ActiveXY()->GetViewType() == YZ ) ? 1 : 0; int nDim2 = ( g_pParentWnd->ActiveXY()->GetViewType() == XY ) ? 1 : 2; for ( b = active_brushes.next ; b != &active_brushes ; b = next ) { next = b->next; if ( ( b->getMins()[nDim1] > maxs[nDim1] || b->getMaxs()[nDim1] < mins[nDim1] ) || ( b->getMins()[nDim2] > maxs[nDim2] || b->getMaxs()[nDim2] < mins[nDim2] ) ) continue; if ( FilterBrush( b ) ) continue; Brush_RemoveFromList( b ); Brush_AddToList( b, &selected_brushes ); #if 0 // old stuff for ( i = 0 ; i < 2 ; i++ ) if ( b->mins[i] > maxs[i] || b->maxs[i] < mins[i] ) break; if ( i == 2 ) { Brush_RemoveFromList( b ); Brush_AddToList( b, &selected_brushes ); } #endif } Sys_UpdateWindows( W_ALL ); }
/* ======================================================================================================================= AddRegionBrushes a regioned map will have temp walls put up at the region boundary ======================================================================================================================= */ void AddRegionBrushes(void) { idVec3 mins, maxs; int i; texdef_t td; if (!region_active) { return; } memset(&td, 0, sizeof(td)); td = g_qeglobals.d_texturewin.texdef; // strcpy (td.name, "REGION"); td.SetName("textures/REGION"); const int REGION_WIDTH = 1024; mins[0] = region_mins[0] - REGION_WIDTH; maxs[0] = region_mins[0] + 1; mins[1] = region_mins[1] - REGION_WIDTH; maxs[1] = region_maxs[1] + REGION_WIDTH; mins[2] = MIN_WORLD_COORD; maxs[2] = MAX_WORLD_COORD; region_sides[0] = Brush_Create(mins, maxs, &td); mins[0] = region_maxs[0] - 1; maxs[0] = region_maxs[0] + REGION_WIDTH; region_sides[1] = Brush_Create(mins, maxs, &td); mins[0] = region_mins[0] - REGION_WIDTH; maxs[0] = region_maxs[0] + REGION_WIDTH; mins[1] = region_mins[1] - REGION_WIDTH; maxs[1] = region_mins[1] + 1; region_sides[2] = Brush_Create(mins, maxs, &td); mins[1] = region_maxs[1] - 1; maxs[1] = region_maxs[1] + REGION_WIDTH; region_sides[3] = Brush_Create(mins, maxs, &td); mins = region_mins; maxs = region_maxs; maxs[2] = mins[2] + REGION_WIDTH; region_sides[4] = Brush_Create(mins, maxs, &td); mins = region_mins; maxs = region_maxs; mins[2] = maxs[2] - REGION_WIDTH; region_sides[5] = Brush_Create(mins, maxs, &td); for (i = 0; i < 6; i++) { Brush_AddToList(region_sides[i], &selected_brushes); Entity_LinkBrush(world_entity, region_sides[i]); Brush_Build(region_sides[i]); } }
void Select_CompleteTall (void) { brush_t *b, *next; //int i; vec3_t mins, maxs; if (!QE_SingleBrush ()) return; g_qeglobals.d_select_mode = sel_brush; VectorCopy (selected_brushes.next->mins, mins); VectorCopy (selected_brushes.next->maxs, maxs); Select_Delete (); int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0; int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2; for (b=active_brushes.next ; b != &active_brushes ; b=next) { next = b->next; if ( (b->maxs[nDim1] > maxs[nDim1] || b->mins[nDim1] < mins[nDim1]) || (b->maxs[nDim2] > maxs[nDim2] || b->mins[nDim2] < mins[nDim2]) ) continue; if (FilterBrush (b)) continue; Brush_RemoveFromList (b); Brush_AddToList (b, &selected_brushes); #if 0 // old stuff for (i=0 ; i<2 ; i++) if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i]) break; if (i == 2) { Brush_RemoveFromList (b); Brush_AddToList (b, &selected_brushes); } #endif } Sys_UpdateWindows (W_ALL); }
void SelectBrush (int entitynum, int brushnum) { entity_t *e; brush_t *b; int i; if (entitynum == 0) e = world_entity; else { e = entities.next; while (--entitynum) { e=e->next; if (e == &entities) { Sys_Status ("No such entity.", 0); return; } } } b = e->brushes.onext; if (b == &e->brushes) { Sys_Status ("No such brush.", 0); return; } while (brushnum--) { b=b->onext; if (b == &e->brushes) { Sys_Status ("No such brush.", 0); return; } } Brush_RemoveFromList (b); Brush_AddToList (b, &selected_brushes); Sys_UpdateWindows (W_ALL); for (i=0 ; i<3 ; i++) { if (g_pParentWnd->GetXYWnd()) g_pParentWnd->GetXYWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2; if (g_pParentWnd->GetXZWnd()) g_pParentWnd->GetXZWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2; if (g_pParentWnd->GetYZWnd()) g_pParentWnd->GetYZWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2; } Sys_Status ("Selected.", 0); }
/* ============ Select_Ray If the origin is inside a brush, that brush will be ignored. ============ */ void Select_Ray( vec3_t origin, vec3_t dir, int flags ) { trace_t t; t = Test_Ray( origin, dir, flags ); if ( !t.brush ) return; if ( flags == SF_SINGLEFACE ) { int nCount = g_SelectedFaces.GetSize(); bool bOk = true; for ( int i = 0; i < nCount; i++ ) { if ( t.face == reinterpret_cast<face_s*>( g_SelectedFaces.GetAt( i ) ) ) { bOk = false; // need to move remove i'th entry g_SelectedFaces.RemoveAt( i, 1 ); g_SelectedFaceBrushes.RemoveAt( i, 1 ); } } if ( bOk ) { g_SelectedFaces.Add( t.face ); g_SelectedFaceBrushes.Add( t.brush ); } //selected_face = t.face; //selected_face_brush = t.brush; Sys_UpdateWindows( W_ALL ); clearSelection(); // Texture_SetTexture requires a brushprimit_texdef fitted to the default width=2 height=2 texture brushprimit_texdef_s brushprimit_texdef; ConvertTexMatWithQTexture( &t.face->brushprimit_texdef, t.face->d_texture, &brushprimit_texdef, NULL ); Texture_SetTexture( &t.face->texdef, &brushprimit_texdef, false, false ); UpdateSurfaceDialog(); return; } // move the brush to the other list clearSelection(); if ( t.selected ) { Brush_RemoveFromList( t.brush ); Brush_AddToList( t.brush, &active_brushes ); UpdatePatchInspector(); } else { Select_Brush( t.brush, !( GetKeyState( VK_MENU ) & 0x8000 ) ); } Sys_UpdateWindows( W_ALL ); }
/* ============= CSG_Subtract ============= */ void CSG_Subtract (void) { brush_t *b, *s, *frag, *front, *back, *next, *snext; face_t *f; int i; Sys_Printf ("Subtracting...\n"); for (b = selected_brushes.next ; b != &selected_brushes ; b=next) { next = b->next; if (b->owner->eclass->fixedsize) continue; // can't use texture from a fixed entity, so don't subtract for (s=active_brushes.next ; s != &active_brushes ; s=snext) { snext = s->next; if (s->owner->eclass->fixedsize || s->patchBrush || s->hiddenBrush) continue; if (FilterBrush (s)) continue; //face_t *pFace = s->brush_faces; // not used if (s->brush_faces->d_texture->bFromShader && (s->brush_faces->d_texture->nShaderFlags & QER_NOCARVE)) { continue; } for (i=0 ; i<3 ; i++) if (b->mins[i] >= s->maxs[i] - ON_EPSILON || b->maxs[i] <= s->mins[i] + ON_EPSILON) break; if (i != 3) continue; // definately don't touch frag = s; for (f = b->brush_faces ; f && frag ; f=f->next) { CSG_SplitBrushByFace (frag, f, &front, &back); Brush_Free (frag); frag = back; if (front) Brush_AddToList (front, &active_brushes); } if (frag) Brush_Free (frag); } } Sys_Printf ("done.\n"); Sys_UpdateWindows (W_ALL); }
// creates a dummy brush in the active brushes list // FIXME : is this one really USED ? void WINAPI QERApp_CreateBrush(vec3_t vMin, vec3_t vMax) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); brush_t* pBrush = Brush_Create(vMin, vMax, &g_qeglobals.d_texturewin.texdef); Entity_LinkBrush (world_entity, pBrush); Brush_Build(pBrush); Brush_AddToList (pBrush, &active_brushes); Select_Brush(pBrush); Sys_UpdateWindows(W_ALL); }
/* ======================================================================================================================= ======================================================================================================================= */ void Map_ApplyRegion( void ) { brush_t *b, *next; region_active = true; for( b = active_brushes.next; b != &active_brushes; b = next ) { next = b->next; if( !Map_IsBrushFiltered( b ) ) { continue; // still filtered } Brush_RemoveFromList( b ); Brush_AddToList( b, &filtered_brushes ); } Sys_UpdateWindows( W_ALL ); }
void Select_Brush (brush_t *brush) { brush_t *b; entity_t *e; selected_face = NULL; if (g_qeglobals.d_select_count < 2) g_qeglobals.d_select_order[g_qeglobals.d_select_count] = brush; g_qeglobals.d_select_count++; e = brush->owner; if (e) { // select complete entity on first click if (e != world_entity) { for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) if (b->owner == e) goto singleselect; for (b=e->brushes.onext ; b != &e->brushes ; b=b->onext) { Brush_RemoveFromList (b); Brush_AddToList (b, &selected_brushes); } } else { singleselect: Brush_RemoveFromList (brush); Brush_AddToList (brush, &selected_brushes); } if (e->eclass) UpdateEntitySel(brush->owner->eclass); } }
void SelectBrush (int entitynum, int brushnum) { entity_t *e; brush_t *b; int i; if (entitynum == 0) e = world_entity; else { e = entities.next; while (--entitynum) { e=e->next; if (e == &entities) { Sys_Printf ("No such entity.\n"); return; } } } b = e->brushes.onext; if (b == &e->brushes) { Sys_Printf ("No such brush.\n"); return; } while (brushnum--) { b=b->onext; if (b == &e->brushes) { Sys_Printf ("No such brush.\n"); return; } } Brush_RemoveFromList (b); Brush_AddToList (b, &selected_brushes); Sys_UpdateWindows (W_ALL); for (i=0 ; i<3 ; i++) g_qeglobals.d_xyz.origin[i] = (b->mins[i] + b->maxs[i])/2; Sys_Printf ("Selected.\n"); }
/* ============= Undo_AddBrushList TTimo: some brushes are just there for UI, and the information is somewhere else for patches it's in the patchMesh_t structure, so when we clone the brush we get that information (brush_t::pPatch) but: models are stored in pBrush->owner->md3Class, and owner epairs and origin parameters are important so, we detect models and push the entity in the undo session (as well as it's BBox brush) same for other items like weapons and ammo etc. ============= */ void Undo_AddBrushList(brush_t *brushlist) { // spog - disable undo if undo levels = 0 if (g_PrefsDlg.m_nUndoLevels == 0) { #ifdef DBG_UNDO Sys_Printf("Undo_AddBrushList: undo is disabled.\n"); #endif return; } brush_t *pBrush; if (!g_lastundo) { Sys_Printf("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Printf("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //copy the brushes to the undo for (pBrush = brushlist->next ; pBrush != NULL && pBrush != brushlist; pBrush=pBrush->next) { //if the brush is already in the undo //++timo FIXME: when does this happen? if (Undo_BrushInUndo(g_lastundo, pBrush)) continue; // do we need to store this brush's entity in the undo? // if it's a fixed size entity, the brush that reprents it is not really relevant, it's used for selecting and moving around // what we want to store for undo is the owner entity, epairs and origin/angle stuff //++timo FIXME: if the entity is not fixed size I don't know, so I don't do it yet if (pBrush->owner->eclass->fixedsize == 1) Undo_AddEntity( pBrush->owner ); // clone the brush brush_t* pClone = Brush_FullClone(pBrush); // save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; // save the old undo ID from previous undos pClone->undoId = pBrush->undoId; Brush_AddToList (pClone, &g_lastundo->brushlist); // track memory size used by undo g_undoMemorySize += Brush_MemorySize(pClone); } }
void CPlugInManager::CommitBrushHandleToMap(void * vp) { g_bScreenUpdates = false; for (int i = 0; i < m_BrushHandles.GetSize(); i++) { brush_t *pb = reinterpret_cast<brush_t*>(m_BrushHandles.GetAt(i)); if (pb == reinterpret_cast<brush_t*>(vp)) { m_BrushHandles.RemoveAt(i); Entity_LinkBrush (world_entity, pb); Brush_Build(pb); Brush_AddToList (pb, &active_brushes); Select_Brush(pb); } } g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); }
/* ============== NewBrushDrag ============== */ void NewBrushDrag (int x, int y) { vec3_t mins, maxs, junk; int i; float temp; brush_t *n; if (!DragDelta (x,y, junk)) return; // delete the current selection if (selected_brushes.next != &selected_brushes) Brush_Free (selected_brushes.next); XY_ToGridPoint (pressx, pressy, mins); mins[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom_z/g_qeglobals.d_gridsize)); XY_ToGridPoint (x, y, maxs); maxs[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top_z/g_qeglobals.d_gridsize)); if (maxs[2] <= mins[2]) maxs[2] = mins[2] + g_qeglobals.d_gridsize; for (i=0 ; i<3 ; i++) { if (mins[i] == maxs[i]) return; // don't create a degenerate brush if (mins[i] > maxs[i]) { temp = mins[i]; mins[i] = maxs[i]; maxs[i] = temp; } } n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef); if (!n) return; Brush_AddToList (n, &selected_brushes); Entity_LinkBrush (world_entity, n); Brush_Build( n ); // Sys_UpdateWindows (W_ALL); Sys_UpdateWindows (W_XY| W_CAMERA); }
brush_t *AddBrushForTerrain( terrainMesh_t *pm, bool bLinkToWorld ) { int j; vec3_t vMin; vec3_t vMax; brush_t *b; face_t *f; // calculate the face normals Terrain_CalcNormals( pm ); // find the farthest points in x,y,z Terrain_CalcBounds( pm, vMin, vMax ); for( j = 0; j < 3; j++ ) { if ( vMin[ j ] == vMax[ j ] ) { vMin[ j ] -= 4; vMax[ j ] += 4; } } b = Brush_Create( vMin, vMax, &pm->heightmap->tri.texdef ); for( f = b->brush_faces; f != NULL; f = f->next ) { // copy the texdef to the brush faces texdef f->texdef = pm->heightmap->tri.texdef; } // FIXME: this entire type of linkage needs to be fixed b->pTerrain = pm; b->terrainBrush = true; pm->pSymbiot = b; pm->bSelected = false; pm->bDirty = true; pm->nListID = -1; if ( bLinkToWorld ) { Brush_AddToList( b, &active_brushes ); Entity_LinkBrush( world_entity, b ); Brush_Build( b, true ); } return b; }
/* =========== AddRegionBrushes a regioned map will have temp walls put up at the region boundary =========== */ void AddRegionBrushes (void) { vec3_t mins, maxs; int i; texdef_t td; if (!region_active) return; memset (&td, 0, sizeof(td)); //strcpy (td.name, "REGION"); td.SetName("REGION"); mins[0] = region_mins[0] - 16; maxs[0] = region_mins[0] + 1; mins[1] = region_mins[1] - 16; maxs[1] = region_maxs[1] + 16; mins[2] = MIN_WORLD_COORD; maxs[2] = MAX_WORLD_COORD; region_sides[0] = Brush_Create (mins, maxs, &td); mins[0] = region_maxs[0] - 1; maxs[0] = region_maxs[0] + 16; region_sides[1] = Brush_Create (mins, maxs, &td); mins[0] = region_mins[0] - 16; maxs[0] = region_maxs[0] + 16; mins[1] = region_mins[1] - 16; maxs[1] = region_mins[1] + 1; region_sides[2] = Brush_Create (mins, maxs, &td); mins[1] = region_maxs[1] - 1; maxs[1] = region_maxs[1] + 16; region_sides[3] = Brush_Create (mins, maxs, &td); for (i=0 ; i<4 ; i++) { Brush_AddToList (region_sides[i], &selected_brushes); Entity_LinkBrush (world_entity, region_sides[i]); Brush_Build( region_sides[i] ); } }
void Curve_BevelBrush( brush_t *b ) { curveBlock_t *cb; face_t *f; // make a copy without any curve flags, but keeping the negative flag bevelBrush = Brush_Clone( b ); for (f = bevelBrush->brush_faces ; f ; f = f->next) { f->texdef.flags &= ~SURF_CURVE; } bevelBrush->curveBrush = false; cb = BrushToCurveBlock(b); SubdivideCurveBlock (cb); Brush_Build( bevelBrush ); Brush_AddToList( bevelBrush, &active_brushes ); Entity_LinkBrush( b->owner, bevelBrush ); Sys_UpdateWindows (W_ALL); bevelBrush = NULL; }
/* If the origin is inside a brush, that brush will be ignored. */ void Select_Ray (vec3_t origin, vec3_t dir, int flags) { trace_t t; t = Test_Ray (origin, dir, flags); if(!t.brush) return; if (flags == SF_SINGLEFACE) { // [12/8/2012] Don't let them select entity faces ~hogsy // [22/8/2012] Simplified ~hogsy if(t.brush->owner->eclass->fixedsize) return; selected_face = t.face; selected_face_brush = t.brush; Sys_UpdateWindows (W_ALL); g_qeglobals.d_select_mode = sel_brush; return; } // move the brush to the other list g_qeglobals.d_select_mode = sel_brush; if (t.selected) { Brush_RemoveFromList (t.brush); Brush_AddToList (t.brush, &active_brushes); } else Select_Brush (t.brush); Sys_UpdateWindows (W_ALL); }
/* ============= Undo_AddBrushList ============= */ void Undo_AddBrushList(brush_t *brushlist) { brush_t *pBrush; if (!g_lastundo) { Sys_Status("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Status("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //copy the brushes to the undo for (pBrush = brushlist->next ; pBrush != NULL && pBrush != brushlist; pBrush=pBrush->next) { //if the brush is already in the undo if (Undo_BrushInUndo(g_lastundo, pBrush)) continue; //clone the brush brush_t* pClone = Brush_FullClone(pBrush); //save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; //save the old undo ID from previous undos pClone->undoId = pBrush->undoId; if ( pBrush->owner && pBrush->owner != world_entity ) { Undo_AddEntity(pBrush->owner); } Brush_AddToList (pClone, &g_lastundo->brushlist); // g_undoMemorySize += Brush_MemorySize(pClone); } }
/* Makes the current brushhave the given number of 2d sides */ void Brush_MakeSided(int sides) { int i; vec3_t mins, maxs; brush_t *b; texdef_t *texdef; face_t *f; vec3_t mid; float width,sv,cv; if(sides < 3) { Sys_Status ("Bad sides number", 0); return; } else if(!QE_SingleBrush()) { Sys_Status ("Must have a single brush selected", 0 ); return; } b = selected_brushes.next; Math_VectorCopy(b->mins,mins); Math_VectorCopy(b->maxs,maxs); texdef = &g_qeglobals.d_texturewin.texdef; Brush_Free (b); // find center of brush width = 8; for (i=0 ; i<2 ; i++) { mid[i] = (maxs[i] + mins[i])*0.5; if (maxs[i] - mins[i] > width) width = maxs[i] - mins[i]; } width /= 2; b = qmalloc (sizeof(brush_t)); // create top face f = Face_Alloc(); f->texdef = *texdef; f->next = b->brush_faces; b->brush_faces = f; f->planepts[2][0] = mins[0];f->planepts[2][1] = mins[1];f->planepts[2][2] = maxs[2]; f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = maxs[2]; f->planepts[0][0] = maxs[0];f->planepts[0][1] = maxs[1];f->planepts[0][2] = maxs[2]; // create bottom face f = Face_Alloc(); f->texdef = *texdef; f->next = b->brush_faces; b->brush_faces = f; f->planepts[0][0] = mins[0];f->planepts[0][1] = mins[1];f->planepts[0][2] = mins[2]; f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = mins[2]; f->planepts[2][0] = maxs[0];f->planepts[2][1] = maxs[1];f->planepts[2][2] = mins[2]; for (i=0 ; i<sides ; i++) { f = Face_Alloc(); f->texdef = *texdef; f->next = b->brush_faces; b->brush_faces = f; sv = sin (i*3.14159265*2/sides); cv = cos (i*3.14159265*2/sides); f->planepts[0][0] = floor(mid[0]+width*cv+0.5); f->planepts[0][1] = floor(mid[1]+width*sv+0.5); f->planepts[0][2] = mins[2]; f->planepts[1][0] = f->planepts[0][0]; f->planepts[1][1] = f->planepts[0][1]; f->planepts[1][2] = maxs[2]; f->planepts[2][0] = floor(f->planepts[0][0] - width*sv + 0.5); f->planepts[2][1] = floor(f->planepts[0][1] + width*cv + 0.5); f->planepts[2][2] = maxs[2]; } Brush_AddToList (b, &selected_brushes); Entity_LinkBrush (world_entity, b); Brush_Build( b ); Sys_UpdateWindows (W_ALL); }