robust algorithm for indirect Brush faces selection
This commit is contained in:
parent
ed50787ee8
commit
73605bf94b
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
)
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user