diff --git a/include/qerplugin.h b/include/qerplugin.h index ce40f3ff..d9bdee3a 100644 --- a/include/qerplugin.h +++ b/include/qerplugin.h @@ -445,6 +445,7 @@ typedef void ( *PFN_QERAPP_POINTFILECLEAR )(); typedef void ( *PFN_QERAPP_SYSSETTITLE )( const char *text ); typedef void ( *PFN_QERAPP_CSGMAKEHOLLOW )(); +typedef void ( *PFN_QERAPP_CSGMAKEHOLLOWMODE )( int mode ); typedef void ( *PFN_QERAPP_REGIONSPAWNPOINT )( FILE *f ); @@ -490,13 +491,6 @@ typedef bfilter_t* ( *PFN_QERPLUG_FILTERADD )( int type, int bmask, const char * typedef void ( *PFN_QERPLUG_FILTERACTIVATE )( void ); -// FIXME: -// add map format extensions -// add texture format handlers -// add surface dialog handler -// add model handler/displayer - -// v1 func table // Plugins need to declare one of these and implement the getfunctable as described above struct _QERFuncTable_1 { @@ -530,7 +524,6 @@ struct _QERFuncTable_1 PFN_QERAPP_RELEASEACTIVEBRUSHHANDLES m_pfnReleaseActiveBrushHandles; PFN_QERAPP_GETACTIVEBRUSHHANDLE m_pfnGetActiveBrushHandle; - //++timo this would need to be removed and replaced by the IShaders interface PFN_QERAPP_TEXTURECOUNT m_pfnTextureCount; PFN_QERAPP_GETTEXTURE m_pfnGetTexture; PFN_QERAPP_GETCURRENTTEXTURE m_pfnGetCurrentTexture; @@ -616,11 +609,10 @@ struct _QERFuncTable_1 PFN_QERAPP_MAPSTARTPOSITION m_pfnMapStartPosition; PFN_QERAPP_MAPREGIONOFF m_pfnMapRegionOff; PFN_QERAPP_SETBUILDWINDINGSNOTEXBUILD m_pfnSetBuildWindingsNoTexBuild; -// PFN_QERAPP_SAVEASDIALOG m_pfnSaveAsDialog; PFN_QERAPP_POINTFILECLEAR m_pfnPointFileClear; - // FIXME TTimo prolly want to move that somewhere else PFN_QERAPP_CSGMAKEHOLLOW m_pfnCSG_MakeHollow; + PFN_QERAPP_CSGMAKEHOLLOWMODE m_pfnCSG_MakeHollowMode; PFN_QERAPP_REGIONSPAWNPOINT m_pfnRegionSpawnPoint; PFN_QERAPP_GETTICKCOUNT m_pfnQGetTickCount; @@ -642,6 +634,7 @@ struct _QERFuncTable_1 #define __QERTABLENAME g_FuncTable #endif #define CSG_MakeHollow __QERTABLENAME.m_pfnCSG_MakeHollow +#define CSG_MakeHollowMode __QERTABLENAME.m_pfnCSG_MakeHollowMode #define Sys_Beep __QERTABLENAME.m_pfnSysBeep #define Sys_Printf __QERTABLENAME.m_pfnSysPrintf #define Sys_FPrintf __QERTABLENAME.m_pfnSysFPrintf diff --git a/radiant/csg.cpp b/radiant/csg.cpp index 5f50e709..4977161a 100644 --- a/radiant/csg.cpp +++ b/radiant/csg.cpp @@ -39,7 +39,10 @@ void Brush_Scale( brush_t* b ){ } } -void CSG_MakeHollow( void ){ +void CSG_MakeHollow(){ + CSG_MakeHollowMode( CSG_HOLLOW_MODE_OVERLAP ); +} +void CSG_MakeHollowMode( int mode ){ brush_t *b, *front, *back, *next; face_t *f; face_t split; @@ -59,8 +62,11 @@ void CSG_MakeHollow( void ){ 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] ); - + if( mode == CSG_HOLLOW_MODE_TOUCH ) { + VectorAdd( f->planepts[i], move, f->planepts[i] ); + } else { + VectorSubtract( split.planepts[i], move, split.planepts[i] ); + } Brush_SplitBrushByFace( b, &split, &front, &back ); if ( back ) { Brush_Free( back ); @@ -68,6 +74,9 @@ void CSG_MakeHollow( void ){ if ( front ) { Brush_AddToList( front, &selected_brushes ); } + if( mode == CSG_HOLLOW_MODE_TOUCH ) { + *f = split; + } } Brush_Free( b ); } diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 9dcaced5..a2b4c758 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -509,6 +509,7 @@ gint HandleCommand( GtkWidget *widget, gpointer data ){ case ID_SELECTION_ARBITRARYROTATION: g_pParentWnd->OnSelectionArbitraryrotation(); break; case ID_SELECT_SCALE: g_pParentWnd->OnSelectScale(); break; case ID_SELECTION_MAKEHOLLOW: g_pParentWnd->OnSelectionMakehollow(); break; + case ID_SELECTION_MAKEHOLLOW_TOUCH: g_pParentWnd->OnSelectionMakehollowTouch(); break; case ID_SELECTION_CSGSUBTRACT: g_pParentWnd->OnSelectionCsgsubtract(); break; case ID_SELECTION_CSGMERGE: g_pParentWnd->OnSelectionCsgmerge(); break; case ID_SELECTION_NOOUTLINE: g_pParentWnd->OnSelectionNoOutline(); break; @@ -1209,8 +1210,10 @@ void MainFrame::create_main_menu( GtkWidget *window, GtkWidget *vbox ){ menu_separator( menu ); create_menu_item_with_mnemonic( menu, _( "Scale..." ), GTK_SIGNAL_FUNC( HandleCommand ), ID_SELECT_SCALE ); menu_in_menu = create_menu_in_menu_with_mnemonic( menu, _( "CSG" ) ); - create_menu_item_with_mnemonic( menu_in_menu, _( "Make _Hollow" ), + create_menu_item_with_mnemonic( menu_in_menu, _( "Make _Hollow Overlap" ), GTK_SIGNAL_FUNC( HandleCommand ), ID_SELECTION_MAKEHOLLOW ); + create_menu_item_with_mnemonic( menu_in_menu, _( "Make _Hollow Touch" ), + G_CALLBACK( HandleCommand ), ID_SELECTION_MAKEHOLLOW_TOUCH ); create_menu_item_with_mnemonic( menu_in_menu, _( "CSG _Subtract" ), GTK_SIGNAL_FUNC( HandleCommand ), ID_SELECTION_CSGSUBTRACT ); create_menu_item_with_mnemonic( menu_in_menu, _( "CSG _Merge" ), @@ -1768,10 +1771,14 @@ void MainFrame::create_main_toolbar( GtkWidget *window, GtkWidget *vbox ){ g_object_set_data( G_OBJECT( window ), "tb_selection_csgmerge", w ); } - w = gtk_toolbar_append_item( GTK_TOOLBAR( toolbar ), "", _( "Hollow" ), "", + w = gtk_toolbar_append_item( GTK_TOOLBAR( toolbar ), "", _( "Hollow Overlap" ), "", new_image_icon("selection_makehollow.png"), GTK_SIGNAL_FUNC( HandleCommand ), GINT_TO_POINTER( ID_SELECTION_MAKEHOLLOW ) ); g_object_set_data( G_OBJECT( window ), "tb_selection_makehollow", w ); + w = gtk_toolbar_append_item( GTK_TOOLBAR( toolbar ), "", _( "Hollow Touch" ), "", + new_image_icon("selection_makehollow.png"), + G_CALLBACK( HandleCommand ), GINT_TO_POINTER( ID_SELECTION_MAKEHOLLOW_TOUCH ) ); + g_object_set_data( G_OBJECT( window ), "tb_selection_makehollow_touch", w ); if ( g_PrefsDlg.m_bWideToolbar ) { w = gtk_toolbar_append_element( GTK_TOOLBAR( toolbar ), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL, @@ -5381,6 +5388,16 @@ void MainFrame::OnSelectionMakehollow(){ Undo_End(); } +void MainFrame::OnSelectionMakehollowTouch(){ + //if (ActiveXY()) + // ActiveXY()->UndoCopy(); + Undo_Start( "hollow" ); + Undo_AddBrushList( &selected_brushes ); + CSG_MakeHollowMode( CSG_HOLLOW_MODE_TOUCH ); + Undo_EndBrushList( &selected_brushes ); + Undo_End(); +} + void MainFrame::OnSelectionCsgsubtract(){ Undo_Start( "CSG subtract" ); CSG_Subtract(); diff --git a/radiant/mainframe.h b/radiant/mainframe.h index 5c3b65bd..a55f1fb5 100644 --- a/radiant/mainframe.h +++ b/radiant/mainframe.h @@ -263,6 +263,7 @@ struct SKeyInfo #define ID_REGION_SETXY 40044 #define ID_REGION_SETBRUSH 40045 #define ID_SELECTION_MAKEHOLLOW 40046 +#define ID_SELECTION_MAKEHOLLOW_TOUCH 40051 #define ID_SELECTION_SELECTPARTIALTALL 40047 #define ID_SELECTION_SELECTCOMPLETETALL 40048 #define ID_SELECTION_CSGSUBTRACT 40049 @@ -682,6 +683,7 @@ void OnSelectionDragvertecies(); void OnSelectionMakeDetail(); void OnSelectionMakeStructural(); void OnSelectionMakehollow(); +void OnSelectionMakehollowTouch(); void OnSelectionSelectcompletetall(); void OnSelectionSelectinside(); void OnSelectionSelectpartialtall(); diff --git a/radiant/pluginmanager.cpp b/radiant/pluginmanager.cpp index 3a9929c8..f25eb1f4 100644 --- a/radiant/pluginmanager.cpp +++ b/radiant/pluginmanager.cpp @@ -2063,6 +2063,7 @@ bool CSynapseClientRadiant::RequestAPI( APIDescriptor_t *pAPI ){ pTable->m_pfnSetBuildWindingsNoTexBuild = &Brush_SetBuildWindingsNoTexBuild; pTable->m_pfnPointFileClear = &Pointfile_Clear; pTable->m_pfnCSG_MakeHollow = &CSG_MakeHollow; + pTable->m_pfnCSG_MakeHollowMode = &CSG_MakeHollowMode; pTable->m_pfnRegionSpawnPoint = &Region_SpawnPoint; pTable->m_pfnQGetTickCount = &QERApp_GetTickCount; pTable->m_pfnGetModelCache = &GetModelCache; diff --git a/radiant/qe3.h b/radiant/qe3.h index 20f22278..5a9ec542 100644 --- a/radiant/qe3.h +++ b/radiant/qe3.h @@ -222,7 +222,10 @@ void Drag_MouseUp( int nButtons = 0 ); // // csg.c // +#define CSG_HOLLOW_MODE_OVERLAP (0) +#define CSG_HOLLOW_MODE_TOUCH (1) void CSG_MakeHollow( void ); +void CSG_MakeHollowMode( int mode ); void CSG_Subtract( void ); void CSG_Merge( void );