CARLA
ProceduralBuilding.h
Go to the documentation of this file.
1 // Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de Barcelona (UAB). This work is licensed under the terms of the MIT license. For a copy, see <https://opensource.org/licenses/MIT>.
2 
3 #pragma once
4 
5 #include "CoreMinimal.h"
6 #include "GameFramework/Actor.h"
7 
8 #include "Components/HierarchicalInstancedStaticMeshComponent.h"
9 
10 #include "ProceduralBuilding.generated.h"
11 
12 
13 // TODO: support n-sides building
14 
16 {
17  TArray<UStaticMesh*>* MainMeshes = nullptr;
18  TArray<TSubclassOf<AActor>>* MainBPs = nullptr;
19  TArray<UStaticMesh*>* CornerMeshes = nullptr;
20  TArray<TSubclassOf<AActor>>* CornerBPs = nullptr;
21  TArray<UStaticMesh*>* AuxiliarMeshes = nullptr;
22  TArray<TSubclassOf<AActor>>* AuxiliarBPs = nullptr;
23 };
24 
25 UCLASS()
26 class CARLA_API AProceduralBuilding : public AActor
27 {
28  GENERATED_BODY()
29 
30 public:
31 
32  // Sets default values for this actor's properties
34 
35  // Looks for the HISMComp on the HISMComps Map that uses the SelectedMesh and returns it.
36  // If doesn't exist its created
37  UFUNCTION(BlueprintCallable, Category="Procedural Building")
38  UHierarchicalInstancedStaticMeshComponent* GetHISMComp(const UStaticMesh* SM);
39 
40  UFUNCTION(BlueprintCallable, CallInEditor, Category="Procedural Building")
41  void ConvertOldBP_ToNativeCodeObject(AActor* BP_Building);
42 
43  UFUNCTION(BlueprintCallable, CallInEditor, Category="Procedural Building")
44  void HideAllChildren();
45 
46  UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion")
47  void SetBaseParameters(
48  const TSet<int>& InDoorsIndexPosition,
49  const TArray<bool>& InUseWallMesh,
50  int InNumFloors,
51  int InLengthX,
52  int InLengthY,
53  bool InCorners,
54  bool InUseFullBlocks);
55 
56  UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion")
57  void SetVisibilityParameters(
58  const TArray<bool>& InSideVisibility,
59  const TArray<bool>& InCornerVisibility,
60  bool InRoofVisibility);
61 
62  UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion")
63  void SetBaseMeshes(
64  const TArray<UStaticMesh*>& InBaseMeshes,
65  const TArray<TSubclassOf<AActor>>& InBaseBPs,
66  const TArray<UStaticMesh*>& InCornerBaseMeshes,
67  const TArray<TSubclassOf<AActor>>& InCornerBaseBPs,
68  const TArray<UStaticMesh*>& InDoorMeshes,
69  const TArray<TSubclassOf<AActor>>& InDoorBPs);
70 
71  UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion")
72  void SetBodyMeshes(
73  const TArray<UStaticMesh*>& InBodyMeshes,
74  const TArray<TSubclassOf<AActor>>& InBodyBPs,
75  const TArray<UStaticMesh*>& InCornerBodyMeshes,
76  const TArray<TSubclassOf<AActor>>& InCornerBodyBPs,
77  const TArray<UStaticMesh*>& InWallMeshes,
78  const TArray<TSubclassOf<AActor>>& InWallBPs);
79 
80  UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion")
81  void SetTopMeshes(
82  const TArray<UStaticMesh*>& InTopMeshes,
83  const TArray<TSubclassOf<AActor>>& InTopBPs,
84  const TArray<UStaticMesh*>& InCornerTopMeshes,
85  const TArray<TSubclassOf<AActor>>& InCornerTopBPs,
86  const TArray<UStaticMesh*>& InRoofMeshes,
87  const TArray<TSubclassOf<AActor>>& InRoofBPs);
88 
89 protected:
90 
91  UFUNCTION(BlueprintCallable, CallInEditor, Category="Procedural Building")
92  void CreateBuilding();
93 
94  UFUNCTION(BlueprintCallable, CallInEditor, Category="Procedural Building")
95  void Reset();
96 
97  UFUNCTION(BlueprintCallable, CallInEditor, Category="Procedural Building")
98  void FixMobility();
99 
100  // TODO: AdvancedDisplay
101  // Map containing the pair with the name of the mesh and the component that uses it
102  UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Procedural Building|Debug")
103  TMap<FString, UHierarchicalInstancedStaticMeshComponent*> HISMComps;
104 
105  // Contains all the ChildActorComps spawned for this Actor
106  UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Procedural Building|Debug")
107  TArray<UChildActorComponent*> ChildActorComps;
108 
109  UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Procedural Building")
110  UStaticMeshComponent* RootSMComp = nullptr;
111 
112  /**
113  * Base Parameters
114  */
115 
116  // Set to contain the index of the doors that need to be placed on the base floor
117  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters", meta=(ToolTip="Index to indicate where the door is placed"))
118  TSet<int> DoorsIndexPosition;
119 
120  // Indicates if the wall has to be filled with the wall-mesh or the body-mesh
121  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters", meta=(ToolTip="True to use wall-mesh instead of body-mesh"))
122  TArray<bool> UseWallMesh;
123 
124  // Number of floors for the building, base and roof not included
125  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters", meta=(ClampMin="0", UIMin="0", ToolTip="Number of floors for the building, base and roof not included"))
126  int NumFloors = 0;
127 
128  // Number of elements in X Axis
129  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters")
130  int LengthX = 0;
131 
132  // Number of elements in Y Axis
133  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters")
134  int LengthY = 0;
135 
136  // Enables the corners of the building
137  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters")
138  bool Corners = false;
139 
140  // Indicates if the meshes that are used on this buildings fill the whole floor
141  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters")
142  bool UseFullBlocks = false;
143 
144  /**
145  * Base Parameters | Visibility
146  */
147 
148  // True to render the side of the building. Each index represents the side
149  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters|Visibility")
150  TArray<bool> SideVisibility;
151 
152  // True to render the corner of the building. Each index represents the corner
153  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters|Visibility")
154  TArray<bool> CornerVisibility;
155 
156  // True to render the roof
157  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters|Visibility")
158  bool RoofVisibility = true;
159 
160 
161  /**
162  * Meshes
163  */
164 
165  /**
166  * Meshes | Base
167  */
168 
169  // Pool of meshes to be randomly selected for the base floor
170  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base")
171  TArray<UStaticMesh*> BaseMeshes;
172 
173  // Pool of BPs to be randomly selected for the base floor
174  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base")
175  TArray<TSubclassOf<AActor>> BaseBPs;
176 
177  // Pool of meshes to be randomly selected for doors
178  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base")
179  TArray<UStaticMesh*> DoorMeshes;
180 
181  // Pool of BPs to be randomly selected for doors
182  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base")
183  TArray<TSubclassOf<AActor>> DoorBPs;
184 
185  // Pool of meshes to be randomly selected for the corners of the base floor
186  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base")
187  TArray<UStaticMesh*> CornerBaseMeshes;
188 
189  // Pool of BPs to be randomly selected for the corners of the base floor
190  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base")
191  TArray<TSubclassOf<AActor>> CornerBaseBPs;
192 
193  /**
194  * Meshes | Body
195  */
196 
197  // Pool of meshes to be randomly selected for the body
198  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body")
199  TArray<UStaticMesh*> BodyMeshes;
200 
201  // Pool of BPs to be randomly selected for the body
202  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body")
203  TArray<TSubclassOf<AActor>> BodyBPs;
204 
205  // Pool of meshes to be randomly selected for the walls of the body
206  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body")
207  TArray<UStaticMesh*> WallMeshes;
208 
209  // Pool of BPs to be randomly selected for the body walls of the body
210  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body")
211  TArray<TSubclassOf<AActor>> WallBPs;
212 
213  // Pool of meshes to be randomly selected for the corners of the body floor
214  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body")
215  TArray<UStaticMesh*> CornerBodyMeshes;
216 
217  // Pool of BPs to be randomly selected for the corners of the body floor
218  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body")
219  TArray<TSubclassOf<AActor>> CornerBodyBPs;
220 
221  /**
222  * Meshes | Top
223  */
224 
225  // Pool of meshes to be randomly selected for the top
226  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top")
227  TArray<UStaticMesh*> TopMeshes;
228 
229  // Pool of BPs to be randomly selected for the top
230  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top")
231  TArray<TSubclassOf<AActor>> TopBPs;
232 
233  // Pool of meshes to be randomly selected for the corners of the top
234  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top")
235  TArray<UStaticMesh*> CornerTopMeshes;
236 
237  // Pool of BPs to be randomly selected for the corners of the top
238  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top")
239  TArray<TSubclassOf<AActor>> CornerTopBPs;
240 
241  // Pool of meshes to be randomly selected for the roof
242  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top")
243  TArray<UStaticMesh*> RoofMeshes;
244 
245  // Pool of BPs to be randomly selected for the roof
246  UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top")
247  TArray<TSubclassOf<AActor>> RoofBPs;
248 
249 private:
250 
251  void Init();
252 
253  void CreateFloor(const FloorMeshCollection& MeshCollection, bool IncludeDoors, bool IncludeWalls);
254 
255  void CreateRoof();
256 
257  // Creates the side of a floor of the building and returns the maximun height of the side
258  float CreateSide(
259  const FloorMeshCollection& MeshCollection,
260  const TSet<int>& AuxiliarPositions,
261  int SideLength,
262  bool MainVisibility,
263  bool CornerVisbility);
264 
265  void CalculateSidesLength();
266 
267  // Calculates the doors of DoorsIndexPosition inside the range between [StartIndex, StartIndex + Length)
268  // The set returns the position (index) of the doors relative to the side, ie: [0, Length)
269  TSet<int> CalculateDoorsIndexInSide(int StartIndex, int Length);
270 
271  //
272  TSet<int> GenerateWallsIndexPositions(int Length);
273 
274  // Check if the main and corner part of the side is visible
275  void CalculateSideVisibilities(int SideIndex, bool& MainVisibility, bool& CornerVisbility);
276 
277  // Choose randomly between the Mesh and BP containers, only one option will be returned.
278  void ChooseGeometryToSpawn(
279  const TArray<UStaticMesh*>& InMeshes,
280  const TArray<TSubclassOf<AActor>>& InMainBPs,
281  UStaticMesh** OutMesh,
282  TSubclassOf<AActor>* OutBP);
283 
284  // Add one part on the side
285  float AddChunck(
286  const UStaticMesh* SelectedMesh,
287  const TSubclassOf<AActor> SelectedBP,
288  bool Visible,
289  FBox& OutSelectedMeshBounds);
290 
291  // Add the Static Mesh on the transform location with the transform orientation
292  void AddMeshToBuilding(const UStaticMesh* SM);
293 
294  // Calculate the Bounds for the Static Mesh
295  FVector GetMeshSize(const UStaticMesh* SM);
296 
297  void UpdateTransformPositionToNextChunk(const FVector& Box);
298 
299  void UpdateTransformPositionToNextSide(const FBox& Box);
300 
301  // The lengths of each side of the building. The length of the array is the number of sides
302  // Helper to iterate throught all the sides of the building
303  TArray<int> SidesLength;
304 
305  // Transform used to spawn the meshes of the building. It is updated (moved) with each new mesh
306  FTransform CurrentTransform = FTransform::Identity;
307 
308  FBox LastSelectedMeshBounds;
309 
310 };
TArray< TSubclassOf< AActor > > * MainBPs
TArray< TSubclassOf< AActor > > * AuxiliarBPs
TArray< UStaticMesh * > * MainMeshes
TArray< TSubclassOf< AActor > > * CornerBPs
TArray< UStaticMesh * > * AuxiliarMeshes
bg::model::box< Point3D > Box
Definition: InMemoryMap.h:52
TArray< UStaticMesh * > * CornerMeshes