Skip to content

AcresSoilVisuals.h#

Acres/Source/Acres/AcresSoilVisuals.h Generated

Render-only ground effects for the farm: rut tiles, field-work detail, standing water and cosmetic particles.

Draws the persistent 25 cm cells the physics writes (FAcresFarmRuntime: ruts, backhoe pits and spoil, and the traces of tillage, drilling, spraying and tyres in FAcresFieldCell) and the pond depths of the 4 m water grid, with ponded water filling the ruts first where the wheel sub-grid has a tile (the same split the tyres feel). Nothing here feeds back into physics: the relief the wheels feel (ruts, pits, spoil) comes from the farm's own maps, and particles are ballistic with no impulse or soil transport.

How it draws: - Rut tiles: 16 m x 16 m procedural meshes (UProceduralMeshComponent, a mesh whose vertices are set from C++ at run time) with 65 x 65 vertices at 25 cm, built near the watched vehicle. A 96 x 96 mask texture tells the terrain material to hide the survey terrain wherever a replacement tile is drawn. - Field-work detail: every 25 cm quad of a tile whose cell holds field work (FAcresFieldCell), a pit or spoil, or a rut deeper than 2 cm leaves the coarse section and is drawn by a fine section of its 4 m block: 4 x 4 sub-quads (6.25 cm) within 40 m of the vehicle, 2 x 2 beyond, whose vertices carry the tool relief (furrows, ridges, clods, drill slots, tread prints; AcresFieldWorkModel.h). The fine sections use M_FieldWork, which reads four small per-tile cell textures (one texel per 25 cm cell) and redraws the same relief per pixel for the shading (Acres/Shaders/AcresFieldWork.ush, built by Tools/ACRE/Tools/make_field_work_materials.py). - Water: a 382 x 382 texture (one texel per 4 m cell) with wetness and pond depth that the ground material samples by world position, a far-field water mesh over the whole grid in 16 sections, and a water surface section on each rut tile. - Particles: 512 instances each of mud clods (sphere mesh, M_MudClod), dust puffs (sphere mesh, translucent M_FieldDust with per-instance opacity) and water drops (glossy M_FieldSplash), each an instanced static mesh component (one draw call for many copies of one mesh) recycled as a ring buffer.

Owned by FAcresFarmRuntime (not created with -nullrhi). Game thread only. World units: the code works in metres and multiplies by 100 when handing positions to Unreal, which uses centimetres. X east, Y south, Z up.

FAcresFieldCell#

struct FAcresFieldCell

Visible trace of field work in one 25 cm cell (FAcresFarmRuntime::FieldCells), quantised for drawing and saving.

Written by the farm on the physics thread when a tool, a tyre or the backhoe passes (AcresFieldWorkModel.h gives the physics behind each number); copied to the visuals as cells change. Angles are Unreal yaw (atan2(Y, X) of the pass direction) in 256 steps per turn; phases are the position of the cell centre across the implement, in 256 steps per tool spacing, measured from the implement's first tool.

Name Type Unit Default Description
Tilled, Drilled, Rut, Sprayed static constexpr uint8 Flag bits.
Flags uint8 0 Flags: Tilled | Drilled | Rut | Sprayed.
TillPattern uint8 0 AcresSim::ETillagePattern (1 tine, 2 disc, 3 spoil). TillHeading,
TillHeading uint8 0 See above.
TillPhase uint8 0 Pass heading and tool phase.
RidgeMm uint8 mm 0 Ridge crest to furrow bottom, mm.
ClodMm uint8 mm 0 Mean clod diameter, mm.
TillDepthQ uint8 0 Working depth, cm (tines), or packer roller groove depth in 0.2 mm steps (disc).
TurnedSe uint8 0 Saturation of the turned soil, 0..255.
DrillHeading, DrillPhase, PressMm, SowMm uint8 Drill: pass heading, row phase, press wheel sinkage (mm) and sowing depth (mm).
RutHeading uint8 0 Tyre print: heading, cell centre across the tyre (-127..127 = -0.5..0.5 of its width), tyre width (cm), lug pitch (cm), print depth (mm).
Field uint8 0 Field bucket of the cell (0 outside fields, 1..59), for the degree days of the seedlings.
RiseM float m 0 Bulking rise of the tilled layer, m. TilledS,
TilledS float s 0 See above.
SownGdd float 0 The field's degree days when the drill passed, deg C day.
SprayedS float s 0 Farm clock at the last tillage and spray pass, s.
SprayM3M2 float 0 Liquid applied, m3/m2.

FAcresFieldChange#

struct FAcresFieldChange

One changed cell handed from the farm to the visuals (FAcresFarmRuntime::UpdateVisuals).

Name Type Unit Default Description
Key FIntPoint Cell key: (floor(X / 0.25 m), floor(Y / 0.25 m)).
Cell FAcresFieldCell Field work in the cell (Flags 0 when none).
RutM float m 0 Wheel rut depth, m.
ReliefM float m 0 Pit (negative) or spoil (positive) height, m.

