Cesium for Unreal 2.13.2
Loading...
Searching...
No Matches
CesiumSunSky.h
Go to the documentation of this file.
1// Copyright 2020-2024 CesiumGS, Inc. and Contributors
2
3#pragma once
4
5#include "CoreMinimal.h"
6
8#include "Components/DirectionalLightComponent.h"
9#include "Components/SkyAtmosphereComponent.h"
10#include "Components/SkyLightComponent.h"
11#include "Components/StaticMeshComponent.h"
12#include "Engine/DirectionalLight.h"
13#include "GameFramework/Actor.h"
14#include "CesiumSunSky.generated.h"
15
17
18/**
19 * A globe-aware sun sky actor. If the georeference is set to CartographicOrigin
20 * (aka Longitude/Latitude/Height) mode, then this actor will automatically
21 * sync its longitude and latitude properties with the georeference's, and
22 * recalculate the sun position whenever those properties change.
23 *
24 * Note: because we use `Planet Center at Component Transform`
25 * for the SkyAtmosphere transform mode, this actor's location will be forced
26 * to the Earth's center if the georeference is set to CartographicOrigin.
27 */
28UCLASS()
29class CESIUMRUNTIME_API ACesiumSunSky : public AActor {
30 GENERATED_BODY()
31
32public:
33 // Sets default values for this actor's properties
35
36 UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
37 USceneComponent* Scene;
38
39 UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
40 USkyLightComponent* SkyLight;
41
42 UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
43 UDirectionalLightComponent* DirectionalLight;
44
45 UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
46 USkyAtmosphereComponent* SkyAtmosphere;
47
48 /**
49 * The Globe Anchor Component that precisely ties this Actor to the Globe.
50 */
51 UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
53
54 /**
55 * Gets the time zone, represented as hours offset from GMT.
56 *
57 * After changing this value from Blueprints or C++, you must call UpdateSun
58 * for it to take effect.
59 */
60 UPROPERTY(
61 EditAnywhere,
62 BlueprintReadWrite,
63 Category = "Cesium|Date and Time",
64 meta = (ClampMin = -12, ClampMax = 14))
65 double TimeZone = -5.0;
66
67 /**
68 * The current solar time represented as hours from midnight.
69 *
70 * After changing this value from Blueprints or C++, you must call UpdateSun
71 * for it to take effect.
72 */
73 UPROPERTY(
74 EditAnywhere,
75 BlueprintReadWrite,
76 Category = "Cesium|Date and Time",
77 meta = (UIMin = 4, UIMax = 22, ClampMin = 0, ClampMax = 23.9999))
78 double SolarTime = 13.0;
79
80 /**
81 * The day of the month.
82 *
83 * After changing this value from Blueprints or C++, you must call UpdateSun
84 * for it to take effect.
85 */
86 UPROPERTY(
87 EditAnywhere,
88 BlueprintReadWrite,
89 Category = "Cesium|Date and Time",
90 meta = (ClampMin = 1, ClampMax = 31))
91 int32 Day = 21;
92
93 /**
94 * The month of the year, where 1 is January and 12 is December.
95 *
96 * After changing this value from Blueprints or C++, you must call UpdateSun
97 * for it to take effect.
98 */
99 UPROPERTY(
100 EditAnywhere,
101 BlueprintReadWrite,
102 Category = "Cesium|Date and Time",
103 meta = (ClampMin = 1, ClampMax = 12))
104 int32 Month = 9;
105
106 /**
107 * The year.
108 *
109 * After changing this value from Blueprints or C++, you must call UpdateSun
110 * for it to take effect.
111 */
112 UPROPERTY(
113 EditAnywhere,
114 BlueprintReadWrite,
115 Category = "Cesium|Date and Time",
116 meta = (UIMin = 1800, UIMax = 2200, ClampMin = 0, ClampMax = 4000))
117 int32 Year = 2019;
118
119 /**
120 * Offset in the sun's position. Should be set to -90 for the sun's position
121 * to be accurate in the Unreal reference frame.
122 *
123 * After changing this value from Blueprints or C++, you must call UpdateSun
124 * for it to take effect.
125 */
126 UPROPERTY(
127 BlueprintReadWrite,
128 Category = "Cesium|Date and Time",
129 meta = (ClampMin = -360, ClampMax = 360))
130 double NorthOffset = -90.0;
131
132 /**
133 * Enables adjustment of the Solar Time for Daylight Saving Time (DST).
134 *
135 * After changing this value from Blueprints or C++, you must call UpdateSun
136 * for it to take effect.
137 */
138 UPROPERTY(
139 EditAnywhere,
140 BlueprintReadWrite,
141 Category = "Cesium|Date and Time|Daylight Savings")
142 bool UseDaylightSavingTime = true;
143
144protected:
145 /**
146 * THIS PROPERTY IS DEPRECATED.
147 *
148 * Get the Georeference instance from the Globe Anchor Component instead.
149 */
150 UPROPERTY(
151 BlueprintReadOnly,
152 Category = "Cesium",
153 BlueprintGetter = GetGeoreference,
154 Meta =
155 (DeprecatedProperty,
156 DeprecationMessage =
157 "Get the Georeference instance from the Globe Anchor Component instead."))
158 ACesiumGeoreference* Georeference_DEPRECATED;
159
160 /**
161 * Gets the Georeference Actor associated with this instance. It is obtained
162 * from the Globe Anchor Component.
163 */
164 UFUNCTION(BlueprintGetter, Category = "Cesium")
166
167 /**
168 * Set the Date at which DST starts in the current year.
169 *
170 * After changing this value from Blueprints or C++, you must call UpdateSun
171 * for it to take effect.
172 */
173 UPROPERTY(
174 EditAnywhere,
175 BlueprintReadWrite,
176 Category = "Cesium|Date and Time|Daylight Savings",
177 meta = (ClampMin = 1, ClampMax = 12),
178 meta = (EditCondition = "UseDaylightSavingTime"))
179 int32 DSTStartMonth = 3;
180
181 /**
182 * Set the Date at which DST starts in the current year.
183 *
184 * After changing this value from Blueprints or C++, you must call UpdateSun
185 * for it to take effect.
186 */
187 UPROPERTY(
188 EditAnywhere,
189 BlueprintReadWrite,
190 Category = "Cesium|Date and Time|Daylight Savings",
191 meta = (ClampMin = 1, ClampMax = 31),
192 meta = (EditCondition = "UseDaylightSavingTime"))
193 int32 DSTStartDay = 10;
194
195 /**
196 * Set the Date at which DST ends in the current year.
197 *
198 * After changing this value from Blueprints or C++, you must call UpdateSun
199 * for it to take effect.
200 */
201 UPROPERTY(
202 EditAnywhere,
203 BlueprintReadWrite,
204 Category = "Cesium|Date and Time|Daylight Savings",
205 meta = (ClampMin = 1, ClampMax = 12),
206 meta = (EditCondition = "UseDaylightSavingTime"))
207 int32 DSTEndMonth = 11;
208
209 /**
210 * Set the Date at which DST ends in the current year.
211 *
212 * After changing this value from Blueprints or C++, you must call UpdateSun
213 * for it to take effect.
214 */
215 UPROPERTY(
216 EditAnywhere,
217 BlueprintReadWrite,
218 Category = "Cesium|Date and Time|Daylight Savings",
219 meta = (ClampMin = 1, ClampMax = 31),
220 meta = (EditCondition = "UseDaylightSavingTime"))
221 int32 DSTEndDay = 3;
222
223 /**
224 * Hour of the DST Switch for both beginning and end.
225 *
226 * After changing this value from Blueprints or C++, you must call UpdateSun
227 * for it to take effect.
228 */
229 UPROPERTY(
230 EditAnywhere,
231 BlueprintReadWrite,
232 Category = "Cesium|Date and Time|Daylight Savings",
233 meta = (ClampMin = 0, ClampMax = 23),
234 meta = (EditCondition = "UseDaylightSavingTime"))
235 int32 DSTSwitchHour = 2;
236
237 /**
238 * Updates the atmosphere automatically given current player pawn's longitude,
239 * latitude, and height. Fixes artifacts seen with the atmosphere rendering
240 * when flying high above the surface, or low to the ground in high latitudes.
241 */
242 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Atmosphere")
243 bool UpdateAtmosphereAtRuntime = true;
244
245 /**
246 * When the player pawn is below this height, which is expressed in kilometers
247 * above the ellipsoid, this Actor will use an atmosphere ground radius that
248 * is calculated to be at or below the terrain surface at the player pawn's
249 * current location. This avoids a gap between the bottom of the atmosphere
250 * and the top of the terrain when zoomed in close to the terrain surface.
251 *
252 * Above CircumscribedGroundThreshold, this Actor will use an atmosphere
253 * ground radius that is guaranteed to be above the terrain surface anywhere
254 * on Earth. This avoids artifacts caused by terrain poking through the
255 * atmosphere when viewing the Earth from far away.
256 *
257 * At player pawn heights in between InscribedGroundThreshold and
258 * CircumscribedGroundThreshold, this Actor uses a linear interpolation
259 * between the two ground radii.
260 *
261 * This value is automatically scaled according to the CesiumGeoreference
262 * Scale and the Actor scale.
263 */
264 UPROPERTY(
265 EditAnywhere,
266 BlueprintReadWrite,
267 meta = (EditCondition = "UpdateAtmosphereAtRuntime"),
268 Category = "Cesium|Atmosphere")
269 double InscribedGroundThreshold = 30.0;
270
271 /**
272 * When the player pawn is above this height, which is expressed in kilometers
273 * above the ellipsoid, this Actor will use an atmosphere ground radius that
274 * is guaranteed to be above the terrain surface anywhere on Earth. This
275 * avoids artifacts caused by terrain poking through the atmosphere when
276 * viewing the Earth from far away.
277 *
278 * Below InscribedGroundThreshold, this Actor will use an atmosphere
279 * ground radius that is calculated to be at or below the terrain surface at
280 * the player pawn's current location. This avoids a gap between the bottom of
281 * the atmosphere and the top of the terrain when zoomed in close to the
282 * terrain surface.
283 *
284 * At heights in between InscribedGroundThreshold and
285 * CircumscribedGroundThreshold, this Actor uses a linear interpolation
286 * between the two ground radii.
287 *
288 * This value is automatically scaled according to the CesiumGeoreference
289 * Scale and the Actor scale.
290 */
291 UPROPERTY(
292 EditAnywhere,
293 BlueprintReadWrite,
294 meta = (EditCondition = "UpdateAtmosphereAtRuntime"),
295 Category = "Cesium|Atmosphere")
296 double CircumscribedGroundThreshold = 100.0;
297
298 /**
299 * The height at which to place the bottom of the atmosphere when the player
300 * pawn is above the CircumscribedGroundThreshold. This is expressed as a
301 * height in kilometers above the maximum radius of the ellipsoid (usually
302 * WGS84). To avoid dark splotchy artifacts in the atmosphere when zoomed out
303 * far from the globe, this value must be above the greatest height achieved
304 * by any part of the tileset.
305 */
306 UPROPERTY(
307 EditAnywhere,
308 BlueprintReadWrite,
309 meta = (EditCondition = "UpdateAtmosphereAtRuntime"),
310 Category = "Cesium|Atmosphere")
311 double CircumscribedGroundHeight = 0.0;
312
313 /**
314 * The height of the atmosphere layer above the ground, in kilometers. This
315 * value is automatically scaled according to the CesiumGeoreference Scale and
316 * the Actor scale. However, Unreal Engine's SkyAtmosphere has a hard-coded
317 * minimum effective value of 0.1, so the atmosphere will look too thick when
318 * the globe is scaled down drastically.
319 */
320 UPROPERTY(
321 EditAnywhere,
322 BlueprintReadOnly,
323 interp,
324 Category = "Cesium|Atmosphere",
325 meta = (UIMin = 1.0, UIMax = 200.0, ClampMin = 0.1, SliderExponent = 2.0))
326 float AtmosphereHeight = 60.0f;
327
328 /**
329 * Makes the aerial perspective look thicker by scaling distances from view
330 * to surfaces (opaque and translucent). This value is automatically scaled
331 * according to the CesiumGeoreference Scale and the Actor scale.
332 */
333 UPROPERTY(
334 EditAnywhere,
335 BlueprintReadOnly,
336 interp,
337 Category = "Cesium|Atmosphere",
338 meta =
339 (DisplayName = "Aerial Perspective View Distance Scale",
340 UIMin = 0.0,
341 UIMax = 3.0,
342 ClampMin = 0.0,
343 SliderExponent = 2.0))
344 float AerialPerspectiveViewDistanceScale = 1.0f;
345
346 /**
347 * The altitude in kilometers at which Rayleigh scattering effect is reduced
348 * to 40%. This value is automatically scaled according to the
349 * CesiumGeoreference Scale and the Actor scale.
350 */
351 UPROPERTY(
352 EditAnywhere,
353 BlueprintReadOnly,
354 interp,
355 Category = "Cesium|Atmosphere",
356 meta =
357 (UIMin = 0.01, UIMax = 20.0, ClampMin = 0.001, SliderExponent = 5.0))
358 float RayleighExponentialDistribution = 8.0f;
359
360 /**
361 * The altitude in kilometers at which Mie effects are reduced to 40%. This
362 * value is automatically scaled according to the CesiumGeoreference Scale and
363 * the Actor scale.
364 */
365 UPROPERTY(
366 EditAnywhere,
367 BlueprintReadOnly,
368 interp,
369 Category = "Cesium|Atmosphere",
370 meta =
371 (UIMin = 0.01, UIMax = 10.0, ClampMin = 0.001, SliderExponent = 5.0))
372 float MieExponentialDistribution = 1.2f;
373
374 /**
375 * False: Use Directional Light component inside CesiumSunSky.
376 * True: Use the assigned Directional Light in the level.
377 */
378 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Sun")
379 bool UseLevelDirectionalLight = false;
380
381 /**
382 * Reference to a manually assigned Directional Light in the level.
383 */
384 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Sun")
385 ADirectionalLight* LevelDirectionalLight;
386
387 /**
388 * The current sun elevation in degrees above the horizontal, as viewed from
389 * the Georeference origin.
390 */
391 UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sun")
392 double Elevation = 0.f;
393
394 /**
395 * The current sun elevation, corrected for atmospheric diffraction, in
396 * degrees above the horizontal, as viewed from the Georeference origin.
397 */
398 UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sun")
399 double CorrectedElevation = 0.f;
400
401 /**
402 * The current sun azimuth in degrees clockwise from North toward East, as
403 * viewed from the Georeference origin.
404 */
405 UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sun")
406 double Azimuth = 0.f;
407
408 /**
409 * A switch to toggle between desktop and mobile rendering code paths.
410 * This will NOT be automatically set when running on mobile, so make sure
411 * to check this setting before building on mobile platforms.
412 */
413 UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Cesium|Mobile")
414 bool UseMobileRendering;
415
416 /**
417 * Mobile platforms currently do not support the SkyAtmosphereComponent.
418 * In lieu of that, use the engine BP_Sky_Sphere class, or a derived class.
419 */
420 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Mobile")
421 TSubclassOf<AActor> SkySphereClass;
422
423 /**
424 * Reference to BP_Sky_Sphere or similar actor (mobile only)
425 */
426 UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Cesium|Mobile")
427 AActor* SkySphereActor;
428
429 /**
430 * Default intensity of directional light that's spawned for mobile rendering.
431 */
432 UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Cesium|Mobile")
433 double MobileDirectionalLightIntensity = 6.f;
434
435public:
436 UFUNCTION(
437 CallInEditor,
438 BlueprintCallable,
439 BlueprintNativeEvent,
440 Category = "Cesium")
441 void UpdateSun();
442 void UpdateSun_Implementation();
443
444 UFUNCTION(CallInEditor, BlueprintCallable, Category = "Cesium")
445 void UpdateAtmosphereRadius();
446
447 /**
448 * Adjusts the time zone of this CesiumSunSky to an estimate based on the
449 * given longitude.
450 *
451 * The time zone is naively calculated from the longitude, where every
452 * 15 degrees equals 1 hour. This may not necessarily match the official
453 * time zone at a given location within that longitude.
454 *
455 * This method will call @ref UpdateSun automatically.
456 *
457 * @param InLongitude The longitude that the calculated time zone will be
458 * based on in degrees in the range [-180, 180].
459 */
460 UFUNCTION(CallInEditor, BlueprintCallable, Category = "Cesium")
461 void EstimateTimeZoneForLongitude(double InLongitude);
462
463 /**
464 * Convert solar time to Hours:Minutes:Seconds. Copied the implementation
465 * from the engine SunSkyBP class.
466 */
467 UFUNCTION(BlueprintCallable, BlueprintPure, Category = Sun)
468 static void GetHMSFromSolarTime(
469 double InSolarTime,
470 int32& Hour,
471 int32& Minute,
472 int32& Second);
473
474 /**
475 * Check whether the current time and date (based on this class instance's
476 * properties) falls within Daylight Savings Time. Copied the implementation
477 * from the engine SunSkyBP class.
478 */
479 UFUNCTION(BlueprintCallable, BlueprintPure, Category = Sun)
480 bool IsDST(
481 bool DSTEnable,
482 int32 InDSTStartMonth,
483 int32 InDSTStartDay,
484 int32 InDSTEndMonth,
485 int32 InDSTEndDay,
486 int32 InDSTSwitchHour) const;
487
488 // Begin AActor Interface
489 /**
490 * Gets called when the actor is first created, and when properties are
491 * changed at edit-time. Refreshes the actor's position w/r/t the georeference
492 * and handles mobile-specific setup if needed.
493 */
494 virtual void OnConstruction(const FTransform& Transform) override;
495 // End AActor Interface
496
497protected:
498 /**
499 * Modifies the sky atmosphere's ground radius, which represents the Earth's
500 * radius in the SkyAtmosphere rendering model. Only changes if there's a >0.1
501 * difference, to reduce redraws.
502 *
503 * @param Sky A pointer to the SkyAtmosphereComponent
504 * @param Radius The radius in kilometers.
505 */
506 UFUNCTION(BlueprintCallable, Category = "Cesium")
507 void
508 SetSkyAtmosphereGroundRadius(USkyAtmosphereComponent* Sky, double Radius);
509
510 /**
511 * Update MobileSkySphere by calling its RefreshMaterial function
512 */
513 UFUNCTION(BlueprintCallable, Category = "Mobile")
514 void UpdateSkySphere();
515
516 virtual void BeginPlay() override;
517 virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
518 virtual void Serialize(FArchive& Ar) override;
519 virtual void Tick(float DeltaSeconds) override;
520 virtual void PostLoad() override;
521 virtual bool ShouldTickIfViewportsOnly() const override;
522
523#if WITH_EDITOR
524 virtual void
525 PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
526#endif
527
528private:
529 void _spawnSkySphere();
530 double _computeScale() const;
531
532 // Sets Directional Light Component in Sky Sphere actor
533 void _setSkySphereDirectionalLight();
534
535 void _setSkyAtmosphereVisibility(bool bVisible);
536
537 // Determines whether mobile sky sphere will be spawned during OnConstruction.
538 bool _wantsSpawnMobileSkySphere;
539
540 void _handleTransformUpdated(
541 USceneComponent* InRootComponent,
542 EUpdateTransformFlags UpdateTransformFlags,
543 ETeleportType Teleport);
544
545 FDelegateHandle _transformUpdatedSubscription;
546};
Controls how global geospatial coordinates are mapped to coordinates in the Unreal Engine level.
A globe-aware sun sky actor.
This component can be added to a movable actor to anchor it to the globe and maintain precise placeme...
virtual void Serialize(FArchive &Ar) override
Handles reading, writing, and reference collecting using FArchive.
TSoftObjectPtr< ACesiumGeoreference > GetGeoreference() const
Gets the designated georeference actor controlling how the owning actor's coordinate system relates t...