From d079351041fe957ab2cf6b36dab38e5546003dc3 Mon Sep 17 00:00:00 2001 From: Garux Date: Wed, 2 Aug 2017 09:13:52 +0300 Subject: [PATCH] Radiant: binds... * QE tool: alt + m1 drag in primitives mode: click on vertex location = quick vertices drag (unlimited selection depth) click outside = brush faces shear misc... * load (aka 'search') tags on m1 dbl click * fix Doom3 crash in FilterAreaportals filterbar button --- radiant/brush.h | 49 +++++++++++---- radiant/filterbar.cpp | 8 ++- radiant/selection.cpp | 137 +++++++++++++++++++++++++++++++++++++++--- radiant/texwindow.cpp | 6 ++ 4 files changed, 177 insertions(+), 23 deletions(-) diff --git a/radiant/brush.h b/radiant/brush.h index 4c3d5fd1..d26547e8 100644 --- a/radiant/brush.h +++ b/radiant/brush.h @@ -2402,9 +2402,6 @@ inline bool triangles_same_winding( const BasicVector3& x1, const Basic } -typedef const Plane3* PlanePointer; -typedef PlanePointer* PlanesIterator; - class VectorLightList : public LightList { typedef std::vector Lights; @@ -2622,7 +2619,7 @@ void testSelect_centroid( Selector& selector, SelectionTest& test ){ } } -void selectPlane( Selector& selector, const Line& line, PlanesIterator first, PlanesIterator last, const PlaneCallback& selectedPlaneCallback ){ +void selectPlane( Selector& selector, const Line& line, const PlaneCallback& selectedPlaneCallback ){ for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i ) { Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) ); @@ -2642,6 +2639,17 @@ void selectReversedPlane( Selector& selector, const SelectedPlanes& selectedPlan } } +bool trySelectPlane( const Line& line ){ + for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i ){ + Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) ); + double dot = vector3_dot( getFace().plane3().normal(), v ); + if ( dot <= 0 ) { + return false; + } + } + return true; +} + void transformComponents( const Matrix4& matrix ){ if ( isSelected() ) { m_face->transform( matrix, false ); @@ -2998,6 +3006,20 @@ void testSelect( Selector& selector, SelectionTest& test ){ Selector_add( selector, *this, best ); } } + +void selectVerticesOnPlanes( SelectionTest& test ){ + Line line( test.getNear(), test.getFar() ); + FaceVertexId faceVertex = m_vertex->m_faceVertex; + do + { + if( m_faceInstances[faceVertex.getFace()].trySelectPlane( line ) ){ + //m_faceInstances[faceVertex.getFace()].select_vertex( faceVertex.getVertex(), true ); + setSelected( true ); + } + faceVertex = next_vertex( m_vertex->m_faces, faceVertex ); + } + while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() ); +} }; class BrushInstanceVisitor @@ -3409,17 +3431,9 @@ void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSys void selectPlanes( Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback ){ test.BeginMesh( localToWorld() ); - PlanePointer brushPlanes[c_brush_maxFaces]; - PlanesIterator j = brushPlanes; - - for ( Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i ) - { - *j++ = &( *i )->plane3(); - } - for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i ) { - ( *i ).selectPlane( selector, Line( test.getNear(), test.getFar() ), brushPlanes, j, selectedPlaneCallback ); + ( *i ).selectPlane( selector, Line( test.getNear(), test.getFar() ), selectedPlaneCallback ); } } void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPlanes ){ @@ -3430,6 +3444,15 @@ void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPla } +void selectVerticesOnPlanes( SelectionTest& test ){ + test.BeginMesh( localToWorld() ); + + for ( VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i ){ + ( *i ).selectVerticesOnPlanes( test ); + } +} + + void transformComponents( const Matrix4& matrix ){ for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i ) { diff --git a/radiant/filterbar.cpp b/radiant/filterbar.cpp index 447e01a5..22535702 100644 --- a/radiant/filterbar.cpp +++ b/radiant/filterbar.cpp @@ -216,11 +216,15 @@ GtkToolbar* create_filter_toolbar(){ toolbar_append_toggle_button( toolbar, "Patches (CTRL + P)", "patch_wireframe.png", "FilterPatches" ); gtk_toolbar_append_space( GTK_TOOLBAR( toolbar ) ); - button = toolbar_append_toggle_button( toolbar, "Areaportals (ALT + 3)\nRightClick: toggle tex\n\tnoDraw\n\tnoDrawNonSolid", "f-areaportal.png", "FilterAreaportals" ); + if ( g_pGameDescription->mGameType == "doom3" ) { + button = toolbar_append_toggle_button( toolbar, "Visportals (ALT + 3)\nRightClick: toggle tex\n\tnoDraw\n\tnoDrawNonSolid", "f-areaportal.png", "FilterVisportals" ); + } + else{ + button = toolbar_append_toggle_button( toolbar, "Areaportals (ALT + 3)\nRightClick: toggle tex\n\tnoDraw\n\tnoDrawNonSolid", "f-areaportal.png", "FilterAreaportals" ); + } g_signal_connect( G_OBJECT( button ), "button_press_event", G_CALLBACK( Areaportals_button_press ), 0 ); - toolbar_append_toggle_button( toolbar, "Translucent (ALT + 4)", "f-translucent.png", "FilterTranslucent" ); button = toolbar_append_toggle_button( toolbar, "Liquids (ALT + 5)\nRightClick: toggle tex\n\twaterCaulk\n\tlavaCaulk\n\tslimeCaulk", "f-liquids.png", "FilterLiquids" ); diff --git a/radiant/selection.cpp b/radiant/selection.cpp index a3df8a31..4e0c67e9 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -1887,6 +1887,59 @@ bool Scene_forEachPlaneSelectable_selectPlanes( scene::Graph& graph, Selector& s return !selectedPlanes.empty(); } + +#include "brush.h" +/* +class TestedBrushPlanesSelectVeritces : public scene::Graph::Walker +{ +SelectionTest& m_test; +public: +TestedBrushPlanesSelectVeritces( SelectionTest& test ) + : m_test( test ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + if ( path.top().get().visible() ) { + Selectable* selectable = Instance_getSelectable( instance ); + if ( selectable != 0 && selectable->isSelected() ) { + BrushInstance* brushInstance = Instance_getBrush( instance ); + if ( brushInstance != 0 ) { + brushInstance->selectVerticesOnPlanes( m_test ); + } + } + } + return true; +} +}; + +void Scene_forEachTestedBrushPlane_selectVertices( scene::Graph& graph, SelectionTest& test ){ + graph.traverse( TestedBrushPlanesSelectVeritces( test ) ); +} +*/ +class BrushPlanesSelectVeritces : public scene::Graph::Walker +{ +SelectionTest& m_test; +public: +BrushPlanesSelectVeritces( SelectionTest& test ) + : m_test( test ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + if ( path.top().get().visible() ) { + Selectable* selectable = Instance_getSelectable( instance ); + if ( selectable != 0 && selectable->isSelected() ) { + BrushInstance* brushInstance = Instance_getBrush( instance ); + if ( brushInstance != 0 ) { + brushInstance->selectVerticesOnPlanes( m_test ); + } + } + } + return true; +} +}; + +void Scene_forEachBrushPlane_selectVertices( scene::Graph& graph, SelectionTest& test ){ + graph.traverse( BrushPlanesSelectVeritces( test ) ); +} + void Scene_Translate_Component_Selected( scene::Graph& graph, const Vector3& translation ); void Scene_Translate_Selected( scene::Graph& graph, const Vector3& translation ); void Scene_TestSelect_Primitive( Selector& selector, SelectionTest& test, const VolumeTest& volume ); @@ -2550,22 +2603,58 @@ std::list& best(){ } }; +class DeepBestSelector : public Selector +{ +SelectionIntersection m_intersection; +Selectable* m_selectable; +SelectionIntersection m_bestIntersection; +std::list m_bestSelectable; +public: +DeepBestSelector() : m_bestIntersection( SelectionIntersection() ), m_bestSelectable( 0 ){ +} + +void pushSelectable( Selectable& selectable ){ + m_intersection = SelectionIntersection(); + m_selectable = &selectable; +} +void popSelectable(){ + if ( m_intersection.equalEpsilon( m_bestIntersection, 0.25f, 2.f ) ) { + m_bestSelectable.push_back( m_selectable ); + m_bestIntersection = m_intersection; + } + else if ( m_intersection < m_bestIntersection ) { + m_bestSelectable.clear(); + m_bestSelectable.push_back( m_selectable ); + m_bestIntersection = m_intersection; + } + m_intersection = SelectionIntersection(); +} +void addIntersection( const SelectionIntersection& intersection ){ + assign_if_closer( m_intersection, intersection ); +} + +std::list& best(){ + return m_bestSelectable; +} +}; + +bool g_bAltDragManipulatorResize = false; + class DragManipulator : public Manipulator { TranslateFree m_freeResize; TranslateFree m_freeDrag; ResizeTranslatable m_resize; DragTranslatable m_drag; -SelectableBool m_dragSelectable; +SelectableBool m_dragSelectable; //drag already selected stuff public: -bool m_selected; +bool m_selected; //selected temporally for drag DragManipulator() : m_freeResize( m_resize ), m_freeDrag( m_drag ), m_selected( false ){ } Manipulatable* GetManipulatable(){ - //globalOutputStream() << ( m_dragSelectable.isSelected() ? "m_freeDrag\n" : "m_freeResize\n" ); return m_dragSelectable.isSelected() ? &m_freeDrag : &m_freeResize; } @@ -2580,12 +2669,38 @@ void testSelect( const View& view, const Matrix4& pivot2world ){ Scene_TestSelect_Primitive( booleanSelector, test, view ); if ( booleanSelector.isSelected() ) { - selector.addSelectable( SelectionIntersection( 0, 0 ), &m_dragSelectable ); - m_selected = false; + if( g_bAltDragManipulatorResize ){ + DeepBestSelector deepSelector; + Scene_TestSelect_Component_Selected( deepSelector, test, view, SelectionSystem::eVertex ); + for ( std::list::iterator i = deepSelector.best().begin(); i != deepSelector.best().end(); ++i ) + { + if ( !( *i )->isSelected() ) { + GlobalSelectionSystem().setSelectedAllComponents( false ); + } + selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) ); + m_selected = true; + m_dragSelectable.setSelected( false ); + } + if( deepSelector.best().empty() ){ + //Scene_forEachTestedBrushPlane_selectVertices( GlobalSceneGraph(), test ); //todo? drag clicked face + Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test ); + m_selected = true; + } + } + else{ + selector.addSelectable( SelectionIntersection( 0, 0 ), &m_dragSelectable ); + m_selected = false; + } } else { - m_selected = Scene_forEachPlaneSelectable_selectPlanes( GlobalSceneGraph(), selector, test ); + if( g_bAltDragManipulatorResize ){ + Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test ); + m_selected = true; + } + else{ + m_selected = Scene_forEachPlaneSelectable_selectPlanes( GlobalSceneGraph(), selector, test ); + } } } else @@ -3562,7 +3677,12 @@ void RadiantSelectionSystem::endMove(){ if ( Mode() == ePrimitive ) { if ( ManipulatorMode() == eDrag ) { - Scene_SelectAll_Component( false, SelectionSystem::eFace ); + if( g_bAltDragManipulatorResize ){ + Scene_SelectAll_Component( false, SelectionSystem::eVertex ); + } + else{ + Scene_SelectAll_Component( false, SelectionSystem::eFace ); + } } } @@ -4157,7 +4277,8 @@ void onMouseDown( const WindowVector& position, ButtonIdentifier button, Modifie //m_selector.m_mouseMoved = false; DeviceVector devicePosition( window_to_normalised_device( position, m_width, m_height ) ); - if ( modifiers == c_modifier_manipulator && m_manipulator.mouseDown( devicePosition ) ) { + g_bAltDragManipulatorResize = ( modifiers == c_modifierAlt ) ? true : false; + if ( ( modifiers == c_modifier_manipulator || modifiers == c_modifierAlt ) && m_manipulator.mouseDown( devicePosition ) ) { g_mouseMovedCallback.insert( MouseEventCallback( Manipulator_::MouseMovedCaller( m_manipulator ) ) ); g_mouseUpCallback.insert( MouseEventCallback( Manipulator_::MouseUpCaller( m_manipulator ) ) ); } diff --git a/radiant/texwindow.cpp b/radiant/texwindow.cpp index ef2ae005..366019ca 100644 --- a/radiant/texwindow.cpp +++ b/radiant/texwindow.cpp @@ -1666,6 +1666,8 @@ void TextureBrowser_createContextMenu( GtkWidget *treeview, GdkEventButton *even gdk_event_get_time( (GdkEvent*)event ) ); } +void TextureBrowser_searchTags(); + gboolean TreeViewTags_onButtonPressed( GtkWidget *treeview, GdkEventButton *event ){ if ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) { GtkTreePath *path; @@ -1680,6 +1682,10 @@ gboolean TreeViewTags_onButtonPressed( GtkWidget *treeview, GdkEventButton *even TextureBrowser_createContextMenu( treeview, event ); return TRUE; } + if( event->type == GDK_2BUTTON_PRESS && event->button == 1 ){ + TextureBrowser_searchTags(); + return TRUE; + } return FALSE; } -- 2.39.2