From 697d2714d68af6e7a0e5c617ef7d053e5ea7c4b7 Mon Sep 17 00:00:00 2001 From: Garux Date: Wed, 2 Aug 2017 09:39:45 +0300 Subject: [PATCH] Radiant: binds... * ctrl + e: ExpandSelectionToPrimitives (select group entities w/o parent node) * ctrl + m3 texture painting by drag misc... * fix: QNAN texture projection after scaling cuboid on Z axis (brush primitives + texture lock) * preferences->display->entities->Names Display Distance (in cam) def = 512u * always show selected/childSelected entity names (unselected is optional) * fix: mouse texture grab/paint commands ignore filtered faces (caulk filter) --- include/ientity.h | 2 + plugins/entity/doom3group.cpp | 2 +- plugins/entity/eclassmodel.cpp | 2 +- plugins/entity/entity.cpp | 8 +++ plugins/entity/entity.h | 1 + plugins/entity/generic.cpp | 4 +- plugins/entity/group.cpp | 2 +- plugins/entity/light.cpp | 2 +- plugins/entity/miscmodel.cpp | 2 +- plugins/entity/namedentity.h | 2 +- radiant/brush_primit.cpp | 3 ++ radiant/entity.cpp | 22 +++++++- radiant/mainframe.cpp | 2 + radiant/select.cpp | 44 ++++++++++++++++ radiant/select.h | 1 + radiant/selection.cpp | 94 +++++++++++++++++++++++++++++----- radiant/surfacedialog.cpp | 7 ++- radiant/xywindow.cpp | 4 +- 18 files changed, 177 insertions(+), 27 deletions(-) diff --git a/include/ientity.h b/include/ientity.h index 5c09d2c4..49116b9d 100644 --- a/include/ientity.h +++ b/include/ientity.h @@ -126,6 +126,8 @@ virtual void setLightRadii( bool lightRadii ) = 0; virtual bool getLightRadii() = 0; virtual void setShowNames( bool showNames ) = 0; virtual bool getShowNames() = 0; +virtual void setShowNamesDist( int dist ) = 0; +virtual int getShowNamesDist() = 0; virtual void setShowTargetNames( bool showNames ) = 0; virtual bool getShowTargetNames() = 0; virtual void setShowAngles( bool showAngles ) = 0; diff --git a/plugins/entity/doom3group.cpp b/plugins/entity/doom3group.cpp index 7e950f30..bdc62b96 100644 --- a/plugins/entity/doom3group.cpp +++ b/plugins/entity/doom3group.cpp @@ -363,7 +363,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l renderer.addRenderable( m_curveCatmullRom.m_renderCurve, localToWorld ); } - if ( g_showNames ) { + if ( g_showNames || selected || childSelected ) { // draw models as usual if ( !isModel() ) { // don't draw the name for worldspawn diff --git a/plugins/entity/eclassmodel.cpp b/plugins/entity/eclassmodel.cpp index 768014a0..7d351c62 100644 --- a/plugins/entity/eclassmodel.cpp +++ b/plugins/entity/eclassmodel.cpp @@ -253,7 +253,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l renderer.PopState(); } renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly ); - if ( g_showNames ) { + if ( g_showNames || selected ) { m_renderName.render( renderer, volume, localToWorld, selected ); } } diff --git a/plugins/entity/entity.cpp b/plugins/entity/entity.cpp index 47e5c015..8cde4297 100644 --- a/plugins/entity/entity.cpp +++ b/plugins/entity/entity.cpp @@ -113,6 +113,7 @@ EntityCreator::KeyValueChangedFunc KeyValue::m_entityKeyValueChanged = 0; Counter* EntityKeyValues::m_counter = 0; bool g_showNames = true; +int g_showNamesDist = 512; bool g_showTargetNames = false; bool g_showAngles = true; bool g_lightRadii = true; @@ -266,6 +267,12 @@ void setShowNames( bool showNames ){ bool getShowNames(){ return g_showNames; } +void setShowNamesDist( int dist ){ + g_showNamesDist = dist; +} +int getShowNamesDist(){ + return g_showNamesDist; +} void setShowTargetNames( bool showNames ){ g_showTargetNames = showNames; } @@ -376,6 +383,7 @@ void Entity_Construct( EGameType gameType ){ } GlobalPreferenceSystem().registerPreference( "SI_ShowNames", BoolImportStringCaller( g_showNames ), BoolExportStringCaller( g_showNames ) ); + GlobalPreferenceSystem().registerPreference( "SI_ShowNamesDist", IntImportStringCaller( g_showNamesDist ), IntExportStringCaller( g_showNamesDist ) ); GlobalPreferenceSystem().registerPreference( "SI_ShowTargetNames", BoolImportStringCaller( g_showTargetNames ), BoolExportStringCaller( g_showTargetNames ) ); GlobalPreferenceSystem().registerPreference( "SI_ShowAngles", BoolImportStringCaller( g_showAngles ), BoolExportStringCaller( g_showAngles ) ); GlobalPreferenceSystem().registerPreference( "LightRadiuses", BoolImportStringCaller( g_lightRadii ), BoolExportStringCaller( g_lightRadii ) ); diff --git a/plugins/entity/entity.h b/plugins/entity/entity.h index 17ad4c79..37a1202b 100644 --- a/plugins/entity/entity.h +++ b/plugins/entity/entity.h @@ -39,6 +39,7 @@ void Entity_Construct( EGameType gameType = eGameTypeQuake3 ); void Entity_Destroy(); extern bool g_showNames; +extern int g_showNamesDist; extern bool g_showTargetNames; extern bool g_showAngles; extern bool g_lightRadii; diff --git a/plugins/entity/generic.cpp b/plugins/entity/generic.cpp index 96ce89fc..e9a838da 100644 --- a/plugins/entity/generic.cpp +++ b/plugins/entity/generic.cpp @@ -219,7 +219,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l renderer.SetState( m_entity.getEntityClass().m_state_fill, Renderer::eFullMaterials ); renderer.addRenderable( m_aabb_solid, localToWorld ); renderArrow( renderer, volume, localToWorld ); - if ( g_showNames ) { + if ( g_showNames || selected ) { m_renderName.render( renderer, volume, localToWorld, selected ); } } @@ -227,7 +227,7 @@ void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly ); renderer.addRenderable( m_aabb_wire, localToWorld ); renderArrow( renderer, volume, localToWorld ); - if ( g_showNames ) { + if ( g_showNames || selected ) { m_renderName.render( renderer, volume, localToWorld, selected ); } } diff --git a/plugins/entity/group.cpp b/plugins/entity/group.cpp index 24148f2d..215d7607 100644 --- a/plugins/entity/group.cpp +++ b/plugins/entity/group.cpp @@ -150,7 +150,7 @@ void detach( scene::Traversable::Observer* observer ){ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected, bool childSelected, const AABB& childBounds ) const { renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly ); - if ( g_showNames ) { + if ( g_showNames || selected || childSelected ) { // don't draw the name for worldspawn if ( !strcmp( m_entity.getEntityClass().name(), "worldspawn" ) ) { return; diff --git a/plugins/entity/light.cpp b/plugins/entity/light.cpp index 445caa02..b0623208 100644 --- a/plugins/entity/light.cpp +++ b/plugins/entity/light.cpp @@ -1460,7 +1460,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l } } - if ( g_showNames && !string_equal( m_named.name(), "light" ) ) { + if ( ( g_showNames || selected ) && !string_equal( m_named.name(), "light" ) ) { m_renderName.render( renderer, volume, localToWorld, selected ); } } diff --git a/plugins/entity/miscmodel.cpp b/plugins/entity/miscmodel.cpp index a573859f..460c579a 100644 --- a/plugins/entity/miscmodel.cpp +++ b/plugins/entity/miscmodel.cpp @@ -195,7 +195,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l m_renderOrigin.render( renderer, volume, localToWorld ); } renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly ); - if ( g_showNames && !string_equal( m_named.name(), "misc_model" ) ) { + if ( ( g_showNames || selected ) && !string_equal( m_named.name(), "misc_model" ) ) { m_renderName.render( renderer, volume, localToWorld, selected ); } } diff --git a/plugins/entity/namedentity.h b/plugins/entity/namedentity.h index 9fdd46c0..c0a9a56c 100644 --- a/plugins/entity/namedentity.h +++ b/plugins/entity/namedentity.h @@ -181,7 +181,7 @@ public: Matrix4 viewproj = matrix4_multiplied_by_matrix4( volume.GetProjection(), volume.GetModelview() ); Vector3 viewer = vector4_to_vector3( viewer_from_viewproj( viewproj ) ); Vector3 pos_in_world = matrix4_transformed_point( localToWorld, m_position ); - if( vector3_length_squared( pos_in_world - viewer ) > 512*512 ){ + if( vector3_length_squared( pos_in_world - viewer ) > g_showNamesDist * g_showNamesDist ){ return; } //globalOutputStream() << viewer[0] << " " << viewer[1] << " " << viewer[2] << " Viewer\n"; diff --git a/radiant/brush_primit.cpp b/radiant/brush_primit.cpp index 0434f4e2..9362a9f9 100644 --- a/radiant/brush_primit.cpp +++ b/radiant/brush_primit.cpp @@ -1345,6 +1345,9 @@ void Texdef_transformLocked( TextureProjection& projection, std::size_t width, s identity2stOriginal = matrix4_multiplied_by_matrix4( identity2stOriginal, identityCorrected ); } + else if( dot != dot ){ //catch QNAN: happens on scaling cuboid on Z and sometimes on rotating + return; + } Matrix4 stTransformed2stOriginal = matrix4_multiplied_by_matrix4( identity2stOriginal, stTransformed2identity ); diff --git a/radiant/entity.cpp b/radiant/entity.cpp index 52931380..6a098460 100644 --- a/radiant/entity.cpp +++ b/radiant/entity.cpp @@ -576,6 +576,24 @@ void Entity_constructPreferences( PreferencesPage& page ){ LightRadiiExportCaller( GlobalEntityCreator() ) ); } +*/ +void ShowNamesDistImport( EntityCreator& self, int value ){ + self.setShowNamesDist( value ); + UpdateAllWindows(); +} +typedef ReferenceCaller1 ShowNamesDistImportCaller; + +void ShowNamesDistExport( EntityCreator& self, const IntImportCallback& importer ){ + importer( self.getShowNamesDist() ); +} +typedef ReferenceCaller1 ShowNamesDistExportCaller; + +void Entity_constructPreferences( PreferencesPage& page ){ + page.appendSpinner( "Names Display Distance", 512.0, 0.0, 200500.0, + IntImportCallback( ShowNamesDistImportCaller( GlobalEntityCreator() ) ), + IntExportCallback( ShowNamesDistExportCaller( GlobalEntityCreator() ) ) + ); +} void Entity_constructPage( PreferenceGroup& group ){ PreferencesPage page( group.createPage( "Entities", "Entity Display Preferences" ) ); Entity_constructPreferences( page ); @@ -583,7 +601,7 @@ void Entity_constructPage( PreferenceGroup& group ){ void Entity_registerPreferencesPage(){ PreferencesDialog_addDisplayPage( FreeCaller1() ); } -*/ + void ShowLightRadiiExport( const BoolImportCallback& importer ){ importer( GlobalEntityCreator().getLightRadii() ); @@ -626,7 +644,7 @@ void Entity_Construct(){ GlobalPreferenceSystem().registerPreference( "SI_Colors5", Vector3ImportStringCaller( g_entity_globals.color_entity ), Vector3ExportStringCaller( g_entity_globals.color_entity ) ); GlobalPreferenceSystem().registerPreference( "LastLightIntensity", IntImportStringCaller( g_iLastLightIntensity ), IntExportStringCaller( g_iLastLightIntensity ) ); -// Entity_registerPreferencesPage(); + Entity_registerPreferencesPage(); } void Entity_Destroy(){ diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 53470b3e..1eb7a80e 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -1937,6 +1937,7 @@ GtkMenuItem* create_edit_menu(){ // menu_tearoff( convert_menu ); // } create_menu_item_with_mnemonic( menu, "Select All Of Type", "SelectAllOfType" ); + create_menu_item_with_mnemonic( menu, "_Expand Selection To Primitives", "ExpandSelectionToPrimitives" ); create_menu_item_with_mnemonic( menu, "_Expand Selection To Entities", "ExpandSelectionToEntities" ); create_menu_item_with_mnemonic( menu, "Select Connected Entities", "SelectConnectedEntities" ); @@ -3478,6 +3479,7 @@ void MainFrame_Construct(){ GlobalCommands_insert( "InvertSelection", FreeCaller(), Accelerator( 'I' ) ); GlobalCommands_insert( "SelectInside", FreeCaller() ); GlobalCommands_insert( "SelectTouching", FreeCaller() ); + GlobalCommands_insert( "ExpandSelectionToPrimitives", FreeCaller(), Accelerator( 'E', (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "ExpandSelectionToEntities", FreeCaller(), Accelerator( 'E', (GdkModifierType)GDK_SHIFT_MASK ) ); GlobalCommands_insert( "SelectConnectedEntities", FreeCaller(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); GlobalCommands_insert( "Preferences", FreeCaller(), Accelerator( 'P' ) ); diff --git a/radiant/select.cpp b/radiant/select.cpp index b53da7f2..a0c72b78 100644 --- a/radiant/select.cpp +++ b/radiant/select.cpp @@ -384,6 +384,50 @@ void post( const scene::Path& path, scene::Instance& instance ) const { } }; +class ExpandSelectionToPrimitivesWalker : public scene::Graph::Walker +{ +mutable std::size_t m_depth; +NodeSmartReference worldspawn; +public: +ExpandSelectionToPrimitivesWalker() : m_depth( 0 ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + ++m_depth; + + if( !path.top().get().visible() ) + return false; + + // ignore worldspawn +// 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; + const bool isContainer = Node_getEntity( path.top() )->isContainer(); + if ( instance.childSelected() || instance.isSelected() ) { + beselected = true; + Instance_setSelected( instance, !isContainer ); + } + return isContainer && beselected; + } + else if ( m_depth == 3 ) { // primitive depth + Instance_setSelected( instance, true ); + return false; + } + return true; +} +void post( const scene::Path& path, scene::Instance& instance ) const { + --m_depth; +} +}; + +void Scene_ExpandSelectionToPrimitives(){ + GlobalSceneGraph().traverse( ExpandSelectionToPrimitivesWalker() ); +} + class ExpandSelectionToEntitiesWalker : public scene::Graph::Walker { mutable std::size_t m_depth; diff --git a/radiant/select.h b/radiant/select.h index 88d25f68..503a3862 100644 --- a/radiant/select.h +++ b/radiant/select.h @@ -31,6 +31,7 @@ void Select_Delete(); void Select_Invert(); void Select_Inside(); void Select_Touching(); +void Scene_ExpandSelectionToPrimitives(); void Scene_ExpandSelectionToEntities(); //void Selection_Flipx(); diff --git a/radiant/selection.cpp b/radiant/selection.cpp index 68a2ab76..daa7ee78 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -4072,6 +4072,75 @@ const ModifierFlags c_modifier_apply_texture2 = c_modifierControl; const ModifierFlags c_modifier_apply_texture3 = c_modifierShift; const ModifierFlags c_modifier_copy_texture = c_modifierNone; + + +void Scene_copyClosestTexture( SelectionTest& test ); +void Scene_applyClosestTexture( SelectionTest& test ); + +class TexManipulator_ +{ +public: +DeviceVector m_epsilon; +const View* m_view; +ModifierFlags m_state; +bool m_undo_begun; + +TexManipulator_() : m_state( c_modifierNone ), m_undo_begun( false ){ +} + +void mouseDown( DeviceVector position ){ + View scissored( *m_view ); + ConstructSelectionTest( scissored, SelectionBoxForPoint( &position[0], &m_epsilon[0] ) ); + SelectionVolume volume( scissored ); + + if ( m_state == c_modifier_apply_texture1 || m_state == c_modifier_apply_texture2 || m_state == c_modifier_apply_texture3 ) { + m_undo_begun = true; + GlobalUndoSystem().start(); + Scene_applyClosestTexture( volume ); + } + else if ( m_state == c_modifier_copy_texture ) { + Scene_copyClosestTexture( volume ); + } +} + +void mouseMoved( DeviceVector position ){ + if( m_undo_begun ){ + View scissored( *m_view ); + ConstructSelectionTest( scissored, SelectionBoxForPoint( &device_constrained( position )[0], &m_epsilon[0] ) ); + SelectionVolume volume( scissored ); + + Scene_applyClosestTexture( volume ); + } +} +typedef MemberCaller1 MouseMovedCaller; + +void mouseUp( DeviceVector position ){ + if( m_undo_begun ){ + GlobalUndoSystem().finish( "paintTexture" ); + m_undo_begun = false; + } + g_mouseMovedCallback.clear(); + g_mouseUpCallback.clear(); +} +typedef MemberCaller1 MouseUpCaller; + +void setState( ModifierFlags state ){ + m_state = state; +} + +ModifierFlags getState() const { + return m_state; +} + +void modifierEnable( ModifierFlags type ){ + setState( bitfield_enable( getState(), type ) ); +} +void modifierDisable( ModifierFlags type ){ + setState( bitfield_disable( getState(), type ) ); +} +}; + + class Selector_ { RadiantSelectionSystem::EModifier modifier_for_state( ModifierFlags state ){ @@ -4253,8 +4322,7 @@ void modifierDisable( ModifierFlags type ){ } }; -void Scene_copyClosestTexture( SelectionTest& test ); -void Scene_applyClosestTexture( SelectionTest& test ); + class RadiantWindowObserver : public SelectionSystemWindowObserver { @@ -4271,6 +4339,7 @@ bool m_mouse_down; public: Selector_ m_selector; Manipulator_ m_manipulator; +TexManipulator_ m_texmanipulator; RadiantWindowObserver() : m_mouse_down( false ){ } @@ -4280,6 +4349,7 @@ void release(){ void setView( const View& view ){ m_selector.m_view = &view; m_manipulator.m_view = &view; + m_texmanipulator.m_view = &view; } void setRectangleDrawCallback( const RectangleCallback& callback ){ m_selector.m_window_update = callback; @@ -4288,7 +4358,7 @@ void onSizeChanged( int width, int height ){ m_width = width; m_height = height; DeviceVector epsilon( SELECT_EPSILON / static_cast( m_width ), SELECT_EPSILON / static_cast( m_height ) ); - m_selector.m_epsilon = m_manipulator.m_epsilon = epsilon; + m_selector.m_epsilon = m_manipulator.m_epsilon = m_texmanipulator.m_epsilon = epsilon; } void onMouseDown( const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers ){ if ( button == c_button_select || ( button == c_button_select2 && modifiers != c_modifierNone ) ) { @@ -4310,18 +4380,14 @@ void onMouseDown( const WindowVector& position, ButtonIdentifier button, Modifie } } else if ( button == c_button_texture ) { + m_mouse_down = true; DeviceVector devicePosition( device_constrained( window_to_normalised_device( position, m_width, m_height ) ) ); - View scissored( *m_selector.m_view ); - ConstructSelectionTest( scissored, SelectionBoxForPoint( &devicePosition[0], &m_selector.m_epsilon[0] ) ); - SelectionVolume volume( scissored ); + m_texmanipulator.mouseDown( devicePosition ); + g_mouseMovedCallback.insert( MouseEventCallback( TexManipulator_::MouseMovedCaller( m_texmanipulator ) ) ); + g_mouseUpCallback.insert( MouseEventCallback( TexManipulator_::MouseUpCaller( m_texmanipulator ) ) ); + - if ( modifiers == c_modifier_apply_texture1 || modifiers == c_modifier_apply_texture2 || modifiers == c_modifier_apply_texture3 ) { - Scene_applyClosestTexture( volume ); - } - else if ( modifiers == c_modifier_copy_texture ) { - Scene_copyClosestTexture( volume ); - } } } void onMouseMotion( const WindowVector& position, ModifierFlags modifiers ){ @@ -4332,7 +4398,7 @@ void onMouseMotion( const WindowVector& position, ModifierFlags modifiers ){ } } void onMouseUp( const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers ){ - if ( ( button == c_button_select || button == c_button_select2 ) && !g_mouseUpCallback.empty() ) { + if ( ( button == c_button_select || button == c_button_select2 || button == c_button_texture ) && !g_mouseUpCallback.empty() ) { m_mouse_down = false; g_mouseUpCallback.get() ( window_to_normalised_device( position, m_width, m_height ) ); @@ -4352,10 +4418,12 @@ void onMouseUp( const WindowVector& position, ButtonIdentifier button, ModifierF void onModifierDown( ModifierFlags type ){ m_selector.modifierEnable( type ); m_manipulator.modifierEnable( type ); + m_texmanipulator.modifierEnable( type ); } void onModifierUp( ModifierFlags type ){ m_selector.modifierDisable( type ); m_manipulator.modifierDisable( type ); + m_texmanipulator.modifierDisable( type ); } }; diff --git a/radiant/surfacedialog.cpp b/radiant/surfacedialog.cpp index cc6c116b..7ff1e8bb 100644 --- a/radiant/surfacedialog.cpp +++ b/radiant/surfacedialog.cpp @@ -1321,6 +1321,9 @@ struct Texturable void Face_getClosest( Face& face, SelectionTest& test, SelectionIntersection& bestIntersection, Texturable& texturable ){ + if ( face.isFiltered() ) { + return; + } SelectionIntersection intersection; face.testSelect( test, intersection ); if ( intersection.valid() @@ -1453,11 +1456,11 @@ void Scene_copyClosestTexture( SelectionTest& test ){ } void Scene_applyClosestTexture( SelectionTest& test ){ - UndoableCommand command( "facePaintTexture" ); +// UndoableCommand command( "facePaintTexture" ); Scene_setClosestTexture( GlobalSceneGraph(), test, TextureBrowser_GetSelectedShader( g_TextureBrowser ), g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags ); - SceneChangeNotify(); + //SceneChangeNotify(); } diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 86064b3a..23b9ca25 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -3038,7 +3038,7 @@ ToggleItem g_show_names( g_show_names_caller ); void ShowNamesToggle(){ GlobalEntityCreator().setShowNames( !GlobalEntityCreator().getShowNames() ); g_show_names.update(); - XY_UpdateAllWindows(); + UpdateAllWindows(); } void ShowTargetNamesExport( const BoolImportCallback& importer ){ @@ -3062,7 +3062,7 @@ ToggleItem g_show_angles( g_show_angles_caller ); void ShowAnglesToggle(){ GlobalEntityCreator().setShowAngles( !GlobalEntityCreator().getShowAngles() ); g_show_angles.update(); - XY_UpdateAllWindows(); + UpdateAllWindows(); } BoolExportCaller g_show_blocks_caller( g_xywindow_globals_private.show_blocks );