Skip to content

AcresSurfaceMap.h#

Acres/Source/Acres/AcresSurfaceMap.h Generated

Ground surface classes of the ACRE tile from vector polygons (pure C++, no Unreal types; Tools/Terramechanics builds and tests it).

The map is the game layer Tools/ACRE/Map/game_layer.py writes to Content/Simulation/ACRE/surface_polygons.json: paved and gravel roads (Purdue Physical Facilities polygons, the RTK-driven N 500 W, imaged corrections), yards, mown grass two-track lanes, verges and lawns, dirt tracks, each a polygon with a class and a priority. Everything else is field. The wheels, the implements and the farm ask ClassAt at their contact points, so the surface changes at the surveyed edge (a few centimetres of polygon precision) instead of at the 1.524 m survey cells of surfaces.u8.

Lookup rule (the Python rasteriser in game_layer.py uses the same one, so the textures and the physics agree): among the polygons that contain the point (even-odd rule, holes excluded) the highest priority wins; on equal priority the later polygon in the file wins. Polygons are bucketed on a square grid (2 m by default); a bucket keeps its candidates sorted by that order, so a query tests the few polygons of one bucket and stops at the first hit.

Coordinates are Unreal world metres: X grid east, Y grid south (the file stores centimetres; the loader divides).

SurfaceClassName#

Class name as used in surface_polygons.json ("field", "asphalt", ...); "field" for an out-of-range index.

const char* SurfaceClassName(int Class);

FindSurfaceClass#

Class index of a name, or -1 when unknown.

int FindSurfaceClass(const char* Name);

ESurfaceClass#

enum ESurfaceClass : int

Surface classes of the game layer, in file order ("classes" in surface_polygons.json).

Value Description
SurfaceField Field soil (the background: tilled or firm, cropped or bare).
SurfaceAsphalt Paved road or lot.
SurfaceConcrete Concrete pad, apron or lot.
SurfaceGravel Gravel road, gravel lane or yard.
SurfaceGrassLane Mown grass two-track lane that carries traffic (compacted sod).
SurfaceGrass Mown grass that is not driven as a lane: verges, strips, lawns (sod).
SurfaceDirt Bare, trafficked dirt track (plot alleys, turn rows, haul roads).
SurfaceClassCount

FSurfacePolygon#

struct FSurfacePolygon

One polygon of the layer. Rings are open (first vertex not repeated), any winding, metres.

Name Type Unit Default Description
Class int SurfaceField ESurfaceClass.
Priority int 0 Higher wins where polygons overlap.
Ring std::vector<double> Outer ring as x0, y0, x1, y1, ... (m).
Holes std::vector<std::vector<double>> Holes, each like Ring.
Id std::string Id from the file (for logs), e.g. "R0007".

FSurfaceMap#

class FSurfaceMap

Point-in-polygon lookup of the layer's surface class.

Example

FSurfaceMap Map;
Map.Build(std::move(Polygons));
const int Class = Map.ClassAt(XM, YM); // SurfaceGravel on N 500 W

FSurfaceMap::Build#

Bucket the polygons. Replaces any previous content.

Argument Description
InPolygons The layer, in file order (ties go to the later polygon).
BucketM Bucket size, m (2 m keeps a bucket to a handful of lane and road polygons).
void Build(std::vector<FSurfacePolygon> InPolygons, double BucketM = 2.0);

FSurfaceMap::ClassAt#

Surface class at a point.

Argument Description
X World X, m (east).
Y World Y, m (south).
OutPolygon Optional; the index of the polygon that decided, or -1 for the field background.

Returns: An ESurfaceClass (SurfaceField where no polygon contains the point or the map is empty).

int ClassAt(double X, double Y, int* OutPolygon = nullptr) const;

FSurfaceMap::Empty#

True when no polygons are loaded.

bool Empty() const ;

FSurfaceMap::GetPolygons#

Loaded polygons, in file order.

const std::vector<FSurfacePolygon>& GetPolygons() const ;

FSurfaceMap::Contains#

Even-odd containment of a point in one polygon (outer ring minus holes).

Argument Description
P Polygon. X, Y: Point, m.

Returns: True if the point is inside.

static bool Contains(const FSurfacePolygon& P, double X, double Y);