/* ============ Select_SetTexture Timo : bFitScale to compute scale on the plane and counteract plane / axial plane snapping Timo : brush primitive texturing the brushprimit_texdef given must be understood as a qtexture_t width=2 height=2 ( HiRes ) Timo : texture plugin, added an IPluginTexdef* parameter must be casted to an IPluginTexdef! if not NULL, get ->Copy() of it into each face or brush ( and remember to hook ) if NULL, means we have no information, ask for a default ============ */ void WINAPI Select_SetTexture( texdef_t* texdef, brushprimit_texdef_s* brushprimit_texdef, bool bFitScale, void* pPlugTexdef ) { brush_s* b; int nCount = g_ptrSelectedFaces.GetSize(); if ( nCount > 0 ) { Undo_Start( "set face textures" ); ASSERT( g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize() ); for ( int i = 0; i < nCount; i++ ) { face_s* selFace = reinterpret_cast<face_s*>( g_ptrSelectedFaces.GetAt( i ) ); brush_s* selBrush = reinterpret_cast<brush_s*>( g_ptrSelectedFaceBrushes.GetAt( i ) ); Undo_AddBrush( selBrush ); SetFaceTexdef( selBrush, selFace, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef*>( pPlugTexdef ) ); Brush_Build( selBrush, bFitScale ); Undo_EndBrush( selBrush ); } Undo_End(); } else if ( selected_brushes.next != &selected_brushes ) { Undo_Start( "set brush textures" ); for ( b = selected_brushes.next ; b != &selected_brushes ; b = b->next ) if ( !b->owner->eclass->fixedsize ) { Undo_AddBrush( b ); Brush_SetTexture( b, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef*>( pPlugTexdef ) ); Undo_EndBrush( b ); } Undo_End(); } Sys_UpdateWindows( W_ALL ); }
void SI_SetTexdef_FaceList(texdef_to_face_t* texdef_face_list, bool b_SetUndoPoint, bool bFit_to_Scale) { texdef_to_face_t* texdef_to_face; bool b_isQuake2; if (g_pGameDescription->quake2) b_isQuake2 = true; else b_isQuake2 = false; if (!texdef_face_list) return; if (b_SetUndoPoint) { if(g_ptrSelectedFaces.GetSize() > 1) Sys_FPrintf(SYS_WRN, "WARNING: Undo NOT supported for multiple face selections\n"); else if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1)) { // Give something to undo to for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next) if (b_isQuake2) SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->orig_texdef, bFit_to_Scale); else SetFaceTexdef(texdef_to_face->face, &texdef_to_face->orig_texdef, &texdef_to_face->orig_bp_texdef, bFit_to_Scale); Undo_Start("set facelist texdefs"); if( selected_brushes.next != &selected_brushes ) Undo_AddBrushList(&selected_brushes); else Undo_AddBrush(texdef_face_list->brush); } } for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next) { if (b_isQuake2) SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->texdef, bFit_to_Scale); else { brushprimit_texdef_t brushprimit_texdef; FakeTexCoordsToTexMat(texdef_to_face->texdef.shift, texdef_to_face->texdef.rotate, texdef_to_face->texdef.scale, brushprimit_texdef.coords); SetFaceTexdef(texdef_to_face->face, &texdef_to_face->texdef, &brushprimit_texdef , bFit_to_Scale); } Brush_Build(texdef_to_face->brush); if(bFit_to_Scale) texdef_to_face->texdef = texdef_to_face->face->texdef; } if ( b_SetUndoPoint ) { if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1) ) { if(selected_brushes.next != &selected_brushes) Undo_EndBrushList(&selected_brushes); else Undo_EndBrush(texdef_face_list->brush); Undo_End(); // Over-write the orig_texdef list, cementing the change. for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next) { texdef_to_face->orig_texdef = texdef_to_face->texdef; texdef_to_face->orig_bp_texdef = texdef_to_face->face->brushprimit_texdef; } } } Sys_UpdateWindows (W_ALL); }
/* ============= CSG_Subtract ============= */ void CSG_Subtract (void) { brush_t *b, *s, *fragments, *nextfragment, *frag, *next, *snext; brush_t fragmentlist; int i, numfragments, numbrushes; Sys_Status ("Subtracting...\n"); if (selected_brushes.next == &selected_brushes) { Sys_Status("No brushes selected.\n"); return; } fragmentlist.next = &fragmentlist; fragmentlist.prev = &fragmentlist; numfragments = 0; numbrushes = 0; for (b = selected_brushes.next ; b != &selected_brushes ; b=next) { next = b->next; if (b->owner->eclass->fixedsize || b->modelHandle > 0) continue; // can't use texture from a fixed entity, so don't subtract // chop all fragments further up for (s = fragmentlist.next; s != &fragmentlist; s = snext) { snext = s->next; 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 fragments = Brush_Subtract(s, b); // if the brushes did not really intersect if (fragments == s) continue; // try to merge fragments fragments = Brush_MergeListPairs(fragments, true); // add the fragments to the list for (frag = fragments; frag; frag = nextfragment) { nextfragment = frag->next; frag->next = NULL; frag->owner = s->owner; Brush_AddToList(frag, &fragmentlist); } // free the original brush Brush_Free(s); } // chop any active brushes up for (s = active_brushes.next; s != &active_brushes; s = snext) { snext = s->next; if (s->owner->eclass->fixedsize || s->pPatch || s->hiddenBrush || s->modelHandle > 0) continue; //face_t *pFace = s->brush_faces; if ( s->brush_faces->d_texture && ( s->brush_faces->d_texture->GetContentFlags()& CONTENTS_NOCSG ) ) { 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 fragments = Brush_Subtract(s, b); // if the brushes did not really intersect if (fragments == s) continue; // Undo_AddBrush(s); // one extra brush chopped up numbrushes++; // try to merge fragments fragments = Brush_MergeListPairs(fragments, true); // add the fragments to the list for (frag = fragments; frag; frag = nextfragment) { nextfragment = frag->next; frag->next = NULL; frag->owner = s->owner; Brush_AddToList(frag, &fragmentlist); } // free the original brush Brush_Free(s); } } // move all fragments to the active brush list for (frag = fragmentlist.next; frag != &fragmentlist; frag = nextfragment) { nextfragment = frag->next; numfragments++; Brush_RemoveFromList(frag); Brush_AddToList(frag, &active_brushes); Undo_EndBrush(frag); } if (numfragments == 0) { common->Printf("Selected brush%s did not intersect with any other brushes.\n", (selected_brushes.next->next == &selected_brushes) ? "":"es"); return; } Sys_Status("done."); common->Printf(" (created %d fragment%s out of %d brush%s)\n", numfragments, (numfragments == 1)?"":"s", numbrushes, (numbrushes == 1)?"":"es"); Sys_UpdateWindows(W_ALL); }