diff --git a/Source/PolygonalMapGenerator/Private/Rivers/IslandRivers.cpp b/Source/PolygonalMapGenerator/Private/Rivers/IslandRivers.cpp index d7c33d8..d180479 100644 --- a/Source/PolygonalMapGenerator/Private/Rivers/IslandRivers.cpp +++ b/Source/PolygonalMapGenerator/Private/Rivers/IslandRivers.cpp @@ -60,6 +60,42 @@ TArray UIslandRivers::FindSpringTriangles_Implementation(UTriang return spring_t.Array(); } +TArray UIslandRivers::CreateRiver(FTriangleIndex RiverTriangle, TArray &s_flow, UTriangleDualMesh* Mesh, const TArray& t_downslope_s) const +{ + // We keep both a set and an array + // The set is for fast lookup when checking if we have already processed a point (we'll be doing this every iteration) + // The array is to keep track of the order in which we have navigated the river + TSet processedSlopes; + TArray river; + while(true) + { + FSideIndex s = t_downslope_s[RiverTriangle]; + + if (!s.IsValid()) + { + break; + } + + s_flow[s]++; + + FTriangleIndex next_t = Mesh->s_outer_t(s); + if (next_t == RiverTriangle) + { + break; + } + if (processedSlopes.Contains(RiverTriangle)) + { + UE_LOG(LogMapGen, Warning, TEXT("Tried to process a slope we've already processed once this loop! We have an infinite loop.")); + break; + } + processedSlopes.Add(RiverTriangle); + river.Add(RiverTriangle); + + RiverTriangle = next_t; + } + return river; +} + void UIslandRivers::AssignSideFlow_Implementation(TArray& s_flow, UTriangleDualMesh* Mesh, const TArray& t_downslope_s, const TArray& river_t) const { if (Mesh) @@ -69,33 +105,7 @@ void UIslandRivers::AssignSideFlow_Implementation(TArray& s_flow, UTriang s_flow.SetNumZeroed(Mesh->NumSides); for (int i = 0; i < river_t.Num(); i++) { - FTriangleIndex t = river_t[i]; - TSet processedSlopes; - for (;;) - { - FSideIndex s = t_downslope_s[t]; - - if (!s.IsValid()) - { - break; - } - - s_flow[s]++; - - FTriangleIndex next_t = Mesh->s_outer_t(s); - if (next_t == t) - { - break; - } - if (processedSlopes.Contains(t)) - { - UE_LOG(LogMapGen, Warning, TEXT("Tried to process a slope we've already processed once this loop! We have an infinite loop.")); - break; - } - processedSlopes.Add(t); - - t = next_t; - } + CreateRiver(river_t[i], s_flow, Mesh, t_downslope_s); } } else diff --git a/Source/PolygonalMapGenerator/Public/Rivers/IslandRivers.h b/Source/PolygonalMapGenerator/Public/Rivers/IslandRivers.h index da46aa8..10e6ffe 100644 --- a/Source/PolygonalMapGenerator/Public/Rivers/IslandRivers.h +++ b/Source/PolygonalMapGenerator/Public/Rivers/IslandRivers.h @@ -48,6 +48,8 @@ protected: */ UFUNCTION(BlueprintPure, BlueprintCallable, Category = "Procedural Generation|Island Generation|Rivers") virtual bool IsTriangleWater(FTriangleIndex t, UTriangleDualMesh* Mesh, const TArray& WaterRegions) const; + UFUNCTION(BlueprintCallable, Category = "Procedural Generation|Island Generation|Rivers") + virtual TArray CreateRiver(FTriangleIndex RiverTriangle, TArray &s_flow, UTriangleDualMesh* Mesh, const TArray& t_downslope_s) const; virtual TArray FindSpringTriangles_Implementation(UTriangleDualMesh* Mesh, const TArray& r_water, const TArray& t_elevation, const TArray& t_downslope_s) const; virtual void AssignSideFlow_Implementation(TArray& s_flow, UTriangleDualMesh* Mesh, const TArray& t_downslope_s, const TArray& river_t) const;