diff --git a/libs/dragplanes.h b/libs/dragplanes.h index bc7e54ff..27ea803b 100644 --- a/libs/dragplanes.h +++ b/libs/dragplanes.h @@ -125,18 +125,8 @@ void selectPlanes( const AABB& aabb, Selector& selector, SelectionTest& test, co for ( std::size_t i = 0; i < 6; ++i ){ const std::size_t index = i * 4; const Vector3 centroid = vector3_mid( corners[indices[index]], corners[indices[index + 2]] ); - const Vector3 projected = vector4_projected( - matrix4_transformed_vector4( - test.getVolume().GetViewMatrix(), - Vector4( centroid, 1 ) - ) - ); - const Vector3 closest_point = vector4_projected( - matrix4_transformed_vector4( - test.getScreen2world(), - Vector4( 0, 0, projected[2], 1 ) - ) - ); + const Vector3 projected = vector4_projected( matrix4_transformed_vector4( test.getVolume().GetViewMatrix(), Vector4( centroid, 1 ) ) ); + const Vector3 closest_point = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, projected[2], 1 ) ) ); if ( vector3_dot( planes[i].normal(), closest_point - corners[indices[index]] ) > 0 && vector3_dot( planes[i].normal(), closest_point - corners[indices[index + 1]] ) > 0 && vector3_dot( planes[i].normal(), closest_point - corners[indices[index + 2]] ) > 0 diff --git a/radiant/brush.h b/radiant/brush.h index be0a0847..d2630028 100644 --- a/radiant/brush.h +++ b/radiant/brush.h @@ -2721,18 +2721,8 @@ void selectReversedPlane( Selector& selector, const SelectedPlanes& selectedPlan } bool trySelectPlane( const SelectionTest& test ){ - const Vector3 projected = vector4_projected( - matrix4_transformed_vector4( - test.getVolume().GetViewMatrix(), - Vector4( getFace().centroid(), 1 ) - ) - ); - const Vector3 closest_point = vector4_projected( - matrix4_transformed_vector4( - test.getScreen2world(), - Vector4( 0, 0, projected[2], 1 ) - ) - ); + const Vector3 projected = vector4_projected( matrix4_transformed_vector4( test.getVolume().GetViewMatrix(), Vector4( getFace().centroid(), 1 ) ) ); + const Vector3 closest_point = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, projected[2], 1 ) ) ); for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i ){ if ( vector3_dot( getFace().plane3().normal(), closest_point - ( *i ).vertex ) < 0.005 ) /* epsilon to prevent almost perpendicular faces pickup */ return false; diff --git a/radiant/brushmanip.cpp b/radiant/brushmanip.cpp index 53184c1b..eeaf9b9a 100644 --- a/radiant/brushmanip.cpp +++ b/radiant/brushmanip.cpp @@ -42,6 +42,13 @@ void Brush_ConstructCuboid( Brush& brush, const AABB& bounds, const char* shader Vector3 mins( vector3_subtracted( bounds.origin, bounds.extents ) ); Vector3 maxs( vector3_added( bounds.origin, bounds.extents ) ); + for( std::size_t i = 0; i < 3; ++i ){ + if( mins[i] < g_MinWorldCoord ) + mins[i] = g_MinWorldCoord; + if( maxs[i] > g_MaxWorldCoord ) + maxs[i] = g_MaxWorldCoord; + } + brush.clear(); brush.reserve( 6 ); @@ -823,15 +830,29 @@ void Scene_BrushConstructPrefab( scene::Graph& graph, EBrushPrefab type, std::si } } -void Scene_BrushResize_Selected( scene::Graph& graph, const AABB& bounds, const char* shader ){ - if ( GlobalSelectionSystem().countSelected() != 0 ) { - const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path(); +#include "filterbar.h" +extern bool g_brush_always_caulk; - Brush* brush = Node_getBrush( path.top() ); - if ( brush != 0 ) { - Brush_ConstructCuboid( *brush, bounds, shader, TextureTransform_getDefault() ); - SceneChangeNotify(); - } +void Scene_BrushResize_Cuboid( scene::Node*& node, const AABB& bounds ){ + if ( node == 0 ) { + NodeSmartReference node_( GlobalBrushCreator().createBrush() ); + Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( node_ ); + + scene::Path brushpath( makeReference( GlobalSceneGraph().root() ) ); + brushpath.push( makeReference( *Map_GetWorldspawn( g_map ) ) ); + brushpath.push( makeReference( node_.get() ) ); + selectPath( brushpath, true ); + + node = node_.get_pointer(); + } + + Brush* brush = Node_getBrush( *node ); + if ( brush != 0 ) { + const char* shader = g_brush_always_caulk? + GetCaulkShader() + : TextureBrowser_GetSelectedShader( GlobalTextureBrowser() ); + Brush_ConstructCuboid( *brush, bounds, shader, TextureTransform_getDefault() ); + SceneChangeNotify(); } } diff --git a/radiant/brushmanip.h b/radiant/brushmanip.h index b4527eb4..0ac510ec 100644 --- a/radiant/brushmanip.h +++ b/radiant/brushmanip.h @@ -45,7 +45,7 @@ class Node; } void Scene_BrushConstructPrefab( scene::Graph& graph, EBrushPrefab type, std::size_t sides, const char* shader ); class AABB; -void Scene_BrushResize_Selected( scene::Graph& graph, const AABB& bounds, const char* shader ); +void Scene_BrushResize_Cuboid( scene::Node*& node, const AABB& bounds ); void Brush_ConstructPlacehoderCuboid( scene::Node& node, const AABB& bounds ); void Scene_BrushSetTexdef_Selected( scene::Graph& graph, const TextureProjection& projection, bool setBasis, bool resetBasis ); void Scene_BrushSetTexdef_Component_Selected( scene::Graph& graph, const TextureProjection& projection, bool setBasis, bool resetBasis ); diff --git a/radiant/brushmodule.cpp b/radiant/brushmodule.cpp index ec68777c..3319ad3a 100644 --- a/radiant/brushmodule.cpp +++ b/radiant/brushmodule.cpp @@ -38,7 +38,7 @@ LatchedBool g_useAlternativeTextureProjection( false, "Use alternative texture-p bool g_multipleBrushTypes = false; EBrushType g_brushTypes[3]; int g_brushType; -bool g_brush_always_caulk; +bool g_brush_always_caulk = false; bool getTextureLockEnabled(){ return g_brush_texturelock_enabled; diff --git a/radiant/selection.cpp b/radiant/selection.cpp index 690a32e3..d3bcc127 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -186,7 +186,7 @@ class Manipulatable { public: virtual void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ) = 0; -virtual void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ) = 0; +virtual void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ) = 0; }; void transform_local2object( Matrix4& object, const Matrix4& local, const Matrix4& local2object ){ @@ -214,7 +214,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const point_on_sphere( m_start, device2manip, x, y ); vector3_normalise( m_start ); } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ Vector3 current; point_on_sphere( current, device2manip, x, y ); @@ -252,7 +252,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const constrain_to_axis( m_start, m_axis ); } /// \brief Converts current position to a normalised vector orthogonal to axis. -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ Vector3 current; point_on_sphere( current, device2manip, x, y ); constrain_to_axis( current, m_axis ); @@ -285,7 +285,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const constrain_to_axis( m_start, m_axis ); } /// \brief Converts current position to a normalised vector orthogonal to axis. -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ Vector3 current; point_on_sphere( current, device2manip, x, y, g_origin, m_radius ); constrain_to_axis( current, m_axis ); @@ -325,7 +325,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const constrain_to_axis( m_start, m_axis ); } /// \brief Converts current position to a normalised vector orthogonal to axis. -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ Vector3 current; point_on_sphere( current, device2manip, x, y, m_sphere_origin ); current -= m_sphere_origin; @@ -375,21 +375,20 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const point_on_axis( m_start, m_axis, device2manip, x, y ); m_bounds = bounds; } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ Vector3 current; point_on_axis( current, m_axis, device2manip, x, y ); current = vector3_scaled( m_axis, distance_for_axis( m_start, current, m_axis ) ); translation_local2object( current, current, manip2object ); if( snapbbox ){ - float grid = GetSnapGridSize(); - Vector3 maxs( m_bounds.origin + m_bounds.extents ); - Vector3 mins( m_bounds.origin - m_bounds.extents ); + const Vector3 maxs( m_bounds.origin + m_bounds.extents ); + const Vector3 mins( m_bounds.origin - m_bounds.extents ); // globalOutputStream() << "current: " << current << "\n"; for( std::size_t i = 0; i < 3; ++i ){ if( m_axis[i] != 0.f ){ - float snapto1 = float_snapped( maxs[i] + current[i] , grid ); - float snapto2 = float_snapped( mins[i] + current[i] , grid ); + float snapto1 = float_snapped( maxs[i] + current[i] , GetSnapGridSize() ); + float snapto2 = float_snapped( mins[i] + current[i] , GetSnapGridSize() ); float dist1 = fabs( fabs( maxs[i] + current[i] ) - fabs( snapto1 ) ); float dist2 = fabs( fabs( mins[i] + current[i] ) - fabs( snapto2 ) ); @@ -426,7 +425,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const point_on_plane( m_start, device2manip, x, y ); m_bounds = bounds; } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ Vector3 current; point_on_plane( current, device2manip, x, y ); current = vector3_subtracted( current, m_start ); @@ -444,14 +443,13 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const translation_local2object( current, current, manip2object ); if( snapbbox ){ - float grid = GetSnapGridSize(); - Vector3 maxs( m_bounds.origin + m_bounds.extents ); - Vector3 mins( m_bounds.origin - m_bounds.extents ); + const Vector3 maxs( m_bounds.origin + m_bounds.extents ); + const Vector3 mins( m_bounds.origin - m_bounds.extents ); //globalOutputStream() << "current: " << current << "\n"; for( std::size_t i = 0; i < 3; ++i ){ if( fabs( current[i] ) > 1e-6f ){ - float snapto1 = float_snapped( maxs[i] + current[i] , grid ); - float snapto2 = float_snapped( mins[i] + current[i] , grid ); + float snapto1 = float_snapped( maxs[i] + current[i] , GetSnapGridSize() ); + float snapto2 = float_snapped( mins[i] + current[i] , GetSnapGridSize() ); float dist1 = fabs( fabs( maxs[i] + current[i] ) - fabs( snapto1 ) ); float dist2 = fabs( fabs( mins[i] + current[i] ) - fabs( snapto2 ) ); @@ -499,7 +497,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const ); m_bounds = bounds; } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ //globalOutputStream() << "manip2object: " << manip2object << " device2manip: " << device2manip << " x: " << x << " y:" << y <<"\n"; Vector3 current; point_on_axis( current, m_axis, device2manip, x, y ); @@ -573,7 +571,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const ); m_bounds = bounds; } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ Vector3 current; point_on_plane( current, device2manip, x, y ); Vector3 delta = vector3_subtracted( current, m_start ); @@ -669,7 +667,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const m_bounds = bounds; m_axis_by_extent = bounds.origin[m_axis_by] + bounds.extents[m_axis_by] * m_axis_by_sign - transform_origin[m_axis_by]; } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ Vector3 current; point_on_axis( current, m_axis_which, device2manip, x, y ); current = vector3_scaled( m_axis_which, distance_for_axis( m_start, current, m_axis_which ) ); @@ -688,7 +686,60 @@ void SetAxes( const Vector3& axis_which, int axis_by, int axis_by_sign ){ } }; +#include "brushmanip.h" +class DragNewBrush : public Manipulatable +{ +private: +Vector3 m_start; +Vector3 m_0; +Vector3 m_size; +scene::Node* m_newBrushNode; +public: +DragNewBrush(){ +} +void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){ + point_on_plane( m_start, device2manip, x, y ); + m_size[0] = m_size[1] = m_size[2] = GetGridSize(); + m_newBrushNode = 0; +} +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ + Vector3 current; + point_on_plane( current, device2manip, x, y ); + current = vector3_subtracted( current, m_start ); + translation_local2object( current, current, manip2object ); + Vector3 current_snapped = vector3_snapped( current, GetSnapGridSize() ); + for ( std::size_t i = 0; i < 3; ++i ) + if( current_snapped[i] == 0 ) + current_snapped[i] = current[i] < 0? -GetGridSize() : GetGridSize(); + if( alt ){ + current_snapped.x() = m_size.x(); + current_snapped.y() = m_size.y(); + } + else{ + current_snapped.z() = m_size.z(); + } + if( snap || snapbbox ){ + const float squaresize = std::max( fabs( current_snapped.x() ), fabs( current_snapped.y() ) ); + current_snapped.x() = current_snapped.x() > 0? squaresize : -squaresize; + current_snapped.y() = current_snapped.y() > 0? squaresize : -squaresize; + if( snapbbox && !alt ) + current_snapped.z() = current_snapped.z() > 0? squaresize : -squaresize; + } + m_size = current_snapped; + + Vector3 mins( m_0 ); + Vector3 maxs( current_snapped + m_0 ); + for ( std::size_t i = 0; i < 3; ++i ) + if( mins[i] > maxs[i] ) + std::swap( mins[i], maxs[i] ); + + Scene_BrushResize_Cuboid( m_newBrushNode, aabb_for_minmax( mins, maxs ) ); +} +void set0( const Vector3& start ){ + m_0 = start; +} +}; @@ -870,13 +921,6 @@ void BestPoint( std::size_t count, Vector4 clipped[9], SelectionIntersection& be } } -// if( cull == eClipCullCW ){ -// globalOutputStream() << "eClipCullCW\n"; -// } -// else if( cull == eClipCullCCW ){ -// globalOutputStream() << "eClipCullCCW\n"; -// } - if ( cull != eClipCullNone && count > 2 ) { double signed_area = triangle_signed_area_XY( normalised[0], normalised[1], normalised[2] ); @@ -2340,18 +2384,8 @@ public: for ( int j = 0; j < 2; ++j ){ const Vector3 normal = j? g_vector3_axes[i] : -g_vector3_axes[i]; const Vector3 centroid = m_bounds.origin + m_bounds.extents * normal; - const Vector3 projected = vector4_projected( - matrix4_transformed_vector4( - view.GetViewMatrix(), - Vector4( centroid, 1 ) - ) - ); - const Vector3 closest_point = vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( 0, 0, projected[2], 1 ) - ) - ); + const Vector3 projected = vector4_projected( matrix4_transformed_vector4( view.GetViewMatrix(), Vector4( centroid, 1 ) ) ); + const Vector3 closest_point = vector4_projected( matrix4_transformed_vector4( screen2world, Vector4( 0, 0, projected[2], 1 ) ) ); const int index = i * 8 + j * 4; if( vector3_dot( normal, closest_point - corners[indices[index]] ) > 0 @@ -3456,6 +3490,39 @@ std::list& best(){ } }; +class BestPointSelector : public Selector +{ +bool m_selected; +SelectionIntersection m_intersection; +SelectionIntersection m_bestIntersection; +Selectable* m_selectable; +public: +BestPointSelector() : m_selected( false ), m_bestIntersection( SelectionIntersection() ){ +} + +void pushSelectable( Selectable& selectable ){ + m_intersection = SelectionIntersection(); +} +void popSelectable(){ + if ( m_intersection.valid() ) + m_selected = true; + if ( m_intersection < m_bestIntersection ) + m_bestIntersection = m_intersection; + m_intersection = SelectionIntersection(); +} +void addIntersection( const SelectionIntersection& intersection ){ + assign_if_closer( m_intersection, intersection ); +} + +bool isSelected(){ + return m_selected; +} +const SelectionIntersection& best(){ + return m_bestIntersection; +} +}; + + bool g_bAltResize_AltSelect = false; //AltDragManipulatorResize + select primitives in component modes bool g_bTmpComponentMode = false; @@ -3465,94 +3532,101 @@ TranslateFree m_freeResize; TranslateFree m_freeDrag; ResizeTranslatable m_resize; DragTranslatable m_drag; -SelectableBool m_dragSelectable; //drag already selected stuff +DragNewBrush m_dragNewBrush; +bool m_dragSelected; //drag selected primitives or components +bool m_selected; //components selected temporally for drag +bool m_newBrush; +Matrix4& m_pivot2world; + public: -bool m_selected; //selected temporally for drag - -DragManipulator() : m_freeResize( m_resize ), m_freeDrag( m_drag ), m_selected( false ){ +DragManipulator( Matrix4& pivot2world ) : m_freeResize( m_resize ), m_freeDrag( m_drag ), m_selected( false ), m_newBrush( false ), m_pivot2world( pivot2world ){ } Manipulatable* GetManipulatable(){ - return m_dragSelectable.isSelected() ? &m_freeDrag : &m_freeResize; + if( m_newBrush ) + return &m_dragNewBrush; + else + return m_dragSelected? &m_freeDrag : &m_freeResize; } void testSelect( const View& view, const Matrix4& pivot2world ){ SelectionPool selector; - SelectionVolume test( view ); - if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ) { - BooleanSelector booleanSelector; + if( GlobalSelectionSystem().countSelected() != 0 ){ + if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){ + BooleanSelector booleanSelector; + Scene_TestSelect_Primitive( booleanSelector, test, view ); - Scene_TestSelect_Primitive( booleanSelector, test, view ); - - if ( booleanSelector.isSelected() ) { - if( g_bAltResize_AltSelect ){ - 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_forEachTestedBrushFace_selectVertices( GlobalSceneGraph(), test ); //drag clicked face - //Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test ); + if ( booleanSelector.isSelected() ) { /* hit a primitive */ + if( g_bAltResize_AltSelect ){ + DeepBestSelector deepSelector; + Scene_TestSelect_Component_Selected( deepSelector, test, view, SelectionSystem::eVertex ); /* try to quickly select hit vertices */ + for ( std::list::iterator i = deepSelector.best().begin(); i != deepSelector.best().end(); ++i ) + selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) ); + if( deepSelector.best().empty() ) /* otherwise drag clicked face's vertices */ + Scene_forEachTestedBrushFace_selectVertices( GlobalSceneGraph(), test ); m_selected = true; } + else{ /* drag a primitive */ + m_dragSelected = true; + } } - else{ - selector.addSelectable( SelectionIntersection( 0, 0 ), &m_dragSelectable ); - m_selected = false; + else{ /* haven't hit a primitive */ + if( g_bAltResize_AltSelect ){ + Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test ); /* select vertices on planeSelectables */ + m_selected = true; + } + else{ + m_selected = Scene_forEachPlaneSelectable_selectPlanes( GlobalSceneGraph(), selector, test ); /* select faces on planeSelectables */ + } } } - else - { - if( g_bAltResize_AltSelect ){ - Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test ); - m_selected = true; - } - else{ - m_selected = Scene_forEachPlaneSelectable_selectPlanes( GlobalSceneGraph(), selector, test ); + else{ + BestSelector bestSelector; + Scene_TestSelect_Component_Selected( bestSelector, test, view, GlobalSelectionSystem().ComponentMode() ); /* drag components */ + for ( std::list::iterator i = bestSelector.best().begin(); i != bestSelector.best().end(); ++i ){ + if ( !( *i )->isSelected() ) + GlobalSelectionSystem().setSelectedAllComponents( false ); + selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) ); + m_dragSelected = true; } + if( GlobalSelectionSystem().countSelectedComponents() != 0 ) /* even if hit nothing, but got selected */ + m_dragSelected = true; } - } - else - { - BestSelector bestSelector; - Scene_TestSelect_Component_Selected( bestSelector, test, view, GlobalSelectionSystem().ComponentMode() ); - for ( std::list::iterator i = bestSelector.best().begin(); i != bestSelector.best().end(); ++i ) - { - if ( !( *i )->isSelected() ) { - GlobalSelectionSystem().setSelectedAllComponents( false ); - } - m_selected = false; - selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) ); - m_dragSelectable.setSelected( true ); - } - if( GlobalSelectionSystem().countSelectedComponents() != 0 ){ - m_dragSelectable.setSelected( true ); - } - } - for ( SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i ) - { - ( *i ).second->setSelected( true ); + for ( SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i ) + ( *i ).second->setSelected( true ); + g_bTmpComponentMode = m_selected; + } + else if( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){ + m_newBrush = true; + BestPointSelector bestPointSelector; + Scene_TestSelect_Primitive( bestPointSelector, test, view ); + Vector3 start; + test.BeginMesh( g_matrix4_identity, true ); + if( bestPointSelector.isSelected() ){ + start = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, bestPointSelector.best().depth(), 1 ) ) ); + } + else{ + const Vector3 near = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, -1, 1 ) ) ); + const Vector3 far = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, 1, 1 ) ) ); + start = vector3_normalised( far - near ) * 256.f + near; + } + vector3_snap( start, GetSnapGridSize() ); + m_dragNewBrush.set0( start ); + m_pivot2world = matrix4_translation_for_vec3( start ); } - g_bTmpComponentMode = m_selected; } void setSelected( bool select ){ + m_dragSelected = select; m_selected = select; - m_dragSelectable.setSelected( select ); + m_newBrush = select; } bool isSelected() const { - return m_selected || m_dragSelectable.isSelected(); + return m_dragSelected || m_selected || m_newBrush; } }; @@ -3590,7 +3664,7 @@ TransformOriginTranslate( TransformOriginTranslatable& transformOriginTranslatab void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){ point_on_plane( m_start, device2manip, x, y ); } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ Vector3 current; point_on_plane( current, device2manip, x, y ); current = vector3_subtracted( current, m_start ); @@ -3838,6 +3912,7 @@ RadiantSelectionSystem() : m_rotate_manipulator( *this, 8, 64 ), m_scale_manipulator( *this, 0, 64 ), m_skew_manipulator( *this, *this, *this, *this, m_bounds, m_pivot2world, m_pivotIsCustom ), + m_drag_manipulator( m_pivot2world ), m_transformOrigin_manipulator( *this, m_pivotIsCustom ), m_pivotChanged( false ), m_pivot_moving( false ), @@ -3979,7 +4054,7 @@ void startMove(){ bool SelectManipulator( const View& view, const float device_point[2], const float device_epsilon[2] ){ bool movingOrigin = false; - if ( !nothingSelected() || ( ManipulatorMode() == eDrag && Mode() == eComponent ) ) { + if ( !nothingSelected() || ManipulatorMode() == eDrag ) { #if defined ( DEBUG_SELECTION ) g_render_clipped.destroy(); #endif @@ -3987,7 +4062,7 @@ bool SelectManipulator( const View& view, const float device_point[2], const flo m_transformOrigin_manipulator.setSelected( false ); m_manipulator->setSelected( false ); - if ( !nothingSelected() || ( ManipulatorMode() == eDrag && Mode() == eComponent ) ) { + { View scissored( view ); ConstructSelectionTest( scissored, SelectionBoxForPoint( device_point, device_epsilon ) ); @@ -4442,7 +4517,7 @@ void transformOriginTranslate( const Vector3& translation, const bool set[3] ){ SceneChangeNotify(); } -void MoveSelected( const View& view, const float device_point[2], bool snap, bool snapbbox ){ +void MoveSelected( const View& view, const float device_point[2], bool snap, bool snapbbox, bool alt ){ if ( m_manipulator->isSelected() ) { if ( !m_undo_begun ) { m_undo_begun = true; @@ -4451,12 +4526,12 @@ void MoveSelected( const View& view, const float device_point[2], bool snap, boo Matrix4 device2manip; ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() ); - m_manipulator->GetManipulatable()->Transform( m_manip2pivot_start, device2manip, device_point[0], device_point[1], snap, snapbbox ); + m_manipulator->GetManipulatable()->Transform( m_manip2pivot_start, device2manip, device_point[0], device_point[1], snap, snapbbox, alt ); } else if( m_transformOrigin_manipulator.isSelected() ){ Matrix4 device2manip; ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() ); - m_transformOrigin_manipulator.GetManipulatable()->Transform( m_manip2pivot_start, device2manip, device_point[0], device_point[1], snap, snapbbox ); + m_transformOrigin_manipulator.GetManipulatable()->Transform( m_manip2pivot_start, device2manip, device_point[0], device_point[1], snap, snapbbox, alt ); } } @@ -4641,10 +4716,8 @@ void RadiantSelectionSystem::Scene_TestSelect( Selector& selector, SelectionTest switch ( mode ) { case eEntity: - { Scene_forEachVisible( GlobalSceneGraph(), view, testselect_entity_visible( selector, test ) ); - } - break; + break; case ePrimitive: Scene_TestSelect_Primitive( selector, test, view ); break; @@ -4685,16 +4758,9 @@ bool RadiantSelectionSystem::endMove(){ freezeTransforms(); - if ( Mode() == ePrimitive ) { - if ( ManipulatorMode() == eDrag ) { - g_bTmpComponentMode = false; - if( g_bAltResize_AltSelect ){ - Scene_SelectAll_Component( false, SelectionSystem::eVertex ); - } - else{ - Scene_SelectAll_Component( false, SelectionSystem::eFace ); - } - } + if ( Mode() == ePrimitive && ManipulatorMode() == eDrag ) { + g_bTmpComponentMode = false; + Scene_SelectAll_Component( false, g_bAltResize_AltSelect? SelectionSystem::eVertex : SelectionSystem::eFace ); } m_pivot_moving = false; @@ -5275,7 +5341,9 @@ bool mouseDown( DeviceVector position ){ void mouseMoved( DeviceVector position ){ if( m_mouseMovedWhilePressed ) - getSelectionSystem().MoveSelected( *m_view, &position[0], ( m_state & c_modifierShift ) == c_modifierShift, ( m_state & c_modifierControl ) == c_modifierControl ); + getSelectionSystem().MoveSelected( *m_view, &position[0], bitfield_enabled( m_state, c_modifierShift ), + bitfield_enabled( m_state, c_modifierControl ), + bitfield_enabled( m_state, c_modifierAlt ) ); } typedef MemberCaller1 MouseMovedCaller; diff --git a/radiant/surfacedialog.cpp b/radiant/surfacedialog.cpp index a76a4f30..a6ba5c74 100644 --- a/radiant/surfacedialog.cpp +++ b/radiant/surfacedialog.cpp @@ -1631,43 +1631,40 @@ public: BrushGetClosestFaceVisibleWalker( SelectionTest& test, Texturable& texturable, bool seamless, bool project ) : m_test( test ), m_texturable( texturable ), m_seamless( seamless ), m_project( project ){ } bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( path.top().get().visible() ) { - BrushInstance* brush = Instance_getBrush( instance ); - if ( brush != 0 ) { - m_test.BeginMesh( brush->localToWorld() ); + if ( !path.top().get().visible() ) + return false; + BrushInstance* brush = Instance_getBrush( instance ); + if ( brush != 0 ) { + m_test.BeginMesh( brush->localToWorld() ); - for ( Brush::const_iterator i = brush->getBrush().begin(); i != brush->getBrush().end(); ++i ) - { - Face_getClosest( *( *i ), m_test, m_bestIntersection, m_texturable, m_seamless, m_project ); - } - } - else + for ( Brush::const_iterator i = brush->getBrush().begin(); i != brush->getBrush().end(); ++i ) { - SelectionTestable* selectionTestable = Instance_getSelectionTestable( instance ); - if ( selectionTestable ) { - bool occluded; - OccludeSelector selector( m_bestIntersection, occluded ); - selectionTestable->testSelect( selector, m_test ); - if ( occluded ) { - Patch* patch = Node_getPatch( path.top() ); - if ( patch != 0 ) { - if( m_project ) - m_texturable.setTexture = makeCallback3( PatchSetTextureProject(), *patch ); - else - m_texturable.setTexture = makeCallback3( PatchSetTexture(), *patch ); - m_texturable.getTexture = makeCallback3( PatchGetTexture(), *patch ); - } + Face_getClosest( *( *i ), m_test, m_bestIntersection, m_texturable, m_seamless, m_project ); + } + } + else + { + SelectionTestable* selectionTestable = Instance_getSelectionTestable( instance ); + if ( selectionTestable ) { + bool occluded; + OccludeSelector selector( m_bestIntersection, occluded ); + selectionTestable->testSelect( selector, m_test ); + if ( occluded ) { + Patch* patch = Node_getPatch( path.top() ); + if ( patch != 0 ) { + if( m_project ) + m_texturable.setTexture = makeCallback3( PatchSetTextureProject(), *patch ); else - { - m_texturable = Texturable(); - } + m_texturable.setTexture = makeCallback3( PatchSetTexture(), *patch ); + m_texturable.getTexture = makeCallback3( PatchGetTexture(), *patch ); + } + else + { + m_texturable = Texturable(); } } } } - else{ - return false; - } return true; } }; diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index e5ff579b..4fdf7dc2 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -75,9 +75,6 @@ void LoadTextureRGBA( qtexture_t* q, unsigned char* pPixels, int nWidth, int nHeight ); -// d1223m -extern bool g_brush_always_caulk; - bool g_bCamEntityMenu = false; //!\todo Rewrite. @@ -1206,7 +1203,7 @@ void XYWnd::NewBrushDrag( int x, int y, bool square, bool cube ){ XY_ToPoint( x, y, maxs ); XY_SnapToGrid( maxs ); - int nDim = ( m_viewType == XY ) ? 2 : ( m_viewType == YZ ) ? 0 : 1; + const int nDim = ( m_viewType == XY ) ? 2 : ( m_viewType == YZ ) ? 0 : 1; mins[nDim] = float_snapped( Select_getWorkZone().d_work_min[nDim], GetSnapGridSize() ); maxs[nDim] = float_snapped( Select_getWorkZone().d_work_max[nDim], GetSnapGridSize() ); @@ -1216,7 +1213,7 @@ void XYWnd::NewBrushDrag( int x, int y, bool square, bool cube ){ } if( square || cube ){ - float squaresize = std::max( fabs( maxs[(nDim + 1) % 3] - mins[(nDim + 1) % 3] ), fabs( maxs[(nDim + 2) % 3] - mins[(nDim + 2) % 3] ) ); + const float squaresize = std::max( fabs( maxs[(nDim + 1) % 3] - mins[(nDim + 1) % 3] ), fabs( maxs[(nDim + 2) % 3] - mins[(nDim + 2) % 3] ) ); maxs[(nDim + 1) % 3] = ( maxs[(nDim + 1) % 3] - mins[(nDim + 1) % 3] ) > 0.f ? ( mins[(nDim + 1) % 3] + squaresize ) : ( mins[(nDim + 1) % 3] - squaresize ); maxs[(nDim + 2) % 3] = ( maxs[(nDim + 2) % 3] - mins[(nDim + 2) % 3] ) > 0.f ? ( mins[(nDim + 2) % 3] + squaresize ) : ( mins[(nDim + 2) % 3] - squaresize ); if( cube ){ @@ -1226,34 +1223,16 @@ void XYWnd::NewBrushDrag( int x, int y, bool square, bool cube ){ for ( int i = 0 ; i < 3 ; i++ ) { - if ( mins[i] == maxs[i] ) { + if ( mins[i] == maxs[i] ) return; // don't create a degenerate brush - } - if ( mins[i] > maxs[i] ) { - float temp = mins[i]; - mins[i] = maxs[i]; - maxs[i] = temp; - } + if ( mins[i] > maxs[i] ) + std::swap( mins[i], maxs[i] ); } - if ( m_NewBrushDrag == 0 ) { + if ( m_NewBrushDrag == 0 ) GlobalUndoSystem().start(); - NodeSmartReference node( GlobalBrushCreator().createBrush() ); - Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( node ); - scene::Path brushpath( makeReference( GlobalSceneGraph().root() ) ); - brushpath.push( makeReference( *Map_GetWorldspawn( g_map ) ) ); - brushpath.push( makeReference( node.get() ) ); - selectPath( brushpath, true ); - - m_NewBrushDrag = node.get_pointer(); - } - - // d1223m - //Scene_BrushResize_Selected(GlobalSceneGraph(), aabb_for_minmax(mins, maxs), TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - Scene_BrushResize_Selected( GlobalSceneGraph(), aabb_for_minmax( mins, maxs ), - g_brush_always_caulk ? - GetCaulkShader() : TextureBrowser_GetSelectedShader( GlobalTextureBrowser() ) ); + Scene_BrushResize_Cuboid( m_NewBrushDrag, aabb_for_minmax( mins, maxs ) ); } int g_entityCreationOffset = 0;