trace_t Test_Ray (vec3_t origin, vec3_t dir, int flags) { brush_t *brush; face_t *face; float dist; trace_t t; memset (&t, 0, sizeof(t)); t.dist = DIST_START; if (! (flags & SF_SELECTED_ONLY) ) for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) { if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) continue; if (FilterBrush (brush)) continue; face = Brush_Ray (origin, dir, brush, &dist); if (dist > 0 && dist < t.dist) { t.dist = dist; t.brush = brush; t.face = face; t.selected = FALSE; } } for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) { if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) continue; if (FilterBrush (brush)) continue; face = Brush_Ray (origin, dir, brush, &dist); if (dist > 0 && dist < t.dist) { t.dist = dist; t.brush = brush; t.face = face; t.selected = TRUE; } } // if entites first, but didn't find any, check regular if ( (flags & SF_ENTITIES_FIRST) && t.brush == NULL) return Test_Ray (origin, dir, flags - SF_ENTITIES_FIRST); return t; }
/* =========== 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 ); }
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 ); }
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; VectorCopy (selected_brushes.next->mins, mins); VectorCopy (selected_brushes.next->maxs, maxs); 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->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); }
/* ==================== Entity_UpdateSoundEmitter Deletes the soundEmitter if the entity should not emit a sound due to it not having one, being filtered away, or the sound mode being turned off. Creates or updates the soundEmitter if needed ==================== */ void Entity_UpdateSoundEmitter( entity_t *ent ) { bool playing = false; // if an entity doesn't have any brushes at all, don't do anything // if the brush isn't displayed (filtered or culled), don't do anything if ( g_pParentWnd->GetCamera()->GetSoundMode() && ent->brushes.onext != &ent->brushes && !FilterBrush(ent->brushes.onext) ) { // check for sounds const char *v = ValueForKey( ent, "s_shader" ); if ( v[0] ) { refSound_t sound; gameEdit->ParseSpawnArgsToRefSound( &ent->epairs, &sound ); if ( !sound.waitfortrigger ) { // waitfortrigger will not start playing immediately if ( !ent->soundEmitter ) { ent->soundEmitter = g_qeglobals.sw->AllocSoundEmitter(); } playing = true; ent->soundEmitter->UpdateEmitter( ent->origin, 0, &sound.parms ); // always play on a single channel, so updates always override ent->soundEmitter->StartSound( sound.shader, SCHANNEL_ONE ); } } } // delete the soundEmitter if not used if ( !playing && ent->soundEmitter ) { ent->soundEmitter->Free( true ); ent->soundEmitter = NULL; } }
void Select_Touching (void) { brush_t *b, *next; int i; vec3_t mins, maxs; if (!QE_SingleBrush ()) return; clearSelection(); 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); }
/* ============= 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); }
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 ); }
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); }
/* ============== XY_Draw ============== */ void XY_Draw (void) { brush_t *brush; float w, h; entity_t *e; double start, end; vec3_t mins, maxs; int drawn, culled; int i; if (!active_brushes.next) return; // not valid yet if (g_qeglobals.d_xy.timing) start = Sys_DoubleTime (); // // clear // g_qeglobals.d_xy.d_dirty = false; glViewport(0, 0, g_qeglobals.d_xy.width, g_qeglobals.d_xy.height); glClearColor ( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2], 0); glClear(GL_COLOR_BUFFER_BIT); // // set up viewpoint // glMatrixMode(GL_PROJECTION); glLoadIdentity (); w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale; h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale; mins[0] = g_qeglobals.d_xy.origin[0] - w; maxs[0] = g_qeglobals.d_xy.origin[0] + w; mins[1] = g_qeglobals.d_xy.origin[1] - h; maxs[1] = g_qeglobals.d_xy.origin[1] + h; glOrtho (mins[0], maxs[0], mins[1], maxs[1], -8000, 8000); // // now draw the grid // XY_DrawGrid (); // // draw stuff // glShadeModel (GL_FLAT); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_1D); glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); glColor3f(0, 0, 0); // glEnable (GL_LINE_SMOOTH); drawn = culled = 0; e = NULL; for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) { if (brush->mins[0] > maxs[0] || brush->mins[1] > maxs[1] || brush->maxs[0] < mins[0] || brush->maxs[1] < mins[1] ) { culled++; continue; // off screen } if (FilterBrush (brush)) continue; drawn++; if (brush->owner != e) { e = brush->owner; glColor3fv(e->eclass->color); } Brush_DrawXY( brush ); } DrawPathLines (); // // draw pointfile // if ( g_qeglobals.d_pointfile_display_list) glCallList (g_qeglobals.d_pointfile_display_list); // // draw block grid // if ( g_qeglobals.show_blocks) XY_DrawBlockGrid (); // // now draw selected brushes // glTranslatef( g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]); glColor3f(1.0, 0.0, 0.0); glEnable (GL_LINE_STIPPLE); glLineStipple (3, 0xaaaa); glLineWidth (2); for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) { drawn++; Brush_DrawXY( brush ); } glDisable (GL_LINE_STIPPLE); glLineWidth (1); // edge / vertex flags if (g_qeglobals.d_select_mode == sel_vertex) { glPointSize (4); glColor3f (0,1,0); glBegin (GL_POINTS); for (i=0 ; i<g_qeglobals.d_numpoints ; i++) glVertex3fv (g_qeglobals.d_points[i]); glEnd (); glPointSize (1); } else if (g_qeglobals.d_select_mode == sel_edge) { float *v1, *v2; glPointSize (4); glColor3f (0,0,1); glBegin (GL_POINTS); for (i=0 ; i<g_qeglobals.d_numedges ; i++) { v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1]; v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2]; glVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5); } glEnd (); glPointSize (1); } glTranslatef (-g_qeglobals.d_select_translate[0], -g_qeglobals.d_select_translate[1], -g_qeglobals.d_select_translate[2]); // // now draw camera point // DrawCameraIcon (); DrawZIcon (); glFinish(); QE_CheckOpenGLForErrors(); if (g_qeglobals.d_xy.timing) { end = Sys_DoubleTime (); Sys_Printf ("xy: %i ms\n", (int)(1000*(end-start))); } }
trace_t Test_Ray( vec3_t origin, vec3_t dir, int flags ) { brush_s* brush; face_s* face; float dist; trace_t t; memset( &t, 0, sizeof( t ) ); t.dist = DIST_START; if ( flags & SF_CYCLE ) { CPtrArray array; brush_s* pToSelect = ( selected_brushes.next != &selected_brushes ) ? selected_brushes.next : NULL; Select_Deselect(); // go through active brushes and accumulate all "hit" brushes for ( brush = active_brushes.next ; brush != &active_brushes ; brush = brush->next ) { //if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) // continue; if ( FilterBrush( brush ) ) continue; if ( !g_PrefsDlg.m_bSelectCurves && brush->patchBrush ) continue; if ( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush ) continue; //if (!g_bShowPatchBounds && brush->patchBrush) // continue; face = Brush_Ray( origin, dir, brush, &dist ); if ( face ) { array.Add( brush ); } } int nSize = array.GetSize(); if ( nSize > 0 ) { bool bFound = false; for ( int i = 0; i < nSize; i++ ) { brush_s* b = reinterpret_cast<brush_s*>( array.GetAt( i ) ); // did we hit the last one selected yet ? if ( b == pToSelect ) { // yes we want to select the next one in the list int n = ( i > 0 ) ? i - 1 : nSize - 1; pToSelect = reinterpret_cast<brush_s*>( array.GetAt( n ) ); bFound = true; break; } } if ( !bFound ) pToSelect = reinterpret_cast<brush_s*>( array.GetAt( 0 ) ); } if ( pToSelect ) { face = Brush_Ray( origin, dir, pToSelect, &dist ); t.dist = dist; t.brush = pToSelect; t.face = face; t.selected = false; return t; } } if ( !( flags & SF_SELECTED_ONLY ) ) { for ( brush = active_brushes.next ; brush != &active_brushes ; brush = brush->next ) { if ( ( flags & SF_ENTITIES_FIRST ) && brush->owner == world_entity ) continue; if ( FilterBrush( brush ) ) continue; if ( !g_PrefsDlg.m_bSelectCurves && brush->patchBrush ) continue; if ( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush ) continue; //if (!g_bShowPatchBounds && brush->patchBrush) // continue; face = Brush_Ray( origin, dir, brush, &dist ); if ( dist > 0 && dist < t.dist ) { t.dist = dist; t.brush = brush; t.face = face; t.selected = false; } } } for ( brush = selected_brushes.next ; brush != 0 && brush != &selected_brushes ; brush = brush->next ) { if ( ( flags & SF_ENTITIES_FIRST ) && brush->owner == world_entity ) continue; if ( FilterBrush( brush ) ) continue; if ( !g_PrefsDlg.m_bSelectCurves && brush->patchBrush ) continue; if ( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush ) continue; face = Brush_Ray( origin, dir, brush, &dist ); if ( dist > 0 && dist < t.dist ) { t.dist = dist; t.brush = brush; t.face = face; t.selected = true; } } // if entites first, but didn't find any, check regular if ( ( flags & SF_ENTITIES_FIRST ) && t.brush == NULL ) return Test_Ray( origin, dir, flags - SF_ENTITIES_FIRST ); return t; }
void Select_AllOfType() { brush_s* b, *next; entity_s* e; if ( ( selected_brushes.next == &selected_brushes ) || ( selected_brushes.next->next != &selected_brushes ) ) { CString strName; if ( g_ptrSelectedFaces.GetSize() == 0 ) { strName = g_qeglobals.d_texturewin.texdef.name; } else { face_s* selFace = reinterpret_cast<face_s*>( g_ptrSelectedFaces.GetAt( 0 ) ); strName = selFace->texdef.name; } Select_Deselect(); for ( b = active_brushes.next ; b != &active_brushes ; b = next ) { next = b->next; if ( FilterBrush( b ) ) continue; if ( b->patchBrush ) { if ( strcmpi( strName, b->pPatch->d_texture->name ) == 0 ) { Brush_RemoveFromList( b ); Brush_AddToList( b, &selected_brushes ); } } else { for ( face_s* pFace = b->brush_faces; pFace; pFace = pFace->next ) { if ( strcmpi( strName, pFace->texdef.name ) == 0 ) { Brush_RemoveFromList( b ); Brush_AddToList( b, &selected_brushes ); } } } } Sys_UpdateWindows( W_ALL ); return; } b = selected_brushes.next; e = b->owner; if ( e != NULL ) { if ( e != world_entity ) { CString strName = e->eclass->name; CString strKey, strVal; bool bCriteria = GetSelectAllCriteria( strKey, strVal ); Sys_Printf( "Selecting all %s(s)\n", strName ); Select_Deselect(); for ( b = active_brushes.next ; b != &active_brushes ; b = next ) { next = b->next; if ( FilterBrush( b ) ) continue; e = b->owner; if ( e != NULL ) { if ( strcmpi( e->eclass->name, strName ) == 0 ) { bool doIt = true; if ( bCriteria ) { CString str = ValueForKey( e, strKey ); if ( str.CompareNoCase( strVal ) != 0 ) { doIt = false; } } if ( doIt ) { Brush_RemoveFromList( b ); Brush_AddToList( b, &selected_brushes ); } } } } } } Sys_UpdateWindows( W_ALL ); }
void Select_AutoCaulk() { /*Sys_Printf*/common->Printf("Caulking...\n"); FacesToCaulk.Clear(); int iSystemBrushesSkipped = 0; face_t *pSelectedFace; brush_t *next; for (brush_t *pSelectedBrush = selected_brushes.next ; pSelectedBrush != &selected_brushes ; pSelectedBrush = next) { next = pSelectedBrush->next; if (pSelectedBrush->owner->eclass->fixedsize) continue; // apparently this means it's a model, so skip it... // new check, we can't caulk a brush that has any "system/" faces... // bool bSystemFacePresent = false; for ( pSelectedFace = pSelectedBrush->brush_faces; pSelectedFace; pSelectedFace = pSelectedFace->next) { if (!strnicmp(pSelectedFace->d_texture->GetName(),"system/",7)) { bSystemFacePresent = true; break; } } if (bSystemFacePresent) { iSystemBrushesSkipped++; continue; // verboten to caulk this. } for (int iBrushListToScan = 0; iBrushListToScan<2; iBrushListToScan++) { brush_t *snext; for (brush_t *pScannedBrush = (iBrushListToScan?active_brushes.next:selected_brushes.next); pScannedBrush != (iBrushListToScan?&active_brushes:&selected_brushes) ; pScannedBrush = snext) { snext = pScannedBrush->next; if ( pScannedBrush == pSelectedBrush) continue; if (pScannedBrush->owner->eclass->fixedsize || pScannedBrush->pPatch || pScannedBrush->hiddenBrush) continue; if (FilterBrush(pScannedBrush)) continue; // idMaterial stuff no longer support this, not sure what else to do. // Searching for other occurences of QER_NOCARVE just shows people REMing the code and ignoring ths issue... // // if (pScannedBrush->brush_faces->d_texture->bFromShader && (pScannedBrush->brush_faces->d_texture->TestMaterialFlag(QER_NOCARVE))) // continue; // basic-reject first to see if brushes can even possibly touch (coplanar counts as touching) // int i; for (i=0 ; i<3 ; i++) { if (pSelectedBrush->mins[i] > pScannedBrush->maxs[i] || pSelectedBrush->maxs[i] < pScannedBrush->mins[i]) { break; } } if (i != 3) continue; // can't be touching // ok, now for the clever stuff, we need to detect only those faces that are both coplanar and smaller // or equal to the face they're coplanar with... // for (pSelectedFace = pSelectedBrush->brush_faces; pSelectedFace; pSelectedFace = pSelectedFace->next) { idWinding *pSelectedWinding = pSelectedFace->face_winding; if (!pSelectedWinding) continue; // freed face, probably won't happen here, but who knows with this program? // SquaredFace_t SelectedSquaredFace; // WindingToSquaredFace( &SelectedSquaredFace, pSelectedWinding); for (face_t *pScannedFace = pScannedBrush->brush_faces; pScannedFace; pScannedFace = pScannedFace->next) { // don't even try caulking against a system face, because these are often transparent and will leave holes // if (!strnicmp(pScannedFace->d_texture->GetName(),"system/",7)) continue; // and don't try caulking against something inherently transparent... // if (pScannedFace->d_texture->TestMaterialFlag(QER_TRANS)) continue; idWinding *pScannedWinding = pScannedFace->face_winding; if (!pScannedWinding) continue; // freed face, probably won't happen here, but who knows with this program? // SquaredFace_t ScannedSquaredFace; // WindingToSquaredFace( &ScannedSquaredFace, pScannedWinding); /* if (VectorCompare(ScannedSquaredFace.v3NormalisedRotationVector, SelectedSquaredFace.v3NormalisedRotationVector) && VectorCompare(ScannedSquaredFace.v3NormalisedElevationVector, SelectedSquaredFace.v3NormalisedElevationVector) ) */ { // brush faces are in parallel planes to each other, so check that their normals // are opposite, by adding them together and testing for zero... // (if normals are opposite, then faces can be against/touching each other?) // idVec3 v3ZeroTest; idVec3 v3Zero;v3Zero.Zero(); //static idVec3 v3Zero={0,0,0}; VectorAdd(pSelectedFace->plane.Normal(),pScannedFace->plane.Normal(),v3ZeroTest); if (v3ZeroTest == v3Zero) { // planes are facing each other... // // coplanar? (this is some maths of Gil's, which I don't even pretend to understand) // float fTotalDist = 0; for (int _i=0; _i<3; _i++) { fTotalDist += fabs( DotProduct(pSelectedFace->plane.Normal(),(*pSelectedWinding)[0]) - DotProduct(pSelectedFace->plane.Normal(),(*pScannedWinding)[i]) ); } //OutputDebugString(va("Dist = %g\n",fTotalDist)); if (fTotalDist > 0.01) continue; // every point in the selected face must be within (or equal to) the bounds of the // scanned face... // // work out the bounds first... // idVec3 v3ScannedBoundsMins, v3ScannedBoundsMaxs; ClearBounds (v3ScannedBoundsMins, v3ScannedBoundsMaxs); int iPoint; for (iPoint=0; iPoint<pScannedWinding->GetNumPoints(); iPoint++) { AddPointToBounds( (*pScannedWinding)[iPoint].ToVec3(), v3ScannedBoundsMins, v3ScannedBoundsMaxs); } // floor 'em... (or .001 differences mess things up... // FloorBounds(v3ScannedBoundsMins, v3ScannedBoundsMaxs); // now check points from selected face... // bool bWithin = true; for (iPoint=0; iPoint < pSelectedWinding->GetNumPoints(); iPoint++) { for (int iXYZ=0; iXYZ<3; iXYZ++) { float f = floor((*pSelectedWinding)[iPoint][iXYZ] + 0.5); if (! ( f >= v3ScannedBoundsMins[iXYZ] && f <= v3ScannedBoundsMaxs[iXYZ] ) ) { bWithin = false; } } } if (bWithin) { PairBrushFace_t PairBrushFace; PairBrushFace.pFace = pSelectedFace; PairBrushFace.pBrush= pSelectedBrush; FacesToCaulk.Append(PairBrushFace); } } } } } } } } // apply caulk... // int iFacesCaulked = 0; if (FacesToCaulk.Num()) { LPCSTR psCaulkName = "textures/common/caulk"; const idMaterial *pCaulk = Texture_ForName(psCaulkName); if (pCaulk) { // // and call some other junk that Radiant wants so so we can use it later... // texdef_t tex; memset (&tex, 0, sizeof(tex)); tex.scale[0] = 1; tex.scale[1] = 1; //tex.flags = pCaulk->flags; // field missing in Q4 //tex.value = pCaulk->value; // ditto //tex.contents = pCaulk->contents; // ditto tex.SetName( pCaulk->GetName() ); //Texture_SetTexture (&tex); for (int iListEntry = 0; iListEntry < FacesToCaulk.Num(); iListEntry++) { PairBrushFace_t &PairBrushFace = FacesToCaulk[iListEntry]; face_t *pFace = PairBrushFace.pFace; brush_t*pBrush= PairBrushFace.pBrush; pFace->d_texture = pCaulk; pFace->texdef = tex; Face_FitTexture(pFace, 1, 1); // this doesn't work here for some reason... duh. Brush_Build(pBrush); iFacesCaulked++; } } else { /*Sys_Printf*/common->Printf(" Unable to locate caulk texture at: \"%s\"!\n",psCaulkName); } } /*Sys_Printf*/common->Printf("( %d faces caulked )\n",iFacesCaulked); if (iSystemBrushesSkipped) { /*Sys_Printf*/common->Printf("( %d system-faced brushes skipped )\n",iSystemBrushesSkipped); } Sys_UpdateWindows (W_ALL); }
void CCamWnd::Cam_Draw() { brush_t *brush; face_t *face; float screenaspect; float yfov; double start, end; int i; /* FILE *f = fopen("g:/nardo/raduffy/editorhack.dat", "w"); if (f != NULL) { fwrite(&m_Camera.origin[0], sizeof(float), 1, f); fwrite(&m_Camera.origin[1], sizeof(float), 1, f); fwrite(&m_Camera.origin[2], sizeof(float), 1, f); fwrite(&m_Camera.angles[PITCH], sizeof(float), 1, f); fwrite(&m_Camera.angles[YAW], sizeof(float), 1, f); fclose(f); } */ if (!active_brushes.next) return; // not valid yet if (m_Camera.timing) start = Sys_DoubleTime (); // // clear // QE_CheckOpenGLForErrors(); qglViewport(0, 0, m_Camera.width, m_Camera.height); qglScissor(0, 0, m_Camera.width, m_Camera.height); qglClearColor (g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0); qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // // set up viewpoint // vec5_t lightPos; if (g_PrefsDlg.m_bGLLighting) { qglEnable(GL_LIGHTING); //qglEnable(GL_LIGHT0); lightPos[0] = lightPos[1] = lightPos[2] = 3.5; lightPos[3] = 1.0; qglLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightPos); //qglLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); //lightPos[0] = lightPos[1] = lightPos[2] = 3.5; //qglLightfv(GL_LIGHT0, GL_AMBIENT, lightPos); } else { qglDisable(GL_LIGHTING); } qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); screenaspect = (float)m_Camera.width / m_Camera.height; yfov = 2*atan((float)m_Camera.height / m_Camera.width)*180/Q_PI; qgluPerspective (yfov, screenaspect, 2, 8192); qglRotatef (-90, 1, 0, 0); // put Z going up qglRotatef (90, 0, 0, 1); // put Z going up qglRotatef (m_Camera.angles[0], 0, 1, 0); qglRotatef (-m_Camera.angles[1], 0, 0, 1); qglTranslatef (-m_Camera.origin[0], -m_Camera.origin[1], -m_Camera.origin[2]); Cam_BuildMatrix (); //if (m_Camera.draw_mode == cd_light) //{ // if (g_PrefsDlg.m_bGLLighting) // { // VectorCopy(m_Camera.origin, lightPos); // lightPos[3] = 1; // qglLightfv(GL_LIGHT0, GL_POSITION, lightPos); // } //} InitCull (); // // draw stuff // GLfloat lAmbient[] = {1.0, 1.0, 1.0, 1.0}; switch (m_Camera.draw_mode) { case cd_wire: qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); qglDisable(GL_TEXTURE_2D); qglDisable(GL_TEXTURE_1D); qglDisable(GL_BLEND); qglDisable(GL_DEPTH_TEST); qglColor3f(1.0, 1.0, 1.0); // qglEnable (GL_LINE_SMOOTH); break; case cd_solid: qglCullFace(GL_FRONT); qglEnable(GL_CULL_FACE); qglShadeModel (GL_FLAT); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglDisable(GL_TEXTURE_2D); qglDisable(GL_BLEND); qglEnable(GL_DEPTH_TEST); qglDepthFunc (GL_LEQUAL); break; case cd_texture: qglCullFace(GL_FRONT); qglEnable(GL_CULL_FACE); qglShadeModel (GL_FLAT); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglEnable(GL_TEXTURE_2D); qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); qglDisable(GL_BLEND); qglEnable(GL_DEPTH_TEST); qglDepthFunc (GL_LEQUAL); break; case cd_blend: qglCullFace(GL_FRONT); qglEnable(GL_CULL_FACE); qglShadeModel (GL_FLAT); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglEnable(GL_TEXTURE_2D); qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); qglDisable(GL_DEPTH_TEST); qglEnable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; } qglMatrixMode(GL_TEXTURE); m_nNumTransBrushes = 0; for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) { //DrawLightRadius(brush); if (CullBrush (brush)) continue; if (FilterBrush (brush)) continue; if ((brush->brush_faces->texdef.flags & (SURF_TRANS33 | SURF_TRANS66)) || (brush->brush_faces->d_texture->bFromShader && brush->brush_faces->d_texture->fTrans != 1.0)) { m_TransBrushes [ m_nNumTransBrushes++ ] = brush; } else { //-- if (brush->patchBrush) //-- m_TransBrushes [ m_nNumTransBrushes++ ] = brush; //-- else Brush_Draw(brush); } } if (g_PrefsDlg.m_bGLLighting) { qglDisable (GL_LIGHTING); } // //qglDepthMask ( 0 ); // Don't write to depth buffer qglEnable ( GL_BLEND ); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for ( i = 0; i < m_nNumTransBrushes; i++ ) Brush_Draw (m_TransBrushes[i]); //qglDepthMask ( 1 ); // Ok, write now qglMatrixMode(GL_PROJECTION); // // now draw selected brushes // if (g_PrefsDlg.m_bGLLighting) { qglEnable (GL_LIGHTING); } qglTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]); qglMatrixMode(GL_TEXTURE); brush_t* pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes; // draw normally for (brush = pList->next ; brush != pList ; brush=brush->next) { //DrawLightRadius(brush); //if (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) // continue; Brush_Draw(brush); } // blend on top qglMatrixMode(GL_PROJECTION); qglDisable (GL_LIGHTING); qglColor4f(1.0, 0.0, 0.0, 0.3); qglEnable (GL_BLEND); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDisable (GL_TEXTURE_2D); for (brush = pList->next ; brush != pList ; brush=brush->next) { if ( (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint) ) continue; for (face=brush->brush_faces ; face ; face=face->next) Face_Draw( face ); } int nCount = g_ptrSelectedFaces.GetSize(); if (nCount > 0) { for (int i = 0; i < nCount; i++) { face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i)); Face_Draw(selFace); } } // non-zbuffered outline qglDisable (GL_BLEND); qglDisable (GL_DEPTH_TEST); qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); qglColor3f (1, 1, 1); for (brush = pList->next ; brush != pList ; brush=brush->next) { if (g_qeglobals.dontDrawSelectedOutlines || (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint)) continue; for (face=brush->brush_faces ; face ; face=face->next) Face_Draw( face ); } // edge / vertex flags if (g_qeglobals.d_select_mode == sel_vertex) { qglPointSize (4); qglColor3f (0,1,0); qglBegin (GL_POINTS); for (i=0 ; i<g_qeglobals.d_numpoints ; i++) qglVertex3fv (g_qeglobals.d_points[i]); qglEnd (); qglPointSize (1); } else if (g_qeglobals.d_select_mode == sel_edge) { float *v1, *v2; qglPointSize (4); qglColor3f (0,0,1); qglBegin (GL_POINTS); for (i=0 ; i<g_qeglobals.d_numedges ; i++) { v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1]; v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2]; qglVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5); } qglEnd (); qglPointSize (1); } g_splineList->draw(static_cast<qboolean>(g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)); if (g_qeglobals.selectObject && (g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)) { g_qeglobals.selectObject->drawSelection(); } // // draw pointfile // qglEnable(GL_DEPTH_TEST); DrawPathLines (); if (g_qeglobals.d_pointfile_display_list) { Pointfile_Draw(); // glCallList (g_qeglobals.d_pointfile_display_list); } // bind back to the default texture so that we don't have problems // elsewhere using/modifying texture maps between contexts qglBindTexture( GL_TEXTURE_2D, 0 ); #if 0 // area selection hack if (g_qeglobals.d_select_mode == sel_area) { qglEnable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglColor4f(0.0, 0.0, 1.0, 0.25); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglRectfv(g_qeglobals.d_vAreaTL, g_qeglobals.d_vAreaBR); qglDisable (GL_BLEND); } #endif qglFinish(); QE_CheckOpenGLForErrors(); // Sys_EndWait(); if (m_Camera.timing) { end = Sys_DoubleTime (); Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start))); } }