From: Garux Date: Wed, 2 Aug 2017 06:13:12 +0000 (+0300) Subject: Radiant: X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=0709fce07d9c630ca0455ebeb58e3806427ca8ce;p=xonotic%2Fnetradiant.git Radiant: binds... * m1 + ctrl drag: snap bbox during manipulators manipulations: drag axis, freedrag: snap bbox edges to grid on dragged axes; allows more varied snappings, then SnapToGrid command scale axis, scale free: snap bbox size on scaled axes to grid misc... * QE tool in a component mode: perform drag w/o hitting any handle too --- diff --git a/radiant/selection.cpp b/radiant/selection.cpp index 13255cfc..a3df8a31 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -192,8 +192,8 @@ float distance_for_axis( const Vector3& a, const Vector3& b, const Vector3& axis class Manipulatable { public: -virtual void Construct( const Matrix4& device2manip, const float x, const float y ) = 0; -virtual void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap ) = 0; +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; }; void transform_local2object( Matrix4& object, const Matrix4& local, const Matrix4& local2object ){ @@ -217,11 +217,11 @@ public: RotateFree( Rotatable& rotatable ) : m_rotatable( rotatable ){ } -void Construct( const Matrix4& device2manip, const float x, const float y ){ +void Construct( const Matrix4& device2manip, const float x, const float y, const AABB bounds, const Vector3 transform_origin ){ 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 ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ Vector3 current; point_on_sphere( current, device2manip, x, y ); @@ -254,12 +254,12 @@ public: RotateAxis( Rotatable& rotatable ) : m_rotatable( rotatable ){ } -void Construct( const Matrix4& device2manip, const float x, const float y ){ +void Construct( const Matrix4& device2manip, const float x, const float y, const AABB bounds, const Vector3 transform_origin ){ point_on_sphere( m_start, device2manip, x, y ); 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 ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ Vector3 current; point_on_sphere( current, device2manip, x, y ); constrain_to_axis( current, m_axis ); @@ -297,20 +297,43 @@ class TranslateAxis : public Manipulatable Vector3 m_start; Vector3 m_axis; Translatable& m_translatable; +AABB m_bounds; public: TranslateAxis( Translatable& translatable ) : m_translatable( translatable ){ } -void Construct( const Matrix4& device2manip, const float x, const float y ){ +void Construct( const Matrix4& device2manip, const float x, const float y, const AABB bounds, const Vector3 transform_origin ){ 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 ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ 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 ); - vector3_snap( current, GetSnapGridSize() ); + if( snapbbox ){ + float grid = GetSnapGridSize(); + Vector3 maxs( m_bounds.origin + m_bounds.extents ); + 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 dist1 = fabs( fabs( maxs[i] + current[i] ) - fabs( snapto1 ) ); + float dist2 = fabs( fabs( mins[i] + current[i] ) - fabs( snapto2 ) ); + +// globalOutputStream() << "maxs[i] + current[i]: " << maxs[i] + current[i] << " snapto1: " << snapto1 << " dist1: " << dist1 << "\n"; +// globalOutputStream() << "mins[i] + current[i]: " << mins[i] + current[i] << " snapto2: " << snapto2 << " dist2: " << dist2 << "\n"; + current[i] = dist2 > dist1 ? snapto1 - maxs[i] : snapto2 - mins[i]; + } + } + } + else{ + vector3_snap( current, GetSnapGridSize() ); + } m_translatable.translate( current ); } @@ -325,14 +348,16 @@ class TranslateFree : public Manipulatable private: Vector3 m_start; Translatable& m_translatable; +AABB m_bounds; public: TranslateFree( Translatable& translatable ) : m_translatable( translatable ){ } -void Construct( const Matrix4& device2manip, const float x, const float y ){ +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_bounds = bounds; } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ Vector3 current; point_on_plane( current, device2manip, x, y ); current = vector3_subtracted( current, m_start ); @@ -349,15 +374,31 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const } translation_local2object( current, current, manip2object ); - vector3_snap( current, GetSnapGridSize() ); + if( snapbbox ){ + float grid = GetSnapGridSize(); + Vector3 maxs( m_bounds.origin + m_bounds.extents ); + Vector3 mins( m_bounds.origin - m_bounds.extents ); +// globalOutputStream() << "current: " << current << "\n"; + for( std::size_t i = 0; i < 3; ++i ){ + if( current[i] != 0.f ){ + float snapto1 = float_snapped( maxs[i] + current[i] , grid ); + float snapto2 = float_snapped( mins[i] + current[i] , grid ); + + float dist1 = fabs( fabs( maxs[i] + current[i] ) - fabs( snapto1 ) ); + float dist2 = fabs( fabs( mins[i] + current[i] ) - fabs( snapto2 ) ); + + current[i] = dist2 > dist1 ? snapto1 - maxs[i] : snapto2 - mins[i]; + } + } + } + else{ + vector3_snap( current, GetSnapGridSize() ); + } m_translatable.translate( current ); } }; -void GetSelectionAABB( AABB& bounds ); -const Matrix4& SelectionSystem_GetPivot2World(); - class Scalable { public: @@ -373,25 +414,23 @@ Vector3 m_axis; Scalable& m_scalable; Vector3 m_choosen_extent; +AABB m_bounds; public: ScaleAxis( Scalable& scalable ) : m_scalable( scalable ){ } -void Construct( const Matrix4& device2manip, const float x, const float y ){ +void Construct( const Matrix4& device2manip, const float x, const float y, const AABB bounds, const Vector3 transform_origin ){ point_on_axis( m_start, m_axis, device2manip, x, y ); - AABB aabb; - GetSelectionAABB( aabb ); - Vector3 transform_origin = vector4_to_vector3( SelectionSystem_GetPivot2World().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] ) + std::max( bounds.origin[0] + bounds.extents[0] - transform_origin[0], - bounds.origin[0] + bounds.extents[0] + transform_origin[0] ), + std::max( bounds.origin[1] + bounds.extents[1] - transform_origin[1], - bounds.origin[1] + bounds.extents[1] + transform_origin[1] ), + std::max( bounds.origin[2] + bounds.extents[2] - transform_origin[2], - bounds.origin[2] + bounds.extents[2] + transform_origin[2] ) ); - + m_bounds = bounds; } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ //globalOutputStream() << "manip2object: " << manip2object << " device2manip: " << device2manip << " x: " << x << " y:" << y <<"\n"; Vector3 current; point_on_axis( current, m_axis, device2manip, x, y ); @@ -414,8 +453,12 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const ); for( std::size_t i = 0; i < 3; i++ ){ - if( m_choosen_extent[i] > 0.0625f ){ //epsilon to prevent super high scale for set of models, having really small extent, formed by origins + if( m_choosen_extent[i] > 0.0625f && m_axis[i] != 0.f ){ //epsilon to prevent super high scale for set of models, having really small extent, formed by origins scale[i] = ( m_choosen_extent[i] + delta[i] ) / m_choosen_extent[i]; + if( snapbbox ){ + float snappdwidth = float_snapped( scale[i] * m_bounds.extents[i] * 2.f, GetSnapGridSize() ); + scale[i] = snappdwidth / ( m_bounds.extents[i] * 2.f ); + } } } if( snap ){ @@ -441,24 +484,23 @@ Vector3 m_start; Scalable& m_scalable; Vector3 m_choosen_extent; +AABB m_bounds; public: ScaleFree( Scalable& scalable ) : m_scalable( scalable ){ } -void Construct( const Matrix4& device2manip, const float x, const float y ){ +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 ); - AABB aabb; - GetSelectionAABB( aabb ); - Vector3 transform_origin = vector4_to_vector3( SelectionSystem_GetPivot2World().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] ) + std::max( bounds.origin[0] + bounds.extents[0] - transform_origin[0], - bounds.origin[0] + bounds.extents[0] + transform_origin[0] ), + std::max( bounds.origin[1] + bounds.extents[1] - transform_origin[1], - bounds.origin[1] + bounds.extents[1] + transform_origin[1] ), + std::max( bounds.origin[2] + bounds.extents[2] - transform_origin[2], - bounds.origin[2] + bounds.extents[2] + transform_origin[2] ) ); + m_bounds = bounds; } -void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap ){ +void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ Vector3 current; point_on_plane( current, device2manip, x, y ); Vector3 delta = vector3_subtracted( current, m_start ); @@ -482,6 +524,10 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const for( std::size_t i = 0; i < 3; i++ ){ if( m_choosen_extent[i] > 0.0625f ){ scale[i] = ( m_choosen_extent[i] + delta[i] ) / m_choosen_extent[i]; + if( snapbbox && start[i] != 0.f ){ + float snappdwidth = float_snapped( scale[i] * m_bounds.extents[i] * 2.f, GetSnapGridSize() ); + scale[i] = snappdwidth / ( m_bounds.extents[i] * 2.f ); + } } } //globalOutputStream() << "pre snap scale: " << scale <<"\n"; @@ -2519,6 +2565,7 @@ DragManipulator() : m_freeResize( m_resize ), m_freeDrag( m_drag ), m_selected( } Manipulatable* GetManipulatable(){ + //globalOutputStream() << ( m_dragSelectable.isSelected() ? "m_freeDrag\n" : "m_freeResize\n" ); return m_dragSelectable.isSelected() ? &m_freeDrag : &m_freeResize; } @@ -2554,6 +2601,9 @@ void testSelect( const View& view, const Matrix4& pivot2world ){ 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 ) @@ -2669,7 +2719,7 @@ Signal1 m_selectionChanged_callbacks; void ConstructPivot() const; void setCustomPivotOrigin( Vector3& point ) const; public: -void getSelectionAABB( AABB& bounds ) const; +AABB getSelectionAABB() const; private: mutable bool m_pivotChanged; bool m_pivot_moving; @@ -2866,7 +2916,7 @@ bool SelectManipulator( const View& view, const float device_point[2], const flo Matrix4 device2manip; ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() ); - m_manipulator->GetManipulatable()->Construct( device2manip, device_point[0], device_point[1] ); + m_manipulator->GetManipulatable()->Construct( device2manip, device_point[0], device_point[1], getSelectionAABB(), vector4_to_vector3( GetPivot2World().t() ) ); m_undo_begun = false; } @@ -3284,7 +3334,7 @@ void scaleSelected( const Vector3& scaling ){ freezeTransforms(); } -void MoveSelected( const View& view, const float device_point[2], bool snap ){ +void MoveSelected( const View& view, const float device_point[2], bool snap, bool snapbbox ){ if ( m_manipulator->isSelected() ) { if ( !m_undo_begun ) { m_undo_begun = true; @@ -3293,7 +3343,7 @@ void MoveSelected( const View& view, const float device_point[2], bool snap ){ 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 ); + m_manipulator->GetManipulatable()->Transform( m_manip2pivot_start, device2manip, device_point[0], device_point[1], snap, snapbbox ); } } @@ -3750,7 +3800,8 @@ void RadiantSelectionSystem::setCustomPivotOrigin( Vector3& point ) const { } } -void RadiantSelectionSystem::getSelectionAABB( AABB& bounds ) const { +AABB RadiantSelectionSystem::getSelectionAABB() const { + AABB bounds; if ( !nothingSelected() ) { if ( Mode() == eComponent ) { Scene_BoundsSelectedComponent( GlobalSceneGraph(), bounds ); @@ -3760,14 +3811,7 @@ void RadiantSelectionSystem::getSelectionAABB( AABB& bounds ) const { Scene_BoundsSelected( GlobalSceneGraph(), bounds ); } } -} - -void GetSelectionAABB( AABB& bounds ){ - getSelectionSystem().getSelectionAABB( bounds ); -} - -const Matrix4& SelectionSystem_GetPivot2World(){ - return getSelectionSystem().GetPivot2World(); + return bounds; } void RadiantSelectionSystem::renderSolid( Renderer& renderer, const VolumeTest& volume ) const { @@ -4043,7 +4087,7 @@ bool mouseDown( DeviceVector position ){ } void mouseMoved( DeviceVector position ){ - getSelectionSystem().MoveSelected( *m_view, &position[0], ( m_state & c_modifierShift ) == c_modifierShift ); + getSelectionSystem().MoveSelected( *m_view, &position[0], ( m_state & c_modifierShift ) == c_modifierShift, ( m_state & c_modifierControl ) == c_modifierControl ); } typedef MemberCaller1 MouseMovedCaller;