diff --git a/include/selectable.h b/include/selectable.h index 44012f12..f8ec32ff 100644 --- a/include/selectable.h +++ b/include/selectable.h @@ -229,6 +229,7 @@ virtual void BeginMesh( const Matrix4& localToWorld, bool twoSided = false ) = 0 virtual const VolumeTest& getVolume() const = 0; virtual const Vector3& getNear() const = 0; virtual const Vector3& getFar() const = 0; +virtual const Matrix4& getScreen2world() const = 0; virtual void TestPoint( const Vector3& point, SelectionIntersection& best ) = 0; virtual void TestPolygon( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best, const DoubleVector3 planepoints[3] ) = 0; virtual void TestLineLoop( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ) = 0; diff --git a/radiant/brush.h b/radiant/brush.h index 3ff3fb26..dbb90b60 100644 --- a/radiant/brush.h +++ b/radiant/brush.h @@ -2720,15 +2720,22 @@ void selectReversedPlane( Selector& selector, const SelectedPlanes& selectedPlan } } -bool trySelectPlane( const Line& line ){ +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 ) + ) + ); for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i ){ - const Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) ); - const double dot = vector3_dot( getFace().plane3().normal(), v ); -// globalOutputStream() << getFace().plane3().normal()[0] << " " << getFace().plane3().normal()[1] << " " << getFace().plane3().normal()[2] << " DOT " << dot << "\n"; - //epsilon to prevent almost perpendicular faces pickup - if ( dot < 0.005 ) { + if ( vector3_dot( getFace().plane3().normal(), closest_point - ( *i ).vertex ) < 0.005 ) /* epsilon to prevent almost perpendicular faces pickup */ return false; - } } return true; } @@ -3549,16 +3556,15 @@ void invertComponentSelection( SelectionSystem::EComponentMode mode ){ void selectPlanes( SelectionTest& test, FaceInstances_ptrs& bestInstances ){ test.BeginMesh( localToWorld() ); - const Line line( test.getNear(), test.getFar() ); - const Vector3 viewer( vector3_normalised( test.getNear() - test.getFar() ) ); + const Vector3 viewdir( vector3_normalised( Vector3( test.getVolume().GetModelview()[2], test.getVolume().GetModelview()[6], test.getVolume().GetModelview()[10] ) ) ); double bestDot = 1; for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i ) { - if( !( *i ).trySelectPlane( line ) ){ + if( !( *i ).trySelectPlane( test ) ){ continue; } - const double dot = fabs( vector3_dot( ( *i ).getFace().plane3().normal(), viewer ) ); + const double dot = fabs( vector3_dot( ( *i ).getFace().plane3().normal(), viewdir ) ); const double diff = bestDot - dot; if( diff > 0.03 ){ bestDot = dot; diff --git a/radiant/selection.cpp b/radiant/selection.cpp index 377d3392..66b60d3d 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -2690,6 +2690,7 @@ const View& m_view; clipcull_t m_cull; Vector3 m_near; Vector3 m_far; +Matrix4 m_screen2world; public: SelectionVolume( const View& view ) : m_view( view ){ @@ -2706,6 +2707,10 @@ const Vector3& getFar() const { return m_far; } +const Matrix4& getScreen2world() const { + return m_screen2world; +} + void BeginMesh( const Matrix4& localToWorld, bool twoSided ){ m_local2view = matrix4_multiplied_by_matrix4( m_view.GetViewMatrix(), localToWorld ); @@ -2714,18 +2719,18 @@ void BeginMesh( const Matrix4& localToWorld, bool twoSided ){ m_cull = twoSided && !m_view.fill() ? eClipCullNone : ( matrix4_handedness( localToWorld ) == MATRIX4_RIGHTHANDED ) ? eClipCullCW : eClipCullCCW; { - Matrix4 screen2world( matrix4_full_inverse( m_local2view ) ); + m_screen2world = matrix4_full_inverse( m_local2view ); m_near = vector4_projected( matrix4_transformed_vector4( - screen2world, + m_screen2world, Vector4( 0, 0, -1, 1 ) ) ); m_far = vector4_projected( matrix4_transformed_vector4( - screen2world, + m_screen2world, Vector4( 0, 0, 1, 1 ) ) );