Agrarsense
InstancedRenderer.h
Go to the documentation of this file.
1// Copyright (c) 2023 FrostBit Software Lab at the Lapland University of Applied Sciences
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
6#pragma once
7
8#include "CoreMinimal.h"
9#include "GameFramework/Actor.h"
10#include "Engine/EngineTypes.h"
11#include "Engine/StaticMesh.h"
12#include "Materials/MaterialInterface.h"
13#include "Components/InstancedStaticMeshComponent.h"
14#include "Components/StaticMeshComponent.h"
15
16#include <vector>
17
21#include "InstancedActorData.h"
22#include "InstancedActor.h"
23
24#include "InstancedRenderer.generated.h"
25
26USTRUCT(Blueprintable)
27struct AGRARSENSE_API FInstanceEntry
28{
29 GENERATED_BODY()
30
31 UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
32 UInstancedStaticMeshComponent* InstancedStaticMeshComponent;
33
34 UPROPERTY(EditAnywhere, BlueprintReadWrite)
35 TSubclassOf<AActor> ActorClass;
36
37 UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
38 TWeakObjectPtr<UStaticMesh> Mesh;
39
40 UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
41 TArray<UMaterialInterface*> Materials;
42
43 UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
44 int32 InstanceEntryIndex = 0;
45
46 UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
47 int32 CustomDepthStencilValue;
48
49 UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
50 bool AllowWorldPositionOffsetDisable = false;
51
52 UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
53 bool IsTree = false;
54
55 bool UsingProxy = false;
56};
57
74UCLASS()
75class AGRARSENSE_API AInstancedRenderer : public AActor
76{
77 GENERATED_BODY()
78
79public:
80
81 AInstancedRenderer(const FObjectInitializer& ObjectInitializer);
82
83 /*
84 * Try to add AInstancedActor into instanced rendering. This is only callable from C++ by design.
85 * @param AInstancedActor AInstancedActor pointer
86 */
87 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
88 bool AddActorToInstancedRendering(AInstancedActor* InstancedActor);
89
90 /*
91 * Remove instance from this Renderer.
92 * @param ComponentIndex index to TArray<UInstancedStaticMeshComponent*>
93 * @param InstanceNumber instance number
94 */
95 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
96 void RemoveInstance(int32 ComponentIndex, int32 InstanceNumber);
97
98 /*
99 * Update one of the instances transform
100 * @param ComponentIndex index to TArray<UInstancedStaticMeshComponent*>
101 * @param InstanceNumber instance number
102 * @param NewTransform Transform to move the instance
103 */
104 void UpdateInstanceTransform(int32 ComponentIndex, int32 InstanceNumber, const FTransform& NewTransform);
105
106 /*
107 * Is this renderer currently rendering all InstancedStaticMeshComponents
108 */
109 UFUNCTION(BlueprintPure, Category = "Instanced Renderer")
110 bool IsRendering() const
111 {
112 return Rendering;
113 }
114
115 /*
116 * Get number of total instances
117 * @return TotalInstanceCount number of total instances
118 */
119 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
120 int32 GetTotalInstanceCount() const
121 {
122 return TotalInstanceCount;
123 }
124
125 /*
126 * Get number of unique instances
127 * @return number of InstancedStaticMeshComponents
128 */
129 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
130 int32 GetUniqueInstancesCount() const
131 {
132 return InstanceEntries.Num();
133 }
134
135 /*
136 * Get Mesh entries TArray
137 * @return TArray<FMeshEntry>
138 */
139 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
140 TArray<FInstanceEntry> GetInstanceEntries() const
141 {
142 return InstanceEntries;
143 }
144
145 /*
146 * Set Instanced Rendering on/off. Debugging purposes.
147 */
148 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
149 void SetInstancedRendering(bool ShouldRender);
150
156 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
157 void SetComponentIndexVisibility(int32 Index, bool Visible);
158
163 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
164 void SetRenderCustomDepth(bool Enabled);
165
170 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
171 void SetWorldPositionOffsetDistance(int32 NewWPODistance);
172
177 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
178 void SetShadowCacheBehaviour(EShadowCacheInvalidationBehavior ShadowCacheInvalidationBehaviour);
179
184 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
185 void SetRenderWorldPositionOffet(bool RenderWPO);
186
187 /*
188 * Log renderer info to console. Debugging purposes.
189 */
190 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
191 void LogInfo() const;
192
193 /*
194 * Toggles instanced static mesh materials between Unreal's default and their original. Debugging purposes.
195 * @param SetUnrealDefaultMaterial - If true, uses the default material; if false, restores original materials.
196 */
197 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
198 void DebugMaterialImpact(bool SetUnrealDefaultMaterial);
199
200 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
201 void ToggleProxyMesh();
202
203 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
204 void SpawnAllInstancesBackActors();
205
206 /*
207 * Spawn speficic ISM instance back to original Actor.
208 */
209 UFUNCTION(BlueprintCallable, Category = "Instanced Renderer")
210 bool SpawnInstanceBackToActor(UInstancedStaticMeshComponent* ISM, int32 Index);
211
212 static AInstancedRenderer* Get()
213 {
214 return Instance;
215 }
216
217protected:
218
223 UPROPERTY(VisibleAnywhere, AdvancedDisplay, BlueprintReadWrite)
224 TArray<FInstanceEntry> InstanceEntries;
225
226 UPROPERTY(BlueprintReadWrite)
227 TArray<UInstancedStaticMeshComponent*> InstancesStaticMeshComponents;
228
229 UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
230 int32 TotalInstanceCount = 0;
231
232private:
233
234 TWeakObjectPtr<UStaticMesh> ProxyMesh;
235
236 static AInstancedRenderer* Instance;
237
238 virtual void BeginPlay() override;
239
240 virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
241
242 UFUNCTION()
243 void OnGraphicsSettingsChanged(FGlobalGraphicsSettings GraphicsSettings);
244
245 UFUNCTION()
246 void OnWeatherParametersChanged(FWeatherParameters WeatherParameters);
247
248 /*
249 * Find existing InstancedStaticMeshComponents array index or create new one for the mesh and its materials
250 * @return index to InstancedStaticMeshComponents array
251 */
252 int32 FindOrAddUniqueMesh(UStaticMeshComponent* StaticMeshComponent, AInstancedActor* InstancedActor);
253
257 int32 WorldPositionOffsetDistance = 30000;
258
259 FWeatherParameters CurrentWeatherParameters;
260
261 bool Rendering = true;
262
263 bool RenderingWPO = true;
264};