Fix some fairly catastrophic bugs in shape collision optimization.

I did a little too much copy & paste last time around....
This commit is contained in:
Jeff Young 2020-10-05 22:22:01 +01:00
parent 6d50c9749c
commit 18a3c4c1db
3 changed files with 95 additions and 70 deletions

View File

@ -107,8 +107,14 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_CIRCLE& aB, int aC
nearest = pn;
nearest_side_dist_sq = side_dist_sq;
// If we're not looking for actual or MTV, short-circuit once we find any collision
if( ( nearest_side_dist_sq == 0 || !aActual ) && !aMTV )
if( aMTV )
continue;
if( nearest_side_dist_sq == 0 )
break;
// If we're not looking for aActual then any collision will do
if( nearest_side_dist_sq < min_dist_sq && !aActual )
break;
}
}
@ -171,6 +177,13 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN_BASE&
int closest_dist = INT_MAX;
VECTOR2I nearest;
if( aB.IsClosed() && aB.PointInside( aA.GetCenter() ) )
{
closest_dist = 0;
nearest = aA.GetCenter();
}
else
{
for( int s = 0; s < aB.GetSegmentCount(); s++ )
{
int collision_dist = 0;
@ -184,20 +197,18 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN_BASE&
{
nearest = pn;
closest_dist = collision_dist;
}
if( closest_dist == 0 || !aActual )
if( closest_dist == 0 )
break;
// If we're not looking for aActual then any collision will do
if( !aActual )
break;
}
}
}
if( aB.IsClosed() && aB.PointInside( aA.GetCenter() ) )
{
closest_dist = 0;
nearest = aA.GetCenter();
}
if( closest_dist == 0 || closest_dist < aClearance )
{
if( aLocation )
@ -251,6 +262,13 @@ static inline bool Collide( const SHAPE_LINE_CHAIN_BASE& aA, const SHAPE_LINE_CH
int closest_dist = INT_MAX;
VECTOR2I nearest;
if( aB.IsClosed() && aA.GetPointCount() > 0 && aB.PointInside( aA.GetPoint( 0 ) ) )
{
closest_dist = 0;
nearest = aA.GetPoint( 0 );
}
else
{
for( int i = 0; i < aB.GetSegmentCount(); i++ )
{
int collision_dist = 0;
@ -264,19 +282,18 @@ static inline bool Collide( const SHAPE_LINE_CHAIN_BASE& aA, const SHAPE_LINE_CH
{
nearest = pn;
closest_dist = collision_dist;
}
if( closest_dist == 0 || !aActual )
if( closest_dist == 0 )
break;
// If we're not looking for aActual then any collision will do
if( !aActual )
break;
}
}
}
if( aB.IsClosed() && aA.GetPointCount() > 0 && aB.PointInside( aA.GetPoint( 0 ) ) )
{
closest_dist = 0;
nearest = aA.GetPoint( 0 );
}
if( closest_dist == 0 || closest_dist < aClearance )
{
if( aLocation )
@ -300,6 +317,13 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN_BASE& a
int closest_dist = INT_MAX;
VECTOR2I nearest;
if( aB.IsClosed() && aB.PointInside( aA.Centre() ) )
{
nearest = aA.Centre();
closest_dist = 0;
}
else
{
for( int s = 0; s < aB.GetSegmentCount(); s++ )
{
int collision_dist = 0;
@ -313,19 +337,18 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN_BASE& a
{
nearest = pn;
closest_dist = collision_dist;
}
if( closest_dist == 0 || !aActual )
if( closest_dist == 0 )
break;
// If we're not looking for aActual then any collision will do
if( !aActual )
break;
}
}
}
if( aB.IsClosed() && aB.PointInside( aA.Centre() ) )
{
nearest = aA.Centre();
closest_dist = 0;
}
if( closest_dist == 0 || closest_dist < aClearance )
{
if( aLocation )

View File

@ -114,7 +114,11 @@ bool SHAPE_LINE_CHAIN_BASE::Collide( const VECTOR2I& aP, int aClearance, int* aA
nearest = pn;
closest_dist_sq = dist_sq;
if( closest_dist_sq == 0 || !aActual )
if( closest_dist_sq == 0 )
break;
// If we're not looking for aActual then any collision will do
if( closest_dist_sq < clearance_sq && !aActual )
break;
}
}
@ -178,7 +182,11 @@ bool SHAPE_LINE_CHAIN_BASE::Collide( const SEG& aSeg, int aClearance, int* aActu
closest_dist_sq = dist_sq;
if( closest_dist_sq == 0 || !aActual )
if( closest_dist_sq == 0)
break;
// If we're not looking for aActual then any collision will do
if( closest_dist_sq < clearance_sq && !aActual )
break;
}
}

View File

@ -24,10 +24,8 @@
#include <vector>
#include <view/view.h>
#include <view/view_item.h>
#include <view/view_group.h>
#include <gal/graphics_abstraction_layer.h>
#include <gal/color4d.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
@ -36,10 +34,6 @@
#include <pcbnew_settings.h>
#include <geometry/shape.h>
#include <geometry/shape_line_chain.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_circle.h>
#include <geometry/convex_hull.h>
#include "pns_node.h"
#include "pns_line_placer.h"