void Terrain_FindReplaceTexture( terrainMesh_t *p, const char *pFind, const char *pReplace, bool bForce ) { int w; int h; terrainVert_t *vert; qtexture_t *texture; texture = Texture_ForName( pReplace ); vert = p->heightmap; for( h = 0; h < p->height; h++ ) { for( w = 0; w < p->width; w++, vert++ ) { if ( bForce || strcmpi( vert->tri.texture->name, pFind ) == 0 ) { vert->tri.texture = texture; vert->tri.texdef.SetName( texture->name ); } } } if ( bForce ) { p->numtextures = 0; Terrain_AddTexture( p, Texture_ForName( pReplace ) ); } else { Terrain_RemoveTexture( p, Texture_ForName( pFind ) ); Terrain_AddTexture( p, texture ); } }
void Texture_ShowInuse(void) { Texture_HideAll(); brush_t *b; for (b = active_brushes.next; b != NULL && b != &active_brushes; b = b->next) { if (b->pPatch) { Texture_ForName(b->pPatch->d_texture->GetName()); } else { for (face_t *f = b->brush_faces; f; f = f->next) { Texture_ForName(f->texdef.name); } } } for (b = selected_brushes.next; b != NULL && b != &selected_brushes; b = b->next) { if (b->pPatch) { Texture_ForName(b->pPatch->d_texture->GetName()); } else { for (face_t *f = b->brush_faces; f; f = f->next) { Texture_ForName(f->texdef.name); } } } Sys_UpdateWindows(W_TEXTURE); g_Inspectors->SetWindowText("Textures (in use)"); }
void FindReplaceTextures( const char* pFind, const char* pReplace, bool bSelected, bool bForce ) { brush_s* pList = ( bSelected ) ? &selected_brushes : &active_brushes; if ( !bSelected ) { Select_Deselect(); } for ( brush_s* pBrush = pList->next ; pBrush != pList; pBrush = pBrush->next ) { if ( pBrush->patchBrush ) { Patch_FindReplaceTexture( pBrush, pFind, pReplace, bForce ); } for ( face_s* pFace = pBrush->brush_faces; pFace; pFace = pFace->next ) { if ( bForce || strcmpi( pFace->texdef.name, pFind ) == 0 ) { pFace->d_texture = Texture_ForName( pReplace ); //strcpy(pFace->texdef.name, pReplace); pFace->texdef.SetName( pReplace ); } } Brush_Build( pBrush ); } Sys_UpdateWindows( W_CAMERA ); }
void CPlugInManager::CommitPatchHandleToMap(int index, patchMesh_t *pMesh, char *texName) { if (PatchesMode==EAllocatedPatches) { patchMesh_t *pPatch = reinterpret_cast<patchMesh_t *>( m_PluginPatches.GetAt(index) ); memcpy( pPatch, pMesh, sizeof( patchMesh_t ) ); // patch texturing, if none given use current texture if (texName) pPatch->d_texture = Texture_ForName(texName); if ( !pPatch->d_texture ) { pPatch->d_texture = Texture_ForName(g_qeglobals.d_texturewin.texdef.name); // checking .. just in case if (!pPatch->d_texture) { #ifdef _DEBUG Sys_Printf("WARNING: failed to set patch to current texture in CPlugInManager::CommitPatchHandleToMap\n"); #endif pPatch->d_texture = notexture; } } g_bScreenUpdates = false; // the bLinkToWorld flag in AddBrushForPatch takes care of Brush_AddToList Entity_linkBrush and Brush_Build brush_t *pb = AddBrushForPatch( pPatch, true ); Select_Brush( pb ); g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); } else { brush_t *pBrush = reinterpret_cast<brush_t *>( m_PatchesHandles.GetAt(index) ); patchMesh_t *pPatch = pBrush->pPatch; pPatch->width = pMesh->width; pPatch->height = pMesh->height; pPatch->contents = pMesh->contents; pPatch->flags = pMesh->flags; pPatch->value = pMesh->value; pPatch->type = pMesh->type; memcpy( pPatch->ctrl, pMesh->ctrl, sizeof(drawVert_t)*MAX_PATCH_HEIGHT*MAX_PATCH_WIDTH ); pPatch->bDirty = true; } }
qtexture_t* WINAPI QERApp_Texture_ForName (const char *name) { // if the texture is not loaded yet, this call will get it loaded // but: when we assign a GL bind number, we need to be in the g_qeglobals.d_hdcBase , g_qeglobals.d_hglrcBase GL context // the plugin may set the GL context to whatever he likes, but then load would fail // NOTE: is context switching time-consuming? then maybe the plugin could handle the context switch and only add a // sanity check in debug mode here // read current context HDC pluginHDC = qwglGetCurrentDC(); HGLRC pluginHGLRC = qwglGetCurrentContext(); qwglMakeCurrent( g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase ); qtexture_t* qtex = Texture_ForName( name ); return qtex; qwglMakeCurrent( pluginHDC, pluginHGLRC ); }
void Brush_BuildWindings( brush_t *b ) { winding_t *w; face_t *face; vec_t v; Brush_SnapPlanepts( b ); // clear the mins/maxs bounds b->mins[0] = b->mins[1] = b->mins[2] = 99999; b->maxs[0] = b->maxs[1] = b->maxs[2] = -99999; Brush_MakeFacePlanes (b); face = b->brush_faces; for ( ; face ; face=face->next) { int i, j; w = face->face_winding = MakeFaceWinding (b, face); face->d_texture = Texture_ForName( face->texdef.name ); if (!w) { continue; } for (i=0 ; i<w->numpoints ; i++) { // add to bounding box for (j=0 ; j<3 ; j++) { v = w->points[i][j]; if (v > b->maxs[j]) b->maxs[j] = v; if (v < b->mins[j]) b->mins[j] = v; } } // setup s and t vectors, and set color BeginTexturingFace( b, face, face->d_texture); for(i = 0; i < w->numpoints; i++) EmitTextureCoordinates(w->points[i],face->d_texture,face); } }
void SetTerrainTexdef( brush_t *brush, terrainFace_t *face, texdef_t *texdef ) { int oldFlags; int oldContents; oldFlags = face->texdef.flags; oldContents = face->texdef.contents; face->texdef = *texdef; face->texdef.flags = ( face->texdef.flags & ~SURF_KEEP ) | ( oldFlags & SURF_KEEP ); face->texdef.contents = ( face->texdef.contents & ~CONTENTS_KEEP ) | ( oldContents & CONTENTS_KEEP ); face->texture = Texture_ForName( texdef->name ); //Terrain_AddTexture( face->texture ); }
brush_t *BrushFromMapPatch(idMapPatch *mappatch, idVec3 origin) { patchMesh_t *pm = MakeNewPatch(mappatch->GetWidth(), mappatch->GetHeight()); pm->d_texture = Texture_ForName(mappatch->GetMaterial()); for (int i = 0; i < mappatch->GetWidth(); i++) { for (int j = 0; j < mappatch->GetHeight(); j++) { pm->ctrl(i, j).xyz = (*mappatch)[j * mappatch->GetWidth() + i].xyz + origin; pm->ctrl(i, j).st = (*mappatch)[j * mappatch->GetWidth() + i].st; } } pm->horzSubdivisions = mappatch->GetHorzSubdivisions(); pm->vertSubdivisions = mappatch->GetVertSubdivisions(); pm->explicitSubdivisions = mappatch->GetExplicitlySubdivided(); if (mappatch->epairs.GetNumKeyVals()) { pm->epairs = new idDict; *pm->epairs = mappatch->epairs; } brush_t *b = AddBrushForPatch(pm, false); return b; }
/* ======================================================================================================================= ======================================================================================================================= */ bool CDialogTextures::loadTree( HTREEITEM item, const idStr &name, CWaitDlg *dlg ) { if ( item == NULL ) { return true; } if ( m_treeTextures.ItemHasChildren( item ) ) { idStr childName; HTREEITEM nextItem; HTREEITEM childItem = m_treeTextures.GetChildItem(item); while ( childItem != NULL ) { nextItem = m_treeTextures.GetNextItem( childItem, TVGN_NEXT ); childName = name + "/" + (const char *)m_treeTextures.GetItemText( childItem ); if ( m_treeTextures.ItemHasChildren( childItem ) ) { if ( !loadTree( childItem, childName, dlg ) ) { return false; } } else { DWORD dw = m_treeTextures.GetItemData( childItem ); if ( dw == TEXTURES || dw == MATERIALS ) { if ( dw == TEXTURES ) { childName = "textures/" + childName; } dlg->SetText( childName.c_str() ); Texture_ForName( childName ); } } if ( dlg->CancelPressed() ) { return false; } childItem = nextItem; } } return true; }
void Terrain_SetTexture( terrainMesh_t *p, texdef_t *tex_def ) { int w; int h; qtexture_t *newtex; terrainVert_t *vert; p->bDirty = 1; newtex = Texture_ForName( tex_def->name ); p->numtextures = 0; Terrain_AddTexture( p, newtex ); vert = p->heightmap; for( h = 0; h < p->height; h++ ) { for( w = 0; w < p->width; w++, vert++ ) { vert->tri.texture = newtex; vert->tri.texdef.SetName( newtex->name ); } } UpdateTerrainInspector(); }
terrainFace_t *Terrain_ParseFace( terrainFace_t *f ) { // read the texturename GetToken( false ); f->texdef.SetName( token ); // Load the texture, and set the face to that texture's defaults f->texture = Texture_ForName( f->texdef.Name() ); // read the texturedef GetToken( false ); f->texdef.shift[ 0 ] = ( float )atoi( token ); GetToken( false ); f->texdef.shift[ 1 ] = ( float )atoi( token ); GetToken( false ); f->texdef.rotate = atof( token ); GetToken( false ); f->texdef.scale[ 0 ] = atof( token ); GetToken( false ); f->texdef.scale[ 1 ] = atof( token ); // the flags and value field aren't necessarily present //f->texture = Texture_ForName( f->texdef.Name() ); f->texdef.flags = f->texture->flags; f->texdef.value = f->texture->value; f->texdef.contents = f->texture->contents; if ( TokenAvailable () ) { GetToken (false); f->texdef.contents = atoi(token); GetToken (false); f->texdef.flags = atoi(token); GetToken (false); f->texdef.value = atoi(token); } return f; }
/* ============== Z_Draw ============== */ void Z_Draw (void) { brush_t *brush; float w, h; double start, end; qtexture_t *q; float top, bottom; vec3_t org_top, org_bottom, dir_up, dir_down; int xCam = z.width/3; if (!active_brushes.next) return; // not valid yet if (z.timing) start = Sys_DoubleTime (); // // clear // qglViewport(0, 0, z.width, z.height); qglClearColor ( 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); /* GL Bug */ /* When not using hw acceleration, gl will fault if we clear the depth buffer bit on the first pass. The hack fix is to set the GL_DEPTH_BUFFER_BIT only after Z_Draw() has been called once. Yeah, right. */ qglClear(glbitClear); glbitClear |= GL_DEPTH_BUFFER_BIT; qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); w = z.width/2 / z.scale; h = z.height/2 / z.scale; qglOrtho (-w, w, z.origin[2]-h, z.origin[2]+h, -8, 8); qglDisable(GL_TEXTURE_2D); qglDisable(GL_TEXTURE_1D); qglDisable(GL_DEPTH_TEST); qglDisable(GL_BLEND); // // now draw the grid // Z_DrawGrid (); // // draw stuff // qglDisable(GL_CULL_FACE); qglShadeModel (GL_FLAT); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglDisable(GL_TEXTURE_2D); qglDisable(GL_BLEND); qglDisable(GL_DEPTH_TEST); // draw filled interiors and edges dir_up[0] = 0 ; dir_up[1] = 0; dir_up[2] = 1; dir_down[0] = 0 ; dir_down[1] = 0; dir_down[2] = -1; VectorCopy (z.origin, org_top); org_top[2] = MAX_WORLD_COORD;//4096; // MAX_WORLD_COORD ? (John said this didn't work, Hmmmmmm) // !suspect! VectorCopy (z.origin, org_bottom); org_bottom[2] = MIN_WORLD_COORD;//-4096; // MIN_WORLD_COORD? " " !suspect! for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) { if (brush->mins[0] >= z.origin[0] || brush->maxs[0] <= z.origin[0] || brush->mins[1] >= z.origin[1] || brush->maxs[1] <= z.origin[1]) continue; if (!Brush_Ray (org_top, dir_down, brush, &top)) continue; top = org_top[2] - top; if (!Brush_Ray (org_bottom, dir_up, brush, &bottom)) continue; bottom = org_bottom[2] + bottom; q = Texture_ForName (brush->brush_faces->texdef.name); qglColor3f (q->color[0], q->color[1], q->color[2]); qglBegin (GL_QUADS); qglVertex2f (-xCam, bottom); qglVertex2f (xCam, bottom); qglVertex2f (xCam, top); qglVertex2f (-xCam, top); qglEnd (); qglColor3f (1,1,1); qglBegin (GL_LINE_LOOP); qglVertex2f (-xCam, bottom); qglVertex2f (xCam, bottom); qglVertex2f (xCam, top); qglVertex2f (-xCam, top); qglEnd (); } // // now draw selected brushes // for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) { if ( !(brush->mins[0] >= z.origin[0] || brush->maxs[0] <= z.origin[0] || brush->mins[1] >= z.origin[1] || brush->maxs[1] <= z.origin[1]) ) { if (Brush_Ray (org_top, dir_down, brush, &top)) { top = org_top[2] - top; if (Brush_Ray (org_bottom, dir_up, brush, &bottom)) { bottom = org_bottom[2] + bottom; q = Texture_ForName (brush->brush_faces->texdef.name); qglColor3f (q->color[0], q->color[1], q->color[2]); qglBegin (GL_QUADS); qglVertex2f (-xCam, bottom); qglVertex2f (xCam, bottom); qglVertex2f (xCam, top); qglVertex2f (-xCam, top); qglEnd (); } } } qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES]); qglBegin (GL_LINE_LOOP); qglVertex2f (-xCam, brush->mins[2]); qglVertex2f (xCam, brush->mins[2]); qglVertex2f (xCam, brush->maxs[2]); qglVertex2f (-xCam, brush->maxs[2]); qglEnd (); } ZDrawCameraIcon (); ZDrawZClip(); qglFinish(); QE_CheckOpenGLForErrors(); if (z.timing) { end = Sys_DoubleTime (); Sys_Printf ("z: %i ms\n", (int)(1000*(end-start))); } }
/* The brush is NOT linked to any list */ brush_t *Brush_Parse(void) { brush_t *b; face_t *f; int i,j; g_qeglobals.d_parsed_brushes++; b = (brush_t*)qmalloc(sizeof(brush_t)); do { if(!GetToken (TRUE)) break; if(!strcmp (token, "}") ) break; f = Face_Alloc(); // add the brush to the end of the chain, so // loading and saving a map doesn't reverse the order f->next = NULL; if (!b->brush_faces) b->brush_faces = f; else { face_t *scan; for (scan=b->brush_faces ; scan->next ; scan=scan->next) ; scan->next = f; } // read the three point plane definition for (i=0 ; i<3 ; i++) { if (i != 0) GetToken (TRUE); if (strcmp (token, "(") ) Error ("parsing brush"); for (j=0 ; j<3 ; j++) { GetToken (false); f->planepts[i][j] = atoi(token); } GetToken (false); if (strcmp (token, ")") ) Error ("parsing brush"); } // read the texturedef GetToken(false); strcpy(f->texdef.name,token); GetToken(false); f->texdef.shift[0] = atoi(token); GetToken(false); f->texdef.shift[1] = atoi(token); GetToken(false); f->texdef.rotate = atoi(token); GetToken(false); f->texdef.scale[0] = atof(token); GetToken(false); f->texdef.scale[1] = atof(token); // the flags and value field aren't necessarily present f->d_texture = Texture_ForName( f->texdef.name ); f->texdef.flags = f->d_texture->flags; f->texdef.value = f->d_texture->value; f->texdef.contents = f->d_texture->contents; if (TokenAvailable ()) { GetToken(false); f->texdef.contents = atoi(token); GetToken(false); f->texdef.flags = atoi(token); GetToken(false); f->texdef.value = atoi(token); } } while (1); return b; }
void Terrain_AddMovePoint( vec3_t v, bool bMulti, bool bFull, int buttons ) { brush_t *pb; terrainMesh_t *p; terrainVert_t *vert; int x; int y; int x1, y1; float dx, dy; float dist; float pd; if ( !g_bSameView && !bMulti && !bFull ) { g_bSameView = true; return; } g_qeglobals.d_numterrapoints = 0; for( pb = active_brushes .next; pb != &active_brushes; pb = pb->next ) { //for( pb = selected_brushes.next; pb != &selected_brushes; pb = pb->next ) { if ( pb->terrainBrush ) { p = pb->pTerrain; x = ( v[ 0 ] - p->origin[ 0 ] ) / p->scale_x; y = ( v[ 1 ] - p->origin[ 1 ] ) / p->scale_x; if ( ( x < 0 ) || ( x >= p->width ) || ( y < 0 ) || ( y >= p->height ) ) { continue; } vert = p->heightmap; for( y1 = 0; y1 < p->height; y1++ ) { for( x1 = 0; x1 < p->width; x1++, vert++ ) { if ( g_qeglobals.d_terrainBrush == TERRAIN_BRUSH_CIRCLE ) { dx = x1 - x; dy = y1 - y; dist = sqrt( dx * dx + dy * dy ); } else { dx = abs( x1 - x ); dy = abs( y1 - y ); if ( dx > dy ) { dist = dx; } else { dist = dy; } } pd = dist * 2.0f / g_qeglobals.d_terrainBrushSize; if ( fabs( pd ) <= 1.0f ) { Terrain_AddPoint( p, vert ); if ( ( buttons & MK_LBUTTON ) && ( g_qeglobals.d_select_mode == sel_terraintexture ) ) { vert->tri.texture = Texture_ForName( g_qeglobals.d_texturewin.texdef.name ); vert->tri.texdef.SetName( vert->tri.texture->name ); Terrain_AddTexture( p, vert->tri.texture ); continue; } if ( g_qeglobals.d_terrainFalloff == TERRAIN_FALLOFF_CURVED ) { if ( g_qeglobals.d_terrainBrush == TERRAIN_BRUSH_CIRCLE ) { vert->scale = ( 0.5f + cos( pd * M_PI ) * 0.5f ); } else { vert->scale = ( 0.5f + cos( dx/ g_qeglobals.d_terrainBrushSize * M_PI ) * 0.5f ) * ( 0.5f + cos( dy/ g_qeglobals.d_terrainBrushSize * M_PI ) * 0.5f ) - 0.25; } } else { vert->scale = 1.0f - pd; } switch( g_qeglobals.d_terrainNoiseType ) { case NOISE_PLUS : vert->scale *= crandom(); break; case NOISE_PLUSMINUS : vert->scale *= random(); break; } } } } } } }
// return is simply a count of how many texture replacements took place, only used for friendly-stats on completion... // // the arg list for this is getting pretty gay now, the reason being that the various update-windows routines that // radiant has don't work like windows ones, where paint messages are just issued then it returns instantly // (and eliminates dup paint calls), radiant actually goes off and performs them, so I need to stop it doing that // when calling this in the middle of a loop... // int FindReplaceTextures(const char* pFind, const char* pReplace, bool bSelected, bool bForce, bool bReScale, bool bSelectOnlyNoReplace, bool bInhibitCameraUpdate /*= false*/, bool bCalledDuringLoopAndNotFirstTime /*= false*/ // sigh, but saves an update-all-windows call ) { int iReplacedCount = 0; if (bSelectOnlyNoReplace) { bSelected = false; bForce = false; } const brush_t* const pList = (bSelected) ? &selected_brushes : &active_brushes; if (!bSelected) { if (!bCalledDuringLoopAndNotFirstTime) Select_Deselect(); } const qtexture_t * const pReplaceTex = Texture_ForName(pReplace); // count them first, so I can show progress.. // int iBrushCount = 0; for (brush_t* pBrush = pList->next ; pBrush != pList; pBrush = pBrush->next) { iBrushCount++; } Sys_Printf("\n"); brush_t* pNextBrush = pList->next->prev; // doesn't matter what value assigned here really. Note sneaky workaround here because can't point at non-const item, so use next->prev for (pBrush = pList->next ; pBrush != pList; pBrush = pNextBrush) { pNextBrush = pBrush->next; // just so they don't think it's locked up... // if ( !((iBrushCount--) & 15)) { Sys_Printf("."); } OutputDebugString(va("iBrushCount = %d\n",iBrushCount)); if (pBrush->patchBrush) { if (bSelectOnlyNoReplace) { if (!stricmp(pFind,Patch_FromBrush_GetTextureName(pBrush))) { g_bScreenUpdates = false; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! Select_Brush(pBrush, false); g_bScreenUpdates = true; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! continue; } } else { iReplacedCount += (Patch_FindReplaceTexture(pBrush, pFind, pReplace, bForce))?1:0; } } for (face_t* pFace = pBrush->brush_faces; pFace; pFace = pFace->next) { if(bForce || strcmpi(pFace->texdef.name, pFind) == 0) { iReplacedCount++; if (bSelectOnlyNoReplace) { g_bScreenUpdates = false; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! Select_Brush(pBrush, false); g_bScreenUpdates = true; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! break; } else { if (bReScale) { if (pFace->d_texture == pReplaceTex) {//not changing textures, so reset the scale instead const float fXAspect = fTEXTURE_SCALE / (float) pFace->texdef.scale[0]; const float fYAspect = fTEXTURE_SCALE / (float) pFace->texdef.scale[1]; pFace->texdef.scale[0] = fTEXTURE_SCALE; pFace->texdef.scale[1] = fTEXTURE_SCALE; pFace->texdef.shift[0] /= fXAspect; pFace->texdef.shift[1] /= fYAspect; } else { const float fXAspect = (float)(pFace->d_texture->width) / (float) pReplaceTex->width; const float fYAspect = (float)(pFace->d_texture->height) / (float) pReplaceTex->height; pFace->texdef.scale[0] *= fXAspect; pFace->texdef.scale[1] *= fYAspect; pFace->texdef.shift[0] /= fXAspect; pFace->texdef.shift[1] /= fYAspect; } } strcpy(pFace->texdef.name, pReplace); pFace->d_texture = (qtexture_t *)pReplaceTex; } } } if (!bSelectOnlyNoReplace) { Brush_Build(pBrush); } } Sys_Printf("\n"); if (!bInhibitCameraUpdate) { Sys_UpdateWindows (W_CAMERA); } return iReplacedCount; }
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 CDialogTextures::OnSelchangedTreeTextures(NMHDR *pNMHDR, LRESULT *pResult) { NM_TREEVIEW *pNMTreeView = (NM_TREEVIEW *) pNMHDR; *pResult = 0; editMaterial = NULL; editGui = ""; mediaName = ""; currentFile.Empty(); m_wndPreview.setDrawable(&m_testDrawable); HTREEITEM item = m_treeTextures.GetSelectedItem(); if (item) { DWORD dw = m_treeTextures.GetItemData(item); mode = dw; if ((dw == TEXTURES) || (dw == MATERIALS)) { idStr matName = m_treeTextures.GetItemText(item); // have to build the name back up HTREEITEM parent = m_treeTextures.GetParentItem(item); while (true) { idStr strParent = m_treeTextures.GetItemText(parent); if ( idStr::Icmp(strParent, TypeNames[dw]) == 0 ) { break; } strParent += "/"; strParent += matName; matName = strParent; parent = m_treeTextures.GetParentItem(parent); if (parent == NULL) { break; } } if ( dw == TEXTURES ) { matName = "textures/" + matName; } const idMaterial *mat = Texture_ForName(matName); editMaterial = mat; m_drawMaterial.setMedia(matName); m_wndPreview.setDrawable(&m_drawMaterial); m_wndPreview.RedrawWindow(); ignoreCollapse = true; Select_SetDefaultTexture(mat, false, setTexture); ignoreCollapse = false; } else if (dw == MODELS) { idStr strParent; idStr modelName = m_treeTextures.GetItemText(item); // have to build the name back up HTREEITEM parent = m_treeTextures.GetParentItem(item); while (true) { strParent = m_treeTextures.GetItemText(parent); if ( idStr::Icmp(strParent, TypeNames[MODELS]) == 0 ) { break; } strParent += "/"; strParent += modelName; modelName = strParent; parent = m_treeTextures.GetParentItem(parent); if (parent == NULL) { break; } } strParent = "models/"; strParent += modelName; m_drawModel.setMedia(strParent); mediaName = strParent; m_wndPreview.setDrawable(&m_drawModel); m_drawModel.SetRealTime(0); m_wndPreview.RedrawWindow(); } else if (dw == SCRIPTS) { } else if (dw == SOUNDS) { } else if (dw == PARTICLES) { idStr strParent; idStr modelName = m_treeTextures.GetItemText(item); // have to build the name back up HTREEITEM parent = m_treeTextures.GetParentItem(item); while (true) { strParent = m_treeTextures.GetItemText(parent); if ( idStr::Icmp(strParent, TypeNames[PARTICLES]) == 0 ) { break; } strParent += "/"; strParent += modelName; modelName = strParent; parent = m_treeTextures.GetParentItem(parent); if (parent == NULL) { break; } } strParent = modelName; mediaName = strParent; mediaName += ".prt"; m_drawModel.setMedia(mediaName); m_drawModel.SetRealTime(50); m_wndPreview.setDrawable(&m_drawModel); m_wndPreview.RedrawWindow(); } else if (dw == GUIS) { idStr strParent; idStr modelName = m_treeTextures.GetItemText(item); // have to build the name back up HTREEITEM parent = m_treeTextures.GetParentItem(item); while (true) { strParent = m_treeTextures.GetItemText(parent); if ( idStr::Icmp(strParent, TypeNames[GUIS]) == 0 ) { break; } strParent += "/"; strParent += modelName; modelName = strParent; parent = m_treeTextures.GetParentItem(parent); if (parent == NULL) { break; } } strParent = "guis/"; strParent += modelName; const idMaterial *mat = declManager->FindMaterial("guisurfs/guipreview"); mat->SetGui(strParent); editGui = strParent; m_drawMaterial.setMedia("guisurfs/guipreview"); m_drawMaterial.setScale(4.4f); m_wndPreview.setDrawable(&m_drawMaterial); m_wndPreview.RedrawWindow(); } } }
/* =========== Drag_Begin =========== */ void Drag_Begin (int x, int y, int buttons, vec3_t xaxis, vec3_t yaxis, vec3_t origin, vec3_t dir) { trace_t t; drag_ok = false; VectorCopy (vec3_origin, pressdelta); VectorCopy (vec3_origin, vPressStart); drag_first = true; peLink = NULL; // shift LBUTTON = select entire brush if (buttons == (MK_LBUTTON | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { int nFlag = (static_cast<bool>(::GetAsyncKeyState(VK_MENU))) ? SF_CYCLE : 0; if (dir[0] == 0 || dir[1] == 0 || dir[2] == 0) // extremely low chance of this happening from camera Select_Ray (origin, dir, nFlag | SF_ENTITIES_FIRST); // hack for XY else Select_Ray (origin, dir, nFlag); return; } // ctrl-shift LBUTTON = select single face if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { Select_Deselect (); Select_Ray (origin, dir, SF_SINGLEFACE); return; } // LBUTTON + all other modifiers = manipulate selection if (buttons & MK_LBUTTON) { Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir); return; } int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; // middle button = grab texture if (buttons == nMouseButton) { t = Test_Ray (origin, dir, false); if (t.face) { g_qeglobals.d_new_brush_bottom_z = t.brush->mins[2]; g_qeglobals.d_new_brush_top_z = t.brush->maxs[2]; Texture_SetTexture (&t.face->texdef); UpdateSurfaceDialog(); UpdatePatchInspector(); } else Sys_Printf ("Did not select a texture\n"); return; } // ctrl-middle button = set entire brush to texture if (buttons == (nMouseButton|MK_CONTROL) ) { t = Test_Ray (origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') Sys_Printf ("Can't change an entity texture\n"); else { Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef, false, false); Sys_UpdateWindows (W_ALL); } } else Sys_Printf ("Didn't hit a btrush\n"); return; } // ctrl-shift-middle button = set single face to texture if (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL) ) { t = Test_Ray (origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') Sys_Printf ("Can't change an entity texture\n"); else { SetFaceTexdef (t.brush, t.face, &g_qeglobals.d_texturewin.texdef, false, false); Brush_Build( t.brush ); Sys_UpdateWindows (W_ALL); } } else Sys_Printf ("Didn't hit a btrush\n"); return; } // shift-middle = (if light) // set face texture info (err...whatever), // else // set brush to texture but preserve any system faces // if (buttons == (nMouseButton | MK_SHIFT)) { Sys_Printf("Set brush face texture info\n"); t = Test_Ray (origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') { if (strcmpi(t.brush->owner->eclass->name, "light") == 0) { CString strBuff; qtexture_t* pTex = Texture_ForName(g_qeglobals.d_texturewin.texdef.name); if (pTex) { vec3_t vColor; VectorCopy(pTex->color, vColor); float fLargest = 0.0f; for (int i = 0; i < 3; i++) { if (vColor[i] > fLargest) fLargest = vColor[i]; } if (fLargest == 0.0f) { vColor[0] = vColor[1] = vColor[2] = 1.0f; } else { float fScale = 1.0f / fLargest; for (int i = 0; i < 3; i++) { vColor[i] *= fScale; } } strBuff.Format("%f %f %f",pTex->color[0], pTex->color[1], pTex->color[2]); SetKeyValue(t.brush->owner, "_color", strBuff.GetBuffer(0)); Sys_UpdateWindows (W_ALL); } } else { Sys_Printf ("Can't select an entity brush face\n"); } } else { Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef, false, true); Sys_UpdateWindows (W_ALL); } } else Sys_Printf ("Didn't hit a brush\n"); return; } }