@@ -32,6 +32,7 @@ type Recast struct {
3232 // extra obstacles
3333 obstaclePool * obstaclePool
3434 extraClippedPolygons []* mesh.Polygon
35+ extraEdges []* edge
3536 extraObstacleId2ClippedPoly map [obstaclePolyPair ]goclipper2.PathsD
3637}
3738
@@ -443,12 +444,25 @@ func (r *Recast) generateGraph() graphs.Graph[geom.Vector2] {
443444
444445func (r * Recast ) prepareEdges (edgeLen int ) {
445446 r .edges = make ([]* edge , 0 , edgeLen )
446- for _ , polygon := range r .extraClippedPolygons {
447+ for _ , polygon := range r .polygons {
447448 r .edges = append (r .edges , polyToEdges (polygon .Points ())... )
448449 for _ , hole := range polygon .Holes () {
449450 r .edges = append (r .edges , polyToEdges (hole .Points ())... )
450451 }
451452 }
453+
454+ extraObstacles := r .obstaclePool .GetList ()
455+ for _ , extraObstacle := range extraObstacles {
456+ r .edges = append (r .edges , polyToEdges (extraObstacle .Points ())... )
457+ }
458+
459+ r .extraEdges = make ([]* edge , 0 , edgeLen )
460+ for _ , polygon := range r .extraClippedPolygons {
461+ r .extraEdges = append (r .extraEdges , polyToEdges (polygon .Points ())... )
462+ for _ , hole := range polygon .Holes () {
463+ r .extraEdges = append (r .extraEdges , polyToEdges (hole .Points ())... )
464+ }
465+ }
452466}
453467
454468func polyToEdges (points []geom.Vector2 ) []* edge {
@@ -588,26 +602,53 @@ func onSegment(p, q, r geom.Vector2) bool {
588602 return qX <= math .Max (pX , rX ) && qX >= math .Min (pX , rX ) && qY <= math .Max (pY , rY ) && qY >= math .Min (pY , rY )
589603}
590604
605+ // pointOnSegment helper function for check point on segment with epsilon
606+ func pointOnSegment (p , a , b geom.Vector2 , eps float64 ) bool {
607+ var (
608+ pX , pY = float64 (p .X ), float64 (p .Y )
609+ aX , aY = float64 (a .X ), float64 (a .Y )
610+ bX , bY = float64 (b .X ), float64 (b .Y )
611+ )
612+
613+ if pX < math .Min (aX , bX )- eps || pX > math .Max (aX , bX )+ eps ||
614+ pY < math .Min (aY , bY )- eps || pY > math .Max (aY , bY )+ eps {
615+ return false
616+ }
617+
618+ cross := (b .X - a .X )* (p .Y - a .Y ) - (b .Y - a .Y )* (p .X - a .X )
619+ return math .Abs (float64 (cross )) <= eps
620+ }
621+
591622func (r * Recast ) getVisiblePoints (point geom.Vector2 ) []geom.Vector2 {
592- visiblePoints := make ([]geom.Vector2 , len (r .vertices ))
623+ visiblePoints := make ([]geom.Vector2 , len (r .extraEdges ))
593624 count := 0
594625
595- // TODO better but not so accurate :( ~99853ns
596- for _ , v := range r .vertices {
597- hasIntersection := false
598- for _ , edge := range r .edges {
599- if lineSegmentIntersection (edge .a , edge .b , v , point ) {
600- hasIntersection = true
601- break
602- }
603- }
604-
605- if ! hasIntersection {
606- visiblePoints [count ] = v
626+ // TODO very fast check ~11146ns
627+ for _ , edge := range r .extraEdges {
628+ if pointOnSegment (point , edge .a , edge .b , 1e-1 ) {
629+ visiblePoints [count ] = edge .a
630+ count ++
631+ visiblePoints [count ] = edge .b
607632 count ++
608633 }
609634 }
610635
636+ // TODO better but not so accurate :( ~99853ns
637+ //for _, v := range r.vertices {
638+ // hasIntersection := false
639+ // for _, edge := range r.edges {
640+ // if lineSegmentIntersection(edge.a, edge.b, v, point) {
641+ // hasIntersection = true
642+ // break
643+ // }
644+ // }
645+ //
646+ // if !hasIntersection {
647+ // visiblePoints[count] = v
648+ // count++
649+ // }
650+ //}
651+
611652 // TODO more accurate but expensive :( ~190585ns
612653 //for _, polygon := range r.polygons {
613654 // points := polygon.Points()
@@ -634,7 +675,7 @@ func (r *Recast) closestPointOnPolygon(startPoint geom.Vector2) (geom.Vector2, b
634675 exist := false
635676
636677 // Check exterior ring
637- for _ , polygon := range r .clippedPolygons {
678+ for _ , polygon := range r .extraClippedPolygons {
638679 clippedPolygon := polygon .Points ()
639680 for i := 0 ; i < len (clippedPolygon ); i ++ {
640681 p1 := clippedPolygon [i ]
0 commit comments