@@ -760,16 +760,14 @@ void NavMeshGenerator2D::generator_parse_source_geometry_data(Ref<NavigationPoly
760
760
static void generator_recursive_process_polytree_items (List<TPPLPoly> &p_tppl_in_polygon, const Clipper2Lib::PolyPathD *p_polypath_item) {
761
761
using namespace Clipper2Lib ;
762
762
763
- Vector<Vector2> polygon_vertices;
763
+ TPPLPoly tp;
764
+ int size = p_polypath_item->Polygon ().size ();
765
+ tp.Init (size);
764
766
767
+ int j = 0 ;
765
768
for (const PointD &polypath_point : p_polypath_item->Polygon ()) {
766
- polygon_vertices.push_back (Vector2 (static_cast <real_t >(polypath_point.x ), static_cast <real_t >(polypath_point.y )));
767
- }
768
-
769
- TPPLPoly tp;
770
- tp.Init (polygon_vertices.size ());
771
- for (int j = 0 ; j < polygon_vertices.size (); j++) {
772
- tp[j] = polygon_vertices[j];
769
+ tp[j] = Vector2 (static_cast <real_t >(polypath_point.x ), static_cast <real_t >(polypath_point.y ));
770
+ ++j;
773
771
}
774
772
775
773
if (p_polypath_item->IsHole ()) {
@@ -842,87 +840,79 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
842
840
return ;
843
841
}
844
842
845
- if (p_navigation_mesh->get_outline_count () == 0 && !p_source_geometry_data->has_data ()) {
846
- return ;
847
- }
848
-
849
- int outline_count = p_navigation_mesh->get_outline_count ();
850
-
851
- Vector<Vector<Vector2>> traversable_outlines;
852
- Vector<Vector<Vector2>> obstruction_outlines;
853
- Vector<NavigationMeshSourceGeometryData2D::ProjectedObstruction> projected_obstructions;
854
-
855
- p_source_geometry_data->get_data (
856
- traversable_outlines,
857
- obstruction_outlines,
858
- projected_obstructions);
859
-
860
- if (outline_count == 0 && traversable_outlines.size () == 0 ) {
861
- return ;
862
- }
863
-
864
843
using namespace Clipper2Lib ;
865
-
866
844
PathsD traversable_polygon_paths;
867
845
PathsD obstruction_polygon_paths;
846
+ int obstruction_polygon_path_size = 0 ;
847
+ {
848
+ RWLockRead read_lock (p_source_geometry_data->geometry_rwlock );
868
849
869
- traversable_polygon_paths. reserve (outline_count + traversable_outlines. size ()) ;
870
- obstruction_polygon_paths. reserve (obstruction_outlines. size () );
850
+ const Vector<Vector<Vector2>> & traversable_outlines = p_source_geometry_data-> traversable_outlines ;
851
+ int outline_count = p_navigation_mesh-> get_outline_count ( );
871
852
872
- for (int i = 0 ; i < outline_count; i++) {
873
- const Vector<Vector2> &traversable_outline = p_navigation_mesh->get_outline (i);
874
- PathD subject_path;
875
- subject_path.reserve (traversable_outline.size ());
876
- for (const Vector2 &traversable_point : traversable_outline) {
877
- const PointD &point = PointD (traversable_point.x , traversable_point.y );
878
- subject_path.push_back (point);
853
+ if (outline_count == 0 && (!p_source_geometry_data->has_data () || (traversable_outlines.is_empty ()))) {
854
+ return ;
879
855
}
880
- traversable_polygon_paths.push_back (subject_path);
881
- }
882
856
883
- for (const Vector<Vector2> &traversable_outline : traversable_outlines) {
884
- PathD subject_path;
885
- subject_path.reserve (traversable_outline.size ());
886
- for (const Vector2 &traversable_point : traversable_outline) {
887
- const PointD &point = PointD (traversable_point.x , traversable_point.y );
888
- subject_path.push_back (point);
889
- }
890
- traversable_polygon_paths.push_back (subject_path);
891
- }
857
+ const Vector<Vector<Vector2>> &obstruction_outlines = p_source_geometry_data->obstruction_outlines ;
858
+ const Vector<NavigationMeshSourceGeometryData2D::ProjectedObstruction> &projected_obstructions = p_source_geometry_data->_projected_obstructions ;
859
+
860
+ traversable_polygon_paths.reserve (outline_count + traversable_outlines.size ());
861
+ obstruction_polygon_paths.reserve (obstruction_outlines.size ());
892
862
893
- for (const Vector<Vector2> &obstruction_outline : obstruction_outlines) {
894
- PathD clip_path;
895
- clip_path.reserve (obstruction_outline.size ());
896
- for (const Vector2 &obstruction_point : obstruction_outline) {
897
- const PointD &point = PointD (obstruction_point.x , obstruction_point.y );
898
- clip_path.push_back (point);
863
+ for (int i = 0 ; i < outline_count; i++) {
864
+ const Vector<Vector2> &traversable_outline = p_navigation_mesh->get_outline (i);
865
+ PathD subject_path;
866
+ subject_path.reserve (traversable_outline.size ());
867
+ for (const Vector2 &traversable_point : traversable_outline) {
868
+ subject_path.emplace_back (traversable_point.x , traversable_point.y );
869
+ }
870
+ traversable_polygon_paths.push_back (std::move (subject_path));
899
871
}
900
- obstruction_polygon_paths.push_back (clip_path);
901
- }
902
872
903
- if (!projected_obstructions.is_empty ()) {
904
- for (const NavigationMeshSourceGeometryData2D::ProjectedObstruction &projected_obstruction : projected_obstructions) {
905
- if (projected_obstruction.carve ) {
906
- continue ;
873
+ for (const Vector<Vector2> &traversable_outline : traversable_outlines) {
874
+ PathD subject_path;
875
+ subject_path.reserve (traversable_outline.size ());
876
+ for (const Vector2 &traversable_point : traversable_outline) {
877
+ subject_path.emplace_back (traversable_point.x , traversable_point.y );
907
878
}
908
- if (projected_obstruction.vertices .is_empty () || projected_obstruction.vertices .size () % 2 != 0 ) {
909
- continue ;
879
+ traversable_polygon_paths.push_back (std::move (subject_path));
880
+ }
881
+
882
+ if (!projected_obstructions.is_empty ()) {
883
+ for (const NavigationMeshSourceGeometryData2D::ProjectedObstruction &projected_obstruction : projected_obstructions) {
884
+ if (projected_obstruction.carve ) {
885
+ continue ;
886
+ }
887
+ if (projected_obstruction.vertices .is_empty () || projected_obstruction.vertices .size () % 2 != 0 ) {
888
+ continue ;
889
+ }
890
+
891
+ PathD clip_path;
892
+ clip_path.reserve (projected_obstruction.vertices .size () / 2 );
893
+ for (int i = 0 ; i < projected_obstruction.vertices .size () / 2 ; i++) {
894
+ clip_path.emplace_back (projected_obstruction.vertices [i * 2 ], projected_obstruction.vertices [i * 2 + 1 ]);
895
+ }
896
+ if (!IsPositive (clip_path)) {
897
+ std::reverse (clip_path.begin (), clip_path.end ());
898
+ }
899
+ obstruction_polygon_paths.push_back (std::move (clip_path));
910
900
}
901
+ }
911
902
903
+ obstruction_polygon_path_size = obstruction_polygon_paths.size ();
904
+ for (const Vector<Vector2> &obstruction_outline : obstruction_outlines) {
912
905
PathD clip_path;
913
- clip_path.reserve (projected_obstruction.vertices .size () / 2 );
914
- for (int i = 0 ; i < projected_obstruction.vertices .size () / 2 ; i++) {
915
- const PointD &point = PointD (projected_obstruction.vertices [i * 2 ], projected_obstruction.vertices [i * 2 + 1 ]);
916
- clip_path.push_back (point);
917
- }
918
- if (!IsPositive (clip_path)) {
919
- std::reverse (clip_path.begin (), clip_path.end ());
906
+ clip_path.reserve (obstruction_outline.size ());
907
+ for (const Vector2 &obstruction_point : obstruction_outline) {
908
+ clip_path.emplace_back (obstruction_point.x , obstruction_point.y );
920
909
}
921
- obstruction_polygon_paths.push_back (clip_path);
910
+ obstruction_polygon_paths.push_back (std::move ( clip_path) );
922
911
}
923
912
}
924
913
925
914
Rect2 baking_rect = p_navigation_mesh->get_baking_rect ();
915
+ PathsD area_obstruction_polygon_paths;
926
916
if (baking_rect.has_area ()) {
927
917
Vector2 baking_rect_offset = p_navigation_mesh->get_baking_rect_offset ();
928
918
@@ -934,48 +924,27 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
934
924
RectD clipper_rect = RectD (rect_begin_x, rect_begin_y, rect_end_x, rect_end_y);
935
925
936
926
traversable_polygon_paths = RectClip (clipper_rect, traversable_polygon_paths);
937
- obstruction_polygon_paths = RectClip (clipper_rect, obstruction_polygon_paths);
927
+ area_obstruction_polygon_paths = RectClip (clipper_rect, obstruction_polygon_paths);
928
+ } else {
929
+ area_obstruction_polygon_paths = obstruction_polygon_paths;
938
930
}
939
931
940
- PathsD path_solution;
941
-
942
932
// first merge all traversable polygons according to user specified fill rule
943
933
PathsD dummy_clip_path;
944
934
traversable_polygon_paths = Union (traversable_polygon_paths, dummy_clip_path, FillRule::NonZero);
945
935
// merge all obstruction polygons, don't allow holes for what is considered "solid" 2D geometry
946
- obstruction_polygon_paths = Union (obstruction_polygon_paths , dummy_clip_path, FillRule::NonZero);
936
+ area_obstruction_polygon_paths = Union (area_obstruction_polygon_paths , dummy_clip_path, FillRule::NonZero);
947
937
948
- path_solution = Difference (traversable_polygon_paths, obstruction_polygon_paths , FillRule::NonZero);
938
+ PathsD path_solution = Difference (traversable_polygon_paths, area_obstruction_polygon_paths , FillRule::NonZero);
949
939
950
940
real_t agent_radius_offset = p_navigation_mesh->get_agent_radius ();
951
941
if (agent_radius_offset > 0.0 ) {
952
942
path_solution = InflatePaths (path_solution, -agent_radius_offset, JoinType::Miter, EndType::Polygon);
953
943
}
954
944
955
- if (!projected_obstructions.is_empty ()) {
956
- obstruction_polygon_paths.resize (0 );
957
- for (const NavigationMeshSourceGeometryData2D::ProjectedObstruction &projected_obstruction : projected_obstructions) {
958
- if (!projected_obstruction.carve ) {
959
- continue ;
960
- }
961
- if (projected_obstruction.vertices .is_empty () || projected_obstruction.vertices .size () % 2 != 0 ) {
962
- continue ;
963
- }
964
-
965
- PathD clip_path;
966
- clip_path.reserve (projected_obstruction.vertices .size () / 2 );
967
- for (int i = 0 ; i < projected_obstruction.vertices .size () / 2 ; i++) {
968
- const PointD &point = PointD (projected_obstruction.vertices [i * 2 ], projected_obstruction.vertices [i * 2 + 1 ]);
969
- clip_path.push_back (point);
970
- }
971
- if (!IsPositive (clip_path)) {
972
- std::reverse (clip_path.begin (), clip_path.end ());
973
- }
974
- obstruction_polygon_paths.push_back (clip_path);
975
- }
976
- if (obstruction_polygon_paths.size () > 0 ) {
977
- path_solution = Difference (path_solution, obstruction_polygon_paths, FillRule::NonZero);
978
- }
945
+ if (obstruction_polygon_path_size > 0 ) {
946
+ obstruction_polygon_paths.resize (obstruction_polygon_path_size);
947
+ path_solution = Difference (path_solution, obstruction_polygon_paths, FillRule::NonZero);
979
948
}
980
949
981
950
// path_solution = RamerDouglasPeucker(path_solution, 0.025); //
@@ -994,41 +963,19 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
994
963
path_solution = RectClip (clipper_rect, path_solution);
995
964
}
996
965
997
- Vector<Vector<Vector2>> new_baked_outlines;
998
-
999
- for (const PathD &scaled_path : path_solution) {
1000
- Vector<Vector2> polypath;
1001
- for (const PointD &scaled_point : scaled_path) {
1002
- polypath.push_back (Vector2 (static_cast <real_t >(scaled_point.x ), static_cast <real_t >(scaled_point.y )));
1003
- }
1004
- new_baked_outlines.push_back (polypath);
1005
- }
1006
-
1007
- if (new_baked_outlines.size () == 0 ) {
966
+ if (path_solution.size () == 0 ) {
1008
967
p_navigation_mesh->clear ();
1009
968
return ;
1010
969
}
1011
970
1012
- PathsD polygon_paths;
1013
- polygon_paths.reserve (new_baked_outlines.size ());
1014
-
1015
- for (const Vector<Vector2> &baked_outline : new_baked_outlines) {
1016
- PathD polygon_path;
1017
- for (const Vector2 &baked_outline_point : baked_outline) {
1018
- const PointD &point = PointD (baked_outline_point.x , baked_outline_point.y );
1019
- polygon_path.push_back (point);
1020
- }
1021
- polygon_paths.push_back (polygon_path);
1022
- }
1023
-
1024
971
ClipType clipper_cliptype = ClipType::Union;
1025
972
1026
973
List<TPPLPoly> tppl_in_polygon, tppl_out_polygon;
1027
974
1028
975
PolyTreeD polytree;
1029
976
ClipperD clipper_D;
1030
977
1031
- clipper_D.AddSubject (polygon_paths );
978
+ clipper_D.AddSubject (path_solution );
1032
979
clipper_D.Execute (clipper_cliptype, FillRule::NonZero, polytree);
1033
980
1034
981
for (size_t i = 0 ; i < polytree.Count (); i++) {
0 commit comments