FAcresFieldClock#

struct FAcresFieldClock

Farm clock and weather the time-dependent traces follow (spray film and turned soil drying, seedlings).

Name Type Unit Default Description
ClockS double s 0 Farm time, s.
EvapMmDay double 2 Potential evaporation, mm/day.
Gdd double Degree days per field bucket (0..59), deg C day.

FAcresMudSpawn#

struct FAcresMudSpawn

One particle to launch, queued by the physics thread through FAcresFarmRuntime::AddMud / AddParticle.

Name Type Unit Default Description
Mud, Dust, Splash static constexpr uint8 Particle kinds: a mud clod, a dust puff, a water drop.
PositionM FVector m Launch point in world metres.
VelocityMps FVector m/s Launch velocity, m/s.
RadiusM double m .03 Clod or drop radius, m (a dust puff's starting radius).
Kind uint8 Mud Kind: Mud, Dust or Splash.

FAcresSoilVisuals#

class FAcresSoilVisuals

Rut tiles, field-work detail, water surfaces and particles around the watched vehicle.

FAcresFarmRuntime creates one in Initialize (after the level is loaded), hands it every changed cell (ApplyChanges) and calls Tick from UpdateVisuals every game frame with the latest water snapshot. The counters below are reported in farm-visuals.json by FAcresFarmRuntime::Export.

Note

Game thread only: it creates and updates Unreal components and textures.

Name Type Unit Default Description
EmittedClods, EmittedDust, EmittedDrops uint64 Particles launched since start: mud clods, dust puffs, water drops.
MaximumRenderedRutM double m 0 Deepest rut drawn so far, m.
MaximumRenderedWaterM double m 0 Deepest water drawn on a rut tile so far, m.
MaximumRenderedReliefM double m 0 Largest field-work relief (furrow, print, pit or spoil) drawn, m. All high-water marks used by tests.
WaterTileCount int 0 Number of live rut tiles that currently draw a water surface (updated every Tick).
FineBlockCount, FineVertexCount int Fine field-work blocks drawn now, their vertices, and fine block rebuilds since start.
BuildSeconds double 0 Game-thread time spent building tiles and blocks since start, s.
bLayerMap bool false True when the ground draws the surface-map layer (M_FarmGroundLayer); false only when that material is missing (the M_FarmGroundRuntime fallback).

FAcresSoilVisuals::TileCount#

Number of live 16 m rut tiles.

Returns: Tile count (edited-terrain tiles plus rut tiles near the vehicle).

int TileCount() const ;

FAcresSoilVisuals::Initialize#

Create the owner actor, textures, materials, far water mesh and particle pools.

Loads heights.f32, surfaces.u8 and grass-lanes.u8 from Content/Simulation/ACRE, swaps the material on every terrain actor tagged "ACRETerrainVisual" for a dynamic instance of M_FarmGroundRuntime (so rut mask, water map and wetness can be set at run time), and applies menu terrain edits: edited 16 m tiles are built immediately and kept for the whole session, and ground-cover instances (tag "ACREGroundCover") are moved onto the edited surface. -NoFieldDetail draws field work the old way (no fine blocks; for frame-time comparisons).

Argument Description
World The level to spawn into.
void Initialize(UWorld* World);

FAcresSoilVisuals::ApplyChanges#

Take changed cells from the farm into the visuals' own copy of the maps; their 16 m tiles and 4 m blocks are redrawn by the next Ticks.

Argument Description
Changes Cells whose rut, relief or field work changed (a cell with nothing left is removed).
void ApplyChanges(const TArray<FAcresFieldChange>& Changes);

FAcresSoilVisuals::Tick#

Per-frame update.

Every 0.5 s copies the water snapshot into the water texture and refreshes water surfaces that changed by more than 0.5 mm. Drops rut tiles more than 75 m from the vehicle (edited tiles stay), rebuilds up to two dirty tiles within 65 m every 0.1 s (only their dirty fine blocks), rebuilds one previously drawn tile within 48 m per frame, re-encodes the cell textures of tiles with drying or growing traces every 2 s, uploads the tile mask, and moves the particles (gravity 9.80665 m/s2; clods and drops end on ground contact, dust puffs grow, drift and fade over 1.6 s).

Argument Description
Dt Frame time, s (the caller caps it at 0.1 s).
VehicleM Watched vehicle position, world metres.
Spawns Particles to launch this frame.
Wetness Soil wetness 0..1 under the vehicle; sets the material's global "FarmWetness".
Water Latest water snapshot (ignored until valid and 382 cells wide).
Clock Farm clock, evaporation and degree days.
void Tick(double Dt, const FVector& VehicleM, const TArray<FAcresMudSpawn>& Spawns, double Wetness, const FAcresWaterSnapshot& Water, const FAcresFieldClock& Clock);