From c845c5cd8f427d39665d6a8b1f6eeff401370d80 Mon Sep 17 00:00:00 2001 From: Garux Date: Wed, 2 Aug 2017 09:09:58 +0300 Subject: [PATCH] Radiant: binds... * Tab: focus camera on selected menus... * Modify->Nudge:+ Nudge +Z, Nudge -Z misc... * improvement of: Scale tool: now scales bbox by gridsize increment * snap transform origin for rotate 90' commands, if one is not custom (is good to stay on grid) * 2d camera icon in ZY, ZX views represents yaw aswell * M3 camera direction control: disabled snapping * M3 camera direction control: affect yaw instead of doing pitch > 90' in ZY, ZX views * fix of: ctrl+m3 in 2d, release ctrl, then m3: m3 drag works like with ctrl pressed * removed 2 buttons mouse option: was only affecting m3 camera control binds * fix of: press any modifier (ctrl/shift/alt) + any mouse, release modifier, then mouse = chase mouse broken * removed 'Right Button Activates Context Menu' preference * brushExport plugin, prtview plugin, bobToolz::Polygon Builder, about, textures reset, messagebox windows live on top of main window * removed 'Update views on camera move' option: camera icon updating is enough quick * fix: bobToolz::split patch rows+columns - works if rows = 3 ( clos and rows were mixed up in general ) * entitySetColour, entityNormalizeColour are undoable * bobToolz::splitPatch commands place result into parent entity (worldspawn or group one) * bobToolz::mergePatches places result into last selected patch's parent entity * bobToolz::mergePatches: remove left empty group entities * SelectAllOfType works for group entities, whose brush(es) are selected (no parent node selection needed). Algorithm is: get [ent inspector's keyName field(if visible) or classname]'s keyValues of selected ents ('no key' counts, as property, too); Then select ents with according keyName+keyValues; Worldspawn is omitted; Otherwise (nothing or worldspawn selected) select primitives, holding selected texture; in 'Faces' component mode = select specifically faces, holding selected texture; * SelectAllOfType selects child primitives of group entities * ExpandSelectionToEntities works for worldspawn entity too --- contrib/bobtoolz/DPatch.cpp | 17 ++- contrib/bobtoolz/bobToolz-GTK.cpp | 2 + contrib/bobtoolz/bobToolz-GTK.h | 7 ++ contrib/bobtoolz/dialogs/dialogs-gtk.cpp | 16 ++- contrib/bobtoolz/funchandlers-GTK.cpp | 17 ++- contrib/brushexport/interface.cpp | 4 +- contrib/brushexport/plugin.cpp | 3 + contrib/brushexport/plugin.h | 3 + contrib/prtview/AboutDialog.cpp | 3 + contrib/prtview/ConfigDialog.cpp | 6 + contrib/prtview/LoadPortalFileDialog.cpp | 6 + contrib/prtview/prtview.cpp | 2 + contrib/prtview/prtview.h | 3 + include/iselection.h | 2 +- radiant/camwindow.cpp | 47 +++++++- radiant/entity.cpp | 17 +-- radiant/mainframe.cpp | 14 ++- radiant/mainframe.h | 6 +- radiant/preferences.cpp | 10 +- radiant/select.cpp | 146 ++++++++++++++++++++--- radiant/selection.cpp | 33 ++--- radiant/view.h | 3 + radiant/xywindow.cpp | 67 ++++++++--- radiant/xywindow.h | 10 +- 24 files changed, 347 insertions(+), 97 deletions(-) create mode 100644 contrib/bobtoolz/bobToolz-GTK.h diff --git a/contrib/bobtoolz/DPatch.cpp b/contrib/bobtoolz/DPatch.cpp index 2228b23b..06b0327b 100644 --- a/contrib/bobtoolz/DPatch.cpp +++ b/contrib/bobtoolz/DPatch.cpp @@ -486,18 +486,23 @@ std::list DPatch::Split(){ int i; int x, y; - if ( width >= 5 ) { + if ( height >= 5 ) { std::list patchColList = SplitCols(); for ( std::list::iterator patchesCol = patchColList.begin(); patchesCol != patchColList.end(); patchesCol++ ) { - std::list patchRowList = ( *patchesCol ).SplitRows(); - for ( std::list::iterator patchesRow = patchRowList.begin(); patchesRow != patchRowList.end(); patchesRow++ ) - { - patchList.push_front( *patchesRow ); + if( width >= 5 ){ + std::list patchRowList = ( *patchesCol ).SplitRows(); + for ( std::list::iterator patchesRow = patchRowList.begin(); patchesRow != patchRowList.end(); patchesRow++ ) + { + patchList.push_front( *patchesRow ); + } + } + else{ + patchList.push_front( *patchesCol ); } } } - else if ( height >= 5 ) { + else if ( width >= 5 ) { std::list patchRowList = SplitRows(); for ( std::list::iterator patchesRow = patchRowList.begin(); patchesRow != patchRowList.end(); patchesRow++ ) { diff --git a/contrib/bobtoolz/bobToolz-GTK.cpp b/contrib/bobtoolz/bobToolz-GTK.cpp index ea6d0b43..e11a6427 100644 --- a/contrib/bobtoolz/bobToolz-GTK.cpp +++ b/contrib/bobtoolz/bobToolz-GTK.cpp @@ -34,6 +34,8 @@ #include "dialogs/dialogs-gtk.h" #include "../../libs/cmdlib.h" +#include "bobToolz-GTK.h" + void BobToolz_construct(){ } diff --git a/contrib/bobtoolz/bobToolz-GTK.h b/contrib/bobtoolz/bobToolz-GTK.h new file mode 100644 index 00000000..d10acc48 --- /dev/null +++ b/contrib/bobtoolz/bobToolz-GTK.h @@ -0,0 +1,7 @@ + +#if !defined(INCLUDED_BOBTOOLZGTK_H) +#define INCLUDED_BOBTOOLZGTK_H + +extern GtkWidget *g_pRadiantWnd; + +#endif diff --git a/contrib/bobtoolz/dialogs/dialogs-gtk.cpp b/contrib/bobtoolz/dialogs/dialogs-gtk.cpp index b596f059..a4a08b7a 100644 --- a/contrib/bobtoolz/dialogs/dialogs-gtk.cpp +++ b/contrib/bobtoolz/dialogs/dialogs-gtk.cpp @@ -28,6 +28,8 @@ #include "../lists.h" #include "../misc.h" +#include "../bobToolz-GTK.h" + /*-------------------------------- Callback Functions @@ -214,6 +216,8 @@ EMessageBoxReturn DoMessageBox( const char* lpText, const char* lpCaption, EMess int loop = 1; window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pRadiantWnd ) ); + gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); gtk_signal_connect( GTK_OBJECT( window ), "delete_event", GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL ); gtk_signal_connect( GTK_OBJECT( window ), "destroy", @@ -307,7 +311,7 @@ EMessageBoxReturn DoMessageBox( const char* lpText, const char* lpCaption, EMess ret = eIDNO; } - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); + gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER_ON_PARENT ); gtk_widget_show( window ); gtk_grab_add( window ); @@ -426,6 +430,7 @@ EMessageBoxReturn DoPolygonBox( PolygonRS* rs ){ int loop = 1; window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pRadiantWnd ) ); gtk_signal_connect( GTK_OBJECT( window ), "delete_event", GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL ); gtk_signal_connect( GTK_OBJECT( window ), "destroy", GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL ); @@ -547,7 +552,8 @@ EMessageBoxReturn DoPolygonBox( PolygonRS* rs ){ // ---- /vbox ---- - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); + gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER_ON_PARENT ); + gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); gtk_widget_show( window ); gtk_grab_add( window ); @@ -1313,6 +1319,8 @@ EMessageBoxReturn DoResetTextureBox( ResetTextureRS* rs ){ int loop = 1; window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pRadiantWnd ) ); + gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); gtk_signal_connect( GTK_OBJECT( window ), "delete_event", GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL ); gtk_signal_connect( GTK_OBJECT( window ), "destroy", GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL ); @@ -1570,7 +1578,7 @@ EMessageBoxReturn DoResetTextureBox( ResetTextureRS* rs ){ // ---- /vbox ---- - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); + gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER_ON_PARENT ); gtk_widget_show( window ); gtk_grab_add( window ); @@ -2012,4 +2020,4 @@ EMessageBoxReturn DoMakeChainBox( MakeChainRS* rs ){ gtk_widget_destroy( window ); return ret; -} \ No newline at end of file +} diff --git a/contrib/bobtoolz/funchandlers-GTK.cpp b/contrib/bobtoolz/funchandlers-GTK.cpp index aa8e6478..d6625365 100644 --- a/contrib/bobtoolz/funchandlers-GTK.cpp +++ b/contrib/bobtoolz/funchandlers-GTK.cpp @@ -462,7 +462,7 @@ void DoMergePatches(){ merge_info = mrgPatches[0].IsMergable( &mrgPatches[1] ); if ( merge_info.mergable ) { - globalOutputStream() << merge_info.pos1 << " " << merge_info.pos2; +// globalOutputStream() << merge_info.pos1 << " " << merge_info.pos2; //Message removed, No tools give feedback on success. //globalOutputStream() << "bobToolz MergePatches: Patches Mergable.\n"; DPatch* newPatch = mrgPatches[0].MergePatches( merge_info, &mrgPatches[0], &mrgPatches[1] ); @@ -480,10 +480,17 @@ void DoMergePatches(){ } else { + newPatch->BuildInRadiant( patches[0]->path().parent().get_pointer() ); + + scene::Instance& parent = *( patches[1]->parent() ); Path_deleteTop( patches[0]->path() ); Path_deleteTop( patches[1]->path() ); + Entity* entity = Node_getEntity( parent.path().top() ); + if ( entity != 0 + && Node_getTraversable( parent.path().top() )->empty() ) { + Path_deleteTop( parent.path() ); + } - newPatch->BuildInRadiant(); delete newPatch; } } @@ -518,7 +525,7 @@ void DoSplitPatch() { std::list patchList = patch.Split(); for ( std::list::iterator patches = patchList.begin(); patches != patchList.end(); patches++ ) { - ( *patches ).BuildInRadiant(); + ( *patches ).BuildInRadiant( instance.path().parent().get_pointer() ); } Path_deleteTop( instance.path() ); @@ -548,7 +555,7 @@ void DoSplitPatchCols() { std::list patchList = patch.SplitCols(); for ( std::list::iterator patches = patchList.begin(); patches != patchList.end(); patches++ ) { - ( *patches ).BuildInRadiant(); + ( *patches ).BuildInRadiant( instance.path().parent().get_pointer() ); } Path_deleteTop( instance.path() ); @@ -578,7 +585,7 @@ void DoSplitPatchRows() { std::list patchList = patch.SplitRows(); for ( std::list::iterator patches = patchList.begin(); patches != patchList.end(); patches++ ) { - ( *patches ).BuildInRadiant(); + ( *patches ).BuildInRadiant( instance.path().parent().get_pointer() ); } Path_deleteTop( instance.path() ); diff --git a/contrib/brushexport/interface.cpp b/contrib/brushexport/interface.cpp index 76279ab0..0342e246 100644 --- a/contrib/brushexport/interface.cpp +++ b/contrib/brushexport/interface.cpp @@ -4,6 +4,7 @@ #include "debugging/debugging.h" #include "callbacks.h" #include "support.h" +#include "plugin.h" #define GLADE_HOOKUP_OBJECT( component,widget,name ) \ g_object_set_data_full( G_OBJECT( component ), name, \ @@ -44,7 +45,8 @@ create_w_plugplug2( void ){ w_plugplug2 = gtk_window_new( GTK_WINDOW_TOPLEVEL ); gtk_widget_set_name( w_plugplug2, "w_plugplug2" ); gtk_window_set_title( GTK_WINDOW( w_plugplug2 ), "BrushExport-Plugin 3.0 by namespace" ); - gtk_window_set_position( GTK_WINDOW( w_plugplug2 ), GTK_WIN_POS_CENTER ); + gtk_window_set_position( GTK_WINDOW( w_plugplug2 ), GTK_WIN_POS_CENTER_ON_PARENT ); + gtk_window_set_transient_for( GTK_WINDOW( w_plugplug2 ), GTK_WINDOW( g_pRadiantWnd ) ); gtk_window_set_destroy_with_parent( GTK_WINDOW( w_plugplug2 ), TRUE ); vbox1 = gtk_vbox_new( FALSE, 0 ); diff --git a/contrib/brushexport/plugin.cpp b/contrib/brushexport/plugin.cpp index 274c840e..58187871 100644 --- a/contrib/brushexport/plugin.cpp +++ b/contrib/brushexport/plugin.cpp @@ -48,12 +48,15 @@ void CreateWindow( void ); void DestroyWindow( void ); bool IsWindowOpen( void ); +GtkWidget *g_pRadiantWnd = NULL; + namespace BrushExport { GtkWindow* g_mainwnd; const char* init( void* hApp, void* pMainWidget ){ g_mainwnd = (GtkWindow*)pMainWidget; + g_pRadiantWnd = (GtkWidget*)pMainWidget; ASSERT_NOTNULL( g_mainwnd ); return ""; } diff --git a/contrib/brushexport/plugin.h b/contrib/brushexport/plugin.h index d924f647..a5e3f4c5 100644 --- a/contrib/brushexport/plugin.h +++ b/contrib/brushexport/plugin.h @@ -22,4 +22,7 @@ #if !defined( INCLUDED_BRUSH_EXPORT_H ) #define INCLUDED_BRUSH_EXPORT_H +typedef struct _GtkWidget GtkWidget; +extern GtkWidget *g_pRadiantWnd; + #endif diff --git a/contrib/prtview/AboutDialog.cpp b/contrib/prtview/AboutDialog.cpp index 1baec68d..5713b162 100644 --- a/contrib/prtview/AboutDialog.cpp +++ b/contrib/prtview/AboutDialog.cpp @@ -53,6 +53,9 @@ void DoAboutDlg(){ int loop = 1, ret = IDCANCEL; dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pRadiantWnd ) ); + gtk_window_set_position( GTK_WINDOW( dlg ),GTK_WIN_POS_CENTER_ON_PARENT ); + gtk_window_set_modal( GTK_WINDOW( dlg ), TRUE ); gtk_window_set_title( GTK_WINDOW( dlg ), "About Portal Viewer" ); gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event", GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL ); diff --git a/contrib/prtview/ConfigDialog.cpp b/contrib/prtview/ConfigDialog.cpp index a91a6a2b..63080a2b 100644 --- a/contrib/prtview/ConfigDialog.cpp +++ b/contrib/prtview/ConfigDialog.cpp @@ -62,6 +62,9 @@ static int DoColor( PackedColour *c ){ clr[2] = ( (double)GetBValue( *c ) ) / 255.0; dlg = gtk_color_selection_dialog_new( "Choose Color" ); + gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pRadiantWnd ) ); + gtk_window_set_position( GTK_WINDOW( dlg ),GTK_WIN_POS_CENTER_ON_PARENT ); + gtk_window_set_modal( GTK_WINDOW( dlg ), TRUE ); gtk_color_selection_set_color( GTK_COLOR_SELECTION( GTK_COLOR_SELECTION_DIALOG( dlg )->colorsel ), clr ); gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event", GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL ); @@ -247,6 +250,9 @@ void DoConfigDialog(){ GtkObject *adj; dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pRadiantWnd ) ); + gtk_window_set_position( GTK_WINDOW( dlg ),GTK_WIN_POS_CENTER_ON_PARENT ); + gtk_window_set_modal( GTK_WINDOW( dlg ), TRUE ); gtk_window_set_title( GTK_WINDOW( dlg ), "Portal Viewer Configuration" ); gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event", GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL ); diff --git a/contrib/prtview/LoadPortalFileDialog.cpp b/contrib/prtview/LoadPortalFileDialog.cpp index f3d4df8d..f2725838 100644 --- a/contrib/prtview/LoadPortalFileDialog.cpp +++ b/contrib/prtview/LoadPortalFileDialog.cpp @@ -76,6 +76,9 @@ static void change_clicked( GtkWidget *widget, gpointer data ){ int loop = 1; file_sel = gtk_file_selection_new( "Locate portal (.prt) file" ); + gtk_window_set_transient_for( GTK_WINDOW( file_sel ), GTK_WINDOW( g_pRadiantWnd ) ); + gtk_window_set_position( GTK_WINDOW( file_sel ),GTK_WIN_POS_CENTER_ON_PARENT ); + gtk_window_set_modal( GTK_WINDOW( file_sel ), TRUE ); gtk_signal_connect( GTK_OBJECT( GTK_FILE_SELECTION( file_sel )->ok_button ), "clicked", GTK_SIGNAL_FUNC( file_sel_callback ), GINT_TO_POINTER( IDOK ) ); gtk_signal_connect( GTK_OBJECT( GTK_FILE_SELECTION( file_sel )->cancel_button ), "clicked", @@ -109,6 +112,9 @@ int DoLoadPortalFileDialog(){ int loop = 1, ret = IDCANCEL; dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pRadiantWnd ) ); + gtk_window_set_position( GTK_WINDOW( dlg ),GTK_WIN_POS_CENTER_ON_PARENT ); + gtk_window_set_modal( GTK_WINDOW( dlg ), TRUE ); gtk_window_set_title( GTK_WINDOW( dlg ), "Load .prt" ); gtk_signal_connect( GTK_OBJECT( dlg ), "delete_event", GTK_SIGNAL_FUNC( dialog_delete_callback ), NULL ); diff --git a/contrib/prtview/prtview.cpp b/contrib/prtview/prtview.cpp index 301ac9ea..2b3d9c04 100644 --- a/contrib/prtview/prtview.cpp +++ b/contrib/prtview/prtview.cpp @@ -201,8 +201,10 @@ static const char *PLUGIN_COMMANDS = Q3R_CMD_LOAD; +GtkWidget *g_pRadiantWnd = NULL; const char* QERPlug_Init( void *hApp, void* pMainWidget ){ + g_pRadiantWnd = (GtkWidget*)pMainWidget; return "Portal Viewer for Q3Radiant"; } diff --git a/contrib/prtview/prtview.h b/contrib/prtview/prtview.h index e149ae80..5b3734f5 100644 --- a/contrib/prtview/prtview.h +++ b/contrib/prtview/prtview.h @@ -28,6 +28,9 @@ void SaveConfig(); int INIGetInt( char *key, int def ); void INISetInt( char *key, int val, char *comment = 0 ); +typedef struct _GtkWidget GtkWidget; +extern GtkWidget *g_pRadiantWnd; + #define IDOK 1 #define IDCANCEL 2 diff --git a/include/iselection.h b/include/iselection.h index 36b27deb..a62a2843 100644 --- a/include/iselection.h +++ b/include/iselection.h @@ -120,7 +120,7 @@ virtual void addSelectionChangeCallback( const SelectionChangeHandler& handler ) virtual void NudgeManipulator( const Vector3& nudge, const Vector3& view ) = 0; virtual void translateSelected( const Vector3& translation ) = 0; -virtual void rotateSelected( const Quaternion& rotation ) = 0; +virtual void rotateSelected( const Quaternion& rotation, bool snapOrigin ) = 0; virtual void scaleSelected( const Vector3& scaling ) = 0; virtual void pivotChanged() const = 0; diff --git a/radiant/camwindow.cpp b/radiant/camwindow.cpp index 1b36589b..45f59016 100644 --- a/radiant/camwindow.cpp +++ b/radiant/camwindow.cpp @@ -712,7 +712,7 @@ static void releaseStates(){ camera_t& getCamera(){ return m_Camera; -}; +} void BenchMark(); void Cam_ChangeFloor( bool up ); @@ -1648,6 +1648,50 @@ void GlobalCamera_ResetAngles(){ Camera_setAngles( camwnd, angles ); } +#include "select.h" + +void GlobalCamera_FocusOnSelected(){ + CamWnd& camwnd = *g_camwnd; + + Vector3 angles( Camera_getAngles( camwnd ) ); + Vector3 radangles( degrees_to_radians( angles[0] ), degrees_to_radians( angles[1] ), degrees_to_radians( angles[2] ) ); + Vector3 viewvector; + viewvector[0] = cos( radangles[1] ) * cos( radangles[0] ); + viewvector[1] = sin( radangles[1] ) * cos( radangles[0] ); + viewvector[2] = sin( radangles[0] ); + + Vector3 camorigin( Camera_getOrigin( camwnd ) ); + + AABB aabb( aabb_for_minmax( Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max ) ); + + View& view = *( camwnd.getCamera().m_view ); + + Plane3 frustumPlanes[4]; + frustumPlanes[0] = plane3_translated( view.getFrustum().left, camorigin - aabb.origin ); + frustumPlanes[1] = plane3_translated( view.getFrustum().right, camorigin - aabb.origin ); + frustumPlanes[2] = plane3_translated( view.getFrustum().top, camorigin - aabb.origin ); + frustumPlanes[3] = plane3_translated( view.getFrustum().bottom, camorigin - aabb.origin ); + + float offset = 64.0f; + + Vector3 corners[8]; + aabb_corners( aabb, corners ); + + for ( size_t i = 0; i < 4; ++i ){ + for ( size_t j = 0; j < 8; ++j ){ + Ray ray( aabb.origin, -viewvector ); + //Plane3 newplane( frustumPlanes[i].normal(), vector3_dot( frustumPlanes[i].normal(), corners[j] - frustumPlanes[i].normal() * 16.0f ) ); + Plane3 newplane( frustumPlanes[i].normal(), vector3_dot( frustumPlanes[i].normal(), corners[j] ) ); + float d = vector3_dot( ray.direction, newplane.normal() ); + if( d != 0 ){ + float s = vector3_dot( newplane.normal() * newplane.dist() - ray.origin, newplane.normal() ) / d; + offset = std::max( offset, s ); + } + } + } + Camera_setOrigin( camwnd, aabb.origin - viewvector * offset ); +} + void Camera_ChangeFloorUp(){ CamWnd& camwnd = *g_camwnd; camwnd.Cam_ChangeFloor( true ); @@ -1911,6 +1955,7 @@ void CameraSpeed_decrease(){ /// \brief Initialisation for things that have the same lifespan as this module. void CamWnd_Construct(){ GlobalCommands_insert( "CenterView", FreeCaller(), Accelerator( GDK_End ) ); + GlobalCommands_insert( "CameraFocusOnSelected", FreeCaller(), Accelerator( GDK_Tab ) ); GlobalToggles_insert( "ToggleCubicClip", FreeCaller(), ToggleItem::AddCallbackCaller( g_getfarclip_item ), Accelerator( '\\', (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "CubicClipZoomIn", FreeCaller(), Accelerator( '[', (GdkModifierType)GDK_CONTROL_MASK ) ); diff --git a/radiant/entity.cpp b/radiant/entity.cpp index 6926b76d..ff82b7ab 100644 --- a/radiant/entity.cpp +++ b/radiant/entity.cpp @@ -490,6 +490,9 @@ void Entity_normalizeColor(){ g_entity_globals.color_entity[1], g_entity_globals.color_entity[2] ); + StringOutputStream command( 256 ); + command << "entityNormalizeColour " << buffer; + UndoableCommand undo( command.c_str() ); Scene_EntitySetKeyValue_Selected( "_color", buffer ); } } @@ -499,10 +502,8 @@ void Entity_normalizeColor(){ void Entity_setColour(){ if ( GlobalSelectionSystem().countSelected() != 0 ) { - bool normalize = false; const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path(); Entity* entity = Node_getEntity( path.top() ); - if ( entity != 0 ) { const char* strColor = entity->getKeyValue( "_color" ); if ( !string_empty( strColor ) ) { @@ -511,21 +512,15 @@ void Entity_setColour(){ g_entity_globals.color_entity = rgb; } } - - if ( g_pGameDescription->mGameType == "doom3" ) { - normalize = false; - } - if ( color_dialog( GTK_WIDGET( MainFrame_getWindow() ), g_entity_globals.color_entity ) ) { - if ( normalize ) { - NormalizeColor( g_entity_globals.color_entity ); - } - char buffer[128]; sprintf( buffer, "%g %g %g", g_entity_globals.color_entity[0], g_entity_globals.color_entity[1], g_entity_globals.color_entity[2] ); + StringOutputStream command( 256 ); + command << "entitySetColour " << buffer; + UndoableCommand undo( command.c_str() ); Scene_EntitySetKeyValue_Selected( "_color", buffer ); } } diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 5442a8e5..8d07afe6 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -144,7 +144,7 @@ struct layout_globals_t }; layout_globals_t g_layout_globals; -glwindow_globals_t g_glwindow_globals; +//glwindow_globals_t g_glwindow_globals; // VFS @@ -1936,6 +1936,7 @@ GtkMenuItem* create_view_menu( MainFrame::EViewStyle style ){ if ( g_Layout_enableDetachableMenus.m_value ) { menu_tearoff( camera_menu ); } + create_menu_item_with_mnemonic( camera_menu, "Focus on Selected", "CameraFocusOnSelected" ); create_menu_item_with_mnemonic( camera_menu, "_Center", "CenterView" ); create_menu_item_with_mnemonic( camera_menu, "_Up Floor", "UpFloor" ); create_menu_item_with_mnemonic( camera_menu, "_Down Floor", "DownFloor" ); @@ -2059,6 +2060,9 @@ GtkMenuItem* create_selection_menu(){ create_menu_item_with_mnemonic( menu_in_menu, "Nudge Right", "SelectNudgeRight" ); create_menu_item_with_mnemonic( menu_in_menu, "Nudge Up", "SelectNudgeUp" ); create_menu_item_with_mnemonic( menu_in_menu, "Nudge Down", "SelectNudgeDown" ); + menu_separator( menu_in_menu ); + create_menu_item_with_mnemonic( menu_in_menu, "Nudge +Z", "MoveSelectionUP" ); + create_menu_item_with_mnemonic( menu_in_menu, "Nudge -Z", "MoveSelectionDOWN" ); } { GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "Rotate" ); @@ -2202,7 +2206,7 @@ GtkMenuItem* create_help_menu(){ create_game_help_menu( menu ); // create_menu_item_with_mnemonic( menu, "Bug report", FreeCaller() ); - create_menu_item_with_mnemonic( menu, "Shortcuts list", FreeCaller() ); + create_menu_item_with_mnemonic( menu, "Shortcuts", FreeCaller() ); create_menu_item_with_mnemonic( menu, "_About", FreeCaller() ); return help_menu_item; @@ -2266,8 +2270,8 @@ void TexdefNudge_registerShortcuts(){ } void SelectNudge_registerShortcuts(){ - command_connect_accelerator( "MoveSelectionDOWN" ); - command_connect_accelerator( "MoveSelectionUP" ); + //command_connect_accelerator( "MoveSelectionDOWN" ); + //command_connect_accelerator( "MoveSelectionUP" ); //command_connect_accelerator("SelectNudgeLeft"); //command_connect_accelerator("SelectNudgeRight"); //command_connect_accelerator("SelectNudgeUp"); @@ -3554,7 +3558,7 @@ void MainFrame_Destroy(){ void GLWindow_Construct(){ - GlobalPreferenceSystem().registerPreference( "MouseButtons", IntImportStringCaller( g_glwindow_globals.m_nMouseType ), IntExportStringCaller( g_glwindow_globals.m_nMouseType ) ); +// GlobalPreferenceSystem().registerPreference( "MouseButtons", IntImportStringCaller( g_glwindow_globals.m_nMouseType ), IntExportStringCaller( g_glwindow_globals.m_nMouseType ) ); } void GLWindow_Destroy(){ diff --git a/radiant/mainframe.h b/radiant/mainframe.h index 34d925b3..1d9cfad7 100644 --- a/radiant/mainframe.h +++ b/radiant/mainframe.h @@ -146,7 +146,7 @@ bool FloatingGroupDialog(){ extern MainFrame* g_pParentWnd; GtkWindow* MainFrame_getWindow(); - +/* enum EMouseButtonMode { ETwoButton = 0, @@ -161,11 +161,11 @@ struct glwindow_globals_t m_nMouseType( EThreeButton ){ } }; - +*/ void GLWindow_Construct(); void GLWindow_Destroy(); -extern glwindow_globals_t g_glwindow_globals; +//extern glwindow_globals_t g_glwindow_globals; template class LatchedValue; typedef LatchedValue LatchedBool; diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 9f0c09dd..b3d176ba 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -82,11 +82,11 @@ void Interface_constructPreferences( PreferencesPage& page ){ } void Mouse_constructPreferences( PreferencesPage& page ){ - { - const char* buttons[] = { "2 button", "3 button", }; - page.appendRadio( "Mouse Type", g_glwindow_globals.m_nMouseType, STRING_ARRAY_RANGE( buttons ) ); - } - page.appendCheckBox( "Right Button", "Activates Context Menu", g_xywindow_globals.m_bRightClick ); +// { +// const char* buttons[] = { "2 button", "3 button", }; +// page.appendRadio( "Mouse Type", g_glwindow_globals.m_nMouseType, STRING_ARRAY_RANGE( buttons ) ); +// } +// page.appendCheckBox( "Right Button", "Activates Context Menu", g_xywindow_globals.m_bRightClick ); page.appendCheckBox( "", "Improved mousewheel zoom", g_xywindow_globals.m_bImprovedWheelZoom ); } void Mouse_constructPage( PreferenceGroup& group ){ diff --git a/radiant/select.cpp b/radiant/select.cpp index beac6a18..83435db0 100644 --- a/radiant/select.cpp +++ b/radiant/select.cpp @@ -319,6 +319,57 @@ void Select_Invert(){ Scene_Invert_Selection( GlobalSceneGraph() ); } +//interesting printings +class ExpandSelectionToEntitiesWalker_dbg : public scene::Graph::Walker +{ +mutable std::size_t m_depth; +NodeSmartReference worldspawn; +public: +ExpandSelectionToEntitiesWalker_dbg() : m_depth( 0 ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + ++m_depth; + globalOutputStream() << "pre depth_" << m_depth; + globalOutputStream() << " path.size()_" << path.size(); + if ( path.top().get() == worldspawn ) + globalOutputStream() << " worldspawn"; + if( path.top().get().isRoot() ) + globalOutputStream() << " path.top().get().isRoot()"; + Entity* entity = Node_getEntity( path.top() ); + if ( entity != 0 ){ + globalOutputStream() << " entity!=0"; + if( entity->isContainer() ){ + globalOutputStream() << " entity->isContainer()"; + } + globalOutputStream() << " classname_" << entity->getKeyValue( "classname" ); + } + globalOutputStream() << "\n"; +// globalOutputStream() << "" << ; +// globalOutputStream() << "" << ; +// globalOutputStream() << "" << ; +// globalOutputStream() << "" << ; + return true; +} +void post( const scene::Path& path, scene::Instance& instance ) const { + globalOutputStream() << "post depth_" << m_depth; + globalOutputStream() << " path.size()_" << path.size(); + if ( path.top().get() == worldspawn ) + globalOutputStream() << " worldspawn"; + if( path.top().get().isRoot() ) + globalOutputStream() << " path.top().get().isRoot()"; + Entity* entity = Node_getEntity( path.top() ); + if ( entity != 0 ){ + globalOutputStream() << " entity!=0"; + if( entity->isContainer() ){ + globalOutputStream() << " entity->isContainer()"; + } + globalOutputStream() << " classname_" << entity->getKeyValue( "classname" ); + } + globalOutputStream() << "\n"; + --m_depth; +} +}; + class ExpandSelectionToEntitiesWalker : public scene::Graph::Walker { mutable std::size_t m_depth; @@ -330,17 +381,21 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const { ++m_depth; // ignore worldspawn - NodeSmartReference me( path.top().get() ); - if ( me == worldspawn ) { - return false; - } +// NodeSmartReference me( path.top().get() ); +// if ( me == worldspawn ) { +// return false; +// } if ( m_depth == 2 ) { // entity depth // traverse and select children if any one is selected + bool beselected = false; if ( instance.childSelected() ) { - Instance_setSelected( instance, true ); + beselected = true; + if( path.top().get() != worldspawn ){ + Instance_setSelected( instance, true ); + } } - return Node_getEntity( path.top() )->isContainer() && instance.isSelected(); + return Node_getEntity( path.top() )->isContainer() && beselected; } else if ( m_depth == 3 ) { // primitive depth Instance_setSelected( instance, true ); @@ -522,20 +577,20 @@ inline Quaternion quaternion_for_axis90( axis_t axis, sign_t sign ){ void Select_RotateAxis( int axis, float deg ){ if ( fabs( deg ) == 90.f ) { - GlobalSelectionSystem().rotateSelected( quaternion_for_axis90( (axis_t)axis, ( deg > 0 ) ? eSignPositive : eSignNegative ) ); + GlobalSelectionSystem().rotateSelected( quaternion_for_axis90( (axis_t)axis, ( deg > 0 ) ? eSignPositive : eSignNegative ), true ); } else { switch ( axis ) { case 0: - GlobalSelectionSystem().rotateSelected( quaternion_for_matrix4_rotation( matrix4_rotation_for_x_degrees( deg ) ) ); + GlobalSelectionSystem().rotateSelected( quaternion_for_matrix4_rotation( matrix4_rotation_for_x_degrees( deg ) ), false ); break; case 1: - GlobalSelectionSystem().rotateSelected( quaternion_for_matrix4_rotation( matrix4_rotation_for_y_degrees( deg ) ) ); + GlobalSelectionSystem().rotateSelected( quaternion_for_matrix4_rotation( matrix4_rotation_for_y_degrees( deg ) ), false ); break; case 2: - GlobalSelectionSystem().rotateSelected( quaternion_for_matrix4_rotation( matrix4_rotation_for_z_degrees( deg ) ) ); + GlobalSelectionSystem().rotateSelected( quaternion_for_matrix4_rotation( matrix4_rotation_for_z_degrees( deg ) ), false ); break; } } @@ -613,18 +668,32 @@ class EntityFindByPropertyValueWalker : public scene::Graph::Walker { const PropertyValues& m_propertyvalues; const char *m_prop; +const NodeSmartReference worldspawn; public: EntityFindByPropertyValueWalker( const char *prop, const PropertyValues& propertyvalues ) - : m_propertyvalues( propertyvalues ), m_prop( prop ){ + : m_propertyvalues( propertyvalues ), m_prop( prop ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){ } bool pre( const scene::Path& path, scene::Instance& instance ) const { if( !path.top().get().visible() ){ return false; } + // ignore worldspawn + if ( path.top().get() == worldspawn ) { + return false; + } + Entity* entity = Node_getEntity( path.top() ); - if ( entity != 0 - && propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) { - Instance_getSelectable( instance )->setSelected( true ); + if ( entity != 0 ){ + if( propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) { + Instance_getSelectable( instance )->setSelected( true ); + return true; + } + return false; + } + else if( path.size() > 2 && !path.top().get().isRoot() ){ + Selectable* selectable = Instance_getSelectable( instance ); + if( selectable != 0 ) + selectable->setSelected( true ); } return true; } @@ -638,9 +707,37 @@ class EntityGetSelectedPropertyValuesWalker : public scene::Graph::Walker { PropertyValues& m_propertyvalues; const char *m_prop; +const NodeSmartReference worldspawn; public: EntityGetSelectedPropertyValuesWalker( const char *prop, PropertyValues& propertyvalues ) - : m_propertyvalues( propertyvalues ), m_prop( prop ){ + : m_propertyvalues( propertyvalues ), m_prop( prop ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + Entity* entity = Node_getEntity( path.top() ); + if ( entity != 0 ){ + if( path.top().get() != worldspawn ){ + Selectable* selectable = Instance_getSelectable( instance ); + if ( ( selectable != 0 && selectable->isSelected() ) || instance.childSelected() ) { + if ( !propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) { + m_propertyvalues.push_back( entity->getKeyValue( m_prop ) ); + } + } + } + return false; + } + return true; +} +}; +/* +class EntityGetSelectedPropertyValuesWalker : public scene::Graph::Walker +{ +PropertyValues& m_propertyvalues; +const char *m_prop; +mutable bool m_selected_children; +const NodeSmartReference worldspawn; +public: +EntityGetSelectedPropertyValuesWalker( const char *prop, PropertyValues& propertyvalues ) + : m_propertyvalues( propertyvalues ), m_prop( prop ), m_selected_children( false ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){ } bool pre( const scene::Path& path, scene::Instance& instance ) const { Selectable* selectable = Instance_getSelectable( instance ); @@ -651,12 +748,27 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const { if ( !propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) { m_propertyvalues.push_back( entity->getKeyValue( m_prop ) ); } + return false; + } + else{ + m_selected_children = true; } } return true; } +void post( const scene::Path& path, scene::Instance& instance ) const { + Entity* entity = Node_getEntity( path.top() ); + if( entity != 0 && m_selected_children ){ + m_selected_children = false; + if( path.top().get() == worldspawn ) + return; + if ( !propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) { + m_propertyvalues.push_back( entity->getKeyValue( m_prop ) ); + } + } +} }; - +*/ void Scene_EntityGetPropertyValues( scene::Graph& graph, const char *prop, PropertyValues& propertyvalues ){ graph.traverse( EntityGetSelectedPropertyValuesWalker( prop, propertyvalues ) ); } @@ -994,7 +1106,7 @@ static gboolean rotatedlg_apply( GtkWidget *widget, RotateDialog* rotateDialog ) command << "rotateSelectedEulerXYZ -x " << eulerXYZ[0] << " -y " << eulerXYZ[1] << " -z " << eulerXYZ[2]; UndoableCommand undo( command.c_str() ); - GlobalSelectionSystem().rotateSelected( quaternion_for_euler_xyz_degrees( eulerXYZ ) ); + GlobalSelectionSystem().rotateSelected( quaternion_for_euler_xyz_degrees( eulerXYZ ), false ); return TRUE; } diff --git a/radiant/selection.cpp b/radiant/selection.cpp index 2188ca58..e4364c10 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -342,8 +342,6 @@ Vector3 m_start; Vector3 m_axis; Scalable& m_scalable; -AABB m_aabb; -Vector3 m_transform_origin; Vector3 m_choosen_extent; public: @@ -353,11 +351,12 @@ ScaleAxis( Scalable& scalable ) void Construct( const Matrix4& device2manip, const float x, const float y ){ point_on_axis( m_start, m_axis, device2manip, x, y ); - GetSelectionAABB( m_aabb ); - m_transform_origin = vector4_to_vector3( ssGetPivot2World().t() ); - m_choosen_extent = Vector3( std::max( m_aabb.origin[0] + m_aabb.extents[0] - m_transform_origin[0], - m_aabb.origin[0] + m_aabb.extents[0] + m_transform_origin[0] ), - std::max( m_aabb.origin[1] + m_aabb.extents[1] - m_transform_origin[1], - m_aabb.origin[1] + m_aabb.extents[1] + m_transform_origin[1] ), - std::max( m_aabb.origin[2] + m_aabb.extents[2] - m_transform_origin[2], - m_aabb.origin[2] + m_aabb.extents[2] + m_transform_origin[2] ) + AABB aabb; + GetSelectionAABB( aabb ); + Vector3 transform_origin = vector4_to_vector3( ssGetPivot2World().t() ); + m_choosen_extent = Vector3( std::max( aabb.origin[0] + aabb.extents[0] - transform_origin[0], - aabb.origin[0] + aabb.extents[0] + transform_origin[0] ), + std::max( aabb.origin[1] + aabb.extents[1] - transform_origin[1], - aabb.origin[1] + aabb.extents[1] + transform_origin[1] ), + std::max( aabb.origin[2] + aabb.extents[2] - transform_origin[2], - aabb.origin[2] + aabb.extents[2] + transform_origin[2] ) ); } @@ -398,8 +397,6 @@ private: Vector3 m_start; Scalable& m_scalable; -AABB m_aabb; -Vector3 m_transform_origin; Vector3 m_choosen_extent; public: @@ -409,11 +406,12 @@ ScaleFree( Scalable& scalable ) void Construct( const Matrix4& device2manip, const float x, const float y ){ point_on_plane( m_start, device2manip, x, y ); - GetSelectionAABB( m_aabb ); - m_transform_origin = vector4_to_vector3( ssGetPivot2World().t() ); - m_choosen_extent = Vector3( std::max( m_aabb.origin[0] + m_aabb.extents[0] - m_transform_origin[0], - m_aabb.origin[0] + m_aabb.extents[0] + m_transform_origin[0] ), - std::max( m_aabb.origin[1] + m_aabb.extents[1] - m_transform_origin[1], - m_aabb.origin[1] + m_aabb.extents[1] + m_transform_origin[1] ), - std::max( m_aabb.origin[2] + m_aabb.extents[2] - m_transform_origin[2], - m_aabb.origin[2] + m_aabb.extents[2] + m_transform_origin[2] ) + AABB aabb; + GetSelectionAABB( aabb ); + Vector3 transform_origin = vector4_to_vector3( ssGetPivot2World().t() ); + m_choosen_extent = Vector3( std::max( aabb.origin[0] + aabb.extents[0] - transform_origin[0], - aabb.origin[0] + aabb.extents[0] + transform_origin[0] ), + std::max( aabb.origin[1] + aabb.extents[1] - transform_origin[1], - aabb.origin[1] + aabb.extents[1] + transform_origin[1] ), + std::max( aabb.origin[2] + aabb.extents[2] - transform_origin[2], - aabb.origin[2] + aabb.extents[2] + transform_origin[2] ) ); } void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y ){ @@ -3197,7 +3195,12 @@ void outputScale( TextOutputStream& ostream ){ ostream << " -scale " << m_scale.x() << " " << m_scale.y() << " " << m_scale.z(); } -void rotateSelected( const Quaternion& rotation ){ +void rotateSelected( const Quaternion& rotation, bool snapOrigin ){ + if( snapOrigin && !m_pivotIsCustom ){ + m_pivot2world.tx() = float_snapped( m_pivot2world.tx(), GetSnapGridSize() ); + m_pivot2world.ty() = float_snapped( m_pivot2world.ty(), GetSnapGridSize() ); + m_pivot2world.tz() = float_snapped( m_pivot2world.tz(), GetSnapGridSize() ); + } startMove(); rotate( rotation ); freezeTransforms(); diff --git a/radiant/view.h b/radiant/view.h index 7e8cdf95..9800464f 100644 --- a/radiant/view.h +++ b/radiant/view.h @@ -186,6 +186,9 @@ bool fill() const { const Vector3& getViewer() const { return vector4_to_vector3( m_viewer ); } +const Frustum& getFrustum() const { + return m_frustum; +} }; #endif diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 3e454e2d..0f785741 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -351,7 +351,7 @@ struct xywindow_globals_private_t bool show_blocks; int blockSize; - bool m_bCamXYUpdate; +// bool m_bCamXYUpdate; bool m_bChaseMouse; bool m_bSizePaint; @@ -368,7 +368,7 @@ struct xywindow_globals_private_t show_blocks( false ), - m_bCamXYUpdate( true ), +// m_bCamXYUpdate( true ), m_bChaseMouse( true ), m_bSizePaint( true ){ } @@ -819,10 +819,10 @@ gboolean xywnd_expose( GtkWidget* widget, GdkEventExpose* event, XYWnd* xywnd ){ void XYWnd_CameraMoved( XYWnd& xywnd ){ - if ( g_xywindow_globals_private.m_bCamXYUpdate ) { +// if ( g_xywindow_globals_private.m_bCamXYUpdate ) { //XYWnd_Update( xywnd ); xywnd.UpdateCameraIcon(); - } +// } } XYWnd::XYWnd() : @@ -1010,7 +1010,8 @@ void XYWnd::SetCustomPivotOrigin( int pointx, int pointy ){ } unsigned int MoveCamera_buttons(){ - return RAD_CONTROL | ( g_glwindow_globals.m_nMouseType == ETwoButton ? RAD_RBUTTON : RAD_MBUTTON ); +// return RAD_CONTROL | ( g_glwindow_globals.m_nMouseType == ETwoButton ? RAD_RBUTTON : RAD_MBUTTON ); + return RAD_CONTROL | RAD_MBUTTON; } void XYWnd_PositionCamera( XYWnd* xywnd, int x, int y, CamWnd& camwnd ){ @@ -1021,16 +1022,17 @@ void XYWnd_PositionCamera( XYWnd* xywnd, int x, int y, CamWnd& camwnd ){ } unsigned int OrientCamera_buttons(){ - if ( g_glwindow_globals.m_nMouseType == ETwoButton ) { - return RAD_RBUTTON | RAD_SHIFT | RAD_CONTROL; - } +// if ( g_glwindow_globals.m_nMouseType == ETwoButton ) { +// return RAD_RBUTTON | RAD_SHIFT | RAD_CONTROL; +// } return RAD_MBUTTON; } void XYWnd_OrientCamera( XYWnd* xywnd, int x, int y, CamWnd& camwnd ){ + //globalOutputStream() << Camera_getAngles( camwnd ) << " b4\n"; Vector3 point = g_vector3_identity; xywnd->XY_ToPoint( x, y, point ); - xywnd->XY_SnapToGrid( point ); + //xywnd->XY_SnapToGrid( point ); vector3_subtract( point, Camera_getOrigin( camwnd ) ); int n1 = ( xywnd->GetViewType() == XY ) ? 1 : 2; @@ -1039,8 +1041,34 @@ void XYWnd_OrientCamera( XYWnd* xywnd, int x, int y, CamWnd& camwnd ){ if ( point[n1] || point[n2] ) { Vector3 angles( Camera_getAngles( camwnd ) ); angles[nAngle] = static_cast( radians_to_degrees( atan2( point[n1], point[n2] ) ) ); + if( angles[CAMERA_YAW] < 0 ) + angles[CAMERA_YAW] = angles[CAMERA_YAW] + 360; + if ( nAngle == CAMERA_PITCH ){ + if( fabs( angles[CAMERA_PITCH] ) > 90 ){ + angles[CAMERA_PITCH] = ( angles[CAMERA_PITCH] > 0 ) ? ( -angles[CAMERA_PITCH] + 180 ) : ( -angles[CAMERA_PITCH] - 180 ); + if( xywnd->GetViewType() == YZ ){ + if( angles[CAMERA_YAW] < 180 ){ + angles[CAMERA_YAW] = 360 - angles[CAMERA_YAW]; + } + } + else if( angles[CAMERA_YAW] < 90 || angles[CAMERA_YAW] > 270 ){ + angles[CAMERA_YAW] = 180 - angles[CAMERA_YAW]; + } + } + else{ + if( xywnd->GetViewType() == YZ ){ + if( angles[CAMERA_YAW] > 180 ){ + angles[CAMERA_YAW] = 360 - angles[CAMERA_YAW]; + } + } + else if( angles[CAMERA_YAW] > 90 && angles[CAMERA_YAW] < 270 ){ + angles[CAMERA_YAW] = 180 - angles[CAMERA_YAW]; + } + } + } Camera_setAngles( camwnd, angles ); } + //globalOutputStream() << Camera_getAngles( camwnd ) << "\n"; } unsigned int SetCustomPivotOrigin_buttons(){ @@ -1207,9 +1235,9 @@ void addItem( const char* name, const char* next ){ }; void XYWnd::OnContextMenu(){ - if ( g_xywindow_globals.m_bRightClick == false ) { - return; - } +// if ( g_xywindow_globals.m_bRightClick == false ) { +// return; +// } if ( m_mnuDrop == 0 ) { // first time, load it up GtkMenu* menu = m_mnuDrop = GTK_MENU( gtk_menu_new() ); @@ -1405,12 +1433,12 @@ void XYWnd::XY_MouseMoved( int x, int y, unsigned int buttons ){ } // control mbutton = move camera - else if ( getButtonState() == MoveCamera_buttons() ) { + else if ( buttons == MoveCamera_buttons() ) { XYWnd_PositionCamera( this, x, y, *g_pParentWnd->GetCamWnd() ); } // mbutton = angle camera - else if ( getButtonState() == OrientCamera_buttons() ) { + else if ( buttons == OrientCamera_buttons() ) { XYWnd_OrientCamera( this, x, y, *g_pParentWnd->GetCamWnd() ); } @@ -2037,6 +2065,7 @@ void XYWnd::XY_DrawBlockGrid(){ void XYWnd::DrawCameraIcon( const Vector3& origin, const Vector3& angles ){ Cam.fov = 48 / m_fScale; Cam.box = 16 / m_fScale; +// globalOutputStream() << "pitch " << angles[CAMERA_PITCH] << " yaw " << angles[CAMERA_YAW] << "\n"; if ( m_viewType == XY ) { Cam.x = origin[0]; @@ -2046,13 +2075,13 @@ void XYWnd::DrawCameraIcon( const Vector3& origin, const Vector3& angles ){ else if ( m_viewType == YZ ) { Cam.x = origin[1]; Cam.y = origin[2]; - Cam.a = degrees_to_radians( angles[CAMERA_PITCH] ); + Cam.a = degrees_to_radians( ( angles[CAMERA_YAW] > 180 ) ? ( 180.0f - angles[CAMERA_PITCH] ) : angles[CAMERA_PITCH] ); } else { Cam.x = origin[0]; Cam.y = origin[2]; - Cam.a = degrees_to_radians( angles[CAMERA_PITCH] ); + Cam.a = degrees_to_radians( ( angles[CAMERA_YAW] < 270 && angles[CAMERA_YAW] > 90 ) ? ( 180.0f - angles[CAMERA_PITCH] ) : angles[CAMERA_PITCH] ); } //glColor3f( 0.0, 0.0, 1.0 ); @@ -2938,7 +2967,7 @@ void Orthographic_constructPreferences( PreferencesPage& page ){ page.appendCheckBox( "", "Solid selection boxes ( no stipple )", g_xywindow_globals.m_bNoStipple ); //page.appendCheckBox( "", "Display size info", g_xywindow_globals_private.m_bSizePaint ); page.appendCheckBox( "", "Chase mouse during drags", g_xywindow_globals_private.m_bChaseMouse ); - page.appendCheckBox( "", "Update views on camera move", g_xywindow_globals_private.m_bCamXYUpdate ); +// page.appendCheckBox( "", "Update views on camera move", g_xywindow_globals_private.m_bCamXYUpdate ); } void Orthographic_constructPage( PreferenceGroup& group ){ PreferencesPage page( group.createPage( "Orthographic", "Orthographic View Preferences" ) ); @@ -2995,7 +3024,7 @@ void XYWindow_Construct(){ GlobalPreferenceSystem().registerPreference( "ClipCaulk", BoolImportStringCaller( g_clip_useCaulk ), BoolExportStringCaller( g_clip_useCaulk ) ); - GlobalPreferenceSystem().registerPreference( "NewRightClick", BoolImportStringCaller( g_xywindow_globals.m_bRightClick ), BoolExportStringCaller( g_xywindow_globals.m_bRightClick ) ); +// GlobalPreferenceSystem().registerPreference( "NewRightClick", BoolImportStringCaller( g_xywindow_globals.m_bRightClick ), BoolExportStringCaller( g_xywindow_globals.m_bRightClick ) ); GlobalPreferenceSystem().registerPreference( "ImprovedWheelZoom", BoolImportStringCaller( g_xywindow_globals.m_bImprovedWheelZoom ), BoolExportStringCaller( g_xywindow_globals.m_bImprovedWheelZoom ) ); GlobalPreferenceSystem().registerPreference( "ChaseMouse", BoolImportStringCaller( g_xywindow_globals_private.m_bChaseMouse ), BoolExportStringCaller( g_xywindow_globals_private.m_bChaseMouse ) ); GlobalPreferenceSystem().registerPreference( "SizePainting", BoolImportStringCaller( g_xywindow_globals_private.m_bSizePaint ), BoolExportStringCaller( g_xywindow_globals_private.m_bSizePaint ) ); @@ -3004,7 +3033,7 @@ void XYWindow_Construct(){ GlobalPreferenceSystem().registerPreference( "SI_ShowCoords", BoolImportStringCaller( g_xywindow_globals_private.show_coordinates ), BoolExportStringCaller( g_xywindow_globals_private.show_coordinates ) ); GlobalPreferenceSystem().registerPreference( "SI_ShowOutlines", BoolImportStringCaller( g_xywindow_globals_private.show_outline ), BoolExportStringCaller( g_xywindow_globals_private.show_outline ) ); GlobalPreferenceSystem().registerPreference( "SI_ShowAxis", BoolImportStringCaller( g_xywindow_globals_private.show_axis ), BoolExportStringCaller( g_xywindow_globals_private.show_axis ) ); - GlobalPreferenceSystem().registerPreference( "CamXYUpdate", BoolImportStringCaller( g_xywindow_globals_private.m_bCamXYUpdate ), BoolExportStringCaller( g_xywindow_globals_private.m_bCamXYUpdate ) ); +// GlobalPreferenceSystem().registerPreference( "CamXYUpdate", BoolImportStringCaller( g_xywindow_globals_private.m_bCamXYUpdate ), BoolExportStringCaller( g_xywindow_globals_private.m_bCamXYUpdate ) ); GlobalPreferenceSystem().registerPreference( "ShowWorkzone", BoolImportStringCaller( g_xywindow_globals_private.d_show_work ), BoolExportStringCaller( g_xywindow_globals_private.d_show_work ) ); GlobalPreferenceSystem().registerPreference( "SI_AxisColors0", Vector3ImportStringCaller( g_xywindow_globals.AxisColorX ), Vector3ExportStringCaller( g_xywindow_globals.AxisColorX ) ); diff --git a/radiant/xywindow.h b/radiant/xywindow.h index 1d978b95..822045a5 100644 --- a/radiant/xywindow.h +++ b/radiant/xywindow.h @@ -212,10 +212,12 @@ bool m_entityCreate; public: void ButtonState_onMouseDown( unsigned int buttons ){ - m_buttonstate |= buttons; + //m_buttonstate |= buttons; + m_buttonstate = buttons; } void ButtonState_onMouseUp( unsigned int buttons ){ - m_buttonstate &= ~buttons; + //m_buttonstate &= ~buttons; + m_buttonstate = 0; } unsigned int getButtonState() const { return m_buttonstate; @@ -265,7 +267,7 @@ struct xywindow_globals_t Vector3 AxisColorY; Vector3 AxisColorZ; - bool m_bRightClick; +// bool m_bRightClick; bool m_bNoStipple; bool m_bImprovedWheelZoom; @@ -283,7 +285,7 @@ struct xywindow_globals_t AxisColorX( 1.f, 0.f, 0.f ), AxisColorY( 0.f, 1.f, 0.f ), AxisColorZ( 0.f, 0.f, 1.f ), - m_bRightClick( true ), +// m_bRightClick( true ), m_bNoStipple( true ), m_bImprovedWheelZoom( true ){ } -- 2.39.2