Skip to content

AcresEnvironment.h#

Acres/Source/Acres/AcresEnvironment.h Generated

Unreal adapter for the weather model: steps AcresEnv::Model and drives the sky, light, fog and rain from it.

The model runs on the physics thread next to the farm, so rain, evaporation and the day's temperature range reach the soil water grid and the crops in simulation time. Once per rendered frame the game thread copies the latest AcresEnv::State under a lock and pushes it into the level's lighting actors: the sun (a directional light), the camera exposure (a post-process volume), the volumetric cloud layer, the exponential height fog, the rain particle system and the MPC_AcresWeather material parameter collection that crop, glTF and ground materials read for wind sway and wetness.

Configuration: Acres/Content/Simulation/environment.json (or the file given by -EnvConfig=), then -Env* command-line overrides, then the legacy -FarmRain= / -FarmTimeScale= / -FarmMinC= / -FarmMaxC= flags. The file and each override go through the same range checks; a rejected file falls back to the defaults and a rejected flag is ignored with a warning.

The owner is AAcresVehiclePawn (AcresVehicle.cpp): it creates one runtime on ACRE maps in BeginPlay, calls Advance from its physics-thread callback and UpdateVisuals from Tick.

FAcresEnvironmentRuntime#

class FAcresEnvironmentRuntime

Owns the weather model and maps its state onto the Unreal scene.

Unreal background for this class: an AActor is an object placed in the level; lighting actors such as ADirectionalLight hold a component that does the actual work. TWeakObjectPtr is a pointer that turns null when Unreal's garbage collector destroys the object (it does not keep it alive); TStrongObjectPtr keeps an object alive from plain C++ code. FCriticalSection / FScopeLock are Unreal's mutex and lock guard. The game thread runs Tick and all rendering-state changes; the physics thread runs the fixed 120 Hz vehicle step.

Usage: call Initialize once on the game thread after the level is loaded, Advance every physics step and UpdateVisuals every frame. The inline accessors lock, so either thread may read Snapshot, TimeScale and Settings.

Example

Environment = MakeShared<FAcresEnvironmentRuntime>();
Environment->Initialize(GetWorld());            // BeginPlay, game thread
Environment->Advance(Dt);                       // AsyncPhysicsTickActor, physics thread
Environment->UpdateVisuals(CameraComponent);    // Tick, game thread
const AcresEnv::State E = Environment->Snapshot();

FAcresEnvironmentRuntime::Initialize#

Loads settings, resets the model and finds the level's lighting actors.

Reads environment.json (or -EnvConfig=), applies the -Env* and legacy command-line flags, then grabs the first directional light, the first unbound (whole-level) post-process volume, the first exponential height fog and the first volumetric cloud. The cloud material is replaced by a dynamic material instance so its parameters can change at runtime. Missing actors are skipped; a ACRES_ENVIRONMENT_READY log line reports what was found.

Argument Description
World The loaded level (Unreal's UWorld). Kept as a weak pointer.

Note

Game thread only. Call before the first Advance.

void Initialize(UWorld* World);

FAcresEnvironmentRuntime::Advance#

Advances the model by real time, scaled by the clock speed.

Simulated time accumulates until at least 0.05 s has built up, then the model steps once, so at real-time speed the model runs at 20 Hz rather than 120 Hz.

Argument Description
RealDtS Real (physics) seconds since the last call, s. 1/120 s here.

Note

Physics thread. Takes the internal lock.

void Advance(double RealDtS);

FAcresEnvironmentRuntime::UpdateVisuals#

Pushes the latest state into the sun, exposure, clouds, fog, rain particles and MPC_AcresWeather.

On the first call with a non-null anchor it spawns the NS_AcresRain Niagara system (Unreal's particle system) and attaches it to the anchor, so the rain box travels with the camera.

Argument Description
ViewAnchor Scene component the rain follows, usually the player camera manager's transform. Null skips rain.

Note

Game thread, once per frame.

void UpdateVisuals(class USceneComponent* ViewAnchor = nullptr);

FAcresEnvironmentRuntime::ReleaseWorldObjects#

Drop the strong reference to the cloud material instance so the world can be garbage collected. Game thread. Call from EndPlay (see FAcresFarmRuntime::ReleaseVisuals).

void ReleaseWorldObjects() ;

FAcresEnvironmentRuntime::Snapshot#

Copy of the latest model state. Safe from any thread.

AcresEnv::State Snapshot() const ;

FAcresEnvironmentRuntime::TimeScale#

Simulated seconds per real second, including the K-key fast-forward (x600). The farm runtime uses the same value.

double TimeScale() const ;

FAcresEnvironmentRuntime::ToggleRain#

J key: toggles a manual rain override.

If an override is active, a press returns to the scheduled rain. Otherwise it forces the opposite of the current weather: 20 mm/h when dry, 0 mm/h when raining. So with a schedule, two presses stop a storm and give it back; without one, two presses start and stop a shower.

void ToggleRain();

FAcresEnvironmentRuntime::ToggleFast#

K key: toggles a x600 fast-forward on top of the configured clock speed.

void ToggleFast();

FAcresEnvironmentRuntime::SetClock#

Restarts the model at a local date and time, keeping every other setting (the RL bridge's "env_clock": the camera test renders each real frame under the sun of its own timestamp, Calibration/Polaris/camera_render.py).

Argument Description
HourLocal Local clock time, h (0 to 24).

Returns: Empty on success, otherwise why the settings were rejected (nothing changes).

Note

Any thread; takes the internal lock.

FString SetClock(int Year, int Month, int Day, double HourLocal);

FAcresEnvironmentRuntime::SetWeather#

Changes the sky and rain from now on (the simulator control's set_conditions): the model restarts at the current local date and time with the preset's clouds and fog, keeping every other setting and the seed.

Argument Description
Preset "clear", "fair", "overcast", "rain" (overcast, 8 mm/h), "storm" (overcast, 30 mm/h), "fog" (overcast, 300 m visibility), or empty to keep the sky.
RainMmH Rain rate, mm/h, from now on; negative takes the preset's (or, without a preset, returns to the scheduled rain).

Returns: Empty on success, otherwise why nothing changed.

Note

Any thread; takes the internal lock.

FString SetWeather(const FString& Preset, double RainMmH);

FAcresEnvironmentRuntime::Summary#

One-line HUD and log text: day, time, temperature, humidity, sun, cloud, rain, wind, visibility, speed.

FString Summary() const;

FAcresEnvironmentRuntime::ToJson#

Settings echo for episode logs (date, clock, temperatures, wind, clouds, rain plan, seed, fog). FJsonObject is Unreal's JSON DOM; TSharedPtr is its shared_ptr.

TSharedPtr<FJsonObject> ToJson() const;

FAcresEnvironmentRuntime::Settings#

Copy of the settings in use. Safe from any thread.

AcresEnv::Settings Settings() const ;

FAcresEnvironmentRuntime::LoadSettings#

Reads an environment.json file into Out and checks physical ranges.

Only keys present in the file are changed. Accepted blocks: clock (date "YYYY-MM-DD", start_hour_local, utc_offset_h, seconds_per_game_minute), site (latitude_deg, longitude_deg), temperature (low_c, high_c, day_to_day_sigma_c), wind (speed_mps, from_deg, turbulence_intensity, roughness_m), clouds ("clear", "fair", "partly", "overcast"), rain (enabled, start_hour, end_hour, total_mm, prior_mm, prior_hours), fog (mode "auto", "off" or "fixed", visibility_m) and seed.

Argument Description
Path File path.
Out Settings to update in place.
Error Set to the first problem found (unreadable file or out-of-range value).

Returns: True if the file parsed and all checks passed. On false, Out is left unchanged.

static bool LoadSettings(const FString& Path, AcresEnv::Settings& Out, FString& Error);

Example

AcresEnv::Settings S;
FString Error;
if (!FAcresEnvironmentRuntime::LoadSettings(Path, S, Error)) UE_LOG(LogTemp, Error, TEXT("%s"), *Error);