Radiant:
misc... * selection system: fixes of: selecting point behind point (not perfectly precise distance) selecting occluded objects and faces via direct and indirect hits * select models from back in 2d
This commit is contained in:
parent
6eee961fcc
commit
3f1c97ebeb
|
|
@ -30,25 +30,54 @@
|
|||
|
||||
class SelectionIntersection
|
||||
{
|
||||
float m_depth;
|
||||
//public:
|
||||
double m_depth;
|
||||
float m_distance;
|
||||
double m_depth2;
|
||||
bool m_direct;
|
||||
public:
|
||||
SelectionIntersection() : m_depth( 1 ), m_distance( 2 ){
|
||||
SelectionIntersection() : m_depth( 1 ), m_distance( 2 ), m_depth2( -1 ), m_direct( false ){
|
||||
}
|
||||
SelectionIntersection( float depth, float distance ) : m_depth( depth ), m_distance( distance ){
|
||||
SelectionIntersection( float depth, float distance ) : m_depth( depth ), m_distance( distance ), m_depth2( -1 ), m_direct( distance == 0.f ){
|
||||
}
|
||||
SelectionIntersection( float depth, float distance, float depth2 ) : m_depth( depth ), m_distance( distance ), m_depth2( depth2 ), m_direct( distance == 0.f ){
|
||||
}
|
||||
bool operator<( const SelectionIntersection& other ) const {
|
||||
if ( m_distance != other.m_distance ) {
|
||||
if ( ( m_direct ^ other.m_direct ) ||
|
||||
( !m_direct && !other.m_direct && fabs( m_distance - other.m_distance ) > 1e-3f /*0.00002f*/ ) ) {
|
||||
return m_distance < other.m_distance;
|
||||
}
|
||||
if( !m_direct && !other.m_direct ){
|
||||
if( fabs( m_depth - other.m_depth ) > 1e-6 ){
|
||||
return m_depth < other.m_depth;
|
||||
}
|
||||
else{
|
||||
return m_depth2 > other.m_depth2;
|
||||
}
|
||||
}
|
||||
if ( m_depth != other.m_depth ) {
|
||||
return m_depth < other.m_depth;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool equalEpsilon( const SelectionIntersection& other, float distanceEpsilon, float depthEpsilon ) const {
|
||||
if ( m_direct ^ other.m_direct ) {
|
||||
return false;
|
||||
}
|
||||
if( !m_direct && !other.m_direct ){
|
||||
#if 1
|
||||
return float_equal_epsilon( m_distance, other.m_distance, distanceEpsilon )
|
||||
&& float_equal_epsilon( m_depth, other.m_depth, static_cast<double>( depthEpsilon ) )
|
||||
&& float_equal_epsilon( m_depth2, other.m_depth2, 3e-7 );
|
||||
#else
|
||||
return ( m_distance == other.m_distance )
|
||||
&& ( m_depth == other.m_depth )
|
||||
&& ( m_depth2 == other.m_depth2 );
|
||||
#endif
|
||||
}
|
||||
return float_equal_epsilon( m_distance, other.m_distance, distanceEpsilon )
|
||||
&& float_equal_epsilon( m_depth, other.m_depth, depthEpsilon );
|
||||
&& float_equal_epsilon( m_depth, other.m_depth, static_cast<double>( depthEpsilon ) )
|
||||
&& float_equal_epsilon( m_depth2, other.m_depth2, static_cast<double>( depthEpsilon ) );
|
||||
}
|
||||
float depth() const {
|
||||
return m_depth;
|
||||
|
|
@ -195,6 +224,8 @@ typedef BasicVector3<float> Vector3;
|
|||
class Matrix4;
|
||||
class VolumeTest;
|
||||
|
||||
typedef BasicVector3<double> DoubleVector3;
|
||||
|
||||
class SelectionTest
|
||||
{
|
||||
public:
|
||||
|
|
@ -203,7 +234,7 @@ virtual const VolumeTest& getVolume() const = 0;
|
|||
virtual const Vector3& getNear() const = 0;
|
||||
virtual const Vector3& getFar() const = 0;
|
||||
virtual void TestPoint( const Vector3& point, SelectionIntersection& best ) = 0;
|
||||
virtual void TestPolygon( const VertexPointer& vertices, std::size_t count, 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;
|
||||
virtual void TestLineStrip( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ) = 0;
|
||||
virtual void TestLines( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ) = 0;
|
||||
|
|
|
|||
|
|
@ -396,17 +396,19 @@ inline void matrix4_transform_direction( const Matrix4& self, BasicVector3<Eleme
|
|||
}
|
||||
|
||||
/// \brief Returns \p vector4 transformed by \p self.
|
||||
inline Vector4 matrix4_transformed_vector4( const Matrix4& self, const Vector4& vector4 ){
|
||||
return Vector4(
|
||||
self[0] * vector4[0] + self[4] * vector4[1] + self[8] * vector4[2] + self[12] * vector4[3],
|
||||
self[1] * vector4[0] + self[5] * vector4[1] + self[9] * vector4[2] + self[13] * vector4[3],
|
||||
self[2] * vector4[0] + self[6] * vector4[1] + self[10] * vector4[2] + self[14] * vector4[3],
|
||||
self[3] * vector4[0] + self[7] * vector4[1] + self[11] * vector4[2] + self[15] * vector4[3]
|
||||
template<typename Element>
|
||||
inline BasicVector4<Element> matrix4_transformed_vector4( const Matrix4& self, const BasicVector4<Element>& vector4 ){
|
||||
return BasicVector4<Element>(
|
||||
static_cast<Element>( self[0] * vector4[0] + self[4] * vector4[1] + self[8] * vector4[2] + self[12] * vector4[3] ),
|
||||
static_cast<Element>( self[1] * vector4[0] + self[5] * vector4[1] + self[9] * vector4[2] + self[13] * vector4[3] ),
|
||||
static_cast<Element>( self[2] * vector4[0] + self[6] * vector4[1] + self[10] * vector4[2] + self[14] * vector4[3] ),
|
||||
static_cast<Element>( self[3] * vector4[0] + self[7] * vector4[1] + self[11] * vector4[2] + self[15] * vector4[3] )
|
||||
);
|
||||
}
|
||||
|
||||
/// \brief Transforms \p vector4 by \p self in-place.
|
||||
inline void matrix4_transform_vector4( const Matrix4& self, Vector4& vector4 ){
|
||||
template<typename Element>
|
||||
inline void matrix4_transform_vector4( const Matrix4& self, BasicVector4<Element>& vector4 ){
|
||||
vector4 = matrix4_transformed_vector4( self, vector4 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ void render( Renderer& renderer, const Matrix4& localToWorld ) const {
|
|||
}
|
||||
|
||||
void testSelect( Selector& selector, SelectionTest& test, const Matrix4& localToWorld ){
|
||||
test.BeginMesh( localToWorld );
|
||||
test.BeginMesh( localToWorld, true );
|
||||
|
||||
SelectionIntersection best;
|
||||
test.TestTriangles(
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ void render( Renderer& renderer, const Matrix4& localToWorld ) const {
|
|||
}
|
||||
|
||||
void testSelect( Selector& selector, SelectionTest& test, const Matrix4& localToWorld ){
|
||||
test.BeginMesh( localToWorld );
|
||||
test.BeginMesh( localToWorld, true );
|
||||
|
||||
SelectionIntersection best;
|
||||
testSelect( test, best );
|
||||
|
|
|
|||
|
|
@ -653,9 +653,9 @@ inline Plane3 Plane3_applyTransform( const Plane3& plane, const Matrix4& matrix
|
|||
// Vector4 normal = matrix4_transformed_vector4( mat, Vector4( plane.normal(), 0 ) );
|
||||
// return plane3_normalised( Plane3( vector4_to_vector3( normal ), vector3_dot( vector4_to_vector3( normal ), vector4_to_vector3( anchor ) ) ) );
|
||||
|
||||
const Vector3 anchor( matrix4_transformed_point( matrix, plane.normal() * plane.dist() ) );
|
||||
const DoubleVector3 anchor( matrix4_transformed_point( matrix, plane.normal() * plane.dist() ) );
|
||||
const Matrix4 mat( matrix4_transposed( matrix4_affine_inverse( matrix ) ) );
|
||||
const Vector3 normal( vector3_normalised( matrix4_transformed_direction( mat, plane.normal() ) ) );
|
||||
const DoubleVector3 normal( vector3_normalised( matrix4_transformed_direction( mat, plane.normal() ) ) );
|
||||
return Plane3( normal, vector3_dot( normal, anchor ) );
|
||||
}
|
||||
|
||||
|
|
@ -801,6 +801,15 @@ PlanePoints& planePoints(){
|
|||
const PlanePoints& planePoints() const {
|
||||
return m_planepts;
|
||||
}
|
||||
const PlanePoints& getPlanePoints(){
|
||||
if( isDoom3Plane() ){
|
||||
m_planepts[0] = m_planeCached.normal() * m_planeCached.dist();
|
||||
ComputeAxisBase( m_planeCached.normal(), m_planepts[1], m_planepts[2] );
|
||||
m_planepts[1] = m_planepts[1] + m_planepts[0];
|
||||
m_planepts[2] = m_planepts[2] + m_planepts[0];
|
||||
}
|
||||
return m_planepts;
|
||||
}
|
||||
const Plane3& plane3() const {
|
||||
return m_planeCached;
|
||||
}
|
||||
|
|
@ -838,8 +847,8 @@ void copy( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){
|
|||
}
|
||||
};
|
||||
|
||||
inline void Winding_testSelect( Winding& winding, SelectionTest& test, SelectionIntersection& best ){
|
||||
test.TestPolygon( VertexPointer( reinterpret_cast<VertexPointer::pointer>( &winding.points.data()->vertex ), sizeof( WindingVertex ) ), winding.numpoints, best );
|
||||
inline void Winding_testSelect( Winding& winding, SelectionTest& test, SelectionIntersection& best, const DoubleVector3 planepoints[3] ){
|
||||
test.TestPolygon( VertexPointer( reinterpret_cast<VertexPointer::pointer>( &winding.points.data()->vertex ), sizeof( WindingVertex ) ), winding.numpoints, best, planepoints );
|
||||
}
|
||||
|
||||
const double GRID_MIN = 0.125;
|
||||
|
|
@ -1155,7 +1164,7 @@ void snapto( float snap ){
|
|||
}
|
||||
|
||||
void testSelect( SelectionTest& test, SelectionIntersection& best ){
|
||||
Winding_testSelect( m_winding, test, best );
|
||||
Winding_testSelect( m_winding, test, best, m_plane.getPlanePoints() );
|
||||
}
|
||||
|
||||
void testSelect_centroid( SelectionTest& test, SelectionIntersection& best ){
|
||||
|
|
|
|||
|
|
@ -732,7 +732,7 @@ inline SelectionIntersection select_point_from_clipped( Vector4& clipped ){
|
|||
return SelectionIntersection( clipped[2] / clipped[3], static_cast<float>( vector3_length_squared( Vector3( clipped[0] / clipped[3], clipped[1] / clipped[3], 0 ) ) ) );
|
||||
}
|
||||
|
||||
void BestPoint( std::size_t count, Vector4 clipped[9], SelectionIntersection& best, clipcull_t cull ){
|
||||
void BestPoint( std::size_t count, Vector4 clipped[9], SelectionIntersection& best, clipcull_t cull, const Plane3* plane = 0 ){
|
||||
Vector3 normalised[9];
|
||||
|
||||
{
|
||||
|
|
@ -744,6 +744,13 @@ 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] );
|
||||
|
||||
|
|
@ -759,6 +766,12 @@ void BestPoint( std::size_t count, Vector4 clipped[9], SelectionIntersection& be
|
|||
assign_if_closer( best, SelectionIntersection( point.z(), 0 ) );
|
||||
}
|
||||
else if ( count > 2 && !point_test_polygon_2d( Vector3( 0, 0, 0 ), normalised, normalised + count ) ) {
|
||||
Plane3 plaine;
|
||||
if( !plane ){
|
||||
plaine = plane3_for_points( normalised[0], normalised[1], normalised[2] );
|
||||
plane = &plaine;
|
||||
}
|
||||
//globalOutputStream() << plane.a << " " << plane.b << " " << plane.c << " " << "\n";
|
||||
point_iterator_t end = normalised + count;
|
||||
for ( point_iterator_t previous = end - 1, current = normalised; current != end; previous = current, ++current )
|
||||
{
|
||||
|
|
@ -768,18 +781,39 @@ void BestPoint( std::size_t count, Vector4 clipped[9], SelectionIntersection& be
|
|||
point.z() = 0;
|
||||
float distance = static_cast<float>( vector3_length_squared( point ) );
|
||||
|
||||
assign_if_closer( best, SelectionIntersection( depth, distance ) );
|
||||
if( plane->c == 0 ){
|
||||
assign_if_closer( best, SelectionIntersection( depth, distance ) );
|
||||
}
|
||||
else{
|
||||
assign_if_closer( best, SelectionIntersection( depth, distance, ray_distance_to_plane(
|
||||
Ray( Vector3( 0, 0, 0 ), Vector3( 0, 0, 1 ) ),
|
||||
*plane
|
||||
) ) );
|
||||
// globalOutputStream() << static_cast<float>( ray_distance_to_plane(
|
||||
// Ray( Vector3( 0, 0, 0 ), Vector3( 0, 0, 1 ) ),
|
||||
// plane
|
||||
// ) ) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( count > 2 ) {
|
||||
Plane3 plaine;
|
||||
if( !plane ){
|
||||
plaine = plane3_for_points( normalised[0], normalised[1], normalised[2] );
|
||||
plane = &plaine;
|
||||
}
|
||||
assign_if_closer(
|
||||
best,
|
||||
SelectionIntersection(
|
||||
static_cast<float>( ray_distance_to_plane(
|
||||
ray_distance_to_plane(
|
||||
Ray( Vector3( 0, 0, 0 ), Vector3( 0, 0, 1 ) ),
|
||||
plane3_for_points( normalised[0], normalised[1], normalised[2] )
|
||||
) ),
|
||||
0
|
||||
*plane
|
||||
),
|
||||
0,
|
||||
ray_distance_to_plane(
|
||||
Ray( Vector3( 10, 8, 0 ), Vector3( 0, 0, 1 ) ),
|
||||
*plane
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -2035,7 +2069,13 @@ void TestPoint( const Vector3& point, SelectionIntersection& best ){
|
|||
best = select_point_from_clipped( clipped );
|
||||
}
|
||||
}
|
||||
void TestPolygon( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ){
|
||||
void TestPolygon( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best, const DoubleVector3 planepoints[3] ){
|
||||
DoubleVector3 pts[3];
|
||||
pts[0] = vector4_projected( matrix4_transformed_vector4( m_local2view, BasicVector4<double>( planepoints[0], 1 ) ) );
|
||||
pts[1] = vector4_projected( matrix4_transformed_vector4( m_local2view, BasicVector4<double>( planepoints[1], 1 ) ) );
|
||||
pts[2] = vector4_projected( matrix4_transformed_vector4( m_local2view, BasicVector4<double>( planepoints[2], 1 ) ) );
|
||||
const Plane3 planeTransformed( plane3_for_points( pts ) );
|
||||
|
||||
Vector4 clipped[9];
|
||||
for ( std::size_t i = 0; i + 2 < count; ++i )
|
||||
{
|
||||
|
|
@ -2049,7 +2089,8 @@ void TestPolygon( const VertexPointer& vertices, std::size_t count, SelectionInt
|
|||
),
|
||||
clipped,
|
||||
best,
|
||||
m_cull
|
||||
m_cull,
|
||||
&planeTransformed
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -3081,6 +3122,32 @@ void deselectComponentsOrAll( bool components ){
|
|||
}
|
||||
}
|
||||
#define SELECT_MATCHING
|
||||
#define SELECT_MATCHING_DEPTH 1e-6f
|
||||
#define SELECT_MATCHING_DIST 1e-6f
|
||||
#define SELECT_MATCHING_COMPONENTS_DIST .25f
|
||||
void SelectionPool_Select( SelectionPool& pool, bool select, float dist_epsilon ){
|
||||
SelectionPool::iterator best = pool.begin();
|
||||
if( ( *best ).second->isSelected() != select ){
|
||||
( *best ).second->setSelected( select );
|
||||
}
|
||||
#ifdef SELECT_MATCHING
|
||||
SelectionPool::iterator i = best;
|
||||
++i;
|
||||
while ( i != pool.end() )
|
||||
{
|
||||
if( ( *i ).first.equalEpsilon( ( *best ).first, dist_epsilon, SELECT_MATCHING_DEPTH ) ){
|
||||
//if( ( *i ).second->isSelected() != select ){
|
||||
( *i ).second->setSelected( select );
|
||||
//}
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
#endif // SELECT_MATCHING
|
||||
}
|
||||
|
||||
void SelectPoint( const View& view, const float device_point[2], const float device_epsilon[2], RadiantSelectionSystem::EModifier modifier, bool face ){
|
||||
//globalOutputStream() << device_point[0] << " " << device_point[1] << "\n";
|
||||
ASSERT_MESSAGE( fabs( device_point[0] ) <= 1.0f && fabs( device_point[1] ) <= 1.0f, "point-selection error" );
|
||||
|
|
@ -3123,50 +3190,12 @@ void SelectPoint( const View& view, const float device_point[2], const float dev
|
|||
break;
|
||||
case RadiantSelectionSystem::eSelect:
|
||||
{
|
||||
SelectionPool::iterator best = selector_point_ents.begin();
|
||||
if( !( *best ).second->isSelected() ){
|
||||
( *best ).second->setSelected( true );
|
||||
}
|
||||
#ifdef SELECT_MATCHING
|
||||
SelectionPool::iterator i = best;
|
||||
++i;
|
||||
while ( i != selector_point_ents.end() )
|
||||
{
|
||||
if( ( *i ).first.equalEpsilon( ( *best ).first, 0.25f, 0.000001f ) ){
|
||||
if( !( *i ).second->isSelected() ){
|
||||
( *i ).second->setSelected( true );
|
||||
}
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
#endif // SELECT_MATCHING
|
||||
SelectionPool_Select( selector_point_ents, true, SELECT_MATCHING_DIST );
|
||||
}
|
||||
break;
|
||||
case RadiantSelectionSystem::eDeselect:
|
||||
{
|
||||
SelectionPool::iterator best = selector_point_ents.begin();
|
||||
if( ( *best ).second->isSelected() ){
|
||||
( *best ).second->setSelected( false );
|
||||
}
|
||||
#ifdef SELECT_MATCHING
|
||||
SelectionPool::iterator i = best;
|
||||
++i;
|
||||
while ( i != selector_point_ents.end() )
|
||||
{
|
||||
if( ( *i ).first.equalEpsilon( ( *best ).first, 0.25f, 0.000001f ) ){
|
||||
if( ( *i ).second->isSelected() ){
|
||||
( *i ).second->setSelected( false );
|
||||
}
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
#endif // SELECT_MATCHING
|
||||
SelectionPool_Select( selector_point_ents, false, SELECT_MATCHING_DIST );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -3186,7 +3215,7 @@ void SelectPoint( const View& view, const float device_point[2], const float dev
|
|||
{
|
||||
case RadiantSelectionSystem::eToggle:
|
||||
{
|
||||
SelectableSortedSet::iterator best = selector.begin();
|
||||
SelectionPool::iterator best = selector.begin();
|
||||
// toggle selection of the object with least depth
|
||||
if ( ( *best ).second->isSelected() ) {
|
||||
( *best ).second->setSelected( false );
|
||||
|
|
@ -3206,7 +3235,7 @@ void SelectPoint( const View& view, const float device_point[2], const float dev
|
|||
// select the next object in the list from the one already selected
|
||||
case RadiantSelectionSystem::eCycle:
|
||||
{
|
||||
bool CycleSelectionOccured = false;
|
||||
bool cycleSelectionOccured = false;
|
||||
SelectionPool::iterator i = selector.begin();
|
||||
while ( i != selector.end() )
|
||||
{
|
||||
|
|
@ -3220,12 +3249,12 @@ void SelectPoint( const View& view, const float device_point[2], const float dev
|
|||
{
|
||||
selector.begin()->second->setSelected( true );
|
||||
}
|
||||
CycleSelectionOccured = true;
|
||||
cycleSelectionOccured = true;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if( !CycleSelectionOccured ){
|
||||
if( !cycleSelectionOccured ){
|
||||
deselectComponentsOrAll( face );
|
||||
( *selector.begin() ).second->setSelected( true );
|
||||
}
|
||||
|
|
@ -3233,50 +3262,12 @@ void SelectPoint( const View& view, const float device_point[2], const float dev
|
|||
break;
|
||||
case RadiantSelectionSystem::eSelect:
|
||||
{
|
||||
SelectionPool::iterator best = selector.begin();
|
||||
if( !( *best ).second->isSelected() ){
|
||||
( *best ).second->setSelected( true );
|
||||
}
|
||||
#ifdef SELECT_MATCHING
|
||||
SelectionPool::iterator i = best;
|
||||
++i;
|
||||
while ( i != selector.end() )
|
||||
{
|
||||
if( ( *i ).first.equalEpsilon( ( *best ).first, Mode() == eComponent ? 0.25f : 0.000001f, 0.000001f ) ){
|
||||
if( !( *i ).second->isSelected() ){
|
||||
( *i ).second->setSelected( true );
|
||||
}
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
#endif // SELECT_MATCHING
|
||||
SelectionPool_Select( selector, true, ( Mode() == eComponent && !g_bAltResize_AltSelect )? SELECT_MATCHING_COMPONENTS_DIST : SELECT_MATCHING_DIST );
|
||||
}
|
||||
break;
|
||||
case RadiantSelectionSystem::eDeselect:
|
||||
{
|
||||
SelectionPool::iterator best = selector.begin();
|
||||
if( ( *best ).second->isSelected() ){
|
||||
( *best ).second->setSelected( false );
|
||||
}
|
||||
#ifdef SELECT_MATCHING
|
||||
SelectionPool::iterator i = best;
|
||||
++i;
|
||||
while ( i != selector.end() )
|
||||
{
|
||||
if( ( *i ).first.equalEpsilon( ( *best ).first, Mode() == eComponent ? 0.25f : 0.000001f, 0.000001f ) ){
|
||||
if( ( *i ).second->isSelected() ){
|
||||
( *i ).second->setSelected( false );
|
||||
}
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
#endif // SELECT_MATCHING
|
||||
SelectionPool_Select( selector, false, ( Mode() == eComponent && !g_bAltResize_AltSelect )? SELECT_MATCHING_COMPONENTS_DIST : SELECT_MATCHING_DIST );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -3309,23 +3300,8 @@ bool SelectPoint_InitPaint( const View& view, const float device_point[2], const
|
|||
Scene_TestSelect( selector_point_ents, volume, scissored, eEntity, ComponentMode() );
|
||||
}
|
||||
if( prefer_point_ents && !selector_point_ents.failed() ){
|
||||
SelectableSortedSet::iterator best = selector_point_ents.begin();
|
||||
const bool wasSelected = ( *best ).second->isSelected();
|
||||
( *best ).second->setSelected( !wasSelected );
|
||||
#ifdef SELECT_MATCHING
|
||||
SelectableSortedSet::iterator i = best;
|
||||
++i;
|
||||
while ( i != selector_point_ents.end() )
|
||||
{
|
||||
if( ( *i ).first.equalEpsilon( ( *best ).first, 0.25f, 0.000001f ) ){
|
||||
( *i ).second->setSelected( !wasSelected );
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
#endif // SELECT_MATCHING
|
||||
const bool wasSelected = ( *selector_point_ents.begin() ).second->isSelected();
|
||||
SelectionPool_Select( selector_point_ents, !wasSelected, SELECT_MATCHING_DIST );
|
||||
return !wasSelected;
|
||||
}
|
||||
else{//do primitives, if ents failed
|
||||
|
|
@ -3336,23 +3312,21 @@ bool SelectPoint_InitPaint( const View& view, const float device_point[2], const
|
|||
Scene_TestSelect( selector, volume, scissored, g_bAltResize_AltSelect ? ePrimitive : Mode(), ComponentMode() );
|
||||
}
|
||||
if ( !selector.failed() ){
|
||||
SelectableSortedSet::iterator best = selector.begin();
|
||||
const bool wasSelected = ( *best ).second->isSelected();
|
||||
( *best ).second->setSelected( !wasSelected );
|
||||
#ifdef SELECT_MATCHING
|
||||
SelectableSortedSet::iterator i = best;
|
||||
++i;
|
||||
const bool wasSelected = ( *selector.begin() ).second->isSelected();
|
||||
SelectionPool_Select( selector, !wasSelected, ( Mode() == eComponent && !g_bAltResize_AltSelect )? SELECT_MATCHING_COMPONENTS_DIST : SELECT_MATCHING_DIST );
|
||||
|
||||
#if 0
|
||||
SelectionPool::iterator best = selector.begin();
|
||||
SelectionPool::iterator i = best;
|
||||
globalOutputStream() << "\n\n\n===========\n";
|
||||
while ( i != selector.end() )
|
||||
{
|
||||
if( ( *i ).first.equalEpsilon( ( *best ).first, Mode() == eComponent ? 0.25f : 0.000001f, 0.000001f ) ){
|
||||
( *i ).second->setSelected( !wasSelected );
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
globalOutputStream() << "depth:" << ( *i ).first.m_depth << " dist:" << ( *i ).first.m_distance << " depth2:" << ( *i ).first.m_depth2 << "\n";
|
||||
globalOutputStream() << "depth - best depth:" << ( *i ).first.m_depth - ( *best ).first.m_depth << "\n";
|
||||
++i;
|
||||
}
|
||||
#endif // SELECT_MATCHING
|
||||
#endif
|
||||
|
||||
return !wasSelected;
|
||||
}
|
||||
else{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user