CARLA
 
载入中...
搜索中...
未找到
MapGenFunctionLibrary.cpp
浏览该文件的文档.
1// Copyright (c) 2023 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
8
9// Engine headers
10#include "AssetRegistry/AssetRegistryModule.h"
11#include "Materials/MaterialInstance.h"
12#include "StaticMeshAttributes.h"
13#include "RenderingThread.h"
14// Carla C++ headers
15
16// Carla plugin headers
17
18
19DEFINE_LOG_CATEGORY(LogCarlaMapGenFunctionLibrary);
20static const float OSMToCentimetersScaleFactor = 100.0f;
21
23 const FProceduralCustomMesh& Data,
24 const TArray<FProcMeshTangent>& ParamTangents,
25 UMaterialInstance* MaterialInstance )
26{
27
28 int32 VertexCount = Data.Vertices.Num();
29 int32 VertexInstanceCount = Data.Triangles.Num();
30 int32 PolygonCount = Data.Vertices.Num()/3;
31
32 FMeshDescription MeshDescription;
33 FStaticMeshAttributes AttributeGetter(MeshDescription);
34 AttributeGetter.Register();
35
36 TPolygonGroupAttributesRef<FName> PolygonGroupNames = AttributeGetter.GetPolygonGroupMaterialSlotNames();
37 TVertexAttributesRef<FVector> VertexPositions = AttributeGetter.GetVertexPositions();
38 TVertexInstanceAttributesRef<FVector> Tangents = AttributeGetter.GetVertexInstanceTangents();
39 TVertexInstanceAttributesRef<float> BinormalSigns = AttributeGetter.GetVertexInstanceBinormalSigns();
40 TVertexInstanceAttributesRef<FVector> Normals = AttributeGetter.GetVertexInstanceNormals();
41 TVertexInstanceAttributesRef<FVector4> Colors = AttributeGetter.GetVertexInstanceColors();
42 TVertexInstanceAttributesRef<FVector2D> UVs = AttributeGetter.GetVertexInstanceUVs();
43
44 // Calculate the totals for each ProcMesh element type
45 FPolygonGroupID PolygonGroupForSection;
46 MeshDescription.ReserveNewVertices(VertexCount);
47 MeshDescription.ReserveNewVertexInstances(VertexInstanceCount);
48 MeshDescription.ReserveNewPolygons(PolygonCount);
49 MeshDescription.ReserveNewEdges(PolygonCount * 2);
50 UVs.SetNumIndices(4);
51
52 // Create Materials
53 TMap<UMaterialInterface*, FPolygonGroupID> UniqueMaterials;
54 const int32 NumSections = 1;
55 UniqueMaterials.Reserve(1);
56 FPolygonGroupID NewPolygonGroup = MeshDescription.CreatePolygonGroup();
57
58 if( MaterialInstance != nullptr ){
59 UMaterialInterface *Material = MaterialInstance;
60 UniqueMaterials.Add(Material, NewPolygonGroup);
61 PolygonGroupNames[NewPolygonGroup] = Material->GetFName();
62 }else{
63 UE_LOG(LogCarla, Error, TEXT("MaterialInstance is nullptr"));
64 }
65 PolygonGroupForSection = NewPolygonGroup;
66
67
68
69 // Create the vertex
70 int32 NumVertex = Data.Vertices.Num();
71 TMap<int32, FVertexID> VertexIndexToVertexID;
72 VertexIndexToVertexID.Reserve(NumVertex);
73 for (int32 VertexIndex = 0; VertexIndex < NumVertex; ++VertexIndex)
74 {
75 const FVector &Vert = Data.Vertices[VertexIndex];
76 const FVertexID VertexID = MeshDescription.CreateVertex();
77 VertexPositions[VertexID] = Vert;
78 VertexIndexToVertexID.Add(VertexIndex, VertexID);
79 }
80
81 // Create the VertexInstance
82 int32 NumIndices = Data.Triangles.Num();
83 int32 NumTri = NumIndices / 3;
84 TMap<int32, FVertexInstanceID> IndiceIndexToVertexInstanceID;
85 IndiceIndexToVertexInstanceID.Reserve(NumVertex);
86 for (int32 IndiceIndex = 0; IndiceIndex < NumIndices; IndiceIndex++)
87 {
88 const int32 VertexIndex = Data.Triangles[IndiceIndex];
89 const FVertexID VertexID = VertexIndexToVertexID[VertexIndex];
90 const FVertexInstanceID VertexInstanceID =
91 MeshDescription.CreateVertexInstance(VertexID);
92 IndiceIndexToVertexInstanceID.Add(IndiceIndex, VertexInstanceID);
93 Normals[VertexInstanceID] = Data.Normals[VertexIndex];
94
95 if(ParamTangents.Num() == Data.Vertices.Num())
96 {
97 Tangents[VertexInstanceID] = ParamTangents[VertexIndex].TangentX;
98 BinormalSigns[VertexInstanceID] =
99 ParamTangents[VertexIndex].bFlipTangentY ? -1.f : 1.f;
100 }else{
101
102 }
103 Colors[VertexInstanceID] = FLinearColor(0,0,0);
104 if(Data.UV0.Num() == Data.Vertices.Num())
105 {
106 UVs.Set(VertexInstanceID, 0, Data.UV0[VertexIndex]);
107 }else{
108 UVs.Set(VertexInstanceID, 0, FVector2D(0,0));
109 }
110 UVs.Set(VertexInstanceID, 1, FVector2D(0,0));
111 UVs.Set(VertexInstanceID, 2, FVector2D(0,0));
112 UVs.Set(VertexInstanceID, 3, FVector2D(0,0));
113 }
114
115 for (int32 TriIdx = 0; TriIdx < NumTri; TriIdx++)
116 {
117 FVertexID VertexIndexes[3];
118 TArray<FVertexInstanceID> VertexInstanceIDs;
119 VertexInstanceIDs.SetNum(3);
120
121 for (int32 CornerIndex = 0; CornerIndex < 3; ++CornerIndex)
122 {
123 const int32 IndiceIndex = (TriIdx * 3) + CornerIndex;
124 const int32 VertexIndex = Data.Triangles[IndiceIndex];
125 VertexIndexes[CornerIndex] = VertexIndexToVertexID[VertexIndex];
126 VertexInstanceIDs[CornerIndex] =
127 IndiceIndexToVertexInstanceID[IndiceIndex];
128 }
129
130 // Insert a polygon into the mesh
131 MeshDescription.CreatePolygon(NewPolygonGroup, VertexInstanceIDs);
132
133 }
134
135 return MeshDescription;
136}
137
139 const FProceduralCustomMesh& Data,
140 const TArray<FProcMeshTangent>& ParamTangents,
141 UMaterialInstance* MaterialInstance,
142 FString MapName,
143 FString FolderName,
144 FName MeshName)
145{
146 IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
147
148 UStaticMesh::FBuildMeshDescriptionsParams Params;
149 Params.bBuildSimpleCollision = true;
150
151 FString PackageName = "/Game/CustomMaps/" + MapName + "/Static/" + FolderName + "/" + MeshName.ToString();
152
153 if (!PlatformFile.DirectoryExists(*PackageName))
154 {
155 //PlatformFile.CreateDirectory(*PackageName);
156 }
157
158
159 FMeshDescription Description = BuildMeshDescriptionFromData(Data,ParamTangents, MaterialInstance);
160
161 if (Description.Polygons().Num() > 0)
162 {
163 UPackage* Package = CreatePackage(*PackageName);
164 check(Package);
165 UStaticMesh* Mesh = NewObject<UStaticMesh>( Package, MeshName, RF_Public | RF_Standalone);
166
167 Mesh->InitResources();
168
169 Mesh->LightingGuid = FGuid::NewGuid();
170 Mesh->StaticMaterials.Add(FStaticMaterial(MaterialInstance));
171 Mesh->BuildFromMeshDescriptions({ &Description }, Params);
172 Mesh->CreateBodySetup();
173 Mesh->BodySetup->CollisionTraceFlag = ECollisionTraceFlag::CTF_UseComplexAsSimple;
174 Mesh->BodySetup->CreatePhysicsMeshes();
175 // Build mesh from source
176 Mesh->NeverStream = false;
177 TArray<UObject*> CreatedAssets;
178 CreatedAssets.Add(Mesh);
179
180 // Notify asset registry of new asset
181 FAssetRegistryModule::AssetCreated(Mesh);
182 //UPackage::SavePackage(Package, Mesh, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *(MeshName.ToString()), GError, nullptr, true, true, SAVE_NoError);
183 Package->MarkPackageDirty();
184 return Mesh;
185 }
186 return nullptr;
187}
188
189FVector2D UMapGenFunctionLibrary::GetTransversemercProjection(float lat, float lon, float lat0, float lon0)
190{
191 // earth radius in m
192 const float R = 6373000.0f;
193 float latt = FMath::DegreesToRadians(lat);
194 float lonn = FMath::DegreesToRadians(lon - lon0);
195 float latt0 = FMath::DegreesToRadians(lat0);
196 float eps = atan(tan(latt)/cos(lonn));
197 float nab = asinh(sin(lonn)/sqrt(tan(latt)*tan(latt)+cos(lonn)*cos(lonn)));
198 float x = R*nab;
199 float y = R*eps;
200 float eps0 = atan(tan(latt0)/cos(0));
201 float nab0 = asinh(sin(0)/sqrt(tan(latt0)*tan(latt0)+cos(0)*cos(0)));
202 float x0 = R*nab0;
203 float y0 = R*eps0;
204 FVector2D Result = FVector2D(x, -(y - y0)) * OSMToCentimetersScaleFactor;
205
206 return Result;
207}
208
210 //FGenericPlatformProcess::Sleep(seconds);
211}
212
214 FlushRenderingCommands(true);
215 FlushPendingDeleteRHIResources_GameThread();
216}
217
219 GEngine->PerformGarbageCollectionAndCleanupActors();
220#if WITH_EDITOR
221 FText TransResetText(FText::FromString("Clean up after Move actors to sublevels"));
222 if ( GEditor->Trans )
223 {
224 GEditor->Trans->Reset(TransResetText);
225 GEditor->Cleanse(true, true, TransResetText);
226 }
227#endif
228}
static const float OSMToCentimetersScaleFactor
DEFINE_LOG_CATEGORY(LogCarlaMapGenFunctionLibrary)
static void FlushRenderingCommandsInBlueprint()
static UStaticMesh * CreateMesh(const FProceduralCustomMesh &Data, const TArray< FProcMeshTangent > &ParamTangents, UMaterialInstance *MaterialInstance, FString MapName, FString FolderName, FName MeshName)
static void SetThreadToSleep(float seconds)
static FMeshDescription BuildMeshDescriptionFromData(const FProceduralCustomMesh &Data, const TArray< FProcMeshTangent > &ParamTangents, UMaterialInstance *MaterialInstance)
static FVector2D GetTransversemercProjection(float lat, float lon, float lat0, float lon0)
A definition of a Carla Mesh.
TArray< FVector2D > UV